Games as data and systems
Components with Zod schemas, resources, events, systems in phases and a seeded RNG. Levels, inputs and replays are validated JSON.
2D and 3D games in TypeScript. The same level, seed and inputs give the same run, tick for tick, in Node and in every browser, so every run is a replay an agent can save, share and check.
npm install umbra-engineimport { defineComponent, defineGame, runGame, z } from "umbra-engine";
const Counter = defineComponent("counter", z.number().int());
// Each tick's input is added to every counter; reaching 10 wins.
const adder = defineGame({
name: "adder",
input: z.number().int(),
components: [Counter],
setup: (world) => { world.spawn(Counter(0)); },
systems: [function add(world, n) { for (const [e, v] of world.query(Counter)) world.set(e, Counter, v + n); }],
outcome: (world) => (world.first(Counter)![1] >= 10 ? "win" : undefined),
});
const r = await runGame(adder, null, { seed: 0, inputs: [3, 3, 3, 3] });
console.log(r.outcome, r.ticks, r.finalStateHash); // "win" 4, and the same hash everywhereThen read Getting started, or open the playground to play the 3D room, the 2D collect game and the 2D physics platformer in your browser.