Last week, the 7DRL Challenge took place. It’s the same game jam that I’ve done three times previously, where game devs have 7 Days to make a RogueLike, a turn-based procedural roleplaying game with permadeath. One of the benefits of this jam is that you’re free to choose which seven days to take, as technically the jam ran from the 5th – 14th March, but you could start at any time as long as you finish at the end of the seventh day. Funnily enough, the past ones I’ve only done on even years (specifically 2016, 2018 and 2020), but I figured I’ll make an exception.
I decided to start the jam on Saturday morning, but I needed an idea. For the week before the jam started, the most I was thinking of doing was something in the realm of Smash TV or Robotron as a roguelike, I was struggling to get anything concrete. Then an idea hit me while, admittingly, I was listening to some sea shanties/acapellas on Youtube, a sea-based exploration and trading roguelike. The player would start out with a weak dingy and move their way up to a massive multi-sail ship through buying and selling items at ports, as well as making other ships surrender their supplies. It felt like a fun idea, so I went with it.
I have developed a mostly streamlined process for working on games in a jam enviroment, based on my previous experience. Coincidentally, I did a pechakucha talk for the local Midland Games Industry talks night:
To summarise, I often use this section that I routinely post during Ludum Dare:
Fortunately, I take advantage of 7DRL’s relaxed rules of pre-existing code and used a base template project that instantly provided me with a title screen menu with options and a blank state for gameplay, combined with some code for tile-based movement and tilemap features from my previous 7DRL entry, built in my own game framework that I’m very familiar with. That there is a good example of Know Your Tools!
Then was the first two rules, Gameplay First and Small Scope, which was what I wanted to focus for the first two days. I wrote myself a checklist of what I wanted in the game using comment blocks in my game’s code, there were three main things I wanted to focus on: Generating Land with ports to sail into, buying and selling stuff in those ports, and combatting other travelling ships.
First was the land generation, which I went on instinct and went with using FastNoise to generate a noise tilemap that I can then define which would be land and which would be ocean. I ultimately went with using a combination of Perlin and Simplex noise to get enough variation in the noise pattern, transformed it to have values between 0-63, and then through experimentation ended up with any tile with a value below 45 being sea and the rest of the values above could be a certain level of land.
The next challenge was to group each land tile into a group of them to make up an island, I ended up using a recursive depth-first search algorithm to go through each tile and all of their neighbouring tiles, using an array flag to avoid any tiles being checked twice, creating a box around each island so I could work out how many ports each island would need and avoid applying tiles to other islands by checking for overlaps.
For placing ports, I was admittingly lazy and decided to just randomly assign every beach tile (the lowest land tile ID) as a potential port and chose at random which one to use. In hindsight, this would cause scenarios where ports are right next to each other, or at least be close on the same island for easy back and forth. I think if I wanted to make choosing port locations more interesting, I might have use algorithms to determine suitable paths between islands near to each other, that way it would make sense for a port to be located close to a near, perhaps with A* path finding or delauney triangulation.
Despite this, I at least had a tilemap with islands separated out so I could start a ship on a random port, and then have it travel to other islands grid by grid. Since I had the data, I decided to make three more tilemaps to render on the sides and corners, setting their location depending on the ship’s location on the map. Combined with the game moving the player to the opposite end of the map if they go too far in one direction, and you have the illusion of a seamless map that wraps around.
Next were the ports and combat, both of which were menus. The port menu used mulitple switch cases, which I was foolish enough to use knowing that I also had my framework had its own Finite State Machine, which I would use with the combat menu. I ended up keeping the stock items (which players can buy and sell) in a separate array from upgrades (which you can only buy) so that stock could be easily increased and reduced in events such as trading and battles, while upgrades have a single purpose.
For battles, I had ships scattered randomly outside the player’s field of view, and those ships would only update when they were in view of the player in order to optimise for AI calculations. I actually had some fun with this, separating the ships into pirates and transport ships, and not only giving them different behaviour to give the generated world some life independent from the player: Pirate ships will always move towards the nearest ship, even if it isn’t the player. They can then engage against the other ship into battle, which means that other ships could sink without you being near them. Meanwhile, transport ships will aim to go to a port, and so will move along a generated path towards a random port.
By the Sunday evening, I had finished the base gameplay, with the most basic visual assets. Unfortunately, gameplay work never really finished because of balancing out the stats or both the player and other ships, not to mention tweaking the land generation. In the end, I’ll see what the reviews will say about how the game feels.
I normally do pixel art myself with piskell and photoshop. However, despite having seven days, the remaining five days were also working days, meaning I only had evenings. That meant I resorted to open source/creative commons art assets. The main ones that helped me were Kenny-NL’s pirate pack for the ship designs and qubodup on OpenGameArt for environment tilesets, with photoshop to aide me in giving the assets a bit more of my own style. I also made use of stock images for the port menu to give a visual aid. I think the only original artwork I actually did was the side view of the ships, the UI box border, and a secret boss. I remarked that I wouldn’t get high marks for graphics, but some of the other participants reassured me that it looks fine. Fortunately, 7DRL doesn’t merit how games look and sound.
So for sound effects, I used sound effect libraries from GDC audio packs and freesound, with the sound of oceans being ambient. However, with it being early 2021 with sea shanties being all the rage, I couldn’t help but make some basic renditions of my own. I didn’t go with any fancy samples and beats like I did with Twist, Turn, Shoot, Burn, just some basic NES chiptune using soundfonts. Of course one of the renditions had to be the Wellerman, since that one blew up on TikTok, but I also know a couple others so I also did renditions of “Leave Her Johnny” and “Bully in the Alley” as well.
What went wrong?
I really should have taken five days off to get the most out of this jam, doing five evenings from 5pm to 11pm (and Saturday 2am) is really tiring and you end up struggling with even the basic tweaks. I already mentioned the placement of sea ports, and how the sea port menu used switch cases when the combat menu used a finite state machine. I also ended up missing out on features that could add to the challenge, like a content weight limit (you can buy infinite amount of stock to sell).
Being better rested and prepared would have also helped me with submitting the game. Word of advice, never use Windows Explorer to set up a .zip folder. I don’t know why, but if you ever try to update a file within a .zip folder, Windows Explorer corrupts it. The best recommendation is to use 7zip or WinRAR instead.
In the end, I’m pretty proud of this game. It feels a lot more complex than KALQL8TR and yet just as novel, I might do a post-jam build some time this week to see if I can fix that menu and sort out the ports and whatever improvements I think I could make, but for now, I hope people enjoy it.