
//SHIFT/haxe is an overhead shooter with vector-style graphics, where you can shift between various shapes to destroy waves of enemies. The game contains many procedural elements, including enemy bosses.
It was developed solo in 48 hours for LD35 using C#, Mongame, and SFXR.
Click on the image, or here to play and rate.
This post will be a postmortem of the development of the game. I am very verbose, so everything is hidden below the fold.
Theme
Looking back over the last 5 LDs, I’ve only had a strong vision for a theme once. I’ll have a few strong ideas for other finalist themes, but then really have to stretch once one is picked. I didn’t have a hard time coming up with ideas for shapeshift, I just had a difficult time finding something I really wanted to make. A few other final themes sparked some ideas I was excited for, but this theme just left me cold. I was sorely tempted to ditch it entirely, but stuck to it because I can always revisit those later.
The final gameplay is very similar to what I envisioned. I did imagine there would be an overworld connecting various “servers” with multiple arenas that would have a boss that unlocked a new shape, but I dropped the overworld portion fairly quickly to keep scope down. I wasn’t really intending for it to be as much of a bullet-hell shooter as it can be, but I’m not sure what I would have done differently to change that.
I designed the gameplay and art style first, knowing what I have worked on in the past. From there, that are style really dictated the digital-computer setting.

Development
I hedged my bets in design to design a game that could leverage the things I had done for LD 33. I had come up with a rendering and collision system. I reasoned that I would be able to leverage that code for an overhead shooter.
The art style in that game was a simple fake-3d overhead perspective. Using a series of 2d rotated image layers offset to give the illusion of 3d makes it very easy to import a new object with a high quality 3d appearance. I had also created a circular collision system on that game meant to limit the number of collision checks between objects.
As it turns out, I reused maybe a dozen lines of code. The player and enemy ships didn’t benefit from the 3d, but it meant I could still get some nice 3d looking effects fairly easily. That only took about 3 lines of very simple code, and a little bit of overhead throughout. I never needed to implement the whole collision system, and a little profiling makes me think I over-engineered it back then.
I started by creating arenas, and specifically drawing the arena walls. I knew I wanted arenas with shape, and while I could have hand placed where each line was drawn, I really wanted to automate the process so I could have variety. Weirdly that code was some of the more complicated and time consuming on the project. Basically the code iterates around a grid of solid and walkable cells that defines the shape. When it hits a wall, it steps around the edge and builds a list of corners. It tracks every edge it steps over in the process so it doesn’t build multiple overlapping walls. Having a system like that allowed me to later add many arenas fairly quickly and I leveraged the code for the end of level teleporter effect.

Next up was the camera. It’s easy to overlook the camera in LD because it’s subtle and it isn’t obvious what a good camera adds to the game. A locked overhead perspective with the player at the center doesn’t feel great in an enclosed space. Especially with bullets that don’t have a max range, it would have felt like a lot of the screen was going to waste. I also didn’t want a locked view that fills the screen, since that would make the arenas feel small. The game projects a point a certain distance in front of the player towards the mouse and centers the view around that. That doesn’t work great around the edges, so I constrained that centering point to keep more of the arena on screen at the edges.
On Saturday I started making enemies. I didn’t really have a specific plan, I just wanted to make sure there was a good variety. Just changing the enemy sprite didn’t feel like it was enough. I wanted to make sure they each behaved differently. Enemies and the player share some base movement, firing, and rotation code. On top of that, enemies make a movement and firing plan via something like a frame-step co-routine. While that executes, each frame they are just constrained by the world’s physics to make sure they keep a reasonable speed check for collisions. When that plan completes they create a new movement plan with a little randomness. Each enemy AI is fairly simple, but the unique behavior adds a lot of depth. The circle moves towards the player on the X or Y axis. The arrow slowly turns to face the player and then fires and rushes in. The W shape strafes left or right and fires 4 bullets at a time. The big green one moves on the X or Y axis randomly, slowly turns to the player, and fires a stream of bullets.
Level variety was important to me, so I planned ahead with things like the dynamic wall construction so that I could slot in multiple maps with minimal overhead. I originally considered procedurally generating levels, but I was worried that the levels would feel very strange or sometimes be impossible. I also considered a level editor, but the maps were simple enough that that felt like overkill. Instead I built an importer that opened all the images stored in a specific folder. It read the images pixel by pixel, and built the collision grid from that. Certain colors on the image translated to map features. I’d experimented with something similar a few months back in a very limited fashion. I think this worked out very well technically, though my level design wasn’t great on a few of the maps.
Procedural Boss Generation
At that point I had most of the trappings of a game, but it needed a feature to really stand out. Just fighting waves of enemies felt too repetitive. I had been toying around with the idea of bosses, but I wasn’t sure if I could pull it off. I started in seriously late on Saturday. The idea was that I could create one master enemy that created a set of enemies that it would control. First, the boss decided randomly whether it was primarily wide or tall, then it determined whether it would be symmetrical left to right and/or front to back. With those variables, it created a virtual grid around the center piece at 0,0. Then it picked either a row or a column and appended a piece to either end of that row or column. If it is symmetrical, it adds pieces to mirror the placed piece. Each piece it adds has a different frequency and difficulty cost, and it stops when it places enough pieces to meet a difficulty threshold.

Once the boss is created, the single boss center piece controls the behavior and total HP. All of the sub-pieces just try to stay in formation and fire occasionally / on command. When the boss is created it also sets a few attributes based on difficulty and randomness. It picks a max speed, and determines what behaviors it will follow (using the same basic enemy co-routine framework). If the boss is wide it tends to strafe more, and if it’s tall it tends to charge more. After a few levels it occasionally stops and fires all weapons or teleports around the map. The results are fairly satisfying. Sometimes you get a real dumb looking boss, but sometimes you get something really awesome. The emergent behavior that comes from the boss trying to move around obstacles is also pretty cool, and (unintentionally) fits the theme well.
Scheduling this project was a bit interesting. The game is fairly safe and well established territory, and there was very little chance of not having a complete-feeling game at the end. As opposed to dedicating Sunday to polish, I polished as I went and triaged features up until the last hour. I constantly asked myself what is the most important feature I could add. That meant some key elements were postponed until late, but that let me be very flexible. For example, the menu to change your shapes out was added late, because I knew I could hard code the shapes to keys if needed. I could instead prioritize the boss system, which is something I would have been very afraid to add late, but turned out to be the highlight of the game.
Audio
I started creating sound effects with SFXR and wiring them in on Sunday, only to discover that the sound system was silently failing. I hadn’t worked on any game audio since I got this computer, and hadn’t tried playing sound during warm-up. Whoops. There wasn’t an obvious fix, so I just cut audio all together and worked on other things. After some other cleanup and polish I circled back because it was too important to the game. I still don’t know why it’s not playing, but I swapped out the monogame audio pipeline for the windows media one built into .Net. It’s really meant more for playing things like application alert sounds and beeps though, not game audio. It has a lot of issues, but it’s key feature is actually working. I wanted to include music in game as well, but just am not confident enough in my music making skills.

What went well
Procedural boss generation turned out way better than expected. You get some wacky bosses, and they’re fun and feel different. If I had known how well that would have turned out, I would have made this a boss rush game.
Enemies were easily identifiable, felt unique, and worked well together to create challenging scenarios.
Could have gone better
I mentioned audio already – I should have tested that during the warm-up
The upgrade system isn’t great. It doesn’t really keep up with the difficulty ramp up, several of the shapes aren’t very useful.
The only reason to not just hold down the trigger is to quiet the sound effect. I was debating healing by not firing, but was worried that would slow down the game.
The gamepad doesn’t work on the weapon configuration screen. I just couldn’t think of a simple way to implement it in time.
Not enough balance time. There were some tiny tweaks that would have been great if I had done more testing.
- I scaled back enemy HP, but enemies still feel bullet-spongy.
- The red enemy is a little frustrating because of the bullet lag – I should have made them continue in the same direction until they hit a wall instead of strafing randomly so you could better predict their movement
- Game ramps up difficulty a little too fast – I doubt many people will unlock all the weapons.
- The flamethrower mode needed longer range to be useful
- The shield mode should have lasted until the shield wore out instead of using a timer
- The little enemies are more of a threat than the bosses – I should have put in a spawn cap for the enemies that spawn in during boss levels and tapered off the normal level spawns more.
- Several levels are just bad. The maze-like normal level and the wide boss level are probably the worst. Without better obstacle avoidance and pathfinding, enemies get stuck in corners and can’t reach the player. Also, the exit placement should probably have always been in the center so you don’t need to truck across the board for it.
- Continue button should have probably been relabeled to better fit the theme.
Future plans
I don’t think I’m going to polish this up and ship it on some platform, but I’m on the fence on that. I do see a lot of potential in expanding it as a boss rush game, but I’m not sure what I’d want the upgrade system to look like. I won’t really touch it until after the voting period, so I can sit on that.