From d88f509bfd44bb46b196fd33c49e64b23430a6d8 Mon Sep 17 00:00:00 2001 From: pat-the-wizard <318180578+pat-the-wizard@users.noreply.github.com> Date: Thu, 8 Oct 2026 10:14:48 +0000 Subject: [PATCH] Docs: pitfalls for agents driving EffectCraft over MCP Adds a short Pitfalls section to docs/agents.md: layer time vs comp time for keyframe tools (#257), layer.timing to set a start time, app.run() in scripts and undo groups, saving early in headless mode (#258), `mcp --gpu` and renderer.active (#262), and the Environment light with lightOptions/source (#261). Docs only; every statement checked against main and a 0.4.0 build. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01S1RGTt6AE3ysiaMQ7X6Nea --- docs/agents.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/agents.md b/docs/agents.md index 36c3bd62..bbc04f77 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -107,6 +107,34 @@ Short recipes; every step is one tool call. The desktop app checks footage in the background after every open (a "Checking footage" job in the Progress panel, `jobs.list`); headless sessions run `footage.check` when they want it. + +### Pitfalls + +Things that tripped up a long agent-driven session (a multi-scene 3D piece built entirely over MCP). + +- **Layer time vs comp time.** `add_keyframe`, `set_property` with `time`, `prop.addKey`, + `keys.select` and `keys.set` take layer time; `get_property` and `render_frame` take comp time; + `run_script`'s `setValueAtTime` and `keyTime` use comp time, as in After Effects. On a layer that + doesn't start at 0, such as a nested comp placed later, subtract the layer's start time from the + comp time before keying (unstretched layers), or set the keys from `run_script` + ([#257](https://github.com/storytold/effectcraft/issues/257)). +- **Moving a layer in time.** `execute_command layer.timing {"layers":["Scene 2"],"start":5.1}` sets + the start time in comp seconds and moves the in and out points with it. +- **Loops in scripts.** `run_script` can call any engine command with `app.run(id, params)`, for + example `app.run("layer.new3dPrimitive", {kind: "cube", position: [x, y, z]})` inside a loop. A + script that throws keeps the edits it already made: wrap it in `app.beginUndoGroup()` / + `app.endUndoGroup()` so one `undo {}` removes them all. (`batch` rolls back on its own.) +- **Save early in headless mode.** The headless server keeps the project in memory only. If the + client restarts the server, unsaved work is gone, so call `save_project {"path": …}` after each + milestone ([#258](https://github.com/storytold/effectcraft/issues/258)). +- **GPU.** Headless sessions render on the CPU. Start the server with `["mcp", "--gpu"]` to use the + GPU compositor; `get_project` shows the backend in use under `renderer.active` + ([#262](https://github.com/storytold/effectcraft/issues/262)). +- **Environment light.** `layer.newLight` also accepts `"kind":"Environment"`: an equirectangular + image that metallic surfaces reflect. Set its `lightOptions/source` to a footage, comp or solid + layer by layer id; with no source it uses the comp's Environment Layer (`layer.environment`) + ([#261](https://github.com/storytold/effectcraft/issues/261)). + ### Cookbook (from end-to-end QA) The scenarios in `crates/automation/tests/qa/` and `apps/effectcraft-cli/tests/qa_template.rs`