First game jam, and first time writing about it. So this article is less organized, and lengthier as I feel out how, and what to write on these things. I’ll have the art assets I made interspersed to break it up a bit.
Though this was for a 2 week game jam, I had a number of practical limitations on my time so it was closer to 1 week. I was visiting my family during this time, so time was spent with them, and also helping when one of them got a serious flu.
Design stayed largely the same as the original concept. The main area I fleshed out more as I went was in how the movement, and attacks would work. For simplicity, and ease of programming, movement was kept to 1 space to begin with. Ships would be able to turn by 1 hex, and make 1 move per turn, while aircraft would be able to turn by 2 hexes, and/or move twice per turn. Initially I was thinking to differentiate the two navies through their movement options by making 1 side move faster.
This got cut along with a shift in perspective on design as I did paper prototyping. Greater movement distances meant either a much larger game grid, or more limited gameplay. The first option sounded bad for readability. Projectiles being proportionately much smaller (assuming still occupying 1 hex) made it harder to see at a glance where things were going, and where danger was. It also meant ships would also be smaller, or would have to be longer. 2-hex-long ships worked fine while turning, because the back of the ship could always logically move to the space previously occupied by the front. But this simple, and intuitive logic falls apart when you get into 3+ hex-length ships. And if the game was completed still requiring each moved hex be assigned individually, this would become very tedious.
So the larger grid was out. Default movement of 1 for all ships was in. For future design I tried stick to this design directive that moves should not feel repetitive. This would result in adding an automatic move to all units. This way if you do not specifically want to order a unit to change course, or attack, you can end your turn without having to input an order for every unit. It works well with the premise. So by default the ships, and aircraft will continue on their paths.
To differentiate the navies I planned to use their attacks instead. I set on early that the Japanese attack plane would drop a torpedo, while the American would need to get closer but attack directly with bombs. But differentiating the ships was harder. The initial plan was to have Japanese destroyers fire torpedoes in a forward arc, and battleship fire in a straight line perpendicular to its path (a diagonal across points of the hexes).
The Americans went through a lot of iterations on possible differences. The destroyers were originally going to have short range guns in a wide arc, but this created a bad kind of asymmetry in my goal of the two navies creating danger for each other. The Japanese destroyers would be lobbing torpedoes across the map, but the short destroyer guns would likely never endanger the Japanese given the size of the kaiju. But if the guns were long range, then they felt too powerful, and too similar to the battleship. The US battleship I aimed to make potentially hit harder, but require more planning, inspired by their use in the war for heavy bombardments of islands. I quickly came to the idea that the US ship could potentially hit twice, but ‘fired’ at the beginning of its turn, not the end. That way there was more planning, and less direct control in what was in its firing arc. The main ideas for that possible arc were:
– still a single line, but hit whatever was in it twice
– use another firing line parallel to the original perpendicular one (problems with executing this on a hex grid)
– two, widely splayed lines angled forward and back from the side of the ship
There were also plans to make the maneuvering options of the airplanes different for each navy. But due to time constraints, many of these uncertainties were never resolved.
The kaiju attacks on the other hand got pretty fleshed out. Each would consist of a series of frames. Each would have at least 3 essential frames:
– 1 – wind up – indicates an attack is coming, and visually communicates roughly what type of movement to expect, may last multiple turns
– 2 – highlight – additional effects are added to the water to give a more specific idea of what is about to be attacked, this frame immediately precedes the attack, and likely only lasts 1 turn
– 3 – strike – the lunge, or equivalent where the kaiju suddenly occupies its new space, and waves are launched out
This framework would ensure that attacks were readable even before a player had learned specific attack patterns, and timings for themselves. It was very important to me that while players may need to learn by failing, they never felt like they got killed out of nowhere by something they couldn’t see coming. This was especially important given the size of the kaiju, and limited nature of the unit movement. Something as simple as the kaiju moving its neck (and thus hitbox) 1 hex backwards without warning could create intensely frustrating experiences.
On this note, I resolved to keep the hitbox of the kaiju as minimal as possible. So I settled on a less Godzilla-y design where most of the beast was visible, but submerged. This way only the above-water head, and neck would require collision. The rest of the body could coil in complex ways during wind ups without causing problems.
Creating the code structure for the hex grid was conceptually straight-forward as expected. But it also ended up being pretty time consuming when building in all the additional functionality needed for other classes to make use of, and implementing all portions of it between the engine, UI, and controls. In short it’s set up as a 2D array with methods built in to account for diagonal relations, and dealing with whether a row is inset or outset. For handling mouse input I found a nice explanation of checking a hex against a point at [PUT THE LINK HERE]. And adapted it so that if the point was outside the hex it would attempt (confirming the new coordinate was in bounds) to shift the selection in the appropriate diagonal.
The grid also had a nice variety of supporting methods based around an enum for directions (6 matching adjacency for a hex). Things like projecting from a coordinate in a direction to return the new coordinate, treating the directions as orientation for translation to vectors, and for passing 2 directions (1 as a base direction, and the other meant as a rotation) to return a relative output orientation.
This was especially handy for managing the unit movement, and attacking. Relative move options could be stored as a list of directions (treated as relative rotations) for each unit. Attack options could use directions as well, one for the direction of the projectile to fire, and a list of directions saved where the projectile would originate.
I was planning to, but didn’t have time to implement this list for the movement options as well. I had the system in place to translate the list of directions to another coordinate. This allowed the waves launched by the kaiju to appear at a distance from the unit’s origin coordinate without needing to be in a straight line (by way of the hex directions). This was also used for keeping track of a unit’s hitboxes, which amounted to managing additional links back to the unit in each other hex that it occupied.
For most units the coordinate, and linked coordinate were all that would be used for collision detection. But for the kaiju boss creature I wanted it to have specific weak spots without needing to take up so much space that I could use entire hexes as the weak spot. So the weak spot on the neck also checks for the direction of an incoming collision relative to the kaiju’s orientation. It registers the collision either way, but only damages the kaiju if angled from the rear.
The last major system was the kaiju attack patterns. Given all the work I did on fleshing out the previous systems, I made very fast progress here. I was storing these attack sequences as collections of directions to hitbox coordinates, a list of projectile attacks to initiate, orientation, and how far to move along it.
I also made a lot of progress on implementing other ship types, and most of the systems were in place for aircraft as well.
The last work described above was getting into the final day though. Running up on the deadline I had to make a lot of cuts at the last minute. I ended up only including destroyers for both navies, and using idential attack patterns. The much tougher part was figuring out how to make it a game without completing the kaiju attack sequences. But I quickly found a solution that required vastly less work, and risks. So the kaiju would only use its 1 sprite, and I would have it regularly attack in a set pattern of only waves every couple turns. Even so it felt way too static, and uninteresting for it to sit in the centre the whole time. So its recurring cycle of actions also included moving. So that the player could anticipate the move, and the attacks that followed I added a 3rd step to the cycle where the kaiju rotated to a random new direction, and paused.
I’m really proud to have some level of finished product given this was my first game jam, I took on an ambitious challenge, and the circumstances of how my work went. That said, it was a mess (as all game jams tend to be) worth learning from.
Consciously I already knew the importance of making things playable early, and of tempering scope. But this exercise made it clear what I still have to internalize in how those are applied in a practical setting with extremely tight deadlines. Most importantly, my final product should have been my goal from the beginning. It’s fine to have the other stuff visualized, and planned, but it was a mistake to shoot for that broader vision as a base product. Rather I should have been thinking in the context of deliverables. Similarly I should have placed a greater emphasis on prioritizing easy to complete elements with a high return on value to the player. I had an easy system already planned for how to add visual wake effects following each ship, which would have made the game a lot more visually engaging.
Setting aside what goals were set, how I approached my goal worked extremely well. Taking the time to implement systems properly, and carefully really paid off. I was much closer to my mechanical goals than I had any right to be. This was because of all the work I did to flesh out the underlying systems as I implemented them. I was much sloppier out of necessity in the final bit of crunch, but this was only possible because of what came before.
The big pivot going into the end I mentioned was a mere ~3 hours before the deadline. I should have considered it sooner, but I’m proud of what I was able to do in that short time thanks to quick thinking, effective cutting of features, and a solid foundation of code, design, and planning to pull from.