From 1e869dca62331d6328fc3f39c92771c8ba3a05aa Mon Sep 17 00:00:00 2001 From: Daniel Widgren Date: Thu, 30 Apr 2026 23:14:32 +0200 Subject: [PATCH] docs: narrow scope to protocol-only transport The previous README claimed full coverage of worlds, terrain, voting, economy, leaderboards, social, tournaments, and storage as stable features. The actual implementation is a thin WS+codec library with scaffolded typed REST helpers, and the architectural direction is to drop those helpers as the SDK narrows to a protocol-only transport. Rewrite the README to: - State the protocol-only scope explicitly - Mark typed REST helpers as deprecated for v1.0 - Show a working WebSocket-based quickstart using only the in-scope API - Point engine/framework integrations at examples/ rather than bundling No code change. Code refactor follows in a separate PR. --- README.md | 84 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 5a50c23..3e30bf0 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,18 @@ TypeScript client SDK for the [Asobi](https://github.com/widgrensit/asobi) game backend. Universal — runs in modern browsers and Node 22+. +## Scope + +asobi-js is a thin transport client for the asobi protocol. It connects, authenticates, encodes and decodes message frames, manages reconnection and session resume, and dispatches RPC calls and pubsub subscriptions. That's the whole library. + +asobi-js does not provide world or match abstractions, voting, terrain, economy, or any other game-shape helper — those are decisions your game makes, not your transport. Phaser, Three.js, and Pixi integrations live as opt-in adapters under [`examples/`](./examples/), not as a bundled API. + +Keeping the core small is deliberate: one library, one job, no surprises in your bundle, no opinions about how your game models itself. If you want game-shape primitives, write them on top of asobi-js — they are 50 lines, not a dependency. + +## Status + +**Pre-1.0.** The current v0.x publishes additional typed REST helpers (matchmaker, leaderboards, economy, social, etc.) inherited from earlier scaffolding. These are scheduled for removal as the SDK narrows to its protocol-only scope. Build new code against the WebSocket transport described below; treat the typed REST modules as deprecated. + ## Installation ```bash @@ -21,59 +33,59 @@ cd sdk_demo_backend && docker compose up -d That serves at `http://localhost:8084` (HTTP + WebSocket on `/ws`) with a 2-player `demo` mode. For the full reference game (arena shooter, boons, modifiers, bots) see [`asobi_arena_lua`](https://github.com/widgrensit/asobi_arena_lua). -## Quick Start +## Quick start ```ts -import { Asobi } from "@widgrensit/asobi"; +import { AsobiWebSocket } from "@widgrensit/asobi"; -const asobi = new Asobi({ baseUrl: "http://localhost:8084" }); - -// Register a player (or login if the username already exists). -const { session_token, player_id } = await asobi.auth.register({ - username: "player1", - password: "secret", - display_name: "Player One", +const ws = new AsobiWebSocket({ + url: "ws://localhost:8084/ws", + token: "your-session-token", }); -console.log("registered as", player_id); -const ws = asobi.websocket(); await ws.connect(); -// Subscribe BEFORE queueing — the server may push immediately. -// match.matched (matchmaker push) and match.joined (reply to a client- -// initiated match.join) both signal "in a match — match.state will follow." -const off = ws.on("match.matched", (payload) => { - console.log("matched", payload.match_id); -}); +// Subscribe to server-pushed events on any topic ws.on("match.state", (payload) => { - console.log("tick", payload.tick, "players", Object.keys(payload.players ?? {}).length); + console.log("tick", payload.tick); }); -ws.sendFire("matchmaker.add", { mode: "demo" }); +// Fire-and-forget pubsub publish +ws.send("match.input", { move_x: 1, move_y: 0 }); + +// RPC: send and await a typed reply +const reply = await ws.send("match.join", { match_id: "abc" }); +console.log("joined", reply); + +// Disconnect cleanly +ws.close(); ``` -`ws.on(event, handler)` returns an unsubscribe function — call it to detach the listener. +Topics (`match.state`, `world.entity_added`, etc.) are opaque to this SDK — you publish and subscribe to whatever your server emits. See the [WebSocket protocol guide](https://github.com/widgrensit/asobi/blob/main/guides/websocket-protocol.md) for the full event surface. + +## API + +```ts +new AsobiWebSocket({ url, token, reconnect?, reconnectInterval?, maxReconnectAttempts?, heartbeatInterval? }) + +ws.connect(): Promise> +ws.close(): void +ws.send(type: string, payload?: object): Promise> // RPC +ws.on(event: string, handler: (payload) => void): void +ws.off(event: string, handler): void +``` -`sendFire(type, payload)` is fire-and-forget. `send(type, payload)` is RPC-style: it allocates a correlation id and resolves with the matching server reply (10 s timeout). +The `"*"` event receives every frame, useful for debugging or building a custom dispatcher. -See the [WebSocket protocol guide](https://github.com/widgrensit/asobi/blob/main/guides/websocket-protocol.md) for the full event surface. +## Engine and framework adapters -## Features +Game-engine and framework integrations live as opt-in examples, not as bundled exports: -| Subsystem | REST | WebSocket | -|---|---|---| -| Auth, players, IAP | ✓ | — | -| Matches & matchmaker | ✓ | ✓ | -| Worlds (MMO-scale, terrain) | ✓ | ✓ | -| Chat & direct messages | ✓ | ✓ | -| Social (friends, groups) | ✓ | — | -| Economy (wallets, store, inventory) | ✓ | — | -| Leaderboards & tournaments | ✓ | — | -| Cloud saves & storage | ✓ | — | -| Presence & notifications | ✓ | ✓ | -| Voting | ✓ | ✓ | +- `examples/phaser/` — Phaser 3 helper for driving the SDK from a Scene +- `examples/three/` — Three.js loop integration +- `examples/pixi/` — Pixi.js loop integration -The `AsobiWebSocket` class exposes a generic `on(event, cb)` event emitter plus typed `send()` / `sendFire()` helpers. The `"*"` event receives all messages, useful for debugging or a custom dispatcher. +(Examples are added as community contributions land.) The REST modules under `Asobi` are the v0.x compatibility surface — the long-term direction is protocol-only (everything over `AsobiWebSocket`).