# Add a YoWorlds world

## Connect to the public alpha

Open [the builder desk](https://49.13.75.214/connect) after saving an account. Register an HTTPS origin and download the verification JSON. Download the standalone multiplayer starter from that page, extract it, copy the provided settings into `.env`, put `yoworlds.json` next to `server.mjs`, install dependencies, and start the server. Reverse-proxy your own HTTPS hostname to its local port with WebSocket upgrades enabled. Choose **Verify & connect**. The world appears without a central restart.

Each generated `pb-<UUID>` ID is stable. Verification proves control of the HTTPS origin; a pending claim does not block another owner from proving control. Each account may register three alpha worlds. Keys are shown once, stored only as hashes centrally, and belong exclusively on the world server. `POST /api/worlds/:id/disable` revokes a world using the owner's central session. Rotation/re-enabling currently requires an operator; keep the original private configuration safe.

Use a registered world ID for a specific portal or `random` for an available destination. The Commons serves as the hub. The client includes a destination picker and a reference-scene preview; a custom third-party scene is not a remotely rendered live preview. Servers refresh the registry every 30 seconds. A downloaded runtime is a versioned snapshot; it does not automatically receive security updates.

The standalone starter includes the server adapter and browser runtime, so it runs without this checkout. The following legacy local generator remains useful for isolated development.

## Generate a local JavaScript world

Build the checkout, then generate a project on its own cookie host:

```powershell
npm run build
npm run world:create -- --id world-c --title "Harbour Studio" --url http://127.0.0.4:3003
npm run world:register -- --world worlds/world-c/world.json
```

Restart the central service and existing worlds to read the registration. In the generated directory, run `npm start`, then enter **Harbour Studio** from the central launcher. Normal operation still uses three applications; this fourth host is an integration fixture. The starter has movement, the approved avatar adapter, a shared gold switch, a wardrobe link and one portal to the Commons. `--portal world-b` chooses a different registered target.

The scaffold emits `server.mjs`, `public/client.js`, `public/index.html`, `world.json`, a package script and a local README. It never overwrites an existing directory. The JavaScript server imports the shared TypeScript adapter using the checkout's Node/tsx runtime. Its imports refer to that checkout by absolute file URLs; update them or regenerate after moving the checkout. No published npm package is required.

Change scene construction in `public/client.js`. The example imports `startWorld`, `buildWorld` and `THREE` from `/client/runtime/three.js`, adds a rotating beacon, and returns the scene and update function. Change spawn, bounded collisions, room limit, portal target, item-ID collection and switch position in the public definition. Registration copies that definition into the local registry, so update the corresponding registry entry and restart after configuration changes. Gameplay uses the shared authoritative room; custom server gameplay remains a server-side extension, not code submitted by players.

## Registry and authority

The default public registry is `data/worlds.json`; private keys are in `data/world-keys.json`. Override with `WORLD_REGISTRY_PATH` and `WORLD_KEYS_PATH`. The registration command generates a fresh random key and completes the private key file before publishing its registry entry. It rejects duplicate IDs, unknown/self portal targets, credential-bearing URLs and duplicate cookie hosts. Missing keys stop startup. Existing A/B environment variables remain supported.

Run registration serially while operating the local deployment. These are operator-owned configuration files, not a concurrent registry service. The command exposes no browser registration API. Do not serve the key file or copy it into a generated project's `public` directory. A world claiming the avatar profile gains no publishing or inventory authority. The central service still checks its own catalogue, ownership, ticket destination, grant, order and referral records.

Public APIs explicitly project world metadata; they do not serialize the deployment configuration. Every service needs its own hostname or IP, including worlds that differ in port. `127.0.0.1`, `.2`, `.3`, and `.4` are used in the isolation test. HTTP remains local development only.

## Browser integration boundaries

- `/client/runtime/sdk.js` exports `YoWorlds`, `RoomConnection` and `RequestError`. It uses ordinary own-origin HTTP and WebSocket APIs with local cookies; it does not import Three.js. `enterSession`, `refreshAppearance`, `getDestinations`, `requestTravel`, and `openStore` return promises. `RoomConnection.on` subscribes to typed state, snapshot, appearance, welcome, central-availability and error events and returns an unsubscribe function.
- `/client/runtime/three.js` adds scene/avatar presentation. `startWorld` supplies loading, connection, offline, expired and Home states, input prediction, remote interpolation, public inspection and full-page navigation. It returns a disposable runtime. `/client/runtime/runtime.css` supplies its UI styles.
- `packages/wire` defines versioned public definitions and bounded messages. `apps/world/server.ts` owns cookie-to-grant storage, central calls, entry/store/travel and room admission. `packages/room` owns world-local authority. Renderers never decide ownership.

The build audits transitive browser module graphs and fails if privileged server modules enter a bundle or the renderer-independent SDK imports Three.js. `reports/browser-bundles.json` records the actual built chunks. The generated-project browser test runs the CLI, registers a random private key, starts the emitted JavaScript server on a separate host, renders an avatar, moves, toggles the switch, visits and returns from the store, and takes the portal to A. It checks host-only cookies, one real travel event, and absence of the key from public metadata/log output. Run `npx playwright test tests/e2e/starter.spec.ts` after building; see `reports/world-starter.json` and `reports/screenshots/generated-world.png`.
