4.5 KiB
4.5 KiB
AGENTS.md
Battle for 'Tismo — HTML5 port of the strategy game. Pure JavaScript: shared game logic runs both in Node (authoritative server) and in the browser (client). There is no build step and no runtime dependency; the client vendors jQuery and everything else (transport included) is hand-written.
Commands
- Install dev dependencies once:
npm install(onlyc8andjsdom, used by the test suite — nothing the game runs needs them). - Run the test suite:
node tests/run_tests.js(aliasnpm test; prints a summary and exits non-zero on failure). - Coverage report:
npm run coverage(c8, writescoverage/). - Start the game server and client locally:
node server/server.js --port 27015 --bind 127.0.0.1. Then openhttp://127.0.0.1:27015/(redirects to/client/index.html). The browser connects tows(s)://<page-origin>/ws. - Install the versioned git hooks (runs the tests on every commit):
./scripts/install-git-hooks.sh; uninstall withgit config --unset core.hooksPath. - Build the deployable packages:
nix build .#serverandnix build .#web. - If
nodeis not on PATH, use the pinned one:nix-shell -p nodejs --run "node tests/run_tests.js".
There is no linter, formatter, or CI. Do not invent commands beyond these.
Gotchas
- Keep the shared modules framework-free: they are imported unchanged by both
server/(Node, ESM) andclient/js/(browser). No Node built-ins and no DOM APIs inshared/(server/websocket.jsis the only place Node built-ins are expected). - Do not add JavaScript libraries. The only third-party code allowed is the
vendored jQuery under
client/vendor/; implement everything else by hand (seeserver/websocket.js, a dependency-free RFC 6455 server). - The game server also serves the app as static files from the repository root,
so modules resolve as
/client/...and/shared/.... Preserve theclient/+shared/layout when packaging (nix/package.nix). - WebSocket state snapshots can be hundreds of KiB; the custom server handles
fragmented and large frames (
server/websocket.js). Do not lower the buffer limits without checking the snapshot path. - Indent
.jsfiles with 2 spaces..editorconfigonly enforces UTF-8.
Architecture
- Game logic is server-authoritative.
shared/game_state.js(GameState) is a framework-free model that owns the world, units, cities, territory, economy, training and visibility.server/game_server.js(GameServer) owns aGameState, validates orders and broadcasts snapshots over the transport inserver/server.js. The browser client is a view:client/js/map_view.jsrebuilds terrain from the shared seed, renders snapshots and sends orders. - Movement is continuous:
server/server.jsadvances movement every tick and strikes an in-game hour everySECONDS_PER_HOURreal seconds. The client extrapolates each unit along its snapshot path and predicts move orders locally (map_view.js), mirroringGameState.find_pathso a click feels instant. Any pathfinding or movement-cost change must be mirrored on both sides or prediction will fight the server. shared/holds the reusable algorithms so they stay testable without a server:hex.js(topology/geometry),map_generator.js,hex_pathfinder.js,terrain_stats.js,rules.js,economyfigures ingame_state.js,game_clock.js,rng.js,noise.js,text_format.js,login_manager.js. Data-driven content (civilisations, units, buildings, governments, technologies) lives inshared/data.js.client/js/splits the UI:app.js(screens and flow),net.js(transport wrapper),game_screen.js(HUD and panels),map_view.js(canvas/DOM map),modals.js(training, buildings, government/technology modals).- Tests live in
tests/as*_test.jsfiles extending theTestCasebase intests/framework/;tests/run_tests.jsdiscovers and runs them. Add a newtests/<topic>_test.jsfor each new pure behaviour.
Deployment
flake.nixexposespackages.<system>.serverand.web, plusnixosModules.default. There is no compiler step:nix/package.nixcopies the app and wrapsnode server/server.js;webis the staticclient/andshared/tree.nix/module.nixruns the server as aservices.battle-for-tismosystemd unit and serves the static client through nginx, redirecting/to/client/index.htmland proxying/wsto the local Node server. The browser client connects to the page's own origin, so HTTPS gives itwss://.- Build locally with
nix build .#serverandnix build .#web.