HOSTING FOR AI-BUILT APPS

Orbit Garden: a tiny universe on Yeeted

Plant a moon and watch a little solar system respond. Switch to A sense of scale to visit Earth and the Moon, the inner planets, the asteroid belt, Neptune and the Kuiper belt, a comet orbit, and our nearest stellar neighbors.

This example is plain HTML, CSS and browser JavaScript modules. There are no packages to install, no build step, database, secret, external font or image request. Yeeted detects the root index.html and serves it as a static app. The root page is also the deployment health probe. Simulation state stays in the current browser tab. Share a snapshot in a URL fragment to reopen it later; fragments stay in the browser and are not sent to the hosting server.

Play

Run and test locally

From this directory:

node --test test/*.test.mjs
python3 -m http.server 8000 --bind 127.0.0.1

Open http://localhost:8000. Use a current browser with ES modules and Canvas. Node 22 or newer is needed only for the tests, not to run the app.

sh smoke.sh http://localhost:8000

Set PLAYWRIGHT_CHANNEL=chrome to use an installed Chrome instead of a Playwright-managed browser.

The optional browser integration test uses an externally installed Playwright:

ORBIT_URL=http://localhost:8000 PLAYWRIGHT_MODULE=/absolute/path/to/playwright/index.mjs \
  node test/browser.mjs

It checks planting, pausing, resetting, touch-sized layout, reduced motion, scale navigation, object visits, the tour, postcard downloads, undo, shared snapshot restoration, invalid links and module loading errors. Physics tests cover momentum, collision mass, bounded orbit drift, input limits and bounded trails. Atlas tests check distance data, projection and zoom invariants.

Deploy on Yeeted

Follow the deployment walkthrough. Deploy the contents of this directory as the source root, not the enclosing examples repository. Include index.html, style.css and every module in src/. No package.json, Dockerfile or yeeted.yaml is needed.

Ask your agent: "Deploy Orbit Garden to Yeeted development from these files, then run its smoke checks." A development preview expires; promote the tested version explicitly if you want an always-on production site. The app is stateless, so replicas need no shared datastore or session coordination.

sh smoke.sh "$PREVIEW_URL"

The repository's live examples suite includes orbit-vanilla and checks its HTML, stylesheet and module endpoints. HTTP probes confirm serving; the browser integration test verifies the actual controls and canvas rendering.

How it works and its limits

src/physics.js implements softened pairwise gravity with fixed-step velocity Verlet integration. All bodies move, including the suns. Touching bodies merge while conserving mass and momentum. Adding a moon introduces new mass and momentum from outside the simulation. This is a playful model in normalized units, not a prediction of real celestial trajectories.

Work is capped at 32 bodies, 180 trail points per body, 16 physics steps per frame and a device-pixel ratio of two. Predictions are limited to 360 steps (240 in the UI) and recalculated at most once per 80 ms while aiming. Static atlas views and paused gardens are redrawn only after an interaction or resize. Slow frames drop catch-up time, so wall time and simulated time can diverge. Escaping bodies remain in the simulation and count toward the limit; zoom out or reset to find them.

src/universe.js contains the educational atlas. Each view uses one linear distance scale; the slider changes that scale logarithmically. Body dots are enlarged when necessary to stay visible. Distances are approximate and positions are schematic, not live ephemerides. Belt particles represent a population, not individually cataloged objects. Comet positions and star directions are illustrative. The Earth close-up is a stylized drawing, not satellite imagery. There are no remote data calls or analytics.

src/catalog.js supplies sourced object facts and shared hit-testing geometry; src/celestial-art.js draws bounded deterministic illustrations. garden.js and explorer.js own their respective controls, while app.js handles the canvas, gestures and animation loop.

src/experiments.js accepts versioned snapshot fragments up to 16 KiB, at most 32 bodies, finite bounded numbers, unique IDs and restricted names/colors. It reconstructs fresh bodies rather than accepting arbitrary object properties. Invalid links reset to a fresh garden with an explanation. Links preserve body state and time, not trails or UI preferences. They are not encrypted: anyone with the link can read its simulation state.

All examples · Deploy an example