Just popping in to say that I'm the designer and programmer of this project
For my part, while I feel I achieved a LOT over the 3 days, it wasn't enough to call it finished. I might have been able to make it work if not for one key roadblock which I realised far too late! But to better explain that, let me talk more about the game concept in general. Wordy post ahead!
The prompt for the LD was 'Running out of power', and the idea which came to me, that I liked the most, was inspired by the movie 'Passengers' (for its narrative focus and context) and 'Keep Talking and Nobody Explodes' and Artemis Spaceship Bridge Simulator (for the asymmetric cooperative play, and particularly the 'disconnected' aspect when it comes to Keep Talking). ERR?R C?DE (so named because of the essential focus of the gameplay, working together to interpret and decrypt codes even when power continues failing ship-wide and some of those codes are corrupted) is a game to be played by two people using two completely separate but in-sync pieces of software -
100% offline.
The first piece of software was made in Unity, and represented the 'gamier' half of the two. In it - as can be seen in the images Bo posted - the player controls the mechanic who has been woken up to fix the ship, and is able to fully wander the ship and interact with all the stuff inside of it. In doing so, the player will gather error/fault codes which the ship is using to communicate what is wrong with it, and how to fix it. The mechanic has no means of 'translating' these codes by themself, which is where the onboard helpful AI comes in.
The second piece of software is a simple command-line application to be used by the other player. This puts them in the role of the ship's AI, a very knowledgeable but restricted entity which can do helpful things like interpret error codes, override locked doors, or create emergency codes to temporarily restore power/lights/systems. The AI, however, can do little to nothing to actually fix the ship itself, nor hook directly in to the ship's diagnostics, which means that the AI-mechanic relationship is entirely codependent and symbiotic. Both have to work together to achieve the common goal, which is to discover the cause of the ship's faults, fix them, and restore power so that the mechanic can go back to cryo sleep and the ship can carry on towards its destination (at least until something else goes wrong and he gets woken up again...)
After building the bones for the Unity-side, which involved creating a system where a keyboard-controlled player could move through rooms connected by doors and ladders (I'll post some of my delightful texture-less, basic-geometry gifs when I get back on that pc), I set to work on deciding how, exactly, the rest of it would work. We needed both halves to be 'in sync', but I wanted to avoid any kind of networking. As well, I didn't want to just hand-craft a scenario, or several scenarios, and have both players just pick the same one and go. No, I wanted to make life
harder for myself. Because that's a great idea in a gamejam.
So I started work on my ScenarioBuilder. Using .NET's in-built Random class, I slowly (quickly? it was only 3 days!) built up a C# library which could do the following:
- Pick a root problem from a list of possible ones (like shield failure, reactor running out of fuel, reactor overheating, etc)
- Pick a knock-on problem caused by the root one (for example, a shield failure might result in a hull breach)
- Do the above step a few more times with either the root problem or any of the others, to get between 2-5 overall problems
- Per problem, pick the effect on the ship (so this would be the 'symptoms' of the problem you are trying to diagnose, which could be certain systems going down, loss of air pressure, etc)
- Per problem, generate a solution required to fix it
A 'solution' involves:
- Between 1-4 individual steps
- A step could be entering the correct code into a particular terminal, pressing a certain button, manually repairing a certain broken panel/object
And each step involves:
- The action (press red button)
- The target (of the control panel in room ABC)
- The code required to learn about the step
Because of course the mechanic can't learn about the solution and its steps until the AI player explains it, but the AI player can't explain it until the mechanic has obtained the correct code for the AI to interpret. The flow should go like this:
- Mechanic obtains a code, eg A56H0
- Mechanic relays this code to the AI, who uses his console application to figure out what it means
- AI relays the decoded information back to the mechanic (which could be something like 'go to room XYZ and trip the switch on the 123 control panel - this corresponds to a solution step)
- The mechanic carries out the action
Repeating the above is the basic loop for completing the solutions and thereby winning the game.
My ScenarioBuilder worked /really/ nicely. The joy of this was that, if both pieces of disconnected software generated the EXACT SAME scenario, they would be able to work together without any networking at all! I was able to generate quite complex and varied scenarios, with different problems, effects and solutions utterly effortlessly once it was finished.
This only corresponds to raw data, though; now I needed to hook it back into the Unity game, make the game properly give the player the codes necessary for the AI to interpret, and then make the game acknowledge that solution steps were being satisfied, when... the roadblock happened.
Turns out that System.Random cannot be 100% relied upon to produce the same random numbers across applications when given the same seed. It was something that I had just taken for granted, foolishly, and discovering that my console app and Unity app were generating different scenarios with the same seed... pretty much scuppered it all, because it was too late, and I was too exhausted, to figure out how to fix it. We called it a day in the state you can see above.
But this is hardly an impossible challenge, and I have since solved it (and very easily, too... but I forgive myself for being too drained to do it at the time). Rather than rely on System.Random, I will be using the
Mersenne Twister for my pseudo-random numbers, which puts their generation entirely under my control.
This puts the core concept sqaurely back on track, which is awesome. Future posts of mine will hopefully have more going on visually, but hey, that's what the artists are for
It'll be nice to just be able to focus on the mechanics and code behind!