So, now that Devtober is over, it's time to summarize what I've learned. And to be honest, I didn't learn much during Devtober, except maybe for these two points:
- Working on the game until 1am, going to bed and waking up at 6:30am to go to work is actually a manageable schedule.
- Even if you have a playable demo that doesn't require install and you post daily updates, nobody will care about your game regardless. Your game has to be either extraordinary or you should also do something else to promote what you're doing.
However, I learned a lot during the development of the game, which started back in September 2018, back when it was just a WebGL engine. And yes, this is also a postmortem for the entire game, since I've reached a point, where not even I like the way it's turning out, due to the reasons I'll discuss further.
What went wrong:
- Gameplay. My main idea for the gameplay, besides the obvious "kill everyone, don't die, but new weapons" was to make the player do tactical decisions, by selecting correct weapons to deal with different enemies. Tuns out that when you have enemies approaching you from all sides, the best weapon is the one that can output most damage. Yeah, sounds random, right?! Although I think I could actually make it work out, if I rebalanced the weapons, decreased their prices, made the enemies tougher and overall gameplay slower, like in Sunless Skies.
- Inheritance. This is the main reason I'm abandoning TDS, it made the architecture of the game trash. Just don't use inheritance, believe me. Use components, instead.
What went right:
- Components. I first started using them when I started implementing different kind of bullets(i.e: bullets, that bounce from walls, bullets, that explode with shards upon hitting ships, etc.) and first I used subclasses of the main class Bullet, until I realized that if I want to be able to combine those different kinds, I'll have to incapsulate them into separate instances and contain them inside of Bullet. In other words, I reinvented the "Composition over inheritance" principle. And after that I never went back to subclassing. Adding a bullet with new behaviour required just to create a new component and attach it to it.
- Weapons. I wanted a flexible system, that would let me create all kinds of bizarre firing patterns, but I couldn't come with anything. beside the fact, that the weapon class should have three main methods: startFire(), stopFire(), update(time: Float) and that the overall firing pattern should consists of several subpatterns, each of which contained bullet positions, velocities, variations in position, variation in velocity length, variation in velocity angle, but defining all of that manually would be too much. I googled "bullet hell pattern implementation", but that didn't bring anything. Eventually, I came up with a builder class for patterns, that used somewhat of a fluent interface, which would allow the user add new bullets to subpatterns, transform and duplicate them. And it turned out to work pretty well, look for example at the definition of heavy machine gun, its shooting pattern consists of three subpatterns(which are named sequences), with 5 bullets each, that would mean I'd have to provide definitions for 15 bullets if I did it without the builder, and I'm not even talking about diamond boss'es rainbow gun, which fires 72 bullets with different velocities and colors:
What went kind of mixed:
- Vector graphics. On one hand, they did look stylish in my opinion, and similar to graphics of Geometry Wars and old school video games, such as Asteroids or Tempest, which was my goal, but the lines turned out to be aliased, which was the consequence of rendering to framebuffer, which is required, if you want to apply post-processing effects, such as bloom. I looked into antialiasing algorithms, but they seemed to be mostly suited for textured surfaces, which is unsurprising, since algorithms for antialiasing lines(e.g.: Xiaolin Wu's algorithm) just draw smooth lines from the very beginning.
- Editor. I had to implement an editor for vector graphics of my own, since there wasn't really anything that suited my needs, and it did turn out to be much better, than typing in the coordinates of line endpoints manually, however, it also suffered from many flaws, and there were many times, when I had to edit the resulting JSON by hand. Main issue, in my opinion, was that I decided to use canvas to draw the shapes, instead of svg. With svg I could easily use some MVVM framework and just bind the locations of points to data in the view model, and not have to re-render the canvas every time some major change was made.
- Physics. Implementing a physics engine of my own was something that I always wanted to do ever since I decided to become a game developer. And I mostly succeeded at it. I represented collision volumes as sets of circles, and used a uniform grid for broad-phase collision detection. So, detecting the collision was trivial so far. What wasn't trivial, though, was resolving them. For that, I'd have to find the circles, that collided first, and I didn't find an efficient way to do that, so I had to use a hack, and use collision boxes formed by those circles instead, which was inaccurate and at times looked odd. Next time I'll just use someone else's physics engine.
- Turns out, developing engines is more fun, than developing games!
Well, I'm not abandoning TDS completely. Yet. I still have some features and bug fixes planned, like adding a money display, rebalancing a couple of enemies and weapons, changing some waves, maybe adding some new weapons and enemies, but that'll be it. I;m not planning to polish this game to the state of a finished product or to add sounds.
Leave a comment
Log in with itch.io to leave a comment.