Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
B6 - Animation Canvas Workflow
Updated 2 weeks agoAnimation Canvas Workflow
Sprites · for creators (advanced). Repaint a whole animation on one steady canvas — onion-skin across frames, draw past the original edges — then compile it straight back to replacements. It's the round-trip tk2d never gave you.
You'll be able to: extract an animation clip onto a uniform editing canvas, edit it with real onion-skinning, and compile it back to runtime files — and know exactly where the feature is solid and where it's still young.
Before you start: B1 (the basic dump-edit loop) and a feel for finding sprites. This is the deep end of sprite work.
Why this exists
tk2d stores every animation frame as a tightly-cropped region at its own size, with a per-frame pivot. That's efficient for the game and hostile to editing: no shared canvas, no common registration, so you can't onion-skin and you can't see how frame 3 lines up against frame 2. The classic workaround — dump each frame and eyeball it — is exactly the pain Custom Knight Creator solved for Hollow Knight by giving you one padded canvas per animation.
This workflow brings that round-trip to Stitchwork: it pads every frame of a clip onto one shared, pivot-aligned canvas, lets you paint across the whole thing, then folds your edits back into the game's tight format on compile.
The buttons
All in Graphics → Animation, on their own row beneath the per-sprite buttons — two ways to extract, then compile:
- Extract Vanilla — Phase 1 from the original art (the safe default).
- Extract As Rendered — Phase 1 from whatever's currently applied (to iterate on prior work — see below).
- Compile Animation from Workspace — Phase 2, folds your edits back into replacements.
[image: the Animation tab with the three workflow buttons on their own row]
What's needed for this image: the Animation tab button row showing Extract Vanilla / Extract As Rendered / Compile.
Phase 1 — Extract
Select the clip (let Hornet idle to get Idle, etc.), and click Extract Vanilla. Stitchwork renders every frame onto one uniform, generously-padded canvas, placing each frame's pivot at the same canvas point — so a fixed feature (an eye, a foot) lands on the same pixel every frame. That shared registration is what makes onion-skinning honest: stack the frames and the motion is real, not jitter.
Two things it gets right that matter:
- Vanilla vs. As Rendered. Extract Vanilla pulls the original sprites even with one of your own packs active — you edit the real thing, not your half-finished skin. Extract As Rendered instead reads the live atlas as drawn right now — everything applied, packs and your root workspace, individual
Sprites/and wholeSpritesheets/— so you can reopen and keep editing prior work. (Enable just your own art first, since "as rendered" means whatever's on screen.) - The frames align. Same canvas size, same pivot, no per-frame drift.
The output lands in a workspace folder beside the collection:
Sprites/{CollectionName}/{ClipName}_WIP/
— one PNG per distinct frame (held/reused frames are de-duplicated), plus a {ClipName}_sidecar.yml. The folder opens automatically.
Editing
Open the _WIP PNGs in your editor or animation tool. Because they're identically sized and registered, you can load them as onion-skin layers and paint with every other frame visible underneath. And the canvas is padded, so you can draw past the original silhouette — a longer needle, a billowing cloak — without running out of room.
The canvas is in the same orientation as your SpriteDumper dumps, so it lines up with the rest of your dumped art rather than mirroring it.
Two don'ts:
- Don't hand-edit the
_sidecar.yml. It carries the registration data compile needs to fold each frame back precisely. Leave it alone; if you want a clean slate, just re-extract. - Don't resize the canvas. Keep each PNG at the dimensions extract issued. Compile checks them and will skip a frame whose size changed rather than guess where the art moved — re-extract if you need different room.
Phase 2 — Compile
Click Compile Animation from Workspace. Stitchwork reads each edited frame and folds it back to the runtime format automatically, deciding per frame:
- Stayed within the original footprint → dropped straight back into its slot. A frame you didn't touch comes out identical to vanilla — no change means no change.
- Grew past the footprint → emitted as an oversized replacement with a precise pivot tag so it still registers correctly, and routed to that frame's own collection/material.
It writes the normal Sprites/... replacements and logs a per-frame report to BepInEx/LogOutput.log. Your edited clip is now live, hot-reloaded like any other sprite work.
Don't ship the _WIP folder. It's an editing workspace — Stitchwork deliberately excludes it from loading. What you ship is the ordinary Sprites/ output compile produced.
Reused frames still ripple
Extract collapses a clip to its distinct sprites, so it won't hand you the same shared frame twice. But the underlying rule from Reused Frames is unchanged: a sprite shared across animations changes everywhere it's used when you repaint it. The canvas makes editing easier; it doesn't make a shared frame private.
Where it's solid, where it's young
Honest status, because this is a new feature:
-
Confirmed: Hornet's
Idle(all one flip mode) andDash Upper(a mixedNone+Tk2dattack) — extract, onion-skin edit, compile, correct in-game. -
Mixed flip modes — handled. Within one clip, the game stores some frames mirrored in the atlas and flips them at render; the onion-skin canvas normalises every frame to one facing for editing, and the compile now re-orients each frame back to its own atlas-native orientation (it records each frame's flip mode and mirrors the ones that need it). A clip that mixes modes no longer comes back with half its frames backwards.
-
Still lightly tested — verify in-game, especially:
- Growing a
None(non-flipped) frame past its footprint. The plain mixed case is confirmed; the oversized-and-non-flipped combination is reasoned-correct but newer. If you extend art past the edge on a non-flipped frame, check the new pixels land on the right side. - Frames spanning multiple atlas pages, the
TPackerCWflip mode, and heavy motion (bounds swinging far wider than a breathing idle).
What a failure looks like: a frame facing the wrong way, a feature that jitters between frames on the canvas, or a grown frame sitting offset in-game. Verify every compiled clip in-game. If one comes back wrong, note the animation name and which symptom — that targeted report is what moves the remaining edges from "lightly tested" to "confirmed."
- Growing a
-
No preview gate yet. A "here's what I'm about to write — OK?" confirmation step is planned but not in this build, so compile writes directly. Two consequences worth knowing before you click:
- Compile writes every frame it can read — including frames you didn't touch. Untouched frames come back out carrying the art they were extracted with, and land as ordinary replacement files.
- Same-named outputs are overwritten. If you hand-edited
Sprites/{Coll}/{Mat}/files for sprites in this clip before extracting, a compile writes over them (extract As Rendered first and your prior art rides along inside the canvas instead — that's what it's for).
Keep your pack under version control or a quick backup while the feature matures, so an unexpected compile is one undo away.
When to reach for it
- This workflow — when you're repainting an animation as a coherent whole and want motion-aware, onion-skinned editing.
- Individual frames (B1) — for a one- or two-frame touch-up; quicker, no round-trip.
- Porting a finished sheet (B3) — when the work already exists as a CKC export or an older sheet-based skin.
You can now take a whole animation onto a steady canvas, edit it the way an animator expects to, and compile it back — with clear eyes about the parts still settling. Next: Bigger Art: Anchors for the oversized-sprite mechanics this builds on, Reused Frames for blast radius — or Appliqué to compile this same canvas into art that only ONE clip uses.
Pages
- A-0 Wikis
- A1 - Getting Started
- A2 - Installing Packs
- A3 - The Pack Manager
- A4 - How Stitchwork Works
- A5 - When Something Looks Wrong
- AEx1 - Conditional Activation
- B0 - Choosing a Workflow
- B1 - Starting a Skin Pack
- B2 - Finding Any Sprite
- B3 - Porting Prior Work — Spritesheets & CKC
- B4 - Texture2D (T2D) Sprites
- B5 - Bigger Art — Anchors
- B6 - Animation Canvas Workflow
- B7 - Sprite Paths Reference
- B8 - The Animation Controller
- BEx1 - Reused frames — one sprite, many animations
- BEx2 - Instance-specific paths — same name, different art
- BEx3 - Appliqué: Per-Clip Art
- C1 - Text & Dialogue
- D1 - Audio
- E1 - Video
- F1 - Priority & Conflicts
- F2 - Distributing Your Pack
- G1 - Dumping & Full Dump
- G2 - Companion Mods
- G3 - Hotkeys
- G4 - Pack Folder Structure
- G5 - Testing With Savestates (DebugMod)
- G6 - Troubleshooting