Why Write Games in Mar?
There are better-known ways to make a 2D game. Unity, Godot, Phaser, LÖVE, plain JavaScript on a canvas. Choosing Mar instead is a real decision, so this chapter is the honest sales pitch: what you get, what you give up, and why the trade is interesting.
One source file, two native runtimes
A Mar game is a frontend app whose page draws to a canvas. That same source runs in two places:
- On the web, the Mar runtime renders your draw list to an HTML canvas, ticks on the browser’s frame clock, and synthesizes audio with the Web Audio API. It works in every modern browser, desktop or phone, with nothing to install.
- On iOS, the same file is bundled into a native SwiftUI app. Drawing goes through SwiftUI’s
Canvas, the tick ridesCADisplayLink, sound is anAVAudioEnginesynthesizer, and controllers arrive via the GameController framework. There is no web view involved; it is a real app you can put on TestFlight.
This is not “write once, run anywhere” by lowest common denominator. The five game-facing modules (Canvas, Sound, Keyboard, Gamepad, Device) are implemented natively on both platforms, and the runtimes are held to byte-identical behavior by a conformance suite. When Part I says your game is deterministic, it means deterministic on both.
The kit is in the box
Mar ships everything a 2D game needs as language modules. There is no package manager step, no plugin, no asset pipeline to configure:
Canvasdraws rectangles, circles, triangles, and text, grouped and transformed.Soundis a chip-tune synthesizer: waves, sweeps, vibrato, arpeggios, chords, sequences.KeyboardandGamepadare mirror-image subscriptions for held keys and buttons.Deviceanswers “what am I running on?” from real capabilities, never user-agent guessing.Time.everyat 16 milliseconds is a vsync-driven game tick with a proper fixed-timestep clock behind it.Random, or five lines of your own seeded generator, covers chance.
The absence of an asset pipeline is a feature with teeth, and chapter 8 (Art from Rectangles) is about the style it produces: games drawn from primitives, the way the machines that invented these genres drew them.
Determinism is a game mechanic
Mar has no floating point. Positions, velocities, angles and projections are integers (money-style Decimal exists too, but games live on Int). Combined with pure functions, this buys properties that are usually expensive:
- Replays for free. Same seed plus same inputs equals the same game, bit for bit, on every platform. A replay is a list of inputs.
- Testable levels. The rhythm-runner example proves its stages are beatable by running a bot through the real
updatefunction in a script. No emulator, no flakiness. - Multiplayer without desync. The card-game example writes its rules once in a shared module; the Go server and the JS client both execute it and must agree. They do, structurally, because there is nothing that can round differently.
- Time travel. The dev-mode debugger scrubs backward through a boss fight, because every frame of your game is just a Model, and Models keep.
The compiler is your QA department
Every claim from The Book of Mar compounds in games, because games are big state machines edited at 2 a.m. The union type that models your phases (Title | Playing | Paused | Over) is checked at every case. Add a Cutscene phase and the compiler lists every screen you forgot. There is no null to crash a frame, no exception to swallow a collision, no stale reference to a despawned enemy, because there are no references, only values.
What you give up
Honesty section. Mar is the wrong tool if you need:
- Bitmap sprites or 3D. There is no image loading and no GPU access. Art is shapes, text, and palette discipline. (The examples include a raycasting FPS and a pseudo-3D racer, so “2D primitives” reaches further than it sounds, but it is still the boundary.)
- Heavy simulation. The runtime is a tree-walking interpreter. It holds sixty frames per second for real games, including an RTS pathfinding hundreds of units, but it is not where you write a particle system with fifty thousand particles. Chapter 14 (Sixty Frames on a Budget) gives the real numbers and the craft.
- Every store. Targets are the web (which includes desktop browsers) and native iOS. There is no Android or desktop binary today.
The proof
Everything this book teaches was extracted from shipped games in the Mar repository’s examples/ folder: an arcade soccer game, a Zelda-style RPG, a four-season pseudo-3D racer, a Norse raycasting FPS, a ten-stage vertical shmup, a one-button rhythm runner, a party reaction duel, an adventure-game port, an asynchronous multiplayer card game, and a real-time strategy game. When a chapter says “this is how you do it”, it is describing how it was actually done, and where a game hit a wall, the wall is documented in Appendix B.
Next: build one.