Posted March 10, 2025 by tjjoris
The three of us have worked together on Jams before and are familiar with each other's strengths and weaknesses, we are able to communicate well and know how to hold each other accountable.
At the end of February 2025 we new we wanted to do a Jam soon so looked for one on itch.io with a timeframe that aligned with ours; 10 days to 2 weeks. We took interest in the GoedWare Jam, having entered in GoedWare Jam #11 with our award winning entry: Science of Realms
We had already decided the platform and language. Tjjoris was new to React so decided the scope must be kept simpler than our previous Jams which used engines such as Godot and Unity.
We were unavailable the first day, but knowing the theme, brainstormed ideas in the discord the matched the theme of "breaking the loop".
We came up with the following ideas:
We decided to go with the simplest idea, Elastic Bands.
The scope of the initial pitch included:
Tjjoris began coding the initial React layout, and linking it with TypeScript objects using useSyncExternalStore(). Starting with the clicking functionality to generate points.
Kay created the first assets, the Elastic Ball, and Broken Elastics.
As soon as possible, Tjjoris deployed the project to itch.io to identify potential deployment challenges. He discovered that the code is more sensitive to syntax problems in deployment than development, such as values that are declared but not used.
Tjjoris also found he had to add a line to the vite.config.ts file, so the deployment knew where the root was located when deploying on itch.
Early in development, Tjjoris identified a memory leak. The root react component was getting re-rendered and in that process was reinstaniating a TypeScript object, which in turn caused the root component to re-render because the component was subscribing to the object created, creating an infinite loop, and memory leak. Dramatically slowing down the tick rate.
Despite using useRef() as a reference to the TypeScript object Tjjoris was unable to keep the typeScript object from reinstantiating. The band-aid solution was to stop the root component from re-rendering.
Tjjoris had added repeatable upgrades, and additional art assets.
We wanted to add one-off upgrades, but the code was not designed with this in mind. The increment rate was added with each upgrade, instead of re-calculating it.
Although this would have been do-able, The choice was made to scrap the one-off upgrades, even though this would remove some of the gameplay choice and depth. Tjjoris did not want to spend time refactoring the upgrade functionality, changing the game layout, and re-considering balance, to add one-off upgrades.
In the previous jams we did, we included features because they seemed cool and in depth, which ended up taking away from the core functionality of the game. It also took away from our time to polish the finished product. Because of this, scrapping one-off upgrades seemed like a good choice.
Kay continued to add art assets. Tarsin gave feedback on the first balance pass that the difference in upgrade tiers needed to be more dramatic. After tuning the .json used to store game stats, the second pass felt a lot better.
Kay provided the final art assets. We decided on the name "Loop Destroyer". Tarsin created a Display Image. And Tjjoris made final bug fixes and layout changes. And the final product was published further ahead of schedule than any of our previous jams.
Keeping the scope simple and cutting features allowed us more time for polish, and more breathing room.
In the end there is more we could have done to polish it, such as make the page respond to window size changes. Although it does change the layout based on the window size when it is loaded.
Some audio would have been nice to add, but we did not have our main audio guy for this jam.
In the end it was a great experience, we're happy with what we've created, and we hope others enjoy it too.