Skip to main content
Glama

smear_frame

Draw a motion smear on one animation frame: stretch or echo the subject along its measured movement vector so fast action reads as speed instead of teleporting.

Instructions

Draw one frame's subject along its own path, so fast movement reads as speed.

Between two frames of a fast movement the eye expects a **smear**: one frame where the
subject is stretched along where it came from, or drawn several times faintly, so the
movement reads as speed rather than as teleportation. `offset_cels` produces the
movement; this describes one frame of it.

The movement vector is taken from the sprite rather than restated by the caller: it is
the shift between the centre of the drawn content on `from_frame` and on `frame`. The
*content* box, not `cel.position`, because any tool here that writes a whole canvas
back leaves the position at (0, 0) on every frame, and a position diff would then read
zero while the drawing plainly moved.

Args:
    frame: The frame to smear. Its own cel is the subject and stays on top, unchanged;
        the trail is drawn behind it. Only this frame is written.
    from_frame: The frame the movement came from. Defaults to the one before `frame`.
    mode: `stretch` draws the subject once, elongated back along the vector and
        thinning to a single pixel at the tip, which is the classic one-frame smear.
        `echo` draws it `steps` times along the vector, each copy a step further down
        the ramp, which is the multiple-exposure smear.
    strength: How far back the smear reaches, as a fraction of the movement. 0.6 is a
        trail that clearly trails; 1.0 reaches all the way to the previous position;
        above 1 it overshoots, which is a real choice an animator makes.
    steps: How many copies `echo` draws. Defaults to 3, and is refused with
        `mode="stretch"` rather than silently ignored.
    ramp: The colours, darkest first, the trail is allowed to use, as `generate_ramp`
        returns them. **Pass this.** Each pixel of the trail is the nearest ramp entry
        to the subject's own colour there, stepped toward the dark end and clamped
        (never wrapped), so `palette_conformance` stays at 1.0, which is the property
        every shading tool here holds to and what a pixel artist actually draws.
        Without it the fallback is opacity, and the fallback **leaves the palette**:
        the trail is then made of colours that are not in the sprite, which is motion
        blur rather than a smear. On an *indexed* sprite the ramp is required rather
        than preferred, and the call is refused without one: an indexed pixel is an
        offset into a palette and carries no alpha, so the fallback would snap every
        copy back to the subject's own colour and draw a solid blob.

Refuses rather than producing a blur of nothing: a frame with no movement to smear
(the two content boxes sit at the same place, and the message says where they are), a
movement too short to smear at this strength (it names the pixels and the length that
would result), `frame` 1 with no earlier frame, `from_frame` equal to `frame`, either
frame undrawn, a group or tilemap layer, a ramp of fewer than two colours or one given
as palette indices, `steps` with `stretch`, and a frame that shares its image with
another frame, since a linked cel would put the smear on every frame in the group and
the whole point is that the unsmeared frames are untouched.

Returns the vector it measured and where it came from, the plots it drew, and the
cel's bounds before and after, so the claim that the smear lies along the movement can
be checked. On an indexed sprite it also returns `trail_on_palette`: what the trail's
own target colours resolve to on this palette, and a warning naming the copies that
will come out the same colour because two of those targets landed on one entry. That
is a different finding from the ramp headroom one above it, which measures the art.
`validate_loop` will now report this frame as breaking the spacing series, which is
correct: a smear frame is one that legitimately does.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
modeNoDefault: "stretch".stretch
rampNo
frameYes
layerYes
stepsNo
filenameYes
strengthNoDefault: 0.6.
from_frameNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv0.10.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are sparse (readOnlyHint=false, openWorldHint=false), so the description must carry behavioral detail, and it does: it discloses the fallback behavior (opacity leaves the palette), the indexed-sprite refusal, the non-destructive nature (only this frame is written, unsmeared frames untouched), linked-cel refusal, and the return contents. This is far richer than the annotations. No contradiction with readOnlyHint=false (it writes).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well structured and front-loaded with the core purpose, then Args, refusals, and returns. It is long but the length is earned by the number of semantic traps (ramp requirement, indexed sprites, refusals). Some repetition exists but it is largely informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 8 params, no output schema, and sparse annotations, the description covers purpose, modes, required args, fallback behavior, refusals, return contents, and interaction with validate_loop. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25%, so the description must compensate, and it does for mode, strength, steps, and ramp, explaining semantics and edge cases (steps refused with stretch, ramp required on indexed sprites). It also explains how the vector is derived (content box, not cel.position). However, filename and layer are not addressed, and the frame/from_frame descriptions are brief.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the verb and resource ("Draw one frame's subject along its own path") and distinguishes this tool from its closest sibling: ``offset_cels`` produces the movement; this describes one frame of it. An agent can tell immediately this is a smear-frame tool, not a movement tool, and it references the sibling that creates the movement being smeared.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description names the alternative (`offset_cels`) and distinguishes its role, states which mode to use when (`stretch` vs `echo`), requires a ramp, and describes refusal conditions that effectively serve as when-not-to-use guidance. It explicitly calls out the indexed-sprite case. Usage conditions are well specified.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools