Contributing to Explodorama
Thank you for wanting to help! The project lives at
code.fuzzyworld.net, which has no issue tracker or
merge requests. Bug reports and playtest notes are welcome through the game's report
link, which opens a prefilled email. Code contributions arrive by email too: share a branch
from any git host, or send a git format-patch, to contrib-68uq+explodorama@fuzzyworld.net
(how to contribute).
Reporting a bug
Send a report and include:
- what you did, what you expected, and what happened instead;
- the seed (shown in the menu, and on the game-over and victory banners) and the level —
with the seed, the same board can be replayed with
?seed=<number>; - the device and browser, and a screenshot if you can.
Getting set up
You need Node.js 22.
npm install
npm run dev # http://localhost:5173, plus a QR code for a phone on the same Wi-Fi
npm test # Vitest
npm run build # type-check and build into dist/
npm run preview # serve the build, with a QR code for a phone on the same Wi-Fi
npm run screenshots # build, then photograph the game into docs/screenshots/ (Playwright)
Seeing what went wrong: under npm run dev, everything the game writes to the browser
console — and every error, caught or not — is printed in the terminal running npm run dev,
marked (client), from any device, including a phone on the Wi-Fi. An error while drawing a
frame or playing a turn is caught, logged with its stack and the device (src/devlog.ts), and
the game carries on instead of freezing.
The URL parameters listed in the README (?seed, ?level, ?charges, ?dev,
?immortal, ?demo) are the quickest way to reach the situation you are working on.
Before you send a change
npm testandnpm run buildboth pass.npm run deployruns exactly these two, and only publishes when they pass.- Rule changes come with tests. Game rules live in
src/sim/and are tested intest/. - The docs are up to date. A change a player can notice belongs in the README and in CHANGELOG.md under Unreleased. A change to the design or to a recorded decision also updates PLAN.md or decisions.md.
- Screenshots are refreshed with
npm run screenshotsif the change alters how the game looks.
How the code is laid out
The README's How it's built section describes the layout. The rules that matter most:
src/sim/stays pure and deterministic. No rendering, no DOM, noMath.random(): every random choice comes from the seed, so a run's seed plus its actions always replay to the same state.- Bump
SIM_VERSIONin src/sim/record.ts whenever a rule change would make an old record replay differently. Saved runs from another version are dropped rather than replayed wrongly. Note the bump in the changelog, and update the version near the top of the README: it is the game's version, also shown in the menu. - Rendering (
src/render/) and the HTML UI (src/ui/) only read the state and the events thatstep()returns; they never change the rules. - Movement on screen comes from the change of state, not from events. The player's and the
enemies' moves are worked out from their tile before and after a turn (
playerTransitioninrender/effects.ts), and a pose (hit, jump, crouch, dying) starts only once the move is done. Something else happening in the same turn then can't skip the move. Keep new animations to that pattern, and add a case totest/animation.test.ts.
Art and other assets
- The game uses art from Kenney packs only, under CC0. Please ask in an issue before bringing in a different pack or another artist's work.
- Copy files unchanged and under the pack's own file names into the matching
assets/kenney*/folder, and keep the pack's licence file next to them. - Icons with a modifier badge are made from those files by
tools/compose-icons.sh (needs ImageMagick 7) into
assets/composed/, not drawn by hand. The results are committed.
Licence
By contributing, you agree that your code is released under the project's MIT licence. Kenney's art is not covered by it; it stays under CC0.