@energy8platform/golem 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +14 -0
  2. package/dist/editor.css +3 -4
  3. package/dist/editor.js +202 -101
  4. package/dist/lib/cli.js +225 -118
  5. package/dist/lib/cli.js.map +4 -4
  6. package/dist/lib/e8/agent.d.ts +35 -0
  7. package/dist/lib/e8/host.d.ts +22 -0
  8. package/dist/lib/e8/node.d.ts +66 -0
  9. package/dist/lib/e8/runtime.d.ts +10 -0
  10. package/dist/lib/e8/schema.d.ts +3 -0
  11. package/dist/lib/e8/types.d.ts +80 -0
  12. package/dist/lib/e8-agent.js +6865 -0
  13. package/dist/lib/e8-agent.js.map +7 -0
  14. package/dist/lib/e8-client.js +116 -0
  15. package/dist/lib/e8-host.js +7005 -0
  16. package/dist/lib/e8-host.js.map +7 -0
  17. package/dist/lib/e8-runtime.js +2079 -0
  18. package/dist/lib/e8-runtime.js.map +7 -0
  19. package/dist/lib/e8-schema.js +7 -0
  20. package/dist/lib/e8-schema.js.map +7 -0
  21. package/dist/lib/editor/api.d.ts +1 -0
  22. package/dist/lib/editor/embed.d.ts +9 -0
  23. package/dist/lib/editor/server.d.ts +23 -1
  24. package/dist/lib/editor/store.d.ts +34 -32
  25. package/dist/lib/editor/timeline.d.ts +15 -0
  26. package/dist/lib/editor-entry.d.ts +1 -1
  27. package/dist/lib/editor-entry.js +226 -118
  28. package/dist/lib/editor-entry.js.map +4 -4
  29. package/dist/lib/harness.js +54 -1
  30. package/dist/lib/interactive-editor.js.map +1 -1
  31. package/dist/lib/rig-check.d.ts +11 -0
  32. package/dist/lib/rig-control-qa.d.ts +8 -8
  33. package/dist/lib/rig-format.d.ts +184 -184
  34. package/dist/lib/rig-import-layers.d.ts +2 -0
  35. package/dist/lib/rig-symbol.d.ts +5 -2
  36. package/dist/lib/rig-tools.d.ts +2 -1
  37. package/dist/lib/rig-version.d.ts +12 -0
  38. package/dist/lib/runtime.js +60 -3
  39. package/dist/lib/runtime.js.map +3 -3
  40. package/dist/lib/tool-schema.d.ts +3 -0
  41. package/dist/lib/tools.d.ts +2 -0
  42. package/dist/lib/tools.js +179 -58
  43. package/dist/lib/tools.js.map +4 -4
  44. package/editor.html +2 -2
  45. package/package.json +38 -3
  46. package/skills/e8-golem/SKILL.md +71 -0
  47. package/skills/golem-symbol-animation/SKILL.md +87 -0
  48. package/skills/golem-symbol-animation/agents/openai.yaml +4 -0
  49. package/skills/golem-symbol-animation/references/facial-controls.md +48 -0
  50. package/skills/golem-symbol-animation/references/game-engine-integration.md +133 -0
  51. package/skills/golem-symbol-animation/references/golem-authoring.md +138 -0
  52. package/skills/golem-symbol-animation/references/interactive-editor.md +17 -0
  53. package/skills/golem-symbol-animation/references/motion-craft.md +116 -0
  54. package/skills/golem-symbol-animation/references/packed-delivery.md +88 -0
  55. package/skills/golem-symbol-animation/references/quantitative-qa.md +109 -0
  56. package/skills/golem-symbol-animation/references/spine-rive-study.md +87 -0
  57. package/skills/golem-symbol-animation/scripts/atlas_parts.py +87 -0
  58. package/skills/golem-symbol-animation/scripts/check_package.py +71 -0
  59. package/skills/golem-symbol-animation/scripts/image_gates.py +143 -0
  60. package/skills/golem-symbol-cutting/SKILL.md +70 -0
  61. package/skills/golem-symbol-cutting/agents/openai.yaml +4 -0
  62. package/skills/golem-symbol-cutting/assets/h1/h1.atlas.png +0 -0
  63. package/skills/golem-symbol-cutting/assets/h1/h1.png +0 -0
  64. package/skills/golem-symbol-cutting/references/cutting-workflow.md +92 -0
  65. package/skills/golem-symbol-cutting/references/facial-layers.md +44 -0
  66. package/skills/golem-symbol-cutting/references/generation-workflow.md +109 -0
  67. package/skills/golem-symbol-cutting/references/golem-handoff.md +62 -0
  68. package/skills/golem-symbol-cutting/references/h1-example.md +46 -0
  69. package/skills/golem-symbol-cutting/references/hybrid-workflow.md +119 -0
  70. package/skills/golem-symbol-cutting/references/registration-and-motion.md +89 -0
  71. package/skills/golem-symbol-cutting/references/spine-rive-construction.md +73 -0
  72. package/skills/golem-symbol-cutting/scripts/atlas_parts.py +87 -0
  73. package/skills/golem-symbol-cutting/scripts/hybrid_parts.py +279 -0
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env python3
2
+ """Image QA for current runtime captures. Pillow + numpy, no character-specific thresholds.
3
+
4
+ image_gates.py CONFIG.json REPORT.json
5
+ Config: {rig,renderer,frames,reference,times:[...],animation:null|id,mode:'rest'|'holes',
6
+ scale:1,region?:[x,y,w,h],maxMean:2,maxP99:12,maxTileMean:6,maxBoundsDelta:2,
7
+ maxHolePixels:20,maxExcludedArea:0.05,maxExcludedFrames:0.1,
8
+ exceptions:[{reason,frames:[indices],mask}], debugFrames?:directory}
9
+ Paths relative to config. Captures must come from rig_render_preview(framesDir,transparent:true).
10
+ Every expected frame is verified and measured. Exceptions are masks with reasons, not skipped frames.
11
+ """
12
+ import argparse
13
+ from collections import deque
14
+ import hashlib
15
+ import json
16
+ from pathlib import Path
17
+ import numpy as np
18
+ from PIL import Image
19
+
20
+
21
+ def sha(p):return hashlib.sha256(Path(p).read_bytes()).hexdigest()
22
+ def image(p):return np.array(Image.open(p).convert('RGBA'))
23
+
24
+
25
+ def labels(m):
26
+ h,w=m.shape;lab=np.zeros(m.shape,np.int32);count=0
27
+ for y,x in zip(*np.nonzero(m)):
28
+ if lab[y,x]:continue
29
+ count+=1;q=deque([(y,x)]);lab[y,x]=count
30
+ while q:
31
+ cy,cx=q.popleft()
32
+ for ny,nx in ((cy-1,cx),(cy+1,cx),(cy,cx-1),(cy,cx+1)):
33
+ if 0<=ny<h and 0<=nx<w and m[ny,nx] and not lab[ny,nx]:lab[ny,nx]=count;q.append((ny,nx))
34
+ return lab,count
35
+
36
+
37
+ def holes(alpha):
38
+ clear=alpha<5;lab,n=labels(clear)
39
+ outside=set(np.unique(np.concatenate([lab[0],lab[-1],lab[:,0],lab[:,-1]])))-{0}
40
+ enclosed=(lab>0)&~np.isin(lab,list(outside))
41
+ # Partial-alpha cracks fully surrounded by artwork. Boundary antialiasing is not a crack.
42
+ from PIL import ImageFilter
43
+ exterior=np.isin(lab,list(outside))
44
+ border=np.array(Image.fromarray(exterior.astype('uint8')*255).filter(ImageFilter.MaxFilter(5)))>0
45
+ seams=(alpha>=5)&(alpha<250)&~border
46
+ return enclosed|seams
47
+
48
+
49
+ def capture(folder,rig,renderer,times,animation,scale=1,region=None,debug=False):
50
+ m=json.loads((folder/'manifest.json').read_text())
51
+ if m.get('version')!=1 or not m.get('frames') or m.get('times')!=times or m.get('animation')!=animation:raise ValueError('capture does not cover requested animation/times')
52
+ if not m.get('transparent'):raise ValueError('image gates require transparent frames')
53
+ opts=m.get('render')
54
+ if opts is None:raise ValueError('capture lacks render settings; capture fresh frames')
55
+ if opts.get('overlayBones') or opts.get('onionSkin') or opts.get('weightBone'):raise ValueError('image gates require artwork without overlays')
56
+ if m.get('scale')!=scale or opts.get('region')!=region:raise ValueError('capture scale/crop differs from declared comparison')
57
+ if bool(opts.get('debugFillMasks'))!=debug:raise ValueError('wrong debug fill mode')
58
+ if sha(rig)!=m.get('rigFile'):raise ValueError('stale rig render')
59
+ if sha(renderer)!=m['identity']['renderer']:raise ValueError('stale renderer')
60
+ current=json.loads(rig.read_text())
61
+ for a in current['assets']:
62
+ if sha(rig.parent/a['src'])!=m['identity']['assets'].get(a['src']):raise ValueError('stale asset: '+a['src'])
63
+ for p,h in m['identity'].get('masks',{}).items():
64
+ if sha(rig.parent/p)!=h:raise ValueError('stale fill mask: '+p)
65
+ names=[f['file'] for f in m['frames']]
66
+ if len(names)!=len(times) or len(set(names))!=len(names) or sorted(names)!=sorted(p.name for p in folder.glob('*.png')):raise ValueError('missing, duplicate or unmanifested frames')
67
+ import re
68
+ for f in m['frames']:
69
+ if not re.fullmatch(r'\d{6}\.png',f['file']) or sha(folder/f['file'])!=f['sha256']:raise ValueError('changed/invalid frame '+f['file'])
70
+ return m
71
+
72
+
73
+ def composite(a,bg):
74
+ alpha=a[...,3:4].astype(float)/255
75
+ return a[...,:3]*alpha+bg*(1-alpha)
76
+
77
+
78
+ def run(cfg,base):
79
+ if cfg.get('mode') not in ('rest','holes'):raise ValueError('mode must be rest or holes')
80
+ times=cfg['times']
81
+ if not times or any(not np.isfinite(t) or t<0 for t in times) or any(b<=a for a,b in zip(times,times[1:])):raise ValueError('expected times must be nonempty and strictly increasing')
82
+ folder=base/cfg['frames'];rig=base/cfg['rig'];renderer=base/cfg['renderer'];animation=cfg.get('animation')
83
+ m=capture(folder,rig,renderer,times,animation,cfg.get('scale',1),cfg.get('region'))
84
+ ref=image(base/cfg['reference']);live=ref[...,3]>0
85
+ if not live.any():raise ValueError('empty reference')
86
+ baseline=holes(ref[...,3]);exceptions=cfg.get('exceptions',[]);excluded_frames=set();rows=[]
87
+ debug=base/cfg['debugFrames'] if cfg.get('debugFrames') else None
88
+ if debug:capture(debug,rig,renderer,times,animation,cfg.get('scale',1),cfg.get('region'),True)
89
+ for i,f in enumerate(m['frames']):
90
+ got=image(folder/f['file'])
91
+ if got.shape!=ref.shape:raise ValueError('reference and capture dimensions differ')
92
+ if not (got[...,3]>8).any():raise ValueError(f'frame {i}: artwork is empty')
93
+ allowed=np.zeros(live.shape,bool)
94
+ for e in exceptions:
95
+ if not e.get('reason','').strip() or not e.get('frames'):raise ValueError('exceptions need an explicit reason and frame indices')
96
+ if any(j<0 or j>=len(times) for j in e['frames']):raise ValueError('exception names an absent frame')
97
+ if i in e['frames']:
98
+ mask=np.array(Image.open(base/e['mask']).convert('L'))>127
99
+ if mask.shape!=live.shape:raise ValueError('exception mask dimensions differ')
100
+ allowed|=mask
101
+ scope=live|(got[...,3]>0)
102
+ fraction=float((allowed&scope).sum()/max(1,scope.sum()))
103
+ if fraction>cfg.get('maxExcludedArea',.05):raise ValueError(f'frame {i}: excluded area {fraction:.1%} exceeds declared budget')
104
+ if allowed.any():excluded_frames.add(i)
105
+ compare=scope&~allowed
106
+ if not compare.any():raise ValueError('no pixels left to judge')
107
+ d=np.maximum(np.abs(composite(ref,0)-composite(got,0)),np.abs(composite(ref,255)-composite(got,255))).mean(axis=2)
108
+ worst_tile=0.0;worst_xy=[0,0]
109
+ for y in range(0,ref.shape[0],16):
110
+ for x in range(0,ref.shape[1],16):
111
+ take=compare[y:y+16,x:x+16]
112
+ if take.any():
113
+ mean=float(d[y:y+16,x:x+16][take].mean())
114
+ if mean>worst_tile:worst_tile=mean;worst_xy=[x,y]
115
+ def bounds(a):
116
+ yy,xx=np.nonzero(a[...,3]>8)
117
+ return np.array([xx.min(),yy.min(),xx.max(),yy.max()]) if len(xx) else None
118
+ rb,gb=bounds(ref),bounds(got)
119
+ bounds_delta=float(np.max(np.abs(rb-gb))) if rb is not None and gb is not None else float('inf')
120
+ # Baseline gaps are exempt pixel by pixel, never by any-overlap component matching.
121
+ # Consequently a large new hole touching one approved curl cannot be waived wholesale.
122
+ marks=holes(got[...,3])&~baseline&~allowed
123
+ row={'frame':i,'time':times[i],'mean':float(d[compare].mean()),'p99':float(np.percentile(d[compare],99)), 'extra_hole_pixels':int(marks.sum()),'excluded_area':fraction,'worst_tile':worst_tile,'worst_tile_xy':worst_xy,'bounds_delta':bounds_delta}
124
+ if debug:
125
+ dbg=image(debug/f['file'])
126
+ if dbg.shape!=ref.shape:raise ValueError('debug capture dimensions differ')
127
+ pink=(dbg[...,0]>200)&(dbg[...,1]<60)&(dbg[...,2]>200)&(dbg[...,3]>128)&~allowed
128
+ row['visible_fill_pixels']=int(pink.sum())
129
+ row['pass']=(row['mean']<=cfg.get('maxMean',2) and row['p99']<=cfg.get('maxP99',12) and worst_tile<=cfg.get('maxTileMean',6) and bounds_delta<=cfg.get('maxBoundsDelta',2)) if cfg['mode']=='rest' else row['extra_hole_pixels']<=cfg.get('maxHolePixels',20)
130
+ row['pass'] &= row.get('visible_fill_pixels',0)==0
131
+ rows.append(row)
132
+ share=len(excluded_frames)/len(times)
133
+ if share>cfg.get('maxExcludedFrames',.1):raise ValueError(f'exceptions affect {share:.1%} of frames, over the declared budget')
134
+ return {'pass':all(r['pass'] for r in rows),'inspected':len(rows),'expected':len(times),'excluded_frame_fraction':share,'reference_sha256':sha(base/cfg['reference']),'config':cfg,'frames':rows}
135
+
136
+
137
+ def main():
138
+ ap=argparse.ArgumentParser(description=__doc__,formatter_class=argparse.RawDescriptionHelpFormatter);ap.add_argument('config',type=Path);ap.add_argument('report',type=Path);a=ap.parse_args()
139
+ try:res=run(json.loads(a.config.read_text()),a.config.parent)
140
+ except Exception as e:res={'pass':False,'error':str(e)}
141
+ a.report.write_text(json.dumps(res,indent=2));print(json.dumps({k:v for k,v in res.items() if k!='frames'}));raise SystemExit(0 if res['pass'] else 1)
142
+
143
+ if __name__=='__main__':main()
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: golem-symbol-cutting
3
+ description: Prepare animation-ready raster parts and atlases for Golem. Preserve approved art with contour cuts and generated hidden surfaces, generate complete parts when requested, or reuse supplied layers and atlases. Include expression swaps, registered assembly and joint coverage checks. Use golem-symbol-animation for subsequent rigging and animation in Golem.
4
+ ---
5
+
6
+ # Golem symbol cutting
7
+
8
+ Design the artwork for the intended performance: actions and extreme poses → motion controls → complete painted parts → registered assembly. Choose extraction, hidden-surface generation, or complete-part generation to preserve the approved appearance and cover the required motion. A logical body part may use several images; several painted features may stay in one image when they move together.
9
+
10
+ ## Establish the animation brief
11
+
12
+ Inspect the source art, assembled reference, existing animation sheets, layers, atlas metadata and skeleton data that are actually available. Preserve originals and keep preparation files in an authoring workspace such as `art/symbol-work/<id>/`, outside the delivered rig directory. Read applicable workspace instructions. A delivered rig folder contains only `rig.json` and one `atlas.png` for all of that symbol's parts and animations; preparation layers, manifests, prompts and QA stay outside it.
13
+
14
+ Reuse the user's existing brief. Establish actions, emotions, transitions, loops, display size, motion range and permitted artwork changes. If an unanswered question would change the required artwork, ask it while continuing independent inspection. If the user delegates creative direction, propose and use a clearly stated working brief. Do not require approval again for decisions already authorized.
15
+
16
+ For each action, describe setup → anticipation → main action → secondary motion → exit pose/transition, as applicable. Mark maximum joint rotations, facial changes, occlusion changes and newly exposed surfaces. Names such as `land`, `idle` and `win` are examples, not a mandatory animation set. An atlas alone does not establish the original choreography or FX frame order.
17
+
18
+ ## Plan the construction
19
+
20
+ For new characters, major bends/turns, or Spine/Rive references, read [references/spine-rive-construction.md](references/spine-rive-construction.md). It connects source mechanisms to cuts, joint backing, topology and registered variants; runtime playback does not reveal all authoring geometry.
21
+
22
+ Read [references/cutting-workflow.md](references/cutting-workflow.md) for cuts, overlap, facial states and the handoff contract. Read [references/h1-example.md](references/h1-example.md) when using the H1 teaching example; do not transfer its anatomy or assumed actions to unrelated characters.
23
+
24
+ Make an action-to-parts table: action → changing feature → control method → required images. Choose group transforms, separate rigid parts, mesh deformation or attachment swaps according to the performance. Do not separate spots, highlights and strokes solely because they are separable. For full characters, also consider planted feet, separate moving hair, clothing chains, grip swaps, props and changing front/back relationships. Pilot the hardest contact and occlusion change before scaling the method to the full cast.
25
+
26
+ For facial variants, FX registration or a reported size/placement defect, read [references/registration-and-motion.md](references/registration-and-motion.md) before preparing replacements. Local expression changes normally need isolated features on a clean base, not independently regenerated complete heads. Define the semantic foreground occluder at each joint: a collar covering a neck must contain the intended collar/hood, not a rectangular chunk of torso. When generation is required, generate that actual part with its hidden continuation.
27
+
28
+ Before generation or extraction, record each part's identity, reference/source, animation purpose, preparation method, orientation, placement, pivot, parent control, slot/draw order, visibility states and overlap requirements. Distinguish measured facts, working assumptions and missing artwork. Use this plan to produce Golem's `layers/layers.json` import sidecar; keep generation/extraction provenance separate from document placement.
29
+
30
+ ## Prepare the artwork
31
+
32
+ For adjustable facial expressions, read [facial-layers.md](references/facial-layers.md) before separating eyes or mouth. It covers measured eyelids, matching skin backing, transparent holes and coordinate transforms.
33
+
34
+ Choose the workflow supported by the inputs:
35
+
36
+ - **Layers available:** preserve source registration and usable hidden artwork; extend only surfaces required by the planned movement.
37
+ - **Atlas available:** use textual `.atlas` metadata for region names, bounds, rotation and trim offsets, and skeleton data for assembly and animation. Without these, reconstruct manually against the reference and state uncertainties. Packing position does not specify draw order or chronology.
38
+ - **Approved flat art / likeness must match:** use the hybrid workflow in [references/hybrid-workflow.md](references/hybrid-workflow.md). Assign visible source pixels by semantic contours, generate hidden continuations, and regenerate a complete prop only when its exposed shape needs it. Hybrid is a first-class deliverable, not a degraded generation mode. Preserve source registration and audit every departure from approved pixels.
39
+ - **Explicitly requested fully generated atlas or permitted redesign:** generate complete isolated parts and backing using [references/generation-workflow.md](references/generation-workflow.md). Do not silently substitute source cuts for that request.
40
+ - **Extraction only / strict pixel preservation:** isolate visible pixels deterministically. Where the requested motion exposes absent surfaces, identify that conflict; do not invent recovered pixels or silently change the artwork.
41
+
42
+ For a whole-symbol transform with no changing occlusion, do not create unnecessary parts or regenerate artwork solely to satisfy a cutting workflow. Preserve the user's requested preparation method.
43
+
44
+ Measure reference and generated/source image dimensions separately. Inspect transparency on checker, light and dark backgrounds. Record crop rectangles in the actual image being cropped, accounting for resized inspection displays; a generated image need not retain the reference's framing or scale. Preserve black outlines and small disconnected alpha components such as fangs, eyelid strokes and sparks unless visual evidence justifies local cleanup.
45
+
46
+ For ink-aware partition, repair guides, landmark fitting, background masks, tone/edge cleanup and registered hybrid assembly, use `scripts/hybrid_parts.py --help` and the hybrid reference. It requires Pillow and numpy. It preserves small islands and has no character-specific canvas constants.
47
+
48
+ For rectangular extraction from a prepared atlas, use the standalone `scripts/atlas_parts.py` (Python and Pillow). Run `--help`. Its manifest is a JSON list of objects such as `{"id":"head_base","rect":[x,y,width,height]}`. Without a manifest it only creates an inspection image. It preserves decoded RGBA pixel values; it does not rotate, mask, remove neighbors, infer part identities or restore hidden artwork.
49
+
50
+ ```sh
51
+ python3 <skill-dir>/scripts/atlas_parts.py <atlas.png> <output-dir> --manifest <crops.json>
52
+ ```
53
+
54
+ Undo packing rotations separately; quarter turns can use lossless pixel transposes. Document the direction and operation. Do not mirror asymmetric paired parts by default. Preserve registration when trimming or resizing. Transparent padding cannot replace painted overlap beneath a joint.
55
+
56
+ Use an available image-generation skill/tool for regeneration; trimming, registration, packing and assembly of the generated parts should remain deterministic. Verify generated artwork against the reference style, outline, color, identity and pose. Do not claim unseen surfaces were recovered exactly from a flat source or silently substitute a source-cut/hybrid package for a fully generated one. If generation is unavailable, report that limitation and complete independent planning rather than claim regeneration succeeded.
57
+
58
+ ## Verify and hand off
59
+
60
+ Reassemble setup using recorded placements and draw order. Compare silhouette, expression, scale and contours with the reference. A matching setup alone does not prove joint coverage. Test the planned extremes and intermediate movement: joint bends, head tilt, open mouth, closed eyes and expression switches, as required by the brief. Inspect joint closeups in motion as well as the symbol at cell size. Static pose mockups can validate artwork coverage; they do not establish native rig or runtime correctness, and a clean numerical checker does not prove textures have no seams.
61
+
62
+ Use the numerical gates in [quantitative-qa.md](../golem-symbol-animation/references/quantitative-qa.md) when claiming setup equivalence or motion coverage; preserve current render hashes, complete sample counts and bounded exceptions.
63
+
64
+ Fix gaps, doubled contours, cut-off tips, neighboring fragments and registration jumps. Check FX frames for complete disconnected fragments and stable alignment. If the planned motion exposes missing artwork, repair that part or revise the motion brief explicitly; do not hide the limitation behind a successful setup render.
65
+
66
+ For a cutting task, keep RGBA layers, a ready-to-import `layers/layers.json` sidecar, brief, provenance and QA in the external authoring workspace. Deliver the verified setup as `rig.json` plus one `atlas.png` using the packing contract in [references/golem-handoff.md](references/golem-handoff.md). The sidecar and loose layers are preparation inputs, not extra files in the final rig folder. For a planning-only task, deliver the plan and label unperformed preparation, packing and QA accurately. Report concrete unresolved items.
67
+
68
+ When Golem animation is requested, pass the existing brief and art package to [golem-symbol-animation](../golem-symbol-animation/SKILL.md). Preserve IDs, coordinate conventions, registration and limitations; do not restart creative planning without a reason. If the sibling is unavailable, deliver the same handoff contract without claiming animation is complete.
69
+
70
+ Read [references/golem-handoff.md](references/golem-handoff.md) before exporting the layers or verifying their import. Golem is the target tool and its current schemas define the deliverable. The workflow uses bones, slots, attachments and meshes similar to Spine, but validation and delivery happen in Golem.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Golem Symbol Cutting"
3
+ short_description: "Generate and prepare animation-ready parts for Golem"
4
+ default_prompt: "Use $golem-symbol-cutting to prepare registered animation-ready parts for Golem, preserving approved visible art with contour cuts and generated hidden surfaces, or generating complete parts when requested."
@@ -0,0 +1,92 @@
1
+ # Cutting decisions and animation handoff
2
+
3
+ ## Map actions to artwork
4
+
5
+ | Planned action | Construction | Required artwork |
6
+ |---|---|---|
7
+ | Whole symbol bounces | Group/root transform | No extra cuts solely for this movement |
8
+ | Head tilts against torso | Head control with neck pivot | Neck and head base continuing under the overlap |
9
+ | Ear or horn settles after an impact | Rigid part or a small mesh | Complete contour, hidden base and coverage at maximum deflection |
10
+ | Blink | Eyelid control or closed-eye swap with coordinated eye visibility | Closed state and a clean backing surface; no remaining white hairline |
11
+ | Gaze shifts | Separate pupil only if required | Complete eye white and a way to contain the pupil within the eye |
12
+ | Brow changes expression | Separate brow, deformation or replacement | Skin restored beneath the original brow |
13
+ | Mouth opens widely | Local mouth swap plus jaw/face deformation when articulation is required | Clean base, mouth cavity, lips and teeth/tongue; continuous lower face for jaw travel |
14
+ | Elbow or knee bends | Segments or a weighted mesh | Joint coverage in extreme poses; continuous clothing at the seam |
15
+ | Hand changes grip | Registered attachment variants | Hand states and prop pieces drawn in front of/behind fingers as needed |
16
+ | Hair, cloth or tail bends | Mesh/bone chain or several parts | Enough painted surface to deform; one image per bone is not required |
17
+ | Flash or smoke plays | Separate FX control and, where appropriate, frame swaps | Every fragment of each frame and a stable registration point |
18
+
19
+ Apply only rows supported by the brief. Large out-of-plane turns may require new views; stretching a single view does not reveal correctly drawn hidden anatomy. Split only for independent movement, deformation, replacement or changing occlusion.
20
+
21
+ ## Overlap and outlines
22
+
23
+ Put seams where another part covers them throughout the intended movement. Preserve visible external outlines without inventing a second outline inside a covered joint. Extending alpha alone does not reconstruct the color and texture of hidden surfaces.
24
+
25
+ Choose painted overlap from the pivot and motion range at the working scale. Avoid a universal pixel margin. Treat transparent space for sampling/meshing/packing separately from painted continuation needed for articulation.
26
+
27
+ After extracting a moving facial feature from flat art, remove its duplicate from the base and restore the underlying surface where needed. A rectangular skin patch can appear pasted on when rotated; use an appropriate mask or replace a larger registered facial region. Alternate full-face images should not be visible together unless the transition deliberately requires a compositing treatment.
28
+
29
+ ## Handoff contract
30
+
31
+ Store this preparation package outside the delivered rig directory, for example
32
+ in `art/symbol-work/<id>/`. Only `rig.json` and one shared `atlas.png` belong in
33
+ the final rig folder. See [golem-handoff.md](golem-handoff.md) for packing.
34
+
35
+ A practical package contains:
36
+
37
+ - `animation-plan.md`: actions, phases, expressions, ranges, loop/transition behavior, and assumptions.
38
+ - `parts-plan.json`: source provenance, image registration and control/slot plan when these are not already recorded elsewhere.
39
+ - When generation is used: full generated references and exact prompts, with generated/source/hybrid provenance per final part.
40
+ - `layers/layers.json`: the Golem import sidecar generated from that plan, with document placement, joints and attachment variants.
41
+ - `crops.json`: only `id` and `rect` entries when using the crop helper.
42
+ - `layers/`: final RGBA PNGs, with orientation and trim documented.
43
+ - `qa/`: contact sheet, setup comparison and tested extreme poses.
44
+
45
+ Use the project's existing equivalent files when available. Do not create empty deliverables. Keep source-atlas coordinates separate from assembled-document coordinates.
46
+
47
+ Define canvas dimensions, units, axis directions, angle sign, side naming, and transformation order once. For a simple pixel-space plan, use X right, Y down and viewer-left/right. Preserve another established convention when supplied and document the conversion.
48
+
49
+ The following record is illustrative, not measured H1 data or an importer schema. It assumes no setup rotation or scale; the image pivot lands at document `[138,283]`:
50
+
51
+ ```json
52
+ {
53
+ "id": "ear_viewer_left",
54
+ "file": "layers/ear_viewer_left.png",
55
+ "source": "atlas.png",
56
+ "extraction": {"method": "crop", "rect": [100, 200, 80, 120]},
57
+ "orientation": {"unpackRotationDegCW": 0, "mirror": false},
58
+ "placement": {"topLeft": [72, 198], "pivotLocal": [66, 85]},
59
+ "parentControl": "head",
60
+ "slot": "ear_viewer_left",
61
+ "drawOrder": 20,
62
+ "setupVisible": true,
63
+ "usedBy": ["idle"],
64
+ "overlap": "The head covers the ear base throughout the tested range.",
65
+ "status": "example_only"
66
+ }
67
+ ```
68
+
69
+ `rect` refers to the original source PNG. `pivotLocal` refers to the final extracted image after unpacking/trimming. `topLeft` places that image in the assembly. If scale/rotation are needed, record a complete transform with a defined pivot instead of leaving the order ambiguous. In this internal convention, draw-order numbers increase from back to front. They are separate from bone hierarchy and atlas region positions.
70
+
71
+ Record named slots and mutually exclusive attachment variants. One slot shows one attachment or none; features visible together require separate slots. Several images belonging to one rigid horn may share a logical control, but need separate slots if they must be visible simultaneously. Preserve their relative transforms.
72
+
73
+ Different-sized expression variants must align by facial landmarks, not just bounding-box centers. Specify the default state, coordinated visibility of companion parts and the registration of every variant. Do not assume a separated eye image includes a separately controllable pupil.
74
+
75
+ For independent facial generation or repeated size/placement corrections, apply
76
+ [registration-and-motion.md](registration-and-motion.md). Verify each state in
77
+ the composed rig; copying the neutral mouth's scale to every generated variant
78
+ does not establish that all mouths match the reference.
79
+
80
+ Before delivery, translate this authoring plan into Golem's `layers/layers.json` as described in [golem-handoff.md](golem-handoff.md). The animation skill should consume the prepared sidecar rather than repeat this conversion. Update the plan and sidecar together when placement changes. Pass existing decisions forward and revise only parts invalidated by a changed action or failed pose test.
81
+
82
+ ## Meaningful QA
83
+
84
+ Use setup overlays/differences and visual comparison. A small aggregate pixel error does not excuse a wrong fang or expression. If the assembled reference has another resolution, record the chosen scale; atlas page dimensions do not define character scale.
85
+
86
+ Test silhouette, joint coverage, outline continuity, eye/mouth placement, draw order and duplicate features in maximum-action poses. Identify mockups as mockups. Check both sides of attachment switches; for continuous movement inspect intermediate poses too, since coverage can fail between endpoints.
87
+
88
+ Inspect closeups of the joints that actually change occlusion, together with native motion/cell-size playback when available. Numerical checks establish schema, references and sampled geometry; they do not detect a painted seam or prove hidden skin/fabric coverage. Describe visual QA separately and limit conclusions to the inspected movement range.
89
+
90
+ When making pixel-equality claims for an extraction workflow, compare all channels explicitly and distinguish visible differences from hidden RGB at alpha zero. A difference image's alpha bounding box alone can miss RGB changes when alpha is unchanged. For regenerated artwork, assess style, landmarks and assembly rather than treating original-pixel equality as the acceptance criterion.
91
+
92
+ Connected-component detection finds alpha islands, not semantic parts or FX frames. A flash can contain dozens of islands. Group fragments by the actual frame, preserve offsets or a shared canvas, and verify alignment in playback. Without timing/sequence evidence, label any proposed FX order as authored rather than recovered.
@@ -0,0 +1,44 @@
1
+ # Preparing a face for adjustable expressions
2
+
3
+ Preserve the approved face/eye pixels where visible. Record each feature's source region,
4
+ measured eye corners and neutral placement; generated hidden eyelids, mouth interiors and
5
+ backing are new artwork, not recovered source pixels. Do not reuse another character's
6
+ landmarks or assume asymmetric eyes are mirrored.
7
+
8
+ Track source pixels → crop-local pixels → logical document placement → atlas texels →
9
+ normalized UVs separately. Cropping changes registration; resizing changes measured
10
+ landmarks. Keep those transforms in the preparation recipe. Atlas placement is not a
11
+ facial landmark. Current Golem does not support replacing an atlas with a larger image
12
+ without updating its sampling metadata; do not promise geometry-preserving HD replacement.
13
+
14
+ For a moving mouth, keep surrounding skin on a matching face base. The movable layer
15
+ contains the lip line or mouth interior, not a rectangular patch of skin. Verify that
16
+ base + extracted feature reconstruct the original neighborhood. For antialiased lines,
17
+ color thresholding alone can leave a halo: account for compositing against the measured
18
+ base, and bound unstable low-alpha recovery. This is preparation guidance, not an
19
+ automatic extraction capability of the current Golem tools.
20
+
21
+ For small expressions without newly exposed surfaces, a continuous local face mesh can
22
+ retain lips, ink and skin in one texture. Pin its perimeter and taper the deformation
23
+ inside it; this differs from moving a rigid rectangle of painted skin. Separate features
24
+ and prepare backing when the motion needs independent overlap or an opening mouth.
25
+
26
+ Adjacent mesh patches can show antialiasing cracks despite coincident boundary vertices.
27
+ A narrow source-derived underlap inside an undeformed boundary band can cover them.
28
+ Keep that underlap out of soft hair/chin silhouettes: duplicating their partial alpha
29
+ darkens the contour. Measure the source's interior alpha first; compressed art can have
30
+ 252–254 alpha in apparently solid skin. Check both added gaps in motion and neutral
31
+ composites after any coverage correction; do not globally force the artwork opaque.
32
+
33
+ Prepare complete closed-eye backing and an uninterrupted eyelid/lash where the open
34
+ source is occluded by hair. Measure open and closed endpoints on each side. Pass the
35
+ measurements and required intermediate states to rigging. Verify both opening and closing,
36
+ including near-open states, a wink, gaze and head motion together.
37
+
38
+ Distinguish genuinely transparent holes (between hair strands, accessory cutouts) from
39
+ hidden regions needing new paint. A repair must not fill the former. Keep repair masks
40
+ and source provenance separate, and inspect alpha compositing on light and dark backgrounds.
41
+
42
+ The handoff records roles, side convention, coordinate transforms, landmarks, backing,
43
+ supported ranges and unresolved coverage. Use the animation skill's facial-controls
44
+ reference for optional parameter grids and combined-pose render checks.
@@ -0,0 +1,109 @@
1
+ # Preparing parts through generation
2
+
3
+ Use for complete parts and hidden-surface repairs where generation is chosen, or when
4
+ the user explicitly requests a generated atlas. For approved flat art whose visible
5
+ appearance must remain fixed, start with [hybrid-workflow.md](hybrid-workflow.md). A visible-pixel cut can match
6
+ setup perfectly while leaving a missing neck, detached wrist or duplicate
7
+ contour as soon as the rig moves. Local patches only under the setup silhouette
8
+ may still leave those joints uncovered.
9
+
10
+ ## Generate the required painted surfaces
11
+
12
+ Use the reference to preserve identity, pose, proportions, ink weight, palette
13
+ and lighting. Specify the isolated part, its hidden continuation, intended
14
+ joint/occlusion, and a genuinely transparent background. Include enough margin
15
+ to retain extremities, but distinguish that margin from painted overlap.
16
+
17
+ Generate each independently authored asset through the available image tool.
18
+ Keep the full generated outputs and exact prompts. In a fully generated package,
19
+ final painted pixels come from generated artwork; the original supplies the
20
+ reference, not crop pixels. In a requested hybrid package, record which parts
21
+ remain original and which surfaces were regenerated.
22
+
23
+ Choose connected surfaces around the performance, for example:
24
+
25
+ - A tilting bust may need a head with a continuous complete neck, plus a clean
26
+ torso whose collar covers the neck base. Do not stop the head at the chin.
27
+ - A hand raising a held carton may need one continuous grip/carton/wrist/sleeve
28
+ image and coat backing underneath. Do not stop the arm at the wrist. Keep the
29
+ grip rigid when the brief does not change it; bend only the intended fabric.
30
+ - A blink or smirk normally uses isolated eyelid/mouth artwork on a clean accepted
31
+ head base. Request only the required feature and backing; exclude unrelated
32
+ cheek, nose or beard pixels. A full-head edit may serve as a generation reference,
33
+ but use full-head runtime swaps only when the performance needs a whole-head
34
+ redraw. Verify every state's landmarks with `registration-and-motion.md`.
35
+
36
+ These examples are construction choices, not a mandatory anatomy or part count.
37
+ For each actual joint, require real skin/fabric and outline continuation through
38
+ the planned range. A straight ink stroke across a hidden part end can become a
39
+ visible seam; do not add one just to make the part look closed on a contact sheet.
40
+
41
+ ## Register and plan occlusion
42
+
43
+ Measure generated dimensions and fit parts using landmarks and joint positions.
44
+ Do not reuse reference crop coordinates or trust equal canvas sizes/bounding
45
+ boxes as proof of alignment. Check that independent generation has not moved a
46
+ collar, enlarged a hand or changed the head angle before rigging around it.
47
+
48
+ Plan front/back relations explicitly. A head may need to draw in front of the
49
+ coat while its neck draws behind the collar. When one continuous generated
50
+ painting spans both relations, derive semantic front/back regions from it with
51
+ painted overlap and coordinated controls. Do not pack a rectangular chunk of
52
+ neighboring face art as a supposedly isolated neck. Packing and bone hierarchy
53
+ do not establish the right draw order.
54
+
55
+ Plan framing before requesting long hidden extensions. A sleeve base can anchor
56
+ to the torso while its wrist moves, using a mesh where fabric bending is part of
57
+ the brief. Meshes cannot supply missing pixels. Do not silently crush a long
58
+ forearm into a thin strip to fit the cell: inspect folds, proportions and base
59
+ contours, and regenerate or revise placement if fitting introduces artifacts.
60
+ Determine overlap from the actual pivot/motion; H2's pixel margins, weights and
61
+ timings are not general presets.
62
+
63
+ ## Verify the generated assembly
64
+
65
+ Use a temporary Golem rig to test joint rotations and translations through
66
+ extremes and intervening frames, following `golem-handoff.md`. Inspect neck/collar,
67
+ wrist/cuff and sleeve/body joins on checker/light/dark backgrounds and in native
68
+ playback where available. Look for gaps, doubled outlines, exposed crop edges,
69
+ flattened fabric, neighboring fragments and attachment jumps. Fix the artwork,
70
+ draw order, pivot or weights responsible; do not reduce the action silently.
71
+
72
+ Compare the regenerated assembly visually with the reference and disclose
73
+ material pose/identity changes. Pixel identity with the original is not the goal
74
+ of regeneration. Save the native closeups/phase checks that support the accepted
75
+ motion range, not only a contact sheet or checker success message.
76
+
77
+ ## Repair prompts and extraction
78
+
79
+ Generation may recreate an occluder that was removed, add an opaque page, shift palette,
80
+ leave a pale fringe, or alter scale. These are possible outcomes to inspect, not guaranteed
81
+ model behaviours. Equal canvas dimensions do not prove registration. Use measured landmarks.
82
+
83
+ Hidden-surface prompt template:
84
+
85
+ > Complete only the exposed continuation of [part/material] in the marked region.
86
+ > The [removed sleeve/hand/prop] has deliberately been removed; do not draw it again.
87
+ > Continue the host part's existing contour, lighting and ink weight through the hidden area.
88
+ > Keep the surrounding reference as a registration guide. Small differences outside the
89
+ > repair are acceptable: the final assembly will retain the approved original pixels there.
90
+ > Return the complete repaired part on a transparent background, with no guide colour.
91
+
92
+ Complete-prop template:
93
+
94
+ > Paint the whole [prop] as one isolated object, including [occluded edge/loop/handle].
95
+ > Match the reference landmarks [list], proportions, ink thickness and palette.
96
+ > Keep [rigid housing] rigid; supply [flexible strap] as a separate surface if it moves independently.
97
+ > No hand, sleeve, body or cast shadow from neighbouring parts; transparent background.
98
+
99
+ These templates describe the deliverable, not a way around tool restrictions. Follow the
100
+ available generator's instructions and inspect the actual result. Do not attribute a failed
101
+ save to one phrase in a prompt without reproducible tool evidence.
102
+
103
+ For a hybrid repair, use this order: fit to unchanged landmarks → remove background only
104
+ inside a reviewed background mask → match tone from comparable opaque host material →
105
+ feather into the host part's own colour → repair a pale fringe only inside a reviewed ink mask.
106
+ Preserve whites of eyes and enclosed highlights. Do not globally remove light pixels or
107
+ paint every soft edge black. `hybrid_parts.py extract` performs these deterministic steps;
108
+ its fit residual and remaining guide-magenta checks fail explicitly. Keep full generations,
109
+ landmarks, masks, exact prompts and fit reports outside the delivered rig folder.
@@ -0,0 +1,62 @@
1
+ # Delivering cut artwork to Golem
2
+
3
+ Golem is the authoring and validation target. Locate the checkout through `package.json`, `src/rig-api.ts` and `src/rig-import-layers.ts`, or use the installed `@energy8platform/golem/tools` registry in a game. Verify current schemas before invoking tools; the installed editor CLI does not necessarily expose the checkout's rig CLI commands. External animation formats do not define this contract.
4
+
5
+ ## Art package
6
+
7
+ Keep the animation brief, RGBA PNGs and a `layers/layers.json` sidecar ready for `rig_import_layers` in the external authoring workspace, not the delivered rig folder. Keep generated originals and exact prompts, source rectangles, masks, unpacking operations and reconstruction notes there as applicable. The animation skill consumes these decisions directly.
8
+
9
+ For ordinary unrotated cutouts, use the final image dimensions in `bbox`, its top-left in Golem document pixels, and the desired joint in the same document space. Golem uses X right, Y down and clockwise-positive degrees. Thus a crop at `[x,y]` with a local pivot `[px,py]` has `joint: [x+px,y+py]`.
10
+
11
+ This illustrative sidecar assumes two 280 × 280 PNGs registered to the same face landmarks:
12
+
13
+ ```json
14
+ [
15
+ {
16
+ "id": "head",
17
+ "file": "head.png",
18
+ "parent": "root",
19
+ "z": 10,
20
+ "bbox": [170, 140, 280, 280],
21
+ "joint": [310, 400]
22
+ },
23
+ {
24
+ "id": "smile",
25
+ "file": "smile.png",
26
+ "bone": "head",
27
+ "slot": "head",
28
+ "swap": true,
29
+ "z": 10,
30
+ "bbox": [170, 140, 280, 280],
31
+ "joint": [310, 400]
32
+ }
33
+ ]
34
+ ```
35
+
36
+ `file` is relative to the layers directory. `bbox` is `[x,y,width,height]` in the assembled document, never a source-atlas rectangle. IDs and references must be unique/valid for their object types. Use explicit `parent`, `bone`, `slot` and `z` when inference would be ambiguous. A semantic label in a planning document does not create a bone: every referenced control must exist or be created during import/setup.
37
+
38
+ A normal layer creates an asset, bone, slot and attachment. `bone` attaches artwork to an existing control without creating another bone. `swap: true` adds an attachment without selecting it: a new slot starts empty; an existing slot keeps its current selection. Choose the setup attachment explicitly afterward. One slot shows one attachment or none; simultaneously visible parts need separate slots even if they move with the same bone. Larger `z` draws in front unless animated draw order overrides it.
39
+
40
+ The current checkout imports document-space `bbox` and `joint` through the full evaluated
41
+ host matrix, including rotation, scale, reflection and shear. `bbox` width/height specify the
42
+ drawn document size; they may differ from PNG dimensions. A sheared local placement becomes
43
+ a four-vertex mesh so the image remains exact in document space. Existing bones and swap
44
+ slots keep their host. On older installations with the translation-only importer, import
45
+ under neutral bones and apply the complete placement afterward; feature-check the installation.
46
+ Bone angles follow their `inherit` mode: under a rotated parent,
47
+ `noRotationOrReflection` removes inherited rotation, so its authored angle cannot be
48
+ computed by always subtracting the parent's angle. Verify the world matrix with `rig_get_pose`.
49
+
50
+ For detailed tools, visibility and preview mechanics, read [golem-authoring.md](../../golem-symbol-animation/references/golem-authoring.md). If the sibling reference is unavailable, inspect the current Golem tool schemas and importer directly.
51
+
52
+ ## Verify the handoff
53
+
54
+ For a completed cutting task, validate the sidecar JSON and PNG dimensions, then import into a temporary Golem setup rig when the checkout is available. Use the registry, CLI or `callTool`; preserve the source artwork and any existing production rig. `rig_import_layers` takes `layersDir` and `relPrefix`: the latter must resolve from the rig directory to the actual image directory. The current importer falls back to filenames only when the sidecar is absent; invalid JSON fails. Older versions also fell back on parse errors. Inspect the resulting IDs, parents and slots rather than trusting invocation success alone.
55
+
56
+ Render setup and compare it with the reference. Use temporary transforms or short test tracks to inspect the planned extremes, intermediate joint movement and both sides of swaps. These are art-coverage checks, not a substitute for authoring the requested animations. Save native joint closeups as well as whole-symbol views. Fix missing surfaces, seams, wrong pivots, visibility and registration before declaring the parts ready. A static image mockup can support coverage checks, but does not replace import validation when Golem is available. If import or motion coverage could not be checked, report that specific limitation.
57
+
58
+ Run `rig_validate` and `rig_check` and read their reports; findings can appear in a successful tool response. In numerical QA, note that `rig_get_pose` returns slot bounds as `[minX,minY,maxX,maxY]`, unlike the import sidecar's rectangle format.
59
+
60
+ For delivery, export the verified setup through `rig_export` to external staging, compare its render and install exactly `rig.json` plus one `atlas.png` in the destination. Keep the loose-layer handoff and QA outside that folder. Follow [packed-delivery.md](../../golem-symbol-animation/references/packed-delivery.md) for packing, package checks and history preservation. If the sibling is unavailable, inspect the current export schema and check that the destination contains only the pair and every asset references a valid frame in `atlas.png`.
61
+
62
+ Continue with `golem-symbol-animation` when performance authoring or game integration is requested; carry the verified parts and brief forward, then pack the complete animated revision. A setup-only export is not a completed animation. Keep packing separate from extraction and only claim stages actually completed.
@@ -0,0 +1,46 @@
1
+ # H1: reference artwork and atlas analysis
2
+
3
+ The teaching inputs are bundled with this skill:
4
+
5
+ - [Assembled reference](../assets/h1/h1.png)
6
+ - [Source atlas](../assets/h1/h1.atlas.png)
7
+
8
+ Use these bundled files only for the H1 teaching example. In another task, use the user's supplied art and do not transfer H1's appearance, anatomy or atlas layout to a different character.
9
+
10
+ ![H1 assembled reference](../assets/h1/h1.png)
11
+
12
+ The atlas is intentionally shown at a reduced display size in Markdown. Measurements and crop coordinates must use the original bundled 2048 × 2048 file rather than the rendered preview.
13
+
14
+ ![H1 source atlas](../assets/h1/h1.atlas.png)
15
+
16
+ ## Observed facts
17
+
18
+ - `h1.png` is a 512 × 512 RGBA PNG showing an assembled red character bust with horns, ears, eyes and a smirk.
19
+ - `h1.atlas.png` is a 2048 × 2048 RGBA PNG containing irregularly packed artwork, not a uniform frame grid.
20
+ - Checker inspection reveals a transparent opening inside the smiling face variant's mouth. It needs correctly registered cavity artwork behind it if the intended mouth is opaque.
21
+ - Visible candidates include face bases, eyes, ears, horns or horn fragments, a nose, mouth/teeth regions, neck/clothing, and many flash/smoke shapes. Narrow dark strokes are easy to miss on black.
22
+ - Facial marks remain painted on the large face images. Do not infer that every facial feature can move independently without further preparation.
23
+ - Only the two PNGs were supplied in `h1` at validation. No textual `.atlas`, skeleton JSON or source layers establish region names, packing rotation, trim offsets, assembly transforms or animation timing.
24
+
25
+ These are visual observations, not a completed semantic segmentation. Exact part rectangles, side assignments of thin strokes, horn assembly and FX chronology still need measurement and reconstruction checks. Never derive original-pixel rectangles from a resized display without accounting for scale.
26
+
27
+ ## Illustrative performance brief
28
+
29
+ The user has not specified H1's actual actions. The following is one possible brief, not recovered author intent:
30
+
31
+ | Action | Performance | Cutting implications |
32
+ |---|---|---|
33
+ | `land` | Arrival/contact, compression, small rebound and settling | Root, head/neck, optional ear/horn secondary controls, covered bases throughout tilt |
34
+ | `idle` | Restrained breathing, slight head motion and a blink | Clean eye backing and coordinated open/closed states; separate ears only if they move independently |
35
+ | `win` | Anticipation, smile/open mouth, accent and return | Compatible face/mouth variants with registered landmarks; cavity and teeth as needed; FX only if part of the chosen action |
36
+
37
+ Replace this table when the brief calls for speech, surprise, attack, impact or another performance. Explosions in the atlas do not establish `hit`, `win`, disappearance or frame order. If skeleton data becomes available, use it to replace assumptions with evidence.
38
+
39
+ ## Lessons to carry forward
40
+
41
+ 1. Match atlas candidates against the assembled image before assigning final names. The horns are asymmetric; do not mirror one to fabricate the other. Test whether a logical horn comprises multiple packed pieces.
42
+ 2. Separate logical controls from images. Horn fragments that form one rigid object should retain their relative placement; skin spots can stay on the base.
43
+ 3. Inspect eye and eyelid artwork before choosing a blink. A separate eye image does not prove a separate pupil; gaze shifts may require a new cut and reconstruction of the eye white.
44
+ 4. A full-face switch must not retain incompatible old mouth artwork, move facial landmarks or expose the background through the mouth. Preserve intentional outlines around the opening.
45
+ 5. Treat each FX frame as a whole, including disconnected sparks. Confirm or explicitly author its order and registration before assigning sequential names.
46
+ 6. Distinguish analysis, measured extraction and a verified rig. This reference documents analysis only; it does not provide final crops or claim exact reconstruction of H1.