Milestone #2 - Map Screens, Game Jams & Level ProgressionHello again!
I've managed to trim my updates down from four months to two. Hopefully one of the new ways I'll be mixing up development this year. For Milestone #2, my goal was to focus more on the game side of the project by implementing one large feature, and several smaller ones. I did also end up doing some engine work which we'll get to shortly.
Unique Level Spawns
One of the features I implemented in Milestone #1 was the neat wipe transition as the player went between levels. I followed this up by setting up unique spawn points in each level, meaning that the player can walk between rooms and return where you would logically expect them to.
As part of this, I split the player platforming script into two parts. The 'Platforming Component' which handles the actual movement and physics of the player, and a 'Player Input Component', which is responsible for getting player inputs and passing them through to the 'Platforming Component'. I did this so I could also create a third 'Auto Input Component', which can be used for cut scene behaviour. You can see it for the small walk the player does from off screen as they enter a level. After a second we return control to the player. This was done primarily to stop the player from accidentally catching the level exit trigger and returning to the previous room.
In implementing this new functionality I also introduced a new piece of engine functionality I called 'Scene Load Parameters', essentially allowing me to pass in any type of data (using the XML system I created in Milestone #1), and have specific components check for that data on a level load. In this example, I pass in the spawn point I want the player to start at.
Screen Shake
Another small feature I implemented was a screen shake component. In this example I've mapped it to the jump button. I'm not 100% sure how I'll use it in the finished game, but I think it'll be useful in adding some visual flair.
Map Screen
The big gameplay feature for this milestone was the map screen. As the size of the game world increases I think it will become a useful tool. This feature was split into 3 main sections:
First, I wanted to create a tool to automatically map out the levels for me.
Second, I wanted a visual indicator that showed which parts of a level the player had been to. I was fascinated with the idea of the map filling in, with my hope being that player will be encouraged to revisit areas where their map has got obvious gaps.
Third, I needed to render all this information during gameplay, and add some visual polish.
This first screenshot shows my initial implementation of the map. I'd decided early on that I wanted a tool to map out the levels for me. This was so I could make quick changes to levels through out development and not have to worry about updating a map texture. I used the 'Scene Load Parameters' feature mentioned above to regenerate the map when I used the game's debug level select. In essence, the tool checks all the collision data for the level and stores it in a grid dependent on object type. As the game is grid based, each cell in the grid will only ever contain one type of object.
Next I scan the empty space in the level, starting from each player spawn point. I do this so I can map the 'player accessible' parts of the level, this is the data I will use to fill in the map later. This is done with some simple recursion checks on a grid cell, followed by it's neighbors, stopping if I hit a solid object (i.e. a wall). Once I have the data for the map, I trim the edges so that the grid only contains areas the camera will see. There's a lot of off screen walls / objects that I don't want to the map to show but need to be there to stop of the player going out of bounds .etc. The map data can then be saved.
I created a series of "Box Tools" that I use for map compression. Given a series of box, the tools are designed to produce the smallest amount of boxes that fill the same space. For example, if I have eight 1x1 boxes sat next to each other, the tool will generate a single 1x8 box instead. For map generation, I run this tool over the entire map grid, crunching down each individual grid cell into a larger box depending on it's type (i.e. Solid, Player Accessible .etc). This can then be saved out to a resource file, which will be loaded into the game on startup.
An example of how the box tool works can be seen above. This is a debug view of my map filling idea. For this, I pass in a box the size of the camera's view, every time the camera moves. You can see how the tool tries to compress the odd shapes I am able to make, with each coloured box representing the largest shape that would fill that space. I was really happy with how this turned out.
Once I was happy that the tool worked, I started to assemble the final render. I implemented some quality of life features, such as having the player's position be rendered, as well as having the map recenter on the player when you open it. I also added the ability to move the map by pressing a button. Finally I added a percentage in the corner of the screen which will tell the player how much of the current level they have visited. As someone who enjoys 100% completing games, I felt this feature would be appreciated.
For some visual police, I added an icon which changes colour depending on whether you are moving the map or the player, and a glitch effect which I feel gives the map a bit of life when it is on screen. The current version of the map unlocks areas as you enter it however I may introduce the ability to unlock areas of the map early by finding collectibles.
After completing the map screen, I took a small creative break from the game to enter the GMTK 2020 Game Jam. The theme was 'Out Of Control', so I made a game called Riotous Railway. I figured the jam would be a good way to test the versatility of my engine, and I was pleasantly surprised how easy it was to prototype gameplay features. You can play the game here:
https://robo_chiz.itch.io/riotous-railway. For Milestone #3, my plan is to do a mixture of engine and gameplay features and I also plan to update this devlog more frequently. I'm hoping that doing this will be easier than trying to do a big summary at the end of each milestone.
Thanks for reading.