# OpenSpatials Connect

The plugin that connects a game to OpenSpatials, so players' avatars cross between games through links and portals. A creator says **"Make my game connect."** to their AI coding agent; the agent follows these skills, adds a small connector to the game, proves it with a self-check, and reports in plain words.

Version 0.5.4 (2026-11-03): skills 0.5.4 with kit 0.5.4 (every schema file name starts with `openspatials-`). The name `openspatials-connect` is proposed and not yet final.

## What is in it

- `skills/`: five skills, each a plain folder with one `SKILL.md` that any agent can read:
  - `connect-a-web-world`: a Three.js, plain canvas or Kaplay game (Steps 1 to 5);
  - `connect-a-godot-world`: a Godot 4 game and its web export;
  - `send-your-avatar-and-items`: the game's own character and items going out, signed with the game's key (Step 7);
  - `check-a-world`: the self-check and the report to the creator (Steps 6 and 8);
  - `register-a-world`: the world's listing for the OpenSpatials registry, and a site file for a site with several worlds.
- `src/`: the kit files the skills copy into a game (`src/skill/templates/`), the self-check and its tools (`src/skill/`, `src/ownership/tools/`, `src/submit/`), the test games and test characters the self-check uses, and the browser harness, in the layout of the OpenSpatials lab's `src/`. The skills call this folder `SKILL_DIR/..` (`SKILL_DIR` is `src/skill`).
- `package.json`, `package-lock.json`: one dependency, `puppeteer-core`, which drives a headless Chrome for the self-check.
- `PLUGIN-FILES.json`: every file with its source in the lab and its SHA-256. `CHANGES.md`: the history. `LICENSE` (MIT-0) and `NOTICES.md` (third-party licences; the Universal Manifest v0.4 schema copy carries its notice beside it, `UNIVERSAL-MANIFEST-NOTICE.md`).

## Install

The plugin is self-contained: at run time it reads nothing outside its own folder and the creator's game folder, and needs no address beyond loopback (the connector it adds to a game does read other games' files when a player crosses; the self-check answers or refuses those requests itself).

1. Put the plugin folder anywhere outside the game (unzip `openspatials-connect-<version>.zip`, or copy the folder).
2. Install its one dependency, once, in the plugin folder, from the lockfile:

   ```sh
   npm ci --ignore-scripts --no-audit --no-fund --no-update-notifier
   ```

   Add `--offline` to install from the npm cache with no network.
3. Give the agent the skills:
   - **Claude Code**, for one session, with nothing else installed: `claude --plugin-dir <plugin folder>`. This works with the claude.ai account's skill and plugin sync off, for example with `--settings '{"syncClaudeAiSkills":false,"syncClaudeAiPlugins":false}'` and its own `CLAUDE_CONFIG_DIR`.
   - **Claude Code**, installed into a configuration: the plugin folder is also a local marketplace (`.claude-plugin/marketplace.json`, named `openspatials-local`): `claude plugin marketplace add <plugin folder>`, then `claude plugin install openspatials-connect@openspatials-local`. Run `npm ci` (step 2) in the installed copy if it was installed before step 2.
   - **Any other agent** (Codex and others): point it at `<plugin folder>/skills/<skill>/SKILL.md`; "Make my game connect." starts with `connect-a-web-world` or `connect-a-godot-world`.

Needs: Node 22; a Chrome or Chrome for Testing for the self-check (`CHROME_PATH` chooses it and always wins); Godot 4 for Godot games (`GODOT` chooses it).

## The hosted service

The plugin does not connect to the OpenSpatials hosted service yet. The service exists as a local MCP server in the lab (`service/server.mjs`), but it is not deployed and its address (`/mcp/` or a subdomain) is not decided, so there is nothing to connect to, and a connection that starts with the plugin would need an address beyond loopback. When it is hosted, the plugin gains an `.mcp.json` entry for its address. MCP has two eras: revision 2026-07-28 has no handshake (each request carries its version and the client's capabilities; `server/discover`), and revisions 2025-11-25 and earlier open with `initialize`. The service speaks both, so the plugin's entry will rely on that and need no revision of its own.

## Build (in the lab)

```sh
node src/plugin/build.mjs --out <folder> --zip --validate   # <folder>/openspatials-connect/ and its zip; claude plugin validate --strict
node src/plugin/build.mjs --check <folder>                  # exit 1 when the built plugin differs from a fresh build
```

The build copies the import closure of the tools and the kit's entries, and the data files the tools read, byte for byte; it never edits a copy. Change the sources in `src/` and build again.
