A short narrative and puzzle driven text adventure about disaster in the final frontier. Repair your spacecraft and get to safety before you run out of breathable air!
This game was created for the [I Can't Write (But Want to Tell a Story)](https://itch.io/jam/i-cant-write-but-want-to-tell-a-story) jam, and built with TypeScript and React.
Tested in Firefox and Chrome; it's playable in Edge but I don't recommend it (practically all the visual effects are broken, and the way it renders the background makes text very hard to read); I don't have a machine capable of testing it with Safari so your mileage may vary.
### Features:
- Classic command-driven text adventure
- Space!
- Ray-traced graphics\*
- In-game map, inventory, and help UI
- Potential sabotage?
- Built in hint system
- Did I mention it's in space?
### Known Issues:
- The "last seen location" for items sometimes does not update correctly.
- When long sections of text are printed, the beginning of the text can be pushed out the top of the screen (although you should still be able to read it by scrolling up).
\* This isn't even a joke! Okay no it is a joke, but it's not a lie. The background image was modeled in Blender and then rendered in the raytracing engine Cycles. The resulting image is used as a static background, but it was raytraced and is the largest of three graphics in the game so it counts.
What? Don't look at me like that - I'm not a wizard, and RTX definitely isn't supported in Javascript yet so this is as good as you're getting for now.
hints.set(Phase.wakeUp,'You may be able to assess your situation better if you find a light.')
hints.set(Phase.hasFlashlight,'With the security door shut and power cut off, you\'ll have to find another way into the rest of the ship.')
hints.set(Phase.checkedUnderSink,`There is a panel under the sink that you might be able to fit through - you'll need a wrench to get it open though.`)
hints.set(Phase.gotWrench,`You have a wrench and can open the panel under the sink.`)
hints.set(Phase.openedSinkPanel,'You can get to the lower deck through the panel under the sink, but be sure not to leave anything behind!')
hints.set(Phase.droppedBelow,'You need to re-start the CO2 scrubber before you run out of clean air.')
hints.set(Phase.droppedBelow,'You need to re-start the CO<sub>2</sub> scrubber before you run out of clean air.')
hints.set(Phase.fixedLifeSupport,'While the immediate threat to your life has been solved, you need to bring the engine back on so you can restore power to your ship.')
hints.set(Phase.examinedEngine,'The engine itself seems to be in good repair, time to go to the mainframe and start up its control systems.')
hints.set(Phase.examinedMainframe,'The engine control systems are missing [thing]. There\'s a spare in the comm room locker, but you\'ll have to find a way to get there.')
hints.set(Phase.examinedDoor,'You need to find a way into the comms room to retrieve [thing] - the door looks like it could be pried open with enough leverage.')
hints.set(Phase.examinedMainframe,'The engine control systems are missing a capacitor. There\'s a spare in the comm room locker, but you\'ll have to find a way to get there.')
hints.set(Phase.examinedDoor,'You need to find a way into the comms room to retrieve the capacitor for your engine controls - the door looks like it could be pried open with enough leverage.')
hints.set(Phase.examinedChair,'The chair looks sturdy enough to work as a lever to get in the door, but it will have to be disassembled first.')
hints.set(Phase.destroyedChair,'You have a bar that should be strong enough to open the door to the comms room - go retrieve the [thing] so you can start the engine again!')
hints.set(Phase.openedDoor,'You found a way into the comms room - retrieve the [thing] from the comms room locker so you can restart the engine.')
hints.set(Phase.destroyedChair,'You have a bar that should be strong enough to open the door to the comms room - go retrieve the the capacitor so you can start the engine again!')
hints.set(Phase.openedDoor,'You found a way into the comms room - retrieve the capacitor from the comms room locker so you can restart the engine.')
hints.set(Phase.examinedLocker,'Someone locked the comms room locker. There\'s a spare key in your overalls - they\'re back in your cabin.')
hints.set(Phase.examinedHoleCannotGetUp,'You can\'t reach up into the bathroom any more - you\'ll have to find something else to use to climb up')
hints.set(Phase.hasNewChair,'You found another chair you can use to reach the bathroom - go get the spare locker key from your cabin.')
hints.set(Phase.returnedUpToBathroom,'Someone locked the comms room locker. There\'s a spare key in your overalls - they\'re back in your cabin.')
hints.set(Phase.hasKey,`You've retrieved the spare key to the comms locker, and can finally get the [thing] to repair the mainframe.`)
hints.set(Phase.hasKey,`You've retrieved the spare key to the comms locker, and can finally get the capacitor to repair the mainframe.`)
hints.set(Phase.unlockedLocker,'Locker is empty - whoever was in your ship made sure you wouldn\'t be able to repair it.')
thrownewError(`The security doors have sealed - you're either going to need to restart the mainframe or find a way to force these open before you can access the comms room.`)
thrownewError(`The security doors have sealed - you're either going to need to restart the mainframe or find a way to force these open before you can access the comms room.`)
thrownewError(`The security doors have sealed - you're either going to need to restart the mainframe or find a way to force these open before you can access the comms room.`)
game.say(`_Focus_, you remind yourself. _The engine is pretty but I've gotta fix that CO<sub>2</sub> filter before I'll have time to bother with this._`)
game.say(`Luckily the CO<sub>2</sub> filter operates independently to the rest of the ship's systems, so you can worry about that fixing first and then come back to the mainframe.`)
thrownewError(`You probably should restart the CO<sub>2</sub> filter before worrying about the mainframe.`)
if(currentPhase<Phase.examinedMainframe){
parser.runCommand(`take apart mainframe`)
thrownewError()
}
thrownewError(`The mainframe's engine control system is damaged, and will have to be repaired before you can bring it online. You believe you have a replacement part in the comms room.`)
thrownewError(`You do not have the proper tools to take this apart.`)
constcurrentPhase=game.getProperty('gamePhase')
if(currentPhase<Phase.fixedLifeSupport)
thrownewError(`You should take care of the CO<sub>2</sub> scrubber before you get distracted taking things apart.`)
if(currentPhase<Phase.destroyedChair){
if(game.hasProperty('examinedMainframe')){
game.say(`The chair's center leg should give you enough leverage to force open the security door, but as you finish taking it apart you remember something that bothers you: if you're not mistaken, that regulator board was brand new. Even when they've gone bad in the past you've usually been able to get a good week or two of use out of them before they failed completely, so seeing one fail this early is definitely unusual.`)
game.say(`You can't remember for sure if that board was replaced in the last refit though, and you'd have to check the work log Wren gave you to be sure. You try to push that idea aside for now - no sense in worrying about it now.`)
}else{
game.say(`Twisting the bolts out of place, you are soon left with one long metal rod, and a small pile of miscelaneous pieces.`)
game.say(`With an uncomfortable grinding noise, and much effort, the security doors slide open allowing you access to the comms room.`)
game.say(`Unfortunately it looks like your chair leg got caught in the mechanism - the good news is this door will stay open, the bad news is you're not getting that back.`)
game.say(`You click the light on and glance around, sighing. The Dawn has certainly seen better days. She flies just fine, but assuming you survive you'll definitely have to use the money from this job to finally replace all the rusty patches with new parts.`)
game.say(`You click the light on and glance around, sighing. The _Dawn_ has certainly seen better days. She flies just fine, but assuming you survive you'll definitely have to use the money from this job to finally replace all the rusty patches with new parts.`)
game.say(`It figures that the easy delivery would turn out to be the one where you have the most problems. All you had to do was take a few sealed boxes to the far side of the galaxy and then fly back - no sneaking, no lying, no fighting or anything!`)
game.say(`You suppose this kind of equipment failure is inevitable, although it's a bit strange since you had the engine checked last week. It was the same cousin who checked the engine as who told you about this job actually.`)
game.say(`"Listen, I know you don't want to get involved in the synth trade but it's just one supply run and they can pay you a lot for it." Wren had said. "I'd do it myself but the Aurora's a flying collection of scrap at this point, and you know how I hate having to find new pilots."`)
game.say(`"Listen, I know you don't want to get involved in the synth trade but it's just one supply run and they can pay you a lot for it." Wren had said. "I'd do it myself but the _Aurora's_ a flying collection of scrap at this point, and you know how I hate having to find new pilots."`)
game.pause()
game.clear()
game.say(`You had groaned at that. "And you think the Ashen Dawn is in any better condition? That's why I brought her to you, numbskull."`)
game.say(`Wren's grin was wide, but knowing. "Listen, after I fix her up let me introduce you to my client Rosalyn - it's a simple supply run, and would be a good shakedown for Dawn after the repairs."`)
game.say(`You had groaned at that. "And you think the _Ashen Dawn_ is in any better condition? That's why I brought her to you, numbskull."`)
game.say(`Wren's grin was wide, but knowing. "Listen, after I fix her up let me introduce you to my client Rosalyn - it's a simple supply run, and would be a good shakedown for _Dawn_ after the repairs."`)
game.say(`As you lower yourself down into the cargo bay you're struck by how empty it looks. Normally this storage bay would have a lot more general-purpose supplies, but you had to clear it out to make room for this delivery. Since you've dropped the cargo and were on your way to get paid, they're no longer here to fill that space.`)
game.pause()
game.clear()
game.say(`You weren't permitted to know what was in the boxes you delivered. "Wares to be sold in the outer markets," Rosalyn said when you asked. "The less you know the less you have to worry." `)
game.say(`You weren't even sure how heavy or light the boxes were - she arranged crews for loading and unloading ahead of time, and the time requirements for delivery were just close enough you hadn't dared stop to investigate along the way. It really was as easy as Wren had said it would be...`)
game.say(`As you look up the stairway you catch a glimpse of light filtering down from above - must be near a star cluster you suppose. Not really any good way to know which one until you can bring the navigation systems back online.`)
game.say(`Okay, with the CO2 scrubber running again, the filter should last for at least a week - plenty of time to get the _Dawn_ back to a spaceport. If the engine issue isn't that bad, maybe she'll last you all the way back to Earth so you can collect your paycheck and do a proper diagnostic.`)
game.say(`Speaking of which, examining the engine is probably the next order of business - if it's gonna keep dropping out of hyperspace on you then this is going to be a long trip home.`)
mainframe.description=mainframe.description?.replace(/Of course.*/,`While the bulk of the mainframe is still there, you've currently taken apart the engine control systems. Looks like there's a faulty capacitor in the engine regulator board, and you'll have to get a replacement from the comms room locker.`)
if(!game.hasProperty('examinedMainframe'))
game.createProperty('examinedMainframe',true)
game.clear()
game.say(`At first glance the mainframe is working as expected - you can bring up the internal atmospheric readings, the operation logs, and anything else that doesn't need engine power. The mainframe even kindly informs you there was some sort of anomalous power output from the engine before it cut from hyperjump, but when you try to bring the engine back online you hear a loud ***pop*** from behind the terminal and start to smell smoke.`)
game.pause()
game.clear()
game.say(`Upon further inspection, it looks like there's a faulty capacitor in the engine regulator board. That would explain the power anomalies - these sort of caps always act a bit weird before they blow completely.`)
game.say(`The _Dawn_ is old enough (and this issue is common with her model of ship) so you luckily have a spare capacitor or two in the comms room locker - although finding a way through the security doors might be a bit tricky.`)
game.say(`As you work your way back to your cabin you start to get a growing sense of unease.`)
game.say(`You don't want to believe it, but something is definitely suspicious about this engine failure - the part was brand new, and now a locker you've never locked in your life is shut tight.`)
game.pause()
game.clear()
game.say(`You don't think about it. Rosalyn and the rest of her synth trade clients would definitely be willing to sabotage your ship, but they wouldn't have known enough to pull it off that quickly they had Wren's help.`)
game.say(`"Come on, Wren," you say to yourself, "don't let me down. The spare will be where I left it, and everything will be all right."`)