tinyworld-integrations

star 953

Use when changing Tiny World Builder API, webhook, SSE, MCP, plugin, or automation examples.

jasonkneen By jasonkneen schedule Updated 6/16/2026

name: tinyworld-integrations description: Use when changing Tiny World Builder API, webhook, SSE, MCP, plugin, or automation examples.

Tiny World Integrations

The app has browser-local integration points plus a small Netlify account backend:

  • Account/profile/cloud-save functions live under netlify/functions/. profile.mjs, builds.mjs, share.mjs, and assets.mjs are routed to /api/profile, /api/builds, /api/share, and /api/assets via each function's exported config.path.
  • Wallet/social functions also live under netlify/functions/: wallet.mjs verifies Phantom-signed Solana wallet challenges and reads $TINYWORLD balances/activity from RPC, wallet-payments.mjs creates Solana Pay payment intents, players.mjs tracks online presence/search/chat requests/parties, and livekit-token.mjs issues LiveKit room tokens when LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET are configured.
  • User auth is Netlify Identity. The browser bridge is self-hosted through vendor/tinyworld-auth.js with an import map to vendored @netlify/identity / gotrue-js; do not reintroduce a remote identity widget script.
  • Account API fetches must send Authorization: Bearer <nf_jwt> when possible and credentials: 'same-origin' so Netlify Functions can resolve the current Identity user. Wallet login uses the same bearer path with signed tw-wallet-v1... session tokens stored under tinyworld:auth:*.
  • For local account/function work, run npx netlify dev and use http://localhost:8888/tiny-world-builder; that port keeps the auth/account UI enabled while the plain static dev server remains anonymous.
  • Cloud worlds are stored as full TinyWorld JSON in Netlify Database builds rows. Existing rows update through PUT /api/builds?id=<id> so named localStorage worlds can stay bound to one cloud row instead of creating duplicates. Public share links create immutable-ish rows in world_shares and load through same-origin ?share=<id> / /api/share?id=<id>.
  • Multiplayer/shared building uses PartyKit separately from Netlify Functions. partykit.json points at party/index.js, local development runs with npm run party:dev on port 1999, and browser rooms connect only when a URL includes ?party=, ?room=, or ?collab=. Collaborate links should reuse a /api/share id as both the world snapshot id and the PartyKit room id: /tiny-world-builder?share=<id>&party=<id>.
  • Local custom assets are account data too: /api/assets stores one asset_libraries row per profile containing custom voxel-build stamps and saved asset templates. Browser hooks in saveCustomVoxelBuildStamps() and saveAssetTemplates() queue a cloud sync after login.
  • Local Netlify Database failures are expected in some netlify dev sessions. Translate 503 Netlify Database is not available... responses into a friendly account/cloud status or warn toast, never a red production-style error toast, raw database message, or visible Local DB offline wording.
  • Wallet/player social functions rely on netlify/database/migrations/20260602120000_wallet_players_social.sql. If those tables are missing in local Netlify dev, classify Postgres 42P01 with isMissingRelations(...) and return a setup-oriented 503 instead of logging raw missing-relation errors as generic 500s.
  • Phantom wallet linking and wallet login must stay challenge/response based: the browser asks Phantom to sign the server-issued message and the function verifies the Ed25519 signature against the Solana public key before linking or minting a wallet session. Do not accept a posted wallet address as proof of ownership. Wallet login requires TINYWORLD_WALLET_SESSION_SECRET (or TINYWORLD_AUTH_SECRET) for HMAC-signed challenge/session tokens. $TINYWORLD mint/payment values come from env (TINYWORLD_TOKEN_MINT, TINYWORLD_PAYMENT_WALLET, optional SOLANA_RPC_URL) rather than client constants.
  • Database schema changes belong in netlify/database/migrations/*.sql. Deploy previews get their own database branch, so use a preview deploy for real Identity + DB verification; local netlify dev is useful for functions but is not a complete Identity social-login test.

Browser-local integration points:

  • Outbound webhooks live in tiny-world-builder.html under // -------- API / webhooks / SSE bridge --------.
  • Optional browser-local probes must be opt-in so the static app stays console-clean: the Cluso in-page embed is LOCAL-DEV-ONLY, injected at runtime by tools/dev-server.js (assets in gitignored cluso/); it must never be referenced by committed/shipped HTML; model-stamp API endpoints load only with ?modelApi=1, ?modelStampApi=1, window.__TWB_MODEL_STAMP_API_ENABLED__ = true, or localStorage['tinyworld:features:model-stamp-api']='1'.
  • fireWebhook(event, payload) batches editor mutations and POSTs { source: 'tiny-world-builder', events } to the configured Developer-panel webhook URL.
  • Inbound automation uses EventSource against the configured Developer-panel SSE URL. Each SSE data: payload must be one JSON command accepted by applyRemoteCommand.
  • Supported inbound ops include place / set_cell, clear, reset, plus runtime-only vehicle controls: vehicle_spawn, vehicle_set_goal, vehicle_controls, vehicle_remove, and vehicle_clear.
  • Runtime vehicles must not pass through each other. Keep traffic behavior in the runtime layer: collision radius + yield radius, brake when another vehicle is inside the envelope, and reroute around occupied road cells after a short blockage when an alternate road path exists.
  • Placed objects on paths are live traffic blockers. isVehicleDrivableCell should allow path cells only when the main kind/extras do not occupy the tile, while bridge cells remain drivable. Call refreshVehiclesForWorldObstacleChange from world edit paths so active auto vehicles reroute immediately when the user drops or removes an obstacle.

Examples live under plugins/examples/:

  • webhook-receiver.js captures outbound webhook batches.
  • sse-command-relay.js exposes /sse for the browser and /command for external clients.
  • send-command.js is a small CLI for the relay.
  • mcp-stdio-bridge.js is a dependency-free MCP stdio server that calls the relay and reads the webhook log.
  • vehicle-road-demo.js is a dependency-free MCP client/demo runner that talks to mcp-stdio-bridge.js, paints a visible road/water/bridge network, spawns runtime vehicles, and retargets them in a loop so the browser remains watchably active.
  • The app also supports browser-native shareable vehicle demo URLs:
    • ?demo=vehicles&seed=tide-ridge-428 creates the small/default visible road demo.
    • ?demo=vehicles-large&seed=metro-culdesac-20&stats=1 creates the default 20×20 scale test with arterial/ring roads, bridge crossings, cul-de-sac endpoints, and 36 autonomous vehicles on long routes.
    • Large-demo params: size= / mapSize= / grid= / gridSize= accept the nearest valid demo grid size from 12 through 20 (12, 16, 20); cars= / carCount= / vehicles= / vehicleCount= accept 1..120 and are capped by available unique endpoints. Keep these demos visually self-identifying: show an active badge, hide overlays that cover the road network, and make vehicles obvious with beacons/markers. During local demo work, tools/dev-server.js should make bare http://localhost:3000/ and no-query http://localhost:3000/tiny-world-builder redirect to the small seed so the user can simply open the port or remembered app URL and watch it. Use the large URL explicitly for scale/perf checks.

When changing command shape, update the app bridge and these examples together.

Install via CLI
npx skills add https://github.com/jasonkneen/tiny-world-builder --skill tinyworld-integrations
Repository Details
star Stars 953
call_split Forks 133
navigation Branch main
article Path SKILL.md
More from Creator