WarpSpeed is the game I've wanted to make since last year, and its the reason I started learning Godot. The basic idea was to theme a rhythm game around the idea of Warp Jumping in scifi. Specifically I love how BattleStar Galactica does its warp drive design where you have to calculate the coordinates to which you're jumping, and since its a calculation done by individuls there is inaccuracy as a built in risk. The inaccuracy can be catastrophic when you jump into a space already occupied with something else, like a planet or another ship. The vibe is similar to how jumping works for the Faraway tree in From too, where you can teleport into another object.
Here what that would look like is you are a ship pilot making N jumps from planet A to planet B. The number of jumps is dependent on the distance between these points and your ships jump distance capability. When you jump, you will have a brief glimpse of where your ship is preparing to land, and in this split second you can correct the course of your ship. This could mean correcting your ship away from landing on an asteroid, to correcting your ship to intentionally land on a resource or treasure. The time you have to correct your ship's course is determined on your ship's jump drive, giving you N beats of a song to correct your course. The probability of your ship landing on a "postivive" space over a "bad" or "neutral" space would be determined by the quality of your ship's computer.
Since you have N beats to correct your ships course, and you can do it on any of the N beats, not just the last beat, the game would feel more like aimlab where you have to click quickly and accuractely, with the main difficulty of the game being quick decision making. EX: Do i want to land on a treasure, or just click on the first empty space i can find given my ship's current damage.
This project is large and will take a long time to balance, so I am no where near completion, but after ~1.5 months I'm near the end of at least making a playable demo. This is only possible because my friend is helping me with the art, and I'm using the music from my friend ElectricDad who you can find on soundcloud here
The rest of this blog post will show how the game as evolved over time, and talk about whats left, but first here is a screenshot of where we're currently at:
I started the project's dev by getting the element grid going. I had made GravityTheGame - Remastered with the intention of reusing its grid logic here, so it didn't take too long to get something basic up with art that i made on Pixquare
After having the grid visible it was easy to "jump" to a new random grid on a timer:
There still weren't too many complexities to work out here since all I was doing was spawning NxM Sprite2D nodes ontop of a TextureRect. The only interesting thought I kept in mind here is whether I should eventually replace the Sprite2d notes with texture rects since I'm not using any of the physics/collision logic for the nodes at any point. As of today 1.5 months later I still haven't changed that, but the question remains.
The next step wast to "jump" to a beat rather than on a timer. For this I tossed in Milky Words" by "Butterclock" as temporary music to develop with, and implemented a basic audio orchestrator.
Much of the idea behind the music controller i made here game from this video:
The basic idea was to (1) determine the bpm for the song (2) determine the ms time for an elapsed beat (3) emit a signal whenever that amount of time has elapsed. The jump runner scene would connect to that signal and determine if sufficient beats had passed to trigger another jump. As beats elapse, we would also update the UI to indicate how many beats were remaining.
Now that a basic set of jumps was implemented, referred to across my project as a Jump Run, I could move on to creating a skeleton for the rest of the game. The first thing I wanted to add was a constellation map that would represent the planets you could jump between.
This was easy to implement in a basic form. Each planet would be represented by some node, here a Button, and later a StaticBody2D. I would define the planets and their connections as a directed graph, and then traverse that graph to build a representation of these nodes in "layers"/"columns". The constellations would be spaced evenly from eachother within their column, and each column would have a fixed padding between them. To begin, moving the constellation map was restricted along the X axis, so that you could only drag left and right. At this point when you clicked on a planet, a jump run would be calculated and launched.
With the basics in place I told my artist friend who would be making the project with me that I had enough in place to start adding some assets from them so that we could start fleshing out a more specific form to the game. For the project in general I thought a good mental model would be to flesh out broad strokes to better picture the game, refine components, and reiterate this process over and over.
We met up over Discord and went over a very very basic design document. I dont know what a real game design document looks like, but i defined the overall image of the game, and made mockups of all the major screens that we would need to complete. They got Pixquare and started fleshing out some game elements themselves. With the new assets available, I swapped out the placeholders I had and started adding menus:
The next steps would be less visual, focusing on game saves and defining what a Jump is and how they differ. Here is the video I added when i completed the Save implementation:
Not very interesting! Idk what i intended to see in that LOL.
At that point I had some issues with how I was managing global state to maintain values between jumps, so I did my first (and so far only) major overhaul. This mostly was non visual elements, changing how a save was represented. Instead of having a single JSON file to represent save state, I implemented each component of the save as a GenericX class. Each GenericX class would contain all the state logically associated with that element, and would be possible to initialize from JSON, and to serialize back into JSON. This eventually looked like a GenericSave that would initialize GenericLevel instances and GenericShip instances. The default values for these level and ship definitions would be in the form of JSON and would define shapes for different shape and level types, helping me quickly add new levels and ships. After a new save is made from that initial read of the level and ship definitions, each subsequent initialization for that save would be from the save state rather than from the default definitions. This would let me modify the ship/level state depending on a player's behavior, progressing the game forward. The major benefits here were that i would no longer have to interact with json directly, instead just having to modify the GenericX classes. For example, if i wanted to add a "upgrade" field to the ship and allow users to by upgrades for the ship, i would only have to define a property for upgrades in the GenericShip class, define populating that property from json, and save that value when serializing a generic ship instance.
With this overhaul done I was very motivated and got a handful of changes done quickly:
The video shows: better planet art, beat visual queues, basic HUD mock up, jump calculations, jump start/end, dialog boxes, a basic garage implementation.
The next thing I wanted to do was flesh out the HUD. I needed to show the player state so that they could understand their progress, and i felt like having the real HUD in place would make the game feel richer, so i mocked up the following elements: fuel gauge, health tracking, money/reputation tracking, beat indicator
The next set of changes was also purely visual. I was procrastinating having to turn this into a meaningful game wtih an actual goal, so i instead added more planets that my friend made, and some aesthetic finess for it.
At this point I couldn't go forward without defining how the game progresses, so I made Missions (story) and Jobs (optional work for currency/rep/rewards). This was largely logic work and UI work, defing GenericJobs, GenericMissions, how they progress, how a story could be defined as a series of GenericMissions and their conditions for initializing/completion, how jobs are offered and completed, etc.
At this point I couldn't stand to look at the HUD and was feeling repulsed by it so I spoke with my friend to develop the next set of art for the game, focusing on the HUD. They sent several options and we tweaked it around until it ended up around here:
This has all the basics needed to make the game, and added a news ticker along the top to tell you of the world and your progress as you spend time in the game.
And thats pretty much where I'm at as of today. The only other thing I implemented was planetary events that could either help or harm you and that decay over time. The next work feels daunting to me since its focused around balance, making the game fun, and adding enough punch to put out a demo. Its exciting to be near the demo for sure, but it also feels grim to start worrying about whether it'll be any fun.
So for now I'm taking a short break. I don't want to start too many games at once without finishing the rest since thats a good way to get nothing done, but I'm going to spend at most a month working on some other prototypes and seeing if I learn anything new that can help with this project. The main idea I'll be working on is a friendslop game that I think would be fun to make with friends (and otherwise too much work to reasonably finish alone in less than a year). Through making it I'll have to interact with physics elements for the first time (meaningfully), and I'll have to mess around with some netcode for multiplayer so I'm really excited.