MVT Games Documentation
Canvas and game applications tend to mix state, rendering, and timing into tangled code that is hard to test, debug, or extend. MVT (Model-View-Ticker) solves this by splitting applications into three strict layers, giving you deterministic models you can unit test, stateless views you can swap, and frame-consistent rendering across the board.
The Three Layers
Ticker (frame loop)
│
├── 1. model.update(deltaMs) ← Models advance state
├── 2. view.refresh() ← Views read state, update presentation
└── 3. renderer draws ← Frame drawn to screen| Layer | Owns | Receives | Must not touch |
|---|---|---|---|
| Model | State, domain logic | deltaMs | Views, rendering, time |
| View | Presentation | Bindings/model | Domain state, timers |
| Ticker | Frame loop | Animation frame | Domain logic, rendering code |
Choose Your Path
Learn MVT
New to the project? The learn path takes you from zero to working understanding in eight short pages:
- What is MVT? - The problem, the solution, the benefits
- Architecture Overview - The frame loop at a glance
- Models - State,
update(deltaMs), determinism - Views - Scene graph,
refresh(), statelessness - The Ticker - Wiring the loop
- Bindings - Connecting views to models
- Walkthrough - Annotated tour of the Asteroids module
- Next Steps - Where to go from here
Reference
Already familiar and need to look something up?
- Architecture Rules - All MVT rules in one page
- Style Guide - Code conventions and naming
- Glossary - Term definitions
- Project Structure - Directory layout and barrel files
- Proven Patterns - The engineering heritage behind MVT
- Reactivity Guide - Events, signals, watchers, and comparison framework
AI Agents
AI coding agents should start with AGENTS.md for compressed orientation.
Contributing
Adding to or maintaining these docs? See the Contributing Guide for page templates, section purposes, and style rules.
Design Philosophy
These guides are built around four principles:
- Separation of concerns - Models own state; views own presentation; the ticker owns time. No layer reaches into another. Public APIs are defined by interfaces, not implementation details.
- Testability by design - Models are deterministic (same
updatecalls produce the same state). Views can be tested with mock bindings. Neither depends on the other. - Explicit over implicit - Time flows through
update(deltaMs), not hidden timers. Data flows throughbindings, not global imports. - Performance without obscurity - Hot-path rules exist to avoid per-tick waste, but clarity still matters. Optimise where it counts; keep everything else readable.