Skip to main content
text-to-motion is a skill from the Summer skill library: a guide your AI agent reads when the task matches, so it builds the good version on the first try. Make custom 2-second animation clips from text on the user’s own rigged models: people, animals, props.

When your agent uses it

  • A custom action the curated motion library lacks — nod, bow, shrug, wave with a specific arm, an emotional gesture
  • Animating a non-humanoid rig — a talking flower, animal, creature, turret or prop
  • Adding clips to an uploaded or custom-rigged GLB/FBX model
  • “make the flower nod” / “animate my creature from a text description”

Install

summer setup installs every skill for your agent. To add only this one:
Swap claude-code for your agent, such as codex or cursor. See Skills for every option.

The skill

Summer-hosted text-to-motion turns a text prompt into a 2-second (60 frames) skeletal clip for the user’s own rigged model. One model covers every skeleton with 5-70 bones: humanoids, animals, creatures, cartoon plants, turrets, props. The operation is assets.generate_motion with backend: "text-to-motion". It answers at once with a job; jobs.wait follows it. The finished job’s result.assets lists one animation asset per prompt x take (id, fileUrl, animationName, prompt, take); each is a GLB of the whole model carrying one animation named after its prompt. Trigger on: “make the flower nod”, “animate my creature”, “custom animation from text”, “a bow / shrug / wave with the right arm”, “animate this uploaded rig”, “the library doesn’t have that move”, any animation request for a non-humanoid rig.

Choose the right route

The order

  1. Confirm the rig. The asset must be the user’s own 3d_model GLB/FBX with one skinned armature and 5-70 bones (assets.search({ scope: "mine", assetType: "3d_model" }) / assets.get). If it is unrigged or has odd bone names, read rigging-for-text-motion.md in this directory.
  2. Agree the clip list and cost. Each prompt x take is one billed clip. Run the call below with dryRun: true first: it checks the rig and returns estimate.credits. Show the list and the credits and wait for the user’s OK before submitting.
  3. Submit once. Up to 8 prompts per call, takes 1-4. For rooted characters pass lockJoints with the base bones:
Pass a stable idempotencyKey if you might retry the same request. Prompt writing and every control: prompts-and-controls.md in this directory. 4. Wait for the job. jobs.wait({ jobId: "<job.id>", timeoutSeconds: 50 }), again until finished is true. A job takes about 1-2 minutes. Do not resubmit while it runs. 5. Review, then import. Import the chosen clip assets with summer_import_asset_by_id(assetId, parent, scenePath). Offer to regenerate weak takes with a rephrased prompt or a higher cfgScale; keep the good ones.

Hard rules

  • Only the user’s own rigged models. Never animate assets owned by someone else.
  • Clips are 2 seconds and not guaranteed to loop. For longer actions chain several prompts (“raises both arms”, “holds the pose”, “lowers the arms”) or loop a good take.
  • Locomotion moves the root. Walk/run/jump clips may translate the character; gameplay code owns movement, so strip or ignore root translation for in-place controllers.
  • Never lock joints on characters that walk or jump; the root would be pinned.
  • Report failures with their code. Job failures starting text_motion: (no skinned armature, too many or too few joints, multiple armatures, unknown lock joint) are input problems and the charge is refunded. Fix the rig or the request; do not retry unchanged.
  • A backend without text-to-motion means it is not enabled on this server yet. Fall back to generate-motion (meshy-library) for humanoid clips and say so; do not retry.
  • Do not promise facial animation, finger detail or lip sync. The model animates the skeleton only; blendshapes stay untouched (facial-and-lipsync covers faces).

Request errors

Refusals answer the one error shape: error.code with one next step, and error.details.was naming the reason below.

Without Summer Engine

In a session without Summer Engine tools (the assets profile; the summer-assets skill has the whole loop), follow the order up to the review in step 5 and skip the import. Save the file where the person asked with out (the summer-assets skill says how), and tell them the path and format. Keep the good takes and name each file after its prompt.

Do not stop early

Done means the chosen clips are imported and playing on the model in the scene. For a playable character continue with character-animation-wiring; for state machines, animation-tree.

From a shell

No Summer MCP tools in this session? Run each one as a command; when summer --version is missing or below 4.0, use npx -y summer-engine@latest in place of summer. Fields are flags in kebab-case (--scene-path res://main.tscn) or one --input '<json>', and summer ops describe <op> prints the exact input. The summer-cli skill has the rest.

Files in this skill

  • generate-motion: Attach a library animation clip (idle, walk, run, attack) to a rigged character via AnimationPlayer.
  • character-model: Generate a rigged humanoid (player, NPC, enemy, boss) from a T-pose reference, previewed before rigging.
  • retarget: Apply animation clips from one rigged character to another: one clip library, many models.
  • asset-strategy: Route any ‘I need a [thing]’ asset request to the right skill: 2D, 3D, audio, video, VFX or animation.

Source: library/skills/text-to-motion/SKILL.md, rendered from summer-engine@4.3.0 on npm.