An 8 × 8 km world generated from one seed, compiled into one Trillion3D cache and played in the browser: on foot, by car or by plane.
Play it ↗ · Trillion3D ↗ · Quick start · Commands · Structure · Deploy
Six regions packed around an airport — mountains, a city with its harbour, a desert, countryside and a coast with islands — share one heightfield, so their borders have no seam. The generator writes them as one glTF; the Trillion3D native compiler turns it into one cache of clustered pages; the page streams what the frame reads under fixed memory budgets. The engine runs physical bodies and streamed cooked collision in its worker. A separate bounded worker advances traffic and pedestrians.
It lives apart from Trillion3D because its cook takes about forty minutes: the engine's own checks stay fast, and this repository cooks only when its generator, its compiler or its engine commit change.
Node ≥ 22.18, pnpm 11, git; Rust (stable) for the cook.
pnpm install
pnpm run engine:compiler # check out the pinned engine, build its native compiler
pnpm run cook # generate and compile the world into dist/assets/<key>/
pnpm run build # bundle the page into dist/
pnpm run serve # http://localhost:4180/A browser with WebGPU plays it; the engine falls back to WebGL2 elsewhere.
On foot, Trillion3D's native physical character owns movement, jumps, collisions and the camera: W A S D or the arrow keys move, Shift runs and Space jumps. Click the canvas to look with the mouse; Escape releases it. E enters or leaves a nearby vehicle. Native controller changes release the pointer; click again to look after switching modes. Crouching and a separate stamina system are not provided; character behavior follows the engine.
| Command | What it does |
|---|---|
pnpm run engine |
Checks out the pinned Trillion3D commit under .engine/ (packages/ only) |
pnpm run engine:compiler |
The same, then builds the native compiler with Cargo |
pnpm run cook |
Generates the world and compiles it (--source-only skips the compiler) |
pnpm run build |
Bundles the engine, the page, the kit and the physics worker into dist/ |
pnpm run serve |
Serves dist/ locally |
pnpm test |
The unit suite (node --test) |
pnpm run validate |
Every gate: validate:quick, validate:typescript, then the tests |
pnpm run validate:quick |
Format, lint, 200-line limit, unused code (knip) |
pnpm run validate:typescript |
Type-checks the page against the engine, then builds it |
generator/ the world: plan and terrain, the six regions, props, glTF writer, physics data
page/ the page: index.html, the play layer and its physics worker, the sky
page/kit/ the panel, counters and seeded numbers, copied from Trillion3D's example kit
scripts/ engine checkout, cook and its key, build, local server, line check
The engine is consumed through its public entry points only, at the commit package.json pins
(trillion3d.commit): the page bundles packages/sdk-browser/src/index.ts and its workers, and
the cook runs the native compiler's command line. pnpm run engine checks that commit out under
.engine/ (ignored by git); nothing of the engine is copied here. A pnpm git dependency cannot
carry it: pnpm packs a git dependency by its files field, which ships the built SDK only.
Moving to a newer engine is one change of trillion3d.commit, proved by validate.
On every push to main, .github/workflows/site.yml cooks the world (or restores it from the
cache under its key), builds the page, and transfers dist/ with rsync. The cooked world is
published under assets/<key>/, a folder whose content never changes: it is served as immutable.
The page declares its own canonical address, https://www.trillion3d.com/openworld/, which the
workflow checks once the transfer is done. The page is served cross-origin isolated
(Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Embedder-Policy: credentialless), like
the portal: the page does not require it, it is a choice of consistency, and since
crossOriginIsolated is true there the engine uses its shared decoding.
What the server holds, installed once by an idempotent script that lives on the server,
ssh -t gosecure 'sudo bash /data/pasquelin/setup/deploy-setup-trillion3d-openworld.sh':
-
The server folder,
/data/pasquelin/trillion3d-openworld/, next to the portal's web root/data/pasquelin/trillion3d/and apart from it, so that neither deploy ever deletes the other's files. -
A deploy key restricted to that folder, write-only, in the deploy user's
authorized_keys:command="/usr/bin/rrsync -wo /data/pasquelin/trillion3d-openworld",restrict ssh-ed25519 AAAA… github-actions-trillion3d-openworld. -
The nginx snippet
/etc/nginx/snippets/trillion3d-openworld.conf, picked up by thewww.trillion3d.comserver throughinclude /etc/nginx/snippets/trillion3d-*.conf;:location = /openworld { return 301 /openworld/; } location ^~ /openworld/ { alias /data/pasquelin/trillion3d-openworld/; index index.html; add_header Cross-Origin-Opener-Policy same-origin; add_header Cross-Origin-Embedder-Policy credentialless; add_header Cache-Control $openworld_cache; }
-
The cache map
/etc/nginx/conf.d/trillion3d-openworld-cache.conf, in thehttpblock: the cooked world underassets/is immutable, the rest (html, json, runtime) is revalidated.map $uri $openworld_cache { ~^/openworld/assets/ "public, max-age=31536000, immutable"; default "no-cache"; }
-
Four repository secrets, whose
gh secret setcommands the setup script prints:DEPLOY_SSH_KEY(the private key),DEPLOY_KNOWN_HOSTS(the server's host key line),DEPLOY_TARGET(user@host) andDEPLOY_SSH_PORT. Until they are set, the deploy job fails with the list of those missing; the checks and the build stay green. A run started before the secrets were set does not see them: rerun only its deploy job,gh run rerun <id> --failed.
The 8 × 8 km frame contains an original rounded island, a southern bay and three offshore islets. Its chosen land target is 42 ±3 km², with at least 250 m of ocean along every outer edge. The northern mountain spine retains the 2,000 m raw relief envelope; erosion and river cuts determine the final summit. Existing desert, countryside, city, airport and coast modules continue to use the shared composed ground.
Run node scripts/island-report.ts 332 and repeat with seed 333 to inspect the generated
land area, dry components, all four shoreline profiles, settlements, placements, missing road
courses and cook key. Area and dry connectivity are 25 m cell-center approximations;
source tests also cover the complete sampled perimeter, composed terrain seams, airport,
land spawns, road segments and actual crop vertices. failedConnections reports route builds
that produced no course; it does not prove geometric road junctions or driving grades. The
traversal issue owns that separate proof. No cooked content or hardware performance result is
included in the geography report.
The rules are Trillion3D's (AGENTS.md): one issue and one pull request per change,
on a branch <issue>-<short-name>, with validate and pr-body green. pnpm install installs
the tracked git hooks; .github/ruleset.json is the ruleset applied to main.
The original CC0 building models and atlases under assets/buildings/ retain their own
asset-specific licenses and pinned provenance. The application license below
does not replace their CC0 terms. Separate street block workloads
can be cooked with pnpm workload one-block, four-blocks or sixteen-blocks and viewed at
workload.html after pnpm build and pnpm serve.
Trillion3D Open World is published under the PolyForm Noncommercial License 1.0.0: free for noncommercial use, study, research and personal projects. Commercial use requires a separate licence from the copyright holder — open an issue or contact the author.
Copyright © 2026 Alban Pasquelin.