بنقرة واحدة
tinyworld-integrations
Use when changing Tiny World Builder API, webhook, SSE, MCP, plugin, or automation examples.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Use when changing Tiny World Builder API, webhook, SSE, MCP, plugin, or automation examples.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Use when changing Tiny World Builder renderer setup, shadows, smoke, voxel clouds, ghost board render cost, frame loop, or GPU performance.
Use when changing the first-class Island Viewer shell, sequential generated-island viewer routing, or viewer-scoped graphics defaults.
Use when adding, importing, designing, reviewing, or animating low-poly / stylized 3D assets in Tiny World Builder, including Three.js procedural meshes, GLB/GLTF assets, Poly Pizza models, material palettes, scale/orientation, silhouettes, clouds/planes/crop dusters, and toolbar thumbnails.
Use when adding or changing persisted user state — settings defaults, audio, camera/orbit, panel positions, feature flags, and the in-app "Save Defaults" pipeline that snapshots localStorage into tinyworld-defaults.json. Also covers the inline-script regex gotcha that has burned us twice.
Tinyverse collectibles lane — pack reveal, frozen islands, play-mode visits. Universe carousel is archived but code stays in repo.
Use when editing Tiny World Builder prompts, model-generated worlds, Auto suggestions, or any model behavior that should create coherent low-poly 3D board scenes.
| name | tinyworld-integrations |
| description | Use when changing Tiny World Builder API, webhook, SSE, MCP, plugin, or automation examples. |
The app has browser-local integration points plus a small Netlify account backend:
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.TINYWORLD_SITE_URL, before
Netlify deploy URL fallbacks. Do not derive Identity verification targets from
request-controlled origins.res.ok branch (resources, tax payouts, GOLD events, etc.) so
retries do not duplicate already-granted durable rewards.data.gridSize) is authoritative. Treat worlds.grid_size as cached metadata that can be stale; DTOs, previews, pricing/count derivation, and room entry should prefer/sync the payload size so an 8x8 map is not shown as 20x20 in multiplayer.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.community.mjs (/api/community) backs the /community
Discord-lite page — rooms, DMs, members, bans, blocks, invites; tables
auto-create + seed on first request. Channel names are forced lowercase and
the super-owner (TINYWORLD_COMMUNITY_OWNER, default jasonkneen) is made an
owner of every room each request via ensureCommunityDefaults. Only staff
(super-owner / TINYWORLD_COMMUNITY_STAFF) or a room owner can create/delete
channels and ban; the same admin flag gates every privileged action.
Members must pass an anti-AI human check (community_verifications) AND have a
mandatory Twitter/X handle on their profile (GitHub optional) before they
can post/DM/join — saveSocials writes the bare handles to
profiles.twitter/profiles.github (idempotent ALTER TABLE ... ADD COLUMN
in ensureTables; migration 20260615020000_add_profile_socials.sql).
Bootstrap returns me.profileComplete; the page shows a forced
"Complete your profile" modal until Twitter is set and renders both handles on
profile cards. Members can fully edit their profile (display name, bio,
avatar, handles) via saveProfile (alias saveSocials). Avatars are an
allowlisted preset set under assets/avatars/*.png (keys in
AVATAR_KEYS) — no user image uploads, so no NSFW image risk. All
user-authored text (display name + bio) is run through checkTextSafety,
a two-layer filter (hard substrings + whole-word, leet/spacing-normalized)
that rejects sexual / nudity / abusive / hateful content. Tested in
tests/community-profile.test.mjs. community.html signs users in in-page (no bounce to the
builder): it loads vendor/tinyworld-auth.js via the import map for Netlify
Identity email login/signup and calls /api/wallet for Phantom login, storing
the session under the shared tinyworld:auth:wallet-session.v1 key.community-webhook.mjs (/api/community/webhook)
is a server-to-server endpoint for an agent (Hermes) to ban/unban/block/hide or restore/delete
messages/purge spam/delete rooms. Auth is a shared secret
(TINYWORLD_COMMUNITY_WEBHOOK_SECRET) via x-tinyworld-signature: sha256=<hmac of raw body> (preferred) or x-webhook-secret. Shared primitives live in
lib/community-moderation.mjs; community.mjs also emits outbound
message.created events to HERMES_COMMUNITY_WEBHOOK_URL (signed, fire-and-
forget) so the agent can observe and react. Full reference:
docs/community-webhook.md.vendor/tinyworld-auth.js with an import map to vendored
@netlify/identity / gotrue-js; do not reintroduce a remote identity
widget script./.netlify/identity/* failures from
the browser getSettings() probe or login calls as "auth unavailable": hide
sign-in/account commands, keep local/static building usable, and leave cloud
save/share/collab actions gated off. For local account work, use Netlify dev
at http://localhost:8888/tiny-world-builder./api/profile, /api/admin-users, or
community preset-avatar saves must be absolute http(s) URLs. Preset avatar
paths under assets/avatars/*.png are normalized with the trusted site origin
from TINYWORLD_SITE_URL / Netlify URL / deploy URL envs before validation
and persistence; already-absolute URLs are left unchanged.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:*.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.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>.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>.viewer seats, not held in a lobby.
Host clients heartbeat public room metadata to /api/collabs; the home page
feed and /collabs page list those rooms with observer links
(observe=1). This public visibility must not grant edit authority; edits
still require a host-assigned role plus server-side island/zone checks.room.close to PartyKit so every connected peer receives room.closed and no
replacement host is promoted, and they POST { action: 'close', roomId } to
/api/collabs so the public registry stores a short-lived tombstone in
collab_room_closures. Heartbeats for tombstoned rooms must return
{ closed: true } instead of recreating the listing./collabs: authenticated world-admin
sessions call /api/collabs with { action: 'hide', roomId } to add a
short-lived collab_room_hides tombstone that removes a room from public
lists without disconnecting occupants, or { action: 'adminClose', roomId }
to use the close tombstone. When a host sees that close tombstone on its
registry heartbeat, the client must send PartyKit room.close before closing
its socket so connected peers get the same shutdown event as a manual host
stop./api/share row. /api/collabs
copies world_shares.owner_auth_id/profile_id into collab_rooms, exposes
GET /api/collabs?mine=1 for the builder world-menu "Shared rooms" section,
and lets the owner/admin hide (make private), unhide, or ownerClose.
GET /api/collabs?roomId=<id>&control=1 can return a signed
tinyworld-collab-control token; the builder sends control.claim to
PartyKit so the original sharer/admin can reclaim host controls when reopening
their own room link instead of staying an observer.zones.set; the server sanitizes zones,
stores editor zoneIds, and must gate every non-host cell.set against
assigned active zones. Client outlines/labels and local edit checks are UX and
desync prevention only; do not rely on them as the authority.packages/tinyworld-mmo-core/.
It is a dependency-free ESM package for shared GOLD allowance, resource tax,
ledger, join-command, and interest-snapshot contracts. Use it when wiring the
TinyWorld economy guide into PartyKit or Netlify Functions instead of copying
constants between runtime files.tinyverse-nexus hub.
/api/worlds should hide that slug from lists and direct loads, published
world data should normalize to one center stargate with
dest: '__world-picker', and PartyKit safeSpawn() should prefer that gate
so players arrive where the in-world picker exit is.netlify/functions/lib/tinyverse-access.mjs. Do not use
accountMeetsCriteria() or a raw profiles.lobby_access flag as the
authoritative gate; migrations should keep lobby_access default false and
clear it for every non-allowlisted profile.[x,z,terrain]; object/resource cells are [x,z,terrain,kind]. Keep the
renderer validator and applyState() tolerant of both tuple lengths.economy: { resource, charges?, label? }. Live resources are currently
fish, ore, plants, and meat; normalize through
packages/tinyworld-mmo-core/normalizeWorldResourceSpec(...) in PartyKit and
Netlify code instead of inferring resources from visual materials or copying
constants. Compact tuple cells remain the default for ordinary terrain/kind
saves.adminSave, build-role seats, or
world.refresh board replacement inside PartyKit rooms. Island editing and
version publication must live in the dedicated draft/version flow./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.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.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.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.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:
tiny-world-builder.html under
// -------- API / webhooks / SSE bridge --------.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.EventSource against the configured Developer-panel
SSE URL. Each SSE data: payload must be one JSON command accepted by
applyRemoteCommand.place / set_cell, clear, reset, plus runtime-only vehicle controls: vehicle_spawn, vehicle_set_goal, vehicle_controls, vehicle_remove, and vehicle_clear.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.?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.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.