Skip to content

Repository files navigation

Tanks!

A top-down arena tank game. Clear the arena; one shot kills anything, including you.

Play it

Three.js renderer over a pure, deterministic 2D simulation — swept ray-vs-AABB shell physics with in-tick reflection, proximity mines, and a data-driven enemy roster.

The canonical roster currently defines 6 enemy types. Its gameplay data lives in tank-defs.json and ai-profiles.json.

Enemy First mission Movement AI profile Mines Shells
Brown 1 Stationary Static basic No Standard shell; slow fire; max 5; 1 bounce
Grey 2 Medium Defensive basic Yes (2) Standard shell; medium fire; max 5; 1 bounce
Olive 3 Slow Defensive rocket No Rocket; slow fire; max 1; no bounces
Teal 5 Slow Mobile mine layer Yes (2) Ricochet rocket; fast fire; max 5; 2 bounces
Yellow 8 Medium Mobile mine layer Yes (4) Standard shell; medium fire; max 1; 1 bounce
Green 12 Stationary Ricochet sniper No Ricochet rocket; slow fire; max 5; 2 bounces

Controls

Move WASD / arrow keys
Aim Mouse
Fire Left click
Drop mine Space / right click
Mute M

Experimental gamepad input and 2–4-player couch co-op are available behind development flags; see the generated dev-flag reference.

Development

Requires Node ^22.13.0 || ^24.0.0.

npm ci                # install from package-lock.json
npm run dev           # Vite development server
npm run verify:quick  # typecheck + Vitest suite (`npm test` is an alias)
npm run verify:build  # production bundle + subpath-portability check
npm run capture -- --list  # list reproducible screenshot/clip recipes
npm run preview       # serve the built bundle

The atomic npm run typecheck, npm run test:unit, and npm run build commands each perform only the named operation. See the verification command reference for full, visual, and subsystem-specific checks. Reproducible local review media is documented in the capture recipe reference.

Design direction, implementation plans, deferred spikes, and research are listed in the documentation index, which is generated from each document's own metadata and separates current direction from the implementation record.

Architecture

src/sim/ is a pure, deterministic core: given a seed and an input stream it produces the same world, tick for tick. It imports nothing from Three.js, the DOM, or Howler — src/sim/purity.test.ts enforces that automatically and fails naming the offending file and token.

Everything else is a one-way projection of sim state:

  • src/render/ interpolates between the previous and current world at the display's refresh rate, independent of the fixed 60 Hz sim.
  • src/audio/ maps SimEvents to sound.
  • src/game/ owns the fixed-timestep loop, the state machine, and the HUD.

The build sets base: './', so dist/ is portable to any static host and any subpath without reconfiguration.

Audio assets

None are committed. public/audio/ holds only a .gitkeep, so the manifest declares nothing and the engine synthesises every sound in Web Audio rather than requesting files that are not there — a deliberate choice, not a degraded mode, so development is never blocked on assets. (It used to declare all ten anyway and let each 404: 10 requests and 93,790 uncached bytes per load, measured against the deployed site.) See CREDITS.md; its attribution tables are intentionally empty rather than fabricated.

License

Source-available, not open source. The two are different, and the difference is the point: you can read this code, but it does not carry an open-source grant.

Three things govern this repository, and every file is under exactly one of them:

  • Code, tests and repository toolingPolyForm Shield 1.0.0, the official text, unmodified.
  • First-party content — artwork, audio, levels and maps, narrative and copy, media, logos and branding — All Rights Reserved. See CONTENT-LICENSE.md, which classifies paths so a reader can tell which of the three applies to any file.
  • Dependencies — their own licenses, recorded in THIRD-PARTY-NOTICES.md.

Shield permits reading and private experimentation, but not using the software to provide a competing product — and that holds whether a competing release is paid or free. LICENSE controls; this paragraph is a summary, not the terms.

The owner may grant exceptions, commercial licenses or modding permissions separately, and separately granted written permission overrides the default.

Outside code and asset contributions are not being accepted yet — see CONTRIBUTING.md for why, and for what is welcome instead.

This section records the project's licensing boundary. It is not legal advice.

About

A deterministic top-down arena tank game with ricochets, mines, and tactical AI.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages