A game engine written in Rust

A game engine an AI can build in, and prove.

Your agent writes the game as documents, plays it on a fixed tick and checks every picture against one a person accepted. You direct it, and every step leaves proof you can read.

Private beta. Version 1 is not public yet. Windows first.

stage 1-1Write it as data

Scenes are files, not clicks.

In most engines a level lives inside the editor, and the only way to change it is to click. In Press Start every scene, material, rig and menu is a plain document an agent can read and write. A change is a small patch laid on top, and the document under it stays as it was.

The engine checks every document before the game starts, and a refusal names the wrong value and how to fix it. Ask which patch set a value, and you get an answer, not a guess.

Read more
base + patch 0 + patch 1the engine's answer
  1. base
    • Health 10 / 10
    • Tint grey
    • Name crate
  2. patch 0
    • Tint blue
  3. patch 1
    • Tint gold
    • Health max 25
    • Name removed
Tint
gold
patch 1
Health.max
25
patch 1
Health.current
10
base
Name
removed
patch 1

verbatim from the engineAn agent asks which patch set each value. The request is copied verbatim from the engine's scene guide, where a test sends it through the real wire and checks this answer.

stage 1-2Same seed, same game

Run it twice. Get the same game.

Most engines play a slightly different game on every run: the frame rate nudges the physics and the dice are rolled fresh. Press Start rolls every die from one seed you can write down, never reads the clock, and steps the world on a fixed tick.

Same seed, same inputs, same frame. So a test is a fact, a replay is exact, and "the bug at tick 340" is something one agent can hand to another.

Today: the same build on the same platform.

Read more
seed 0x5eedtick 240 / 240
run A
run B
tickrun Arun BPASS
0006a059ae83a9ff47b6a059ae83a9ff47b✓
0404edc74743e7f1c7f4edc74743e7f1c7f✓
080945a5f7bde1f6fa8945a5f7bde1f6fa8✓
120184c7e529ed26059184c7e529ed26059✓
160b308ffa24fc8bc09b308ffa24fc8bc09✓
200d5c13fefb4253fd4d5c13fefb4253fd4✓
240c33a5e745a750293c33a5e745a750293✓

PASSevery line matches

illustration · drawn in your browserA small simulation drawn in your browser: one seed, a fixed tick, no clock, and a checksum of the whole state every 40 ticks. The engine's own replay checks its checksums the same way.

stage 1-3Every core, one answer

All your cores. The same answer.

A game's systems run across every core of the machine, and Press Start keeps it that way: nothing is slowed to one thread to make it repeatable.

When two systems touch the same data, the engine insists on an order and refuses to build until one is declared, naming both. Sums are added in a fixed order. So the game you replay does not depend on how many cores ran it.

We have not measured a speed-up yet, so we do not quote one.

Read more
Every core, one answer8 cores

same data · order declared

state checksumc33a5e745a750293same

illustration · drawn in your browserAn illustration: the same systems dealt onto 8, 4 or 2 cores. The checksum comes from the browser simulation above, and it does not move.

stage 1-4Pictures are tests

Every picture is checked, pixel by pixel.

When the engine draws something in a test, the frame is compared with a golden: a picture a person looked at and accepted. If the picture changes, the test fails and leaves the new frame beside the old one for a person to judge.

A tool can suggest a golden. It can never accept one.

spriteengine 45aeffd
rig2d-character-tick-35this runthe golden

PASS · 0 px differ

  1. 01shot on one reference graphics card
  2. 02compared pixel by pixel
  3. 03accepted by a person, in a reviewed commit

the same character, three ticks

  • rig2d-character-tick-03tick-03
  • rig2d-character-tick-35tick-35
  • rig2d-character-tick-40tick-40

verbatim from the engineAccepted goldens from the engine's 2D rig tests, shown at their own pixels and scaled without smoothing. The engine has 189 accepted goldens today.

stage 1-5Held to a reference

Measured against the tools you already trust.

We do not grade our own homework. Each part of the engine is held against the tool the industry already relies on for it, on the same scenes.

Where our answer differs, the difference is written down with both numbers and a reason, and the disagreement is settled toward the reference.

Read more
Held to a reference71 reference tools in all
Press Startthe reference
PhysicsJolt · PhysX
NavigationRecast
UI layoutChromium · Yoga
Text shapingHarfBuzz
LightingMitsuba
MeshesBlender · Manifold

Parity is the bar. Not every feature meets it yet, and the misses are recorded.

Held to a referenceReference tools are named as plain text. They are compared against and never ship in the engine.

stage 1-6The game answers back

The game answers back.

An agent cannot squint at a screenshot and know the game is right. So a running Press Start game answers four verbs: query, command, capture and control.

Your agent asks for the state, changes it through one door, takes a picture and steps time, on the same surface the engine's own tests use. You bring the AI. The engine brings data and verbs.

Read more
four verbstick 132
  1. query4 bodies · ball at 286, 35 · score 1 : 0
  2. commandball placed at the centre · journal #1
  3. capturecaptured · id 7bf92eca
  4. controlstepped to tick 132 · checksum 7bf92eca

illustration · drawn in your browserAn illustration: the engine's four verbs played on the small browser simulation. The verbs are the engine's; the game is a sketch.

stage 1-7Your code

Your game is your code.

A game on Press Start is a normal Rust codebase, and it is yours. 89 engine crates bring what a game needs: terrain, physics, animation, UI, navigation, networking and more.

Nothing hides behind a menu. The engine is tested the way your game will be: by code that runs, steps and asserts.

A game is Rust code plus documents, both plain text.

Read more
use press_start_test_app::{advance, fixed_step_app};

#[derive(Resource, Default)]
struct TickCount(u64);

fn count_ticks(mut count: ResMut<TickCount>) {
    count.0 += 1;
}

#[test]
fn three_fixed_steps_a_frame_are_thirty_after_ten_frames() {
    let mut app = fixed_step_app(3);
    app.init_resource::<TickCount>();
    app.add_systems(FixedUpdate, count_ticks);

    app.update(); // priming: Startup runs, zero fixed steps
    assert_eq!(app.world().resource::<TickCount>().0, 0);

    advance(&mut app, 10);
    assert_eq!(app.world().resource::<TickCount>().0, 30);
}
from the engine · imports trimmedOne of the engine's own tests, imports trimmed: a fixed-step app runs three ticks a frame, so ten frames are thirty ticks.docs/00-build-a-game/test-app.md · 35-55 · 45aeffd

stage 1-8Built today

What is built, counted by a tool.

We keep a checklist of everything a full game engine needs: 404 features, from terrain to crash reports. A feature counts as built only when a test holds every line of its description, and the tally is made by a tool, never by hand.

Today 103 are built and 129 are partly there, with the missing parts named. We publish the misses.

Built todayengine c998685

103of 404 · built

  • World buildingscenes, terrain, 2D, navigation16/54
  • Simulationphysics, input, cameras17/67
  • Renderinglighting, shaders, textures7/57
  • Asset creationmodeling, rigging, animation18/75
  • Game servicesaudio, UI, save, localisation24/85
  • Reachnetworking, export, platforms4/42
  • Beyond the usualwhat no engine ships, written down anyway17/24

stage 1-9The road

Where we are.

Press Start is not public yet. This is where it is going, one line a stop, with no dates.

Read more
  1. Nowyou are herePrivate beta. The engine is built and tested in private, and the list is open.
  2. NextVersion 1. A launcher, a new project from a template, save, build, Windows export. No account required, and it works offline.
  3. ThenVersion 1.x. Regular releases, more of the engine, more platforms.
player 1 · ready

Want in early?

Join the beta and we email you when version 1 opens. Nothing else, unless you ask.