Erin's a rookie artificer at a magical lab. In this game you play as her, trying to get all your work done by the end of the week.
Thing is, Erin's disabled. She only has so many spoons in a day. Good luck getting everything done in time!
Click the image to view the video.
The game logic is defined with Ink, a language designed for the creation of games with branching narratives.
src
| components
|__ Choices.jsx
|__ Ending.jsx
|__ Scene.jsx*
|__ Story.jsx
| state
|__ actions.js*
|__ index.js*
|__ reducers.js
| App.jsx*
| index.css
| main.jsx
| particles.ts
| the_lab.json*
The entire game is stored in the_lab.json. It's read and interpreted by Ink.js, displayed with React, and tied together by Redux.
The only viable way to extract information about the current state of the game is through the use of Ink's tags. Ink has its own internal variables, which are fed into their tags. actions.js reads these tags when updating the game state, reducers.js translates the tags to a redux state, which redux then attaches to and translates into props for react.
So if the writing isn't quite up to par... that's why. I had to untangle the spaghetti I'd created. It was fun :D
actions.js extracts the gameplay information from Ink, reducers.js translates that information into something more easily worked with, and index.js creates and holds the store.
actions.js also contains the fabled makeChoice() function, the workhorse of this strange engine.
Whenever the player makes a choice in the game, makeChoice() is called. Redux dispatches all the game info from that choice to <App>'s props and updates the store, passed along to <App> via main.jsx
The bulk of the React side of things happens in App.jsx and Scene.jsx, changing out the Elements, their content, and their classes based on the current game state. Thanks to Tailwind, the change in classes also changes the appearance of the app as well.
<App> then passes all that game information along to <Scene> and the whole family tree of components. <App> and <Scene> work together to transform the screen with Tailwind and new elements using a combination of useState() and useEffect()s.
One of the major bugs that had me scrounging through redux code for hours was solved by adding "choices" on line 13 of Scene.jsx.
the-lab/src/components/Scene.jsx
Lines 7 to 13 in 10913ba