Start --> Quickstart

The path is the same for you and for a coding agent. Package install is public. Creator login is a browser device flow. Never paste an access token. After the first ship, fine-tune the game and ship again.

1. Create a project

Sign in at app.lokiplay.cc and create a project. Copy the project ID. If you use an agent, copy the project prompt from the desk and paste it into the repo.

2. Install the client

In the game repository, pin the published SDK. Keep the existing stack and UI.

npm view @lokiplay/sdk@0.5.8 version
npm install @lokiplay/sdk@0.5.8

Import it as usual, but leave @lokiplay/sdk external in the production build (Vite: build.rollupOptions.external: ["@lokiplay/sdk"]) and ship an ES module entry. Loki serves the SDK from the game host at /loki/sdk.js and maps the import to it, so compatible networking fixes reach players on refresh without a rebuild. Do not import it from a Web Worker or cache it in a game service worker. Check the finished build with npx lokiplay preview before you ship.

Optional overlay:

npm install @lokiplay/ui-web@0.5.8

Do not install @loki/*, unofficial packages named Loki, or @heroiclabs/nakama-js.

3. Add a room-entry flow

Installing the SDK does not add any screen. Run the flow through the lobby controller and build every screen yourself, in the game’s own theme:

const lobby = client.createLobby({
  makeRoom: () => client.createSynchronizedRoom({ initialState, reduce }),
  minPlayers: 2,
  leaderboardId: "high-scores",
});
lobby.subscribe((state) => render(state)); // phase, room, publicRooms, leaderboard
await lobby.createPrivate();               // or createPublic(), joinWithCode(code), joinPublic(roomId)

The controller draws nothing. It creates a fresh room for each match, awaits leave() before another entry, times out every creating, joining, and searching step, cancels a search, and decides when the roster is ready to start. Every game builds these screens:

  • Create room, join with an invite code, copy invite, and start when ready.
  • A Create private room control and a Create public room control, a public room list, and join from that list.
  • A Match control with searching, cancel, timeout, waiting, and error states.
  • A per-game Leaderboard with display-name collection or a sensible fallback, plus loading, empty, pagination, submission, and error states.

Public rooms, Match, and the Leaderboard are required in every game. Loki’s SDK does not add a public lobby screen, and the Loki overlay does not create, list, or join rooms. Do not make every room public.

Player count, teams, and scoring stay creator decisions; if the game has no numeric result to store, ask the creator once what to record instead of inventing a scoring rule. Leaderboards are per-game/project and available to guest sessions without a creator account — client-submitted scores are not an anti-cheat boundary.

4. Write game.json

{
  "schemaVersion": 1,
  "name": "my-game",
  "entrypoint": "index.html",
  "multiplayer": {
    "enabled": true,
    "authority": "host",
    "maxPlayers": 8,
    "tickRate": 30
  },
  "networkAllowlist": []
}

Do not invent extra game.json fields. See the manifest.

5. Integrate the SDK

On a Loki play page, call createHostedLokiClient({ projectId }) once at boot. It listens for loki:init, requests the session immediately, and returns an authenticated client. Do not wait for a Create/Join click — the play shell times out around 15 seconds.

import { createHostedLokiClient } from "@lokiplay/sdk";

const client = await createHostedLokiClient({
  projectId, // the UUID from the creator desk
  fallbackTransport, // optional FirstPartyTransport for local preview
});

const room = client.createSynchronizedRoom({
  initialState,
  reduce,
});

await room.create();
// or: await room.join({ inviteCode });

Pick createSynchronizedRoom() for turns and discrete events. Pick createRealtimeRoom() only for a continuous host simulation. Do not run both for the same mode. Details: multiplayer.

6. Log in and connect

Login still needs the production API origin in the environment:

LOKI_API_URL=https://api.lokiplay.cc npx lokiplay@0.5.8 login

Open the printed URL, confirm the code, and approve this terminal. Then:

npx lokiplay@0.5.8 connect --project <project-uuid>

That writes .loki/project.json and AGENTS.md. It does not put secrets in the repo.

7. Validate and ship

npx lokiplay@0.5.8 validate
npx lokiplay@0.5.8 ship

ship builds the project, copies game.json into the output, validates, uploads a zip, waits for security review, activates the release, and prints a playable URL. A blocked or quarantined build never becomes that URL.

8. Fine-tune, then play

Open the playable URL. Invite with the 6-digit room code Loki issued. Then keep going: confirm seats and start conditions, fix the lobby, tune the reducer or realtime profile, and ship again. Do not invent room keys.

The play link does not pick up those changes by itself. Local edits, including game.json, the lobby, and authority, stay off the live URL until ship activates a new release. The same link then serves that release. Reload the page after the ship.