Charades where you type the clue instead of acting it out. A player types a free-text motion description, and DeepMotion's SayMotion API generates it live on a 3D character in about 20 seconds — everyone else races to guess what it just performed.
Concept prototype — one hypothesis, not a shipped game
Full round captured from the running prototype: type a prompt → live SayMotion generation → reveal on the imported character.
~20sruntime text-to-motion generation latency, per the live SayMotion API
0pre-baked animations — every clip is generated at runtime from a typed prompt
5async API calls orchestrated per round: auth, model lookup, submit, poll, download
2undocumented integration surprises found by reading the SDK source, not the docs
What this prototype tests
A design bet and a technical bet, tested together
Design bet: watching an AI generate a chaotic physical interpretation of a friend's prompt, then racing to guess it, is fun enough on its own to want another round. Technical bet: a .glb file returned by a partner API can be downloaded and played back on a runtime-imported skeleton in Godot 4.6. Full concept in design/gdd/game-concept.md.
Pillar 1
AI is the performer, not you
No player is ever judged on their own acting — the AI takes the credit or the blame, removing the embarrassment barrier Charades normally carries.
Pillar 2
Chaos is content
A weird or wrong AI-generated animation isn't a bug, it's the punchline. Features that make output more "correct" at the cost of funny lose.
Pillar 3
Every reveal is shareable
The generated clip is the entire marketing engine — every UX and technical call defaults toward "this could be posted online in 10 seconds."
Pillar 4
Nobody waits bored
Real generation latency (15-25s) is a fact of the tech, designed around rather than hidden — every wait needs something to react to.
Live API integration
A real partner API, driven end to end at runtime
scripts/saymotion_client.gd is a from-scratch GDScript client for DeepMotion's SayMotion REST API — no SDK for Godot exists, so this reads raw HTTP responses, parses a session cookie by hand, and drives an async job through to a playable animation.
Two surprises the docs didn't mention
Found by reading the official SDK source and logging raw responses when the quickstart wasn't enough — the kind of debugging a forward-deployed engineer does against any partner's real API.
Symptom · job submit always 500'd
"Model not found" on every job, despite valid auth and a well-formed prompt — the quickstart doesn't mention a required parameter.
Fix
SayMotion requires a model param naming one of the account's own character model IDs. Added _ensure_model_id(), lazily resolved via listModels and cached for the session.
Symptom · polling crashed on the first real job
Code assumed the job id (rid) was numeric and cast it with int() — it crashed the moment a real job came back.
Fix
Logged the raw response: rid is an opaque string like "u5op75geKRgmDXVRfQAB21-text2motion". Never cast it — pass it through as-is.
Symptom · session cookie never attached
Godot's HTTPRequest has no cookie jar — the API's session auth relies on the browser/client remembering a cookie between calls.
Fix
Parses the raw Set-Cookie response header by hand for the dmsess value, then threads it manually into every subsequent request.
Prototype scope, stated up front
Built to answer one question, not to ship
This is a single-scene, single-screen local test — the point is to de-risk the SayMotion integration and the core fun loop before any production build starts. Failure is designed for: every network/API error surfaces its exact message in-UI, and a manual .glb-upload button stays available so a live playtest never hard-stops on an API hiccup.
Deliberately not in this prototype — deferred to the real MVP if the hypothesis holds:
No networking or multiplayer — one shared screen, verbal guessing, local test group only
No accounts, no persistent scoring across sessions
No art polish, no audio, no character skins — 8 hardcoded secret words
No server-side credential relay — the API secret is read client-side from a local .env, which is fine for a prototype but must never ship this way in production
Why this matters for forward-deployed engineering
The same loop as a customer integration
Spec before code
The full design (pillars, MDA player-psychology breakdown, MVP cut lines) was written down before any prototype code, so the prototype tested one clear hypothesis instead of drifting.
A real partner API, not a mock
No Godot SDK exists for SayMotion — integrated the raw REST API directly: manual cookie handling, async job polling, and two undocumented requirements found by reading the source.
Fails visibly, ships a fallback
Every API failure surfaces its exact error in-UI, with a manual upload path as a fallback — production-grade resilience thinking applied even to a throwaway prototype.