Crawler's Den is a demo I made for the Summer Games Tournament this year. You can grab it here. This blog I'd like to share my reflections on developing the project on LEX2 and Leadwerks in general.
When I started the project, my template had no animation manger, and the puppeteer system was just coming online. The goal was to recreate the AI and Events map and write the entire thing in C++. Not only to test the puppeteer system and my ideas on how to link said puppeteers to the flowgraph, but I would have classes to derive from when I start working on Vectronic again.
Right now, LEX2 is a template that gets installed in the Templates folder of the Leadwerks App Directory. However, upon creating a template, I noticed that the project and sources didn't seem to copy over as they did in testing. I think it has to do with the project manager's date based system as I was on the beta branch when I started. So fixing my project was no biggie, but not something I'd like to ship out.
The player was the first thing to get coded as I wrote about here. I based my player code of the Source engine's player because I really like how that feels. It wasn't long until I had a player that can walk, jump, crouch, and use/pickup objects. Neat! I'm really happy how it turned out. There are some improvements I thought I can make, but it was drawing close to the deadline so it has to wait.
The animation system was next. Without it, no gun and no crawlers. I started transferring code line by line but I didn't understand how to convert for inpairs loops to C++. This is when CrazyCarpet got involved as he was very willing to help as he needed an animation system for his stuff too. It took a few days to iron out, and minus slight problems I'm having, it works pretty much the same as it's lua variant. You can read the topic here about it which includes a link to the final code on Aggror's Wiki.
Now having the animation system in place, the weapon was next. I first translated the FPSGun script from 3.2 as it was a lot simpler and it was something to get started. I later added bullets, and allowance of different weapon types although the project would just need a pistol.
The crawler was something I put on the backburner as I never did AI in Leadwerks before. I was aware of the functions, but never needed to use them. This was my first project where I needed to use the navmesh system too. I did level design next because I really wanted to start mapping.
I needed to start from scratch with the map. The AI and Events map used meters instead of centimeters so nothing lined up with the grid anymore. there was once an option to switch between the two measurements, but I guess Josh took it out, or it's under legacy features. Ether way, I wanted to use centimeters. I shelled the map out by eye and feel, I hardly went back to the source material as that would require switching the project and such. I had the map mostly shelled out before I started to work on textures.
I usually use Paint.Net for raster artwork, but I decided for this project to use an older version of Photoshop. Not only because it's "what the pros use" but I want to use a file format that could be readable in other software. PSDs can be read by gimp so if there comes a day in which I'm making games on a non-windows machine, I can still open psds. I should learn how to use gimp and ditch Paint.net as PDN is Windows only. But I wanted to make a game, not learn new software.
Now that I know how to properly port in models from blender, I had a lot of fun modeling for my scene. Making support beams, trims vents, and such was really fun, and everything got imported correctly. I had the best luck using FBX ASCII 6.2 versus the Binary 7.4 option, and Applying scale made sure that everything was sized correctly with a default scale setting as 1,1,1 like it should be. I couldn't remodel everything, I just remodeled things that wouldn't connect together right due to the measurement change. There was some old models I just used the model editors scale tool.
While building my level was really fun, optimizing was the exact opposite. I limited my shadows, optimized my prop settings, made lights smaller, and collapsed a lot of modular pieces together and with my 750Ti, I get 90fps in the first room and 70ish in the showdown room. One thing I always thought was a good idea was to develop on medium range hardware. If you were to develop on lets say a 980Ti, you could get away with a few more expenses, but throw it on an older card, and it might chug, Develop on a mid-range card, and it'll play fine on that, better on newer and powerful hardware. I was cutting batches and polys like crazy but I couldn't get to a point where the entire scene was 100fps. I've added a wireframe view mode to my console options to see what was being drawn that shouldn't in which made me develop a portal volume that could hide, or show all the objects in it's volume while ignoring collapsed brushes.
I eventually ditched the portal volumes because of a bug that I didn't feel like fixing, and I only saw 5 more frames in the end which wasn't worth the flowgraph mess I had to do. If I could get it to be automatic and fix that bug, I might re-add it.
There was a time when I sent the project to CrazyCarpet to debug something and this is when I learned that my theory about developing on mid-range hardware was correct. He reported 100-120+ frames on his 980, and for some reason was getting better results on his 750. My PC is no spring chicken, but he was getting 100 frames all round on a 750, meanwhile I drop to 70 on my 750Ti?
While I'm really happy that my pain and suffering resulted in better performance on newer hardware, it'd be great if I could have those results on my end.
The deadline was drawing near, and it was time to do the crawler, and a few other classes. By this time, I've developed and successfully created a way for my puppeteer class to communicate with the flowgraph. In short, each puppeteer has it's own lua script in which you can set the values and write the inputs and outputs to the class. Inputs are handled through a message system while outputs are fired by the entitles component class. I'd have to write another blog on how it works but I'm sure weeks after I do, there might be an official way to link C++ classes to your game and the flowgraph. So I played with that converting more scripts to C++. Then it came time for the crawler.
The crawler was a bit more difficult, and this is when I noticed an issue with the animation manager. It wasn't playing looping animations correctly. A quick line comment of --n fixed this, but to this day there is a problem in which it has a hard time going from attacking to running. It defaults back to it's idle animation and then glides around. Might be my monster code, but I was going on the last few days and the map wasn't done yet.
I was using the beta branch for a while, then Josh pushed a broken build which put me back on 4.1. I noticed the editor runs more smoothly on the default branch than the beta branch. I would think that this has to do with a debug settings or garbage collection that's enabled when Josh does development and only turns it off during prime time. But then, the beta branch was "fixed" so I jumped to that while keeping my game on 4.1 (I archive releases). I noticed a bug with the probes, and my map got corrupted on it. Thankfully I made a backup, so I didn't lose everything. I went back to the speedy stable release, finished my map and went to upload it.
Uploading is always a chore on my connection. I really hate when I spend hours uploading something and then after all that it fails to upload due to some error. This is why the Vectronic Demo is out of date on the game launcher, and why Crawler's Den is only on my dropbox right now. I should have used my mobile data, but I didn't for some reason.
Ether way, besides a few small bugs, the project is out and playable using LEX2. Here is a summary of working with it.
- No worry about back end stuff, besides somethings I needed to improve thanks to this project, I didn't have to spend a week writing window, context or world code.
- Console was a god send allowing me to easily debug my map in-game. Loading whatever map I want without the editor or hard coding was pretty dope.
- Once they were done, the puppeteers are really neat to work with. They are set up like lua scripts, and all the hooking is done in the base class.
- The precaching and Asset Manager worked amazingly well. No more slowdowns on loading models in real time, and no crashes because you mistyped the path. Really handy!
- I made a volume class for triggers and such. Works way better than collision based ones.
- Project's don't copy right with the project manager. Again, might be the date based system.
- The input system isn't done. It uses SDL for it's input handling and there is a bug in which all inputs must be done in UpdateWorld. CrazyCarpet said he'll look at this so we can correctly place movement inputs in UpdatePhysics.
- I feel as though Puppeteers should be called actors. They are called puppeteers because there was a class called Actor which was the actual entity doing the actions instead of a separate class controlling the entity.
- A lot of commented out code. I need to delete some things I've commented out months ago.
- It was kind of a pain to make sure the core code was synced up with the base project, the game project and the git repo. I want it so that all games off of LEX2 use the same Core files.
- Some reason I couldn't derive from my volume triggers....
I have an idea for this going forward but I don't want to express it just yet. No matter how I go forward, the foundation is here to stay. It might get cleaned up, maybe edited a lot, but I don't see a need for a rewrite, it's all solid.
Thank you for reading this, I hope you have fun with Crawler's Den!