Slot factory · Arena Linux · Darwin editor

SpAIne

A prompt-first factory that patches real slot trees: catalog the exploded original, pick QUÉ (which assets) and CÓMO (how to edit), send classified originals to Spline on a Mac, approve v2 skins, recompile a new bundle. The original in src/ stays bit-identical.

SpAIne is not a second Forge and not a Grabbr feature. It lives as a module at /opt/forge/spaine, mounted on Forge :8766 through handleSpaine. Grabbr (grabbr.jailbroken.tech, :8790) is a thin client: capture, gallery, SpAIne tab, proxy /v1/spaine/*. Imagine Lab paints stills on :8791. Genie Spine Reskin paints atlas skins on :8765/:5173 and is not merged into forge.service. Chile headed Chrome on 127.0.0.1:9336 is Grabbr Stake capture — never kill it.

This book is the English unification of the living Spanish docs 00–13, the ha-spaine plugin, the real CLI and HTTP surface, two distinct jobs (HPlay Joker’s Diamond originals vs Axion Horror Circus 1.0.23), and the measured smoke of 2026-10-28. Operator chat stays Spanish; this HTML is the English book.

piloto Horror Circus 1.0.23 · v1 skin + ogg, director intact · magix gem not this piloto

Glossary

These names collide in conversation. They are different products, runtimes, and machines.

WordWhat it actually is
SpineEsoteric Software 2D skeletal animation. Horror Circus uses Spine 4.1.24 JSON + Symbols.atlas + WebP pages. Bones, slots, attachments, idle/win timelines. SpAIne v1 reskins the paint and leaves the rig.
Splinespline.design — 3D / Hana 2D visual editor. Desktop app is macOS only (uname prints Darwin). Hosted MCP is https://mcp.spline.design/mcp with OAuth scopes spline:read spline:write. Not a substitute for Spine 4.1 atlases.
SpAIneThis factory: plugin ha-spaine + Forge runtime. Name is a pun on Spine. Job: inventory a slot tree, pick assets, edit via Spline/Imagine/ElevenLabs, apply copy-on-write, zip a new bundle id.
GrabbrPublic game-images client at grabbr.jailbroken.tech / :8790. Capture (Pragmatic/Unity today), gallery, SpAIne tab. Does not implement Spine or ElevenLabs logic. Pointer docs: /opt/hallallow/apps/game-images-api/docs/spaine/README.md. HTTP API.en.md is the Grabbr capture API — mentioned here, not dumped.
ForgeHost and work surface, forge.jailbroken.tech, :8766. SpAIne extends Forge. Do not rewrite local/serve.mjs core, public/index.html, bulk, arena-reels, RGS, or Caddy Host.
GenieGenieLabs Reskin Studio vendored at /opt/forge/spaine/vendor/genie-reskin. UI :5173, API :8765. Paints existing Spine rigs. PolyForm Noncommercial. Not inside forge.service.
DarwinThe macOS kernel name. Spline.app and desktop MCP stdio run only there. Arena is Linux (nl30347.ispiria.net) and cannot spawn /Applications/Spline.app.
Hosted MCPhttps://mcp.spline.design/mcp enabled in Arena Grok/Claude/Cursor. First call needs Spline OAuth. If 401 AuthRequired: HOLD. Never substitute Three.js.
Imagine LabStills painter. imagina.jailbroken.tech and local :8791. Model grok-imagine-image-2.0 via SuperGrok OAuth. Used by cli.mjs gen-stills and Genie Generate.
ElevenLabsSinger, not director. One cue = one ogg. Key in secrets/elevenlabs.env. Sounds.json remains the conductor.
AxionPixi slot engine of Horror Circus 1.0.23. Manifest + JSON + Spine 4.1 + loose oggs. Not Magix Howler sprites, not Arena Zeus nine one-shots.
MagixForge gem engine with a 3-cut sounds.ogg sprite (bgm, big_win, bgm_freespin). Wrong packing for this piloto. Do not collapse Horror Circus to Magix.
Translaxion template/opt/translaxion/data/slotre/horrorcircus-template/ — the game already directs audio. The clone changed files and left rules.
hall_salaShared cookie for console / pentest / audit / forge / ticketing / Grabbr.
QUÉ / CÓMOWhat (catalog codes, chips AA–BN) and How (edit brief). Stored in select.json. The Mac pack is that original plus that brief, not a generic prompt.
Triple nameEngine code AA / Manifest webp Joker.webp / atlas folder JOKER. v1 never renames to “make them match.”
Absorbed

INDEX.md, 00-producto.md, 12-spline-mcp.md, 08-pack.md, Grabbr README, PLUGIN.md

Product — closed decisions

Name: SpAIne (a game with Spine). Internal use, operator plus friends, allowed to resemble originals. Editing is not a loose PNG crop. From any capture job the factory can reskin a mascot, shift a palette, replace symbols, or run a full theme: background, reel frame, UI, mascot, palette, sounds, copy.

Example order: “replace candy symbols and theme with emoticons.” The system must propose something finished and coherent, not a collage.

Roles

PieceRole
ForgeHost and labour. SpAIne extends it.
GrabbrThin client: capture, gallery, QUÉ/CÓMO tab, mockups, proxy.
Imagine LabStills: symbols, background, frame, logo, HUD.
ElevenLabsCue generation. Does not write the orchestra.
Genie Spine ReskinLab to paint atlas skins. Separate ports.
Spline MacVisual editor of selected QUÉ. Bridge is outbox/inbox.
Grok + ClaudePlan / critique / prompts on subscription. Hosted Spline MCP on Arena.

What “edit” means in v1

Horror Circus symbols are puppets, not still figurines. Each has idle (loop), spin blur, land, win (~4 s, no loop), nowin still, paytable miniature. v1 does not invent 55-bone marionettes. v1 changes the skin and leaves bones and timings. Audio premium is a director: which stem enters, when, at what volume, who ducks whom. The piloto must respect Sounds.json + Manifest.json, not crush them with a Magix 3-cut sprite.

Downloads (both, when the engine matches)

  • Forge / Magix gems — only if the destination engine is Magix. Not this piloto.
  • Grabbr capture zip (tree + unpacked/).

Adobe mode

Not now. Default is simplified, more prompt than manual timeline surgery.

Four layers on every point (P / V / A)

LayerAnswers
ActualWhat is on disk / in the ecosystem, measured.
TechnicalNames, paths, contracts, formats.
Non-technicalWhat it means for you or the player.
How-toHow it is done today (CLI / HTTP / Grabbr) and in the game.

P1 — Where SpAIne lives

Actual. Module /opt/forge/spaine mounted via handleSpaine on :8766. Plugin ha-spaine. Grabbr tab + proxy. Docs /opt/forge/docs/spaine/ 00–13. Genie separate. Imagine :8791.

Technical. Extend Forge: no rewrite of serve core, bulk, arena-reels, rgs, Caddy Host. Jobs in spaine/jobs/<id>/. Grabbr calls Forge over HTTP.

Non-technical. SpAIne is the workshop. Grabbr is the shop window. Spline Mac is the visual bench for the selected QUÉ.

How-to. node /opt/forge/spaine/cli.mjs status · Grabbr SpAIne mode · plugin ctl.sh pipeline.

P2 — Capture in

Grabbr POST /v1/capture pulls traffic (PP Unity historically). Horror Circus did not come from that capture: dump /tmp/hc-cmp/axion-live/ → hydrate → jobs/horrorcircus-1.0.23/src. Pipeline start without a URL skips Grabbr if src/ already exists. ingest --capture=<id> does attach a Grabbr zip to the apartado. A useful capture must keep a playable tree, not a flat gallery: Manifest, Sounds, Symbols, Reels, webp, Spine json+atlas, ogg.

P3 — The order

Grabbr chips QUÉ (AA–BN from catalog) + textarea CÓMO + “Send selected to Spline”. HTTP POST /spaine/select {codes,how} → select.json. Outbox per code. You mark the clown (AA) and write “neon clown, keep silhouette.” The zip the Mac downloads is that original plus that order.

P4 — Mockups on the real base

cli.mjs mockup writes jobs/horrorcircus-1.0.23/mockups/board-current.png (background + frame + stills). Grabbr GET /v1/spaine/mockup.png. N variants are not in UI yet. Compose 16:9 boards, pick one, only then Generate the full set. Shared 5–7 colour palette across every prompt.

P5 — Apply → play → zip

apply copy-on-write src/ → dst/ + SPAINE-BUNDLE.json (new id). recompile = atlas-repack + zip (measured 6 110 526 bytes). Spline approve overwrites the still in dst/. Playable temporary deploy in a browser is still a hole this cut. Magix gems exist in Forge; they are not this piloto. First you play it. If the clown moves and the saw sings on win, then you download. Downloading first is buying a blind zip.

P6 — Models and audio APIs

Imagine Lab live. gen-stills painted gen/stills/AA-Joker.png. gen-sfx UI_Button ogg. Horror Circus is N oggs + Manifest names + Sounds.json. Mixing the Magix pipeline here crushes the director. Local LLM deferred. v1: ElevenLabs one cue = one ogg, exact Manifest names.

P7 — Spline Mac as the intermediate step

Outbox/inbox under jobs/<id>/bridge/. Smoke AA: class spine-atlas-part, original.webp + blur, brief.md, mcp-request.json, zip 92 721 bytes. Approve copied v2 to dst/assets/images/symbols/Joker.webp. Desktop MCP = Spline.app on Darwin; Arena uses hosted mcp.spline.design. Reject returns that asset to editing; the rest of the job continues.

Absorbed

00-producto.md, 04-puntos-producto.md, INDEX.md

Pipeline — Forge ↔ Grabbr ↔ Spline Mac

The contract is a state machine on disk. Forge starts from a slot base. Grabbr captures. Forge catalogs the exploded zip in an apartado. The user picks QUÉ and CÓMO. Selected originals travel to Spline (classify, save in Spline.app, attach MCP brief, edit). Approve sends v2 back to Forge for recompile. Reject keeps editing. src/ is never overwritten. Apply/recompile uses a new bundle id.

Forge job Grabbr catalog QUÉ/CÓMO Spline review recompile zip src/ bit-identical · dst/ copy-on-write · new bundle id · Magix gem is not this piloto

Click a state. The panel describes what happens on disk for that state — idle through recompiled. Reject of one asset is review → editing without resetting the job.

On-disk layout

/opt/forge/spaine/jobs/<id>/
  src/                     exploded original (hydrate or Grabbr ingest)
  catalog.json             classification of each cell
  select.json              { codes, how }
  pipeline.json            state + history
  bridge/outbox/<CODE>/    pack for the Mac (original + classify + brief + mcp-request)
  bridge/inbox/<CODE>/     asset.v2.* + status.json
  bridge/approved/<CODE>/  copy of what was approved
  dst/                     copy-on-write + v2
  gen/zip/<id>.zip         recompiled pack
  mockups/board-current.png
  inventory.json · validate.json · SPAINE-BUNDLE.json (in dst/)

Flow numbered

  1. Forge starts a job on a slot base.
  2. That slot is sent to Grabbr capture (POST /v1/capture) unless src is already hydrated.
  3. Download, explode the zip, catalog, store in the apartado jobs/<id>/.
  4. User chooses QUÉ (codes AA…) and CÓMO (edit request).
  5. The QUÉ that live on Arena (exploded original) are packed for Spline Mac: classified original, saved for Spline.app import, brief + mcp-request.json, then edited in Spline.
  6. 5.a user approves → asset v2 returns to Forge inbox → recompile. 5.b user rejects → keep modifying until approve.

Measured smoke (2026-10-28, Arena)

Piloto horrorcircus-1.0.23, src/ already hydrated (Grabbr capture not fired).

StepResult
cli.mjs startPASS, skippedCapture: true, state ingesting
catalogPASS, 8 codes AA–BN
select --codes=AA --how='neon clown…'PASS
spline-packclass spine-atlas-part, original+blur copied
spline-zip --code=AA92 721 bytes
claim / inbox (v2 = copy of original, Mac absent)PASS
approve --code=AAdst/assets/images/symbols/Joker.webp
recompileatlas 38 placements, zip 6 110 526 bytes, state recompiled
Grabbr GET /v1/spaine/spline/outbox/AA.zipHTTP 200, 92721
Chrome :9336PID intact

Libs: lib/pipeline.mjs catalog.mjs select.mjs spline-bridge.mjs review.mjs.

SSH Arena→Mac is not required. The operator downloads AA.zip from the outbox (Grabbr or Forge), opens it in Spline.app, the MCP agent follows brief.md / mcp-request.json. PNG v2 uploads to inbox. Approve in Grabbr.

Absorbed

13-pipeline.md, 00-producto.md, cli.mjs, routes.mjs, pipeline.json (read-only)

CLI — real commands from cli.mjs

Runtime entry: node /opt/forge/spaine/cli.mjs <cmd>. Plugin wrapper: bash ~/.grok/plugins/ha-spaine/scripts/ctl.sh <cmd> (forwards to the same CLI). Flags are --name= style. --json dumps JSON. Default job id is horrorcircus-1.0.23 from defaults.json.

Usage string from the default branch of cli.mjs:

usage: cli.mjs status|hydrate|inventory|validate-tree|mockup|apply|plan|qa|
  gen-stills|gen-sfx|atlas-repack|zip|pipeline|start|ingest|catalog|select|
  spline-pack|spline-zip|spline-claim|inbox|approve|reject|recompile|bridge

Copy/paste — factory loop

node /opt/forge/spaine/cli.mjs status
node /opt/forge/spaine/cli.mjs hydrate
node /opt/forge/spaine/cli.mjs inventory
node /opt/forge/spaine/cli.mjs validate
node /opt/forge/spaine/cli.mjs mockup
node /opt/forge/spaine/cli.mjs catalog
node /opt/forge/spaine/cli.mjs select --codes=AA --how='neon clown, keep silhouette'
node /opt/forge/spaine/cli.mjs spline-pack
node /opt/forge/spaine/cli.mjs spline-zip --code=AA
node /opt/forge/spaine/cli.mjs spline-claim --code=AA
node /opt/forge/spaine/cli.mjs inbox --code=AA --file=/path/v2.png
node /opt/forge/spaine/cli.mjs approve --code=AA
node /opt/forge/spaine/cli.mjs reject --code=AA --note='more glow'
node /opt/forge/spaine/cli.mjs recompile
node /opt/forge/spaine/cli.mjs pipeline

Copy/paste — paint and audio without Spline

node /opt/forge/spaine/cli.mjs gen-stills --codes=AA --prompt='emerald royal jester, same silhouette'
node /opt/forge/spaine/cli.mjs gen-sfx --stems=UI_Button
node /opt/forge/spaine/cli.mjs atlas-repack
node /opt/forge/spaine/cli.mjs apply
node /opt/forge/spaine/cli.mjs zip

Copy/paste — start a named job

node /opt/forge/spaine/cli.mjs start --name='Horror Circus' --provider=axion
node /opt/forge/spaine/cli.mjs ingest --capture=<grabbrId>

Piloto already hydrated: start without --url does not fire Grabbr; it catalogs jobs/horrorcircus-1.0.23/src.

What each command does

CommandOn disk / behaviour
statusPrints runtime, piloto id, dump path, snd overlay, job dir, magixGem: false.
hydrateCopies dump /tmp/hc-cmp/axion-live (or --dump=) into the job src/, overlays real oggs from /tmp/hc-cmp/snd (CDN files without .ogg are often HTML 404), validates.
inventoryLists 8 codes + 18 stems + 8 atlas folders. Writes inventory.json. Exit 2 if not ok.
validate / validate-treeFail-closed: ogg that is HTML 404 is HOLD. Expects Manifest names with loader-appended .ogg.
mockupComposes background + reelhose + 5×3 stills ~200×190 → mockups/board-current.png.
planNo extra engine. LLM-in-chat against inventory.json and the how-to.
applyCopy-on-write src→dst, new bundle id (--new-id= optional). Sounds.json / Reels.json hashes must stay identical.
gen-stillsImagine Lab. --codes=AA,BB --prompt=. Default codes from defaults.json.
gen-sfxElevenLabs. --stems=UI_Button comma list. Theme default “horror circus slot”.
atlas-repackRepack parts; measured 38 placements on the piloto.
zip / grabbrWrites gen/zip/<id>.zip.
pipeline / pipestatusJob of pipeline.json.
start--name --provider --url/--slotUrl. Skips capture if src exists.
ingest--capture= Grabbr capture id → explode into apartado.
catalogClassifies each cell (webp, blur, atlas folder, Spline class).
select--codes=AA --how='…' or trailing words as how.
spline-pack / outboxWrites classify + original + blur + brief + mcp-request per selected code.
spline-zip--code=AA zips that outbox folder.
spline-claimMarks the Mac claimed the pack; state editing.
inbox--code=AA --file=/path/v2.png drops v2.
approve / rejectCopy to dst/approved or return to editing with --note=.
recompileatlas-repack + zip, state recompiled.
bridgeLists outbox, inbox, catalog codes, select.
qavalidate + presence of board-current.png. Magix: “not this piloto”.

defaults.json (measured)

pilotoId horrorcircus-1.0.23, dump /tmp/hc-cmp/axion-live, overlay /tmp/hc-cmp/snd, template /opt/translaxion/data/slotre/horrorcircus-template/game, jobsRoot /opt/forge/spaine/jobs, codes AA–BN, read-only JSON: Sounds, Reels, Pays, Game, CoinSettings. Triple map is the law of names (AA/Joker/JOKER … BN/Bonus/DIAMOND).

Absorbed

cli.mjs, defaults.json, 07-howto-piloto.md, 13-pipeline.md, SKILL.md

HTTP — Forge :8766 and Grabbr proxy

Mounted by export async function handleSpaine in /opt/forge/spaine/routes.mjs. Paths that do not start with /spaine return false so Forge can keep serving bulk/rgs. Unknown /spaine/… returns 404 JSON {ok:false, error:"spaine-route"}.

Forge routes (from routes.mjs, not invented)

MethodPathBody / notes
GET/spaine/health{ok, module:"spaine", piloto, magixGem:false}
GET/spaine/inventoryinventory of piloto tree
GET/spaine/validate200 or 409
POST/spaine/hydratehydrate dump → job src
POST/spaine/mockupcompose board
GET/spaine/mockup.pngboard-current.png or HOLD no-mockup
POST/spaine/applycopy-on-write
POST/spaine/atlas-repack
POST / GET/spaine/zipGET streams the zip file
GET/spaine/pipelinestatusJob; ?id=
POST/spaine/pipeline/start{name, provider, slotUrl|url, id}
POST/spaine/pipeline/ingest{captureId|capture, id}
POST / GET/spaine/catalogPOST catalogs; GET loads catalog.json
POST / GET/spaine/select{codes, how}
POST/spaine/spline/packpack outbox
GET/spaine/spline/outboxlist
GET/spaine/spline/outbox/AA.zipzipOutboxCode; any [A-Za-z0-9_]+
POST/spaine/spline/claim{code}
POST / GET/spaine/spline/inboxPOST {code, file}
POST/spaine/review/approve{code, note}
POST/spaine/review/reject{code, note}
POST/spaine/recompile

Grabbr proxy

Same paths under /v1/spaine/…. Tab SpAIne: health Forge/Genie, mockup, zip, chips QUÉ, CÓMO textarea, Send to Spline, outbox zip per code, approve/reject. Cookie hall_sala. Zero Spine/ElevenLabs logic in Grabbr.

Documented Grabbr surface (pointer README, not the full Grabbr HTTP API):

  • GET /v1/spaine health
  • GET/POST /v1/spaine/catalog select pipeline
  • POST /v1/spaine/spline/pack · GET …/outbox/AA.zip
  • POST /v1/spaine/review/approve reject recompile
Absorbed

routes.mjs, 13-pipeline.md, Grabbr docs/spaine/README.md

Ports, hosts, and what you must not merge

ServiceWhereLaw
Grabbrpublic grabbr.jailbroken.tech, local :8790Thin client. Restart game-images-api if needed; do not kill headed Chrome.
Forgeforge.jailbroken.tech :8766GET /spaine/health ok. Extend, do not replace serve.mjs.
Genie Reskin:8765 API, :5173 UIDo not merge into forge.service. ctl.sh start|stop|status in vendor tree.
Imagine Labimagina.jailbroken.tech + :8791Paint GO. SuperGrok OAuth. GEMINI_API_KEY unused for Generate.
Chile CDP Chrome127.0.0.1:9336 PID 1901346NEVER kill. Do not reuse this port for extra HPlay capture.
Spline hosted MCPhttps://mcp.spline.design/mcpOAuth. 401 = HOLD.
Spline desktop MCPDarwin Spline.app stdio 127.0.0.1Disabled on Arena Linux (enabled=false).

Auth across console / pentest / audit / forge / ticketing / Grabbr: cookie hall_sala.

Absorbed

INDEX.md, 11-reskin-app.md, 12-spline-mcp.md, jokers README

Job: Jokers Diamond original (HPlay)

This is a different job from Horror Circus. Magix gem is not for the Horror Circus piloto, and Horror Circus art is not this HPlay original. Do not mix the two packs in one outbox brief.

Original HPlay
Hosthttps://hplay.games/game/launcher
IdsgameId=13121200, demo, language=es, merchantId=0199ece3-…
TitleJoker’s Diamond
EngineClosed HPlay pack (obfuscated JS)
Grid5×3
Board capture/root/hplay-hc.png

Job path: /opt/forge/spaine/jobs/jokers-diamond-hplay/. State measured in pipeline.json: spline_ready. History: idle → cataloged (8 stills cropped from hplay-hc.png) → selected (all 8 symbols + logo, 3D + animated) → spline_ready. grabbrId is null — stills were cropped from the screenshot, not a Grabbr Unity capture.

Outbox codes: BAR, BELL, GRAPE, SHOE, ORNG, SEVEN, MELON, LOGO. Each brief says explicitly: take this ORIGINAL Jokers Diamond (HPlay gameId 13121200) 2D still — NOT Horror Circus / Axion premium. Classify, save original in Spline, rebuild as a 3D object matching the still (gold casino / fruit / plaque), looping idle (slow Y-turn + bob + gold glints), silhouette readable as a slot symbol.

Spline hosted MCP for this job: HOLD oauth (grok mcp doctor spline → AuthRequired 401). Sign in; do not fake the edit in Three.js.

Evidence limit: the original does not ship loose figurines. Comparison of stills is the real screen. Audio of the original could not be extracted (closed pack). Ear comparison is product family vs the measured Horror Circus score. Full paytable stills are not on hplay-hc.png — HOLD, do not invent missing cells from memory.

If the mental “original” was a Hacksaw Horror Circus or another provider: this 13121200 is Joker’s Diamond. Homonyms of the clone name are different games (GameArt Circus of Horror, Join Games Horror Circus, Relax Zombie Circus, Hacksaw Klowns).

Absorbed

01-original-vs-clon.md, jobs/jokers-diamond-hplay/README.md, pipeline.json (read-only), INDEX.md

Job: Horror Circus Axion 1.0.23

Host: https://games.stage.axiongames.io/HorrorCircus/ · gameId=jdhorrorcircus · jurisdiction 99 · demo · currency ARS · brand gamesplay. Title Horror Circus / sign CIRCUS OF HORROR. Engine Axion Pixi, build 1.0.23, Spine 4.1.24. Grid 5×3 (reels.symbols [3,3,3,3,3]).

Live pack: https://games.stage.axiongames.io/HorrorCircus/game/. Local copies /tmp/hc-cmp/axion-live/ and /opt/hallallow/apps/game-images-api/cache/hc-cmp/. Translaxion template /opt/translaxion/data/slotre/horrorcircus-template/. Job /opt/forge/spaine/jobs/horrorcircus-1.0.23/.

Headless Chromium stuck on the loader; visual analysis of the clone is the files the game downloads — what the player sees after load.

It is not a gentle repaint of the same look. They share the skeleton of a classic 5×3 (columns, lines, spin on the right, menu on the left, balance below). The entire costume changed. The blood tie: the Joker and the diamond. Leftover names inside (folder Joker_Sounds, line atlas joker_atlas, files Juggling, shoes, Square, Circle) are the fingerprint of painting on a template, not a 1:1 look copy.

Group by group (player language)

Stage. Original: luxury casino theatre, gold arch, champagne. Clone: BG_Background.webp horror tent, CIRCUS OF HORROR in acid green, red curtains, red-yellow spiral floor. They did not retouch the theatre. They replaced it.

Reel furniture. Original: beige window, thick gold. Clone: Reel.webp blue wooden drum, five bands, violet rim, blood splatter. In a reskin this group weighs as much as the symbols: gold frame + clowns = halfway.

Logo. Original JOKER’S DIAMOND jewel letters. Clone title lives in the background neon; animated Logo.json. Diamond survives as scatter, not as the name.

Palette. Original gold/beige/grape/red-7. Clone tent purple, slime green, blood, saw orange, brain pink, cracked-diamond blue. Whole temperature, not a metal tint.

HUD. Same logical posts. Clone adds buy feature (HorrorCircus_54) that the original screenshot does not show. Moving spin changes the genre; recolouring it does not.

Symbol table — leftover drawer names

CodeFile (old name)What you seeEcho in Joker’s Diamond
AAJoker.webpHorror jester, 55 bones, aria Win_JokerJoker of the logo
BBSeal.webpZombie monkey, Win_MonkeyNothing; mid fruit
CCJuggling.webpChainsaw, Win_SawBell / horseshoe
DDshoes.webpRed tricycle, no ariaLow fruit
EEBall.webpHyperreal balloon, Win_BalloonNothing
FFSquare.webpBrain, 48 bones, no ariaA shape
GGCircle.webpHORROR CIRCUS / ADMIT ONE ticketA shape
BNBonus.webpCracked diamond + BONUS, Bonus_LandingTitle diamond + scatter

The electrician never relabelled the drawers. SpAIne must write into the drawer, not invent new drawers.

How they move

Original: still figures dropping, generic reel blur, win = shine / line / count. Clone: each symbol is an actor — idle lives, spin is a blurred photo, land returns the puppet, win ~4 s acting, nowin quiet photo, paytable miniature. Paylines are six Spine choreographies (payline0…5), not a yellow Excel underline. Wild internal WD. Reel x: -546, -278, 0, 277, 546. Cell ~200×190. The original is a luxury sticker album. The clone is a puppet theatre. That is why symbols feel considerably better: they move as characters.

What they did not change (chassis)

Five reels × three visible, cell-sized symbols, paylines, wild WD, scatter that opens extras, spin right / menu left / money down, autoplay, info, sound on/off, joker+diamond DNA. Same machine, different show inside. “Considerable symbol upgrades” lands. “A few light look changes” does not. What is light is the chassis.

Job tree (structure, read-only)

src/ hydrated playable tree (assets/images, json, spine, sounds/Joker_Sounds, Manifest). dst/ copy-on-write plus approved AA still. genie/joker/ exploded 37 JOKER regions for Reskin Studio — never written back over src. bridge/outbox/AA/ original.webp, original.blur.webp, classify.json, brief.md, mcp-request.json, AA.zip. Catalog 8 items. Mockup board-current.png. Zip 6.1 MB under gen/zip/.

Absorbed

01-original-vs-clon.md, 05-puntos-visual.md, job tree listing (read-only), catalog.json head

Visual and motion — V1 to V20

Image loader on the clone: Manifest.json preload.images — the name is what the engine asks (AA, Bg, reelhose); the file is what you see.

V1. Background

Actual. Original gold theatre (capture hplay-hc.png). Clone BG_Background.webp (171588 bytes in cache). Same file registered twice as Bg and BaseGame_Bg. Portrait: Potrait_Background.webp + black_bg_potrait.webp.

Technical. Stage names Bg, BaseGame_Bg, portrait_Bg, portrait_Bg_screen. Not Spine; full-screen texture. 16:9 from Config.json 1920×1080.

Non-technical. The theatre. If you do not change it, the new clown looks like a sticker on the old casino.

How-to. Generate 1920×1080 with Imagine, same palette as symbols. Replace the webp without changing name Bg. Also generate portrait or vertical keeps the old stage. No JSON change required.

V2. Reel frame / drum

Actual. Clone Reel.webp name reelhose, 119368 bytes, five blue bands + blood + violet hoop.

Technical. Static texture under symbols. Positions in Reels.json: x = -546, -278, 0, 277, 546; y = -150; symbol_size 200×190; symbol_above/below = 1. Lights are separate Spine (reelLight, ReelSpinGlow, reelBlure).

Non-technical. The cabinet. In the clone it is dirty on purpose. A jewellery frame with chainsaws feels fake.

How-to. Measure current Reel.webp, generate five columns aligned to those x. Keep name reelhose. If the new drum does not fit 200×190, symbols float or clip — do not stretch by eye.

V3. Logo

Not a loose PNG in preload.images. Lives in preload.spine.anim.assets, registered GameLogo1, 3 bones. Texture in UI atlas spine.atlas/spine.webp, not Symbols.atlas. Clone also paints CIRCUS OF HORROR on the arch — two logos. Reskin: paint text on the new background and replace Logo.json attachments, or you ship two brands.

V4. Palette

There is no palette.json. Colour is distributed across every webp, Spine lights, ticket type, background sign. Extract 5–7 colours from the order or a ref and pass them to all generations. A loose per-symbol prompt splits the set.

V5. HUD

Same logical layout. Buy feature. Skins in Spine box.json (69 bones, anims AA…GG, BN and *_P portrait) + Upper_Desktop.json. lightFrame follows the win ladder. Rule texts in Pays.json with placeholders {%HorrorCircus_1%}. i18n: 191 strings in translaxion export. v1 reskin: recolour box + lightFrame + Upper_Desktop. Do not delete buy. Do not blindly translate keys.

V6. The name trick

Three layers that do not match. Never rename AA or Symbols.json keys in v1. Replace: stills in assets/images/symbols, blurs, atlas regions with the same names (JOKER/…, BIKE/PEDAL), SmallSymbols. If you change Manifest name AA and not the rest, the reel goes empty.

V7. AA — Joker

joker.json Spine 4.1.24, 55 bones, 38 slots, anims idle, start, Static, Static_Blur, win. Aria Win_Joker 3.67 s. Idle/land → jokerJson.symbol_atlas.idle scale 0.0973 loop; win → start duration 4. Small scale because the skeleton is drawn large. Do not regenerate 55 bones. Paint atlas folder JOKER/ (face, hat, bells, neck) and leave joker.json. Still Joker.webp covers nowin and mockups. Match hat purple/red/green to the background or it will float.

V8. BB — Seal / monkey

seal.json 40 bones, atlas MONKEY, Win_Monkey 4.00 s, scale 0.0913. Do not rename to Monkey.webp in v1 (breaks Manifest BB url) unless you update Manifest and SmallSymbols together — better not.

V9. CC — Juggling / saw

Juggling.json 12 bones, atlas SAW, Win_Saw 4.00 s, scale 0.1882 (skeleton modelled smaller). 12 bones means chain and housing can move; if you paint one PNG and the chain attachment stays the old saw, you get a hybrid. Cover every SAW/ region.

V10. DD — shoes / tricycle

shoes.json 10 bones, atlas BIKE (BACK WHEEL, PEDAL, MASA, Slime pedal). No aria. Scale 0.1929. Paytable shoe_Small.png. Audio falls to generic Payline. Do not invent symbolWin_DD in v1 if you want the same rhythm; the director does not expect it.

V11. EE — Ball / balloon

Ball.json 2 bones, atlas BALLOON including BOOM/SAW-idle/boom_#####. Win_Balloon 4.00 s. Scale 0.211. Acting is scale/glow/boom, not puppet. Treat boom as part of the symbol. If boom stays red balloon and idle is blue, the win looks broken.

V12. FF — Square / brain

Square.json 48 bones (more than the saw), atlas BRAIN, no aria. The still lies about simplicity. Mandatory to pass through atlas BRAIN/, not only the webp. If you only change Square.webp, Spine idle still shows the old brain.

V13. GG — Circle / ticket

circle.json 3 bones, atlas TICKET, copy HORROR CIRCUS / ADMIT ONE painted in the texture, not i18n. Changing HUD language does not change the ticket. If the reskin changes the game name, repaint ticket + background arch + Logo. Three sites. Forget one = two brands.

V14. BN — Bonus / diamond scatter

diamond.json 9 bones, atlas DIAMOND, Win_Diamond, landing Bonus_Landing priority 1. Scale 0.2168. Reels.json reelStopSounds.BN. Buy feature HorrorCircus_54. Wild is WD (no WD webp in symbol preload — overlay / other path). Keep the word BONUS unless the order asks another scatter language. Do not touch reelStopSounds if you want the landing sting.

V15. Spin blurs

Eight webp in BlurSymbols/*_Blur.webp, Manifest AA_Blur…BN_Blur. During spin the engine does not use the puppet; it uses the smeared photo. Generate each blur from the new still (vertical motion blur, same silhouette). Do not reuse the clown blur for the brain.

V16. Paytable miniatures

payline_info points at Joker_Small.png, Seal_Small.png, Juggling_Small.png, shoe_Small.png, Ball_Small.png, … Bonus_Small.png. Spritesheet SmallSymbols.json. If the reel is horror and the paytable still shows juggling, the player thinks there are two games.

V17. Symbols atlas — the most important how-to

Symbols.atlas 17105 bytes, pages Symbols.webp + Symbols_2.webp, 2048², filter Linear, 781 lines. Folders BALLOON, BIKE, BRAIN, DIAMOND, JOKER, MONKEY, SAW, TICKET. Skeletons reference attachment names, not the Manifest still. Joker.webp and atlas JOKER/face can diverge: one is nowin, the other is idle.

v1 skin: (1) export regions by bounds, (2) paint each crop same w×h or update bounds, (3) restick into 2048² keeping names, (4) leave joker.json / bones / timelines, (5) test idle and win — empty slot = missing region. Do not emit a new joker.json from an Imagine video. Spine 4.1.24, 55 bones, meshes: nothing in the stack emits that well.

V18. Lights, glow, big win, lines

SpineBonesAnims (idea)
reelLight.json41light per reel 1–6 play/stop
ReelSpinGlow.json1glow per reel 1–5
reelBlure.json1column blur A–E
lightFrame.json10stop, play, win, big, huge, mega
payline.json2payline1–5 (reels JSON speaks payline0–5: off-by-one to confirm in play)
wins.json53big/huge/mega + End + _P portrait + clearTrack
winsText.json42those win texts
box.json69boxes AA…BN + portrait

Sounds.json win2+ asks animation bigwinStyle → hooks wins.json bigWin. v1 full theme: recolour textures in spine.atlas / spine.webp, not Symbols.atlas. Do not delete megaWin. Even a symbols-only reskin should tint lights or old gold fights new horror.

V19. Reel geometry — what you do not “paint”

5×3 visible, 1 above + 1 below, spin_speed 0.015, wild WD, skip_win_turbo true. Changing to 6×4 is another game, not a reskin. SpAIne v1 treats Reels.json as read-only.

V20. Fonts

Loader: Syifa, SansSerifBldFLF, Roboto Condensed Bold, NotoSans. Preload: Arial Black, Arial. Ticket and arch are painted, not these faces. v1: do not change fonts unless the prompt asks another writing. Brand flavour lives in textures.

Absorbed

05-puntos-visual.md, 01-original-vs-clon.md, defaults.json triple

Dynamic audio — the director

Look does not end at the drawing. In Horror Circus sound is directed: the engine decides which stem enters, when, at what volume, and who ducks whom, according to what just happened on the board. The folder is still named Joker_Sounds — a scar of the original. The content is already horror circus. Measured from live clone Sounds.json, Manifest, CDN oggs, ffprobe 2026-10-28. Loader appends .ogg at runtime (no extension → 404).

Original Joker’s Diamond — ear family

Audio pack could not be extracted (closed). In this family the ear is generic casino: theatre bed that sits there, whoosh on spin, same clack on every reel, roughly the same “you won” whether grape or 7, menu clicks. Everything sounds. Almost nothing tells a story.

Clone — a director, not a playlist

LayerLive fileDurationUse
BedMain_BGM.ogg124.88 s loopStarts in basespin. Does not reset per spin
Reel motorReel_Spin.ogg4.20 s loopPlay reels.start_spin, stop reels.stop_spin
Stop hitReel_Stop.ogg0.22 sOne per reel, cascade
Scatter exceptionBonus_Landing.ogg1.34 sIf symbol is BN, replaces clack (priority 1)
Aria clownWin_Joker.ogg3.67 ssymbolWin_AA
Aria monkeyWin_Monkey.ogg4.00 ssymbolWin_BB
Aria sawWin_Saw.ogg4.00 ssymbolWin_CC
Aria balloonWin_Balloon.ogg4.00 ssymbolWin_EE
Aria diamondWin_Diamond.ogg4.00 ssymbolWin_BN
Line / small winPayline_Win.ogg4.00 swin0 and win1 (same file; count behaviour changes)
BigBig_Win.ogg8.00 swin2 15×–30×
HugeHuge_Win.ogg8.03 swin3 30×–45× + pre-win 3 s
MegaMega_Win.ogg8.00 swin4 45×+ + pre-win 3 s
Win closeWin_Stop.ogg2.00 sCadence of close
CounterCounterloop.ogg4.82 s loop volume 0.3While the number climbs
Counter closeCounterloop_Stop.ogg0.89 sWhen the number arrives
Panel clickUI_Button.ogg0.75 sAlmost the whole menu
Spin triggerSpin_Button.ogg0.10 sOnly the spin button

A spin, second by second

0.00 s — button. spinButton on button.spin. Not the menu click. The ear reads “action.”

0.00 s — the bed continues. basegameBgm type bgm, loop, event states.basespin. If they cut the music every spin, it feels cheap.

With the spin — motor. reelSpin loop tied to state, not a fixed timer. Short turbo = loop cuts on reels.stop_spin.

Stop, reel by reel. Each column asks reelStop (0.22 s). Five clacks in a staircase = “mechanical machine.”

Exception: diamond landed. reelStopSounds: default reelStop; BN → bonusLanding priority 1. The diamond announces it landed even while others still spin. A silent scatter feels like decoration; one with its own voice feels like an event.

No prize. Motor off, clacks, bed. No false fanfare.

With a line. Two things at once: character voice if it is one of the expensive ones, and prize theme by multiple. Symbol win anims last 4 s. Arias last ~3.7–4.0 s. Ear and puppet finish together.

Ladder of “how fat was it”

IdRangeStageTypeCountCoinsSpriteExtra
win00–1×Payline_WinnormalnononoTip: no circus number
win11–15×Payline_WinnormalyesnoyesSame file; turns the counter on
win215–30×Big_Winbigyesyesyesanimation bigwinStyle
win330–45×Huge_Winbigyesyesyespre_win: 3
win445×+Mega_Winbigyesyesyespre_win: 3, end: -1

win0 vs win1 share a file. Difference is whether they light the counter. A small prize does not eat 8 s of opera. From Big: coins (rain, CoinSettings.json, up to 52 particles) + bigwinStyle. Huge/Mega: 3 s of “it’s coming” before the banner. sound_sprite true on win1…win4: the engine crops the block by how long the number takes. It is not an mp3 that always plays whole. At the end: Win_Stop or Counterloop_Stop. There is a close, not a dry cut.

A0–A22 how-to (factory)

A0. Magix/Forge gems have 1 sounds.ogg with 3 sprites. Arena Zeus: 9 one-shots. Horror Circus = events → stage → file. Not interchangeable. ElevenLabs is the singer. Sounds.json is the director. Filling a Magix engine with pretty singers still sounds like a radio with three buttons. Do not pack this piloto to Magix sprite.

A1 Bed. ~2 min loop, crossfade at the cut. Do not shorten to 8 s. Same tonality as arias or they fight.

A2 Spin trigger. ~100 ms transient, peak at start. Do not reuse UI click.

A3 Menu family. One UI_Button.ogg ~0.6–0.8 s for many keys (menu, buy, bet, turbo, info, history, mute…). Mute: button.sound_music_off. Do not point spinButton at this stage.

A4 Reel motor. 3–5 s grain, spliceable. File length is not spin length. Test that cutting on any beat does not click.

A5 Clack. ~200 ms impact, short tail, headroom for five in a row. Do not last 1 s: they overlap between reels.

A6 Scatter landing. 1.2–1.5 s sting, same character as Win_Diamond but shorter. Do not delete BN from reelStopSounds. Do not reuse this file for diamond line win.

A7–A11 Arias. AA/BB/CC/EE/BN only. Duration ±200 ms vs Symbols.json win duration 4. Distinct character (if both are “clown laugh”, they collide in memory). Balloon boom lives inside the 4 s, first third plus tonal tail. Landing ≠ aria: two phrases (“treasure fell” then “treasure pays”).

A12 Lows without aria. No symbolWin_DD/FF/GG, no Win_Bike / Win_Brain / Win_Ticket. They look like they win and sound like a line. Adding a brain aria is patching the director, not a reskin — outside the minimum piloto.

A13–A17 Ladder. One Payline_Win.ogg that survives being cropped. Big 8 s more energy than Payline. Huge bigger than Big, less than Mega, buildup in first 3 s. Mega must be distinguishable blind from Huge. Three files Big/Huge/Mega have to differ.

A18 Close. 1.5–2.5 s resolution. Not a click.

A19 Counter. Spliceable loop, unspectacular, mix ~-10 dB vs arias, volume 0.3 is the only explicit volume in Sounds.json. Stop < 1 s. Do not put melody on it.

A20 Coins. Not their own ogg. coins:true on win2+ plus CoinSettings. Put coin texture in the Big/Huge/Mega bed or let the counter loop be “money.” Do not create a cue the director does not call.

A21 Mix timeline. spinButton → reelSpin loop ON (BGM continues) → stops (reelStop × n or bonusLanding if BN) → reelSpin OFF → if pay: symbolWin_* in parallel with win0|1|2|3|4 → if rollup: counterloop 0.3 until number → counterloopStop and/or winEnd. BGM never cut. If BGM restarts, Apply broke type bgm or replaced the engine with Magix.

A22 Magix anti-how-to. Sprite times in ms: bgm [0, 19619, true], big_win [19679, 20991], bgm_freespin [40730, 19619, true]. Three buttons. No per-symbol, no reelStop, no pre_win, no counter 0.3. Correct format for Magix lines5x3 and a quality ceiling of that radio. Forbidden to collapse Axion Horror Circus to 3 cuts. Choose engine before generating audio.

Ear checklist (piloto)

  • Bed does not jump when you spin.
  • Reel motor starts and dies with the motion.
  • Five clacks; the diamond does not clack, it sings.
  • Aria ~4 s with the win face.
  • Small prize ≠ 8 s opera.
  • 15× / 30× / 45× change track; Huge/Mega have 3 s of “it’s coming.”
  • Counter is heard underneath, does not cover.
  • There is a close, not a dry cut.
  • Mute cuts music and sfx.

If that is not heard playing the deploy, it is not done. Magix 3 cuts or Arena Zeus 9 one-shots, however pretty ElevenLabs is, play flat. Painting on a mute engine does not reach this.

Absorbed

02-audio-dinamico.md, 06-puntos-audio.md, defaults.json expectedStems

Spline MCP — Mac app and hosted

Spline.design is a 3D / Hana 2D editor. Distinct from Spine 2D (Esoteric). SpAIne still ships Spine 4.1 atlases; this MCP is another surface (3D mockups, Hana HUD, refs).

Darwin is the macOS kernel. Spline.app installs under /Applications on that Mac. Desktop MCP starts the Electron binary (ELECTRON_RUN_AS_NODE=1) and talks on 127.0.0.1 with open Spline tabs on that same machine. Arena is Linux. Here the hosted MCP runs. SSH to the Mac is not required for SpAIne or hosted MCP.

What is on disk (2026-10-28)

WhereWhat
Arena Grok ~/.grok/config.toml[mcp_servers.spline] hosted enabled
Arena Grok[mcp_servers.spline-desktop] stdio Mac paths, enabled=false (no Spline.app on this Linux)
Claude Arena settings.jsonmcpServers.spline hosted
Cursor Arena mcp.jsonhosted + desktop paste
Canonical JSON/opt/forge/spaine/mcp/spline-desktop.mcp.json · spline-hosted.mcp.json
Skill~/.grok/skills/spline/SKILL.md (official splinetool)
Mac installer/opt/forge/spaine/mcp/install-spline-mcp-mac.sh

Mac app JSON (paste):

{
  "mcpServers": {
    "Spline": {
      "type": "stdio",
      "command": "/Applications/Spline.app/Contents/MacOS/Spline",
      "args": ["/Applications/Spline.app/Contents/Resources/spline-mcp.cjs"],
      "env": { "ELECTRON_RUN_AS_NODE": "1" }
    }
  }
}

How to keep desktop MCP alive

  1. Spline.app installed and opened at least once.
  2. On the Mac: bash /opt/forge/spaine/mcp/install-spline-mcp-mac.sh (or paste JSON into ~/.claude.json / Cursor / Grok).
  3. Restart Grok / Claude / Cursor on that Mac.
  4. Settings → MCP in Spline: turn the client you use on.

This Arena session cannot spawn Spline.app. Hosted MCP can: first call asks Spline OAuth in the browser (grok mcp doctor spline or Settings MCP). If OAuth 401: HOLD. Never substitute Three.js.

Relation to SpAIne

Horror Circus piloto = Spine 4.1 atlas + oggs. Genie Reskin :8765/:5173. Spline MCP = visual editor of selected QUÉ. Arena→Mac bridge is the outbox: classify + original + brief + mcp-request.json. v2 returns through inbox; Forge recompiles. Spline does not overwrite joker.json or src/. Measured outbox: jobs/horrorcircus-1.0.23/bridge/outbox/AA/.

Absorbed

12-spline-mcp.md, 13-pipeline.md, jokers pipeline.json spline block

Genie Spine Reskin (reskin-app)

Upstream: github.com/GenielabsOpenSource/spine-animation-ai/tree/main/reskin-app. Vendor lab: /opt/forge/spaine/vendor/genie-reskin (PolyForm NC — internal lab; commercial HOLD). Ports 8765 / 5173. Forge stays 8766. Chrome 9336 untouched.

It does not rebuild bones. It loads an existing Spine rig, paints it in spine-pixi-v8, Imagine (grok-imagine-image-2.0, SuperGrok OAuth) reskins the mounted frame, SAM crops per slot (no rectangular bleed), rewrites atlas + Spine-{skin}.json, reloads the same puppet.

Why upstream explode is not enough

Horror Circus is not {name}.json + {name}.png + {name}.atlas. Rig is joker.json 4.1.24, 55 bones, 38 slots. Atlas uses bounds: dialect (spine-pixi-v8 does not parse it). Sheets Symbols.webp 2048² + Symbols_2.webp (FACE lives on _2). Attachments path "JOKER/FACE" (not name). Job unpack did not even bring the WebPs (json/atlas only).

Our script: /opt/forge/spaine/lib/ingest-joker-genie.py — download/use pages in genie/pages/ (Axion stage CDN, 200 measured), crop 37 JOKER/* regions (0 miss vs attachments), sanitize JOKER/FACE → JOKER_FACE in atlas and path, repack Spine 4.x xy/size/orig/offset + Spine.json/atlas/png (Genie opener requires the same stem), write jobs/horrorcircus-1.0.23/genie/joker/. src/ bit-identical. Measured: atlas 1024², POST /api/project/open → skins default, 5 anims, joker slots.

Lab live

bash /opt/forge/spaine/vendor/genie-reskin/ctl.sh start|stop|status
UI     http://127.0.0.1:5173/
API    http://127.0.0.1:8765/api/health  → {"ok":true}
open   POST /api/project/open  path=/opt/forge/spaine/jobs/horrorcircus-1.0.23/genie/joker

In the UI: Open that folder. Play idle / win. Generate paints with Imagine (same OAuth as Lab :8791). Still asks FAL_KEY for Bria on rebake.

HOLD (real)

GateState
Imagine / SuperGrokGO for paint. ~/.grok/auth.json + grok-voice.mjs. GEMINI_API_KEY unused.
SAM_SERVER_URLempty. SAM step and Magic Select HOLD. Brush/lasso still work. Generate paints; per-slot slice HOLD without SAM/FAL.
FAL_KEYBria bg-remove optional. Generate/Retouch no longer require FAL. Empty = SAM/Bria slice HOLD.
magic_cut.onnxnot copied to app/frontend/public/
spine-pixi-v8 4.2.114 vs JSON 4.1.24open PASS; deform/mesh on canvas = validate by eye on idle/win
PolyForm NCdo not pack Genie inside a paid product
has_part_png: falselist_part_pngs looks for {slot}.png; we have JOKER_{SLOT}.png. Canvas uses packed atlas. Method exploded of generate may fail; use atlas.

SpAIne flow (Imagine GO; SAM slice HOLD)

  1. Generate skin horror-v2 (or the theme prompt).
  2. Refine masks / HSL.
  3. Export inside genie/joker/.
  4. SpAIne apply: copy atlas+skin to job dst/, new bundle id, Forge temp deploy. Do not touch Sounds.json / Reels.json / bone hashes.

Do not put Vite/uvicorn in forge.service or Caddy of forge.jailbroken.tech without an order. Do not write skins over src/. Do not explode the whole Symbols.atlas (305 regions, 8 characters) into one Genie project — one rig per folder. Do not inject walk/run presets from the 4.2 builder.

Absorbed

11-reskin-app.md, 10-spine-animation-ai.md

Genielabs Spine Animation AI × SpAIne

Clone measured 2026-10-28 at /tmp/hc-cmp/spine-animation-ai. License PolyForm Noncommercial 1.0.0. Commercial slots / paid Forge = separate license at genielabs.tech. Internal lab: document HOLD until the operator signs.

ScriptDoes
split_character.py1 PNG → parts (Gemini + OpenCV)
position_parts.pySIFT+RANSAC vs assembled reference
build_spine_json.pySkeleton Spine 4.2.0 + presets idle/walk/run/wave/jump/attack
make_atlas.pyTexture packer
generate_spine_player.pypreview.html (Spine Web Player)
reskin-app/Reskin Studio. Our lab: Imagine paints, SAM crops per slot (HOLD), atlas+skin, rig untouched

Twelve principles → Axion reel clips

Horror Circus already uses pose-to-pose in Spine (idle, start, Static, Static_Blur, win). No walk/run. Repo presets are humanoid platformer. Rename/adapt to idle / win / Static; do not inject walk into Axion.

PrincipleOn the reel
Squash & stretchBalloon / brain / diamond on win; constant volume (scale X×Y ≈ 1)
Anticipationwin: 2–4 frames of “charge” (saw back, joker inhale) before the hit
StagingSymbol reads at 80–120 px; no secondary that covers the icon
Pose to poseKeys in JSON; Pixi interpolates. SpAIne does not straight-ahead frame by frame
Follow throughJoker: HAT / BELL / TONGUE after FACE. Saw: blood after sawbody
Slow in / outBezier like [0.25, 0, 0.75, 1]; idle slow, win snappy
ArcBells and saw on an arc, not linear translation
SecondaryIdle: eyelids / slime. Win: do not compete with the payoff
TimingIdle ~2.0s loop. Win ~0.6–1.0s = one SFX beat (Axion win faces are ~4 s; keep audio lock)
Exaggeration+20–40% vs realism; do not break reel AABB
Solid drawingThe paint; the rig is already solid (55 bones)
AppealSilhouette of the still, not the skill

Fit (fail-closed)

GO — Reskin Studio on the existing rig: explode_spine_atlas.py on bounds: dialect, open joker.json + atlas, prompt look, Imagine paint, SAM per slot (HOLD without server), new atlas + extra skin, export to SpAIne dst/ without touching Sounds/Reels/bone hashes. That is “premium stills that already animate”: motion exists; paint changes.

HOLD — build_spine_json.py from scratch: emits spine 4.2.0 vs Axion 4.1.24; humanoid 10–16 bones ≠ joker 55 (HAT CONTROL, BELL*, EYE CONTROL); anim names walk/attack ≠ Static / Static_Blur / win. Inventing a 55-bone rig from Imagine stills is the same HOLD as gen-stills already had.

HOLD — split_character + auto-rig for the cast: useful for a new 8–12 part symbol (ticket, diamond). Not for replacing joker.json. If using the builder: pin "spine" to 4.1.24 and validate timelines (repo converts to 4.2 wire: bezier per property, not per key). Diff against real joker.json before apply.

Prompting: do not ask walk. Attach JSON+atlas. Explicit Spine version. Keep idle, start, Static, Static_Blur, win. If emitting adjustments.json, use Genielabs format (original_offset / user_offset dx,dy,drot / final_offset + draw_order). Y-up, +rot CCW. Output 4.1.24 JSON, not 4.2.0.

Deps if the lab is installed: Python opencv Pillow numpy; reskin-app SAM_SERVER_URL, Node 18, FastAPI :8765 + Vite :5173. Do not glue this into forge.service :8766.

Absorbed

10-spine-animation-ai.md

Pack — plugin + runtime + Grabbr

The operator idea: a pack with plugin and everything required so inventory → mockups → skin + audio → play → zip runs alone and runs well. On disk 2026-10-28: plugin + runtime + hydrate/inventory/validate/mockup/apply/gen-stills/gen-sfx/atlas-repack/zip and pipeline 13. Imagine paint GO. ElevenLabs per cue GO. Grabbr tab GO. SAM slice HOLD. Playable deploy HOLD.

Nothing else is required before starting the pack. First automatic cut does not even reskin to emojis: it ingests the Horror Circus tree, classifies each cell/cue, validates the tree is playable, and leaves the pipeline ready for Apply. Creative reskin is the next cut, director intact.

Defaults if there is no counter-order

DefaultValue
HA plugin nameha-spaine
Runtime/opt/forge/spaine/ (extend Forge, do not stomp serve.mjs)
ClientGrabbr, thin
PilotoHorror Circus 1.0.23 tree
v1skin + ogg; Sounds.json / Spine bones / Reels.json read-only
Authhall_sala
PainterImagine Lab (Grok subscription)
SingerElevenLabs (secrets/elevenlabs.env)
PlanGrok + Claude subscription
Magix 3-cut enginenot in this piloto

Three layers, one factory

Not a 10-agent AML team. Not a second Forge. A plugin that orchestrates + a Forge runtime that does the dirty work + buttons in Grabbr.

Layer A — plugin ~/.grok/plugins/ha-spaine: plugin.json, PLUGIN.md, NORTHSTAR.md, CONTRACT.md, skill, command /ha-spaine, scripts/ctl.sh. Real libs live in the runtime, not theatre: inventory, catalog, validate-tree, compose-mockup, gen-stills, gen-sfx, atlas-repack, zip-pack, apply, pipeline, select, spline-bridge, review. Few agents: conductor + optional stills/sfx/atlas. Do not clone ha-hackers.

Layer B — runtime workdirs jobs/<bundleId>/src|dst|mockups, HTTP on :8766, temp deploy of dst/ with the same Axion engine, not Magix lines5x3. Hooks via handleSpaine / routes.mjs.

Layer C — Grabbr tab only. Zero Spine/ElevenLabs logic.

NORTHSTAR

Success = the tree plays with the same score (Sounds.json) and the same bones, new skin and oggs, original intact. The Spline bridge (QUÉ/CÓMO → outbox → approve v2) is part of the path, not the close. Not success: “there is a plugin”, “there are PNGs”, “there is a Magix zip”, “there is a brief without v2”.

CONTRACT doneWhen (measured 2026-10-28)

  1. ctl.sh inventory on Horror Circus lists 8 codes + 18 stems + 8 atlas folders.
  2. ctl.sh validate PASS (real oggs, not HTML 404).
  3. ctl.sh mockup writes board-current.png on tree stills.
  4. ctl.sh apply copy-on-write, Sounds.json/Reels.json hash identical, new bundle id.
  5. Original dump bit-identical.
  6. catalog → 8 items. select + spline-pack → outbox with classify+brief.
  7. approve + recompile → zip in gen/zip/.

Never in v1

Regenerate joker.json from video. Arias for DD/FF/GG. Adobe mode. Rename AA / Juggling.webp “so they match.” Kill Chrome :9336. Magix 3-cut sprite on this tree. Ten team-forge agents.

Build order already PASS

  1. Plugin + inventory/validate — PASS.
  2. Mockup real board — PASS (board-current.png).
  3. Forge handleSpaine — PASS (:8766).
  4. gen-stills / gen-sfx — PASS (AA Imagine, UI_Button ogg).
  5. atlas-repack 38 placements — PASS.
  6. Grabbr tab + pipeline 13 — PASS (catalog 8, outbox AA, recompile zip).
  7. Play URL Forge + Spline.app on Darwin — next.

Inventory is no longer handmade: catalog.json comes from the tree.

Absorbed

08-pack.md, PLUGIN.md, NORTHSTAR.md, CONTRACT.md, SKILL.md, commands/ha-spaine.md, runtime README.md

How-to — piloto at Horror Circus level

End-to-end procedure to reach that level (full theme + audio director) on a slot that already has a score. Base: Axion Horror Circus 1.0.23 tree. Runtime /opt/forge/spaine. Recipe and commands that already run.

Success condition

You play the Forge deploy and: 5×3 board with new skin (background, frame, 8 symbols, blurs); old puppets, new faces (idle/win ~4 s); bed does not jump on spin; reel motor on/off with motion; clack ×5, diamond sings on land; arias AA/BB/CC/EE/BN fitted; win0 ≠ opera; 15/30/45 change track; counter low + close; mute cuts everything; job original intact; new bundle id; Grabbr zip + (if applicable) gem. If there are only pretty PNGs in a gallery: it is not done.

1. Freeze the source tree

Copy /tmp/hc-cmp/axion-live/ (or a future Grabbr capture) to workdir src/. Verify Manifest, Sounds, Symbols, Reels, BG_Background, Reel, eight symbol webps, eight blurs, eight spine jsons, Symbols.atlas + pages, Joker_Sounds/*.ogg. Read-only: Sounds.json (events), Reels.json, Symbols.json (stages), Spine bone jsons, Manifest names AA…BN, Bg, reelhose.

2. Inventory

cli.mjs inventory and catalog. Per group: code, file, atlas folder, cues, aria, Spline class. The plan LLM does not invent cells. It only fills “new skin / new ogg” against catalog.json.

3. Order

QUÉ = chips / --codes. CÓMO = textarea / --how. Full theme = product default; the Spline cut works the marked codes. N variations in UI: a hole. Refs: Forge inbox + files in the outbox pack.

4. Mockups before atlas and ogg

Compose board: background + reelhose + 5×3 stills at 200×190. N variants if asked. Pick. Only then Imagine in batch (8 stills + 8 blurs + background + frame + ticket/logo). Palette: 5–7 colours from the pick, the same in every prompt.

5. Puppet skin (atlas)

Parse Symbols.atlas → regions per folder JOKER|MONKEY|SAW|BIKE|BALLOON|BRAIN|TICKET|DIAMOND. Crop pages by bounds. Regen each crop. Repack 2048², same region names. Leave joker.json etc. Dry test: Spine 4.1 viewer (or the game itself) anim idle and start per skeleton. Empty slot = missing region. Manifest stills and SmallSymbols in parallel, same face, or nowin ≠ idle.

6. Audio (one cue = one ogg)

ElevenLabs table — copy durations from the audio chapter. Export ogg. Exact file names. The loader does not forgive Main_BGM.mp3. Do not generate Win_Brain / Win_Bike / Win_Ticket in v1.

7. Brand texts (three sites)

If the theme changes name: arch in BG_Background.webp; TICKET/ texture + Circle.webp; Logo.json / spine.atlas. i18n HorrorCircus_* only if the order changes rules, not for a visual reskin.

8. Pack

Workdir dst/ = copy of src/. Overwrite only skin binaries and ogg (and atlas). Sounds.json / Reels.json / Spine bones = empty diff. New bundle id. src/ preserved.

9. Deploy and QA

Serve dst/ as the Horror Circus template is already served (Forge temporary, same host pattern). Play visual checklist and ear checklist. Typical failure: you hear 3 Magix cuts → packed to the wrong engine.

10. Download

After QA: Grabbr-style zip (tree + unpacked). Magix gem not for this piloto (different engine). If later there is a second Magix piloto, then yes a 3-sprite sounds.json.

What not to do

  • Rename AA or Juggling.webp “to match” without updating Manifest + Symbols + Small + sounds.
  • Regenerate joker.json from an mp4.
  • A single win.mp3 for all multiples.
  • Magix 3-cut sprite on this tree.
  • Apply without mockup pick.
  • Zip before playing it.
  • Kill Grabbr Chrome :9336.
  • Overwrite serve.mjs / Caddy Host / job originals.
Absorbed

07-howto-piloto.md, 03-que-falta.md, CONTRACT.md

Provenance — Horror Circus 1.0.23 art

Date 2026-10-28. Sources: job src, translaxion template, axion-live dump, SerpAPI Google Lens, grep/XMP/C2PA. No secrets. Question: is the art unique design for this slot or a stock pack (Envato/Craftpix/Freepik/etc.)?

Code / metadata (measured)

SignalResult
copyright / artist / license / Envato / Freepik / Craftpix / OpenGameArt / Shutterstock in json, atlas, js, html, md, txt0 (except TexturePacker URL)
TexturePackerSmallSymbols.json + coins.json → app: codeandweb.com/texturepacker = tool, not stock credit
Spineskeleton.spine = 4.1.24, joker hash 1iibqR/ZjhM, 55 bones, anims idle/start/Static/Static_Blur/win
Leftover namesfiles Joker/Seal/Juggling/shoes vs atlas folders JOKER/MONKEY/SAW/BIKE/BRAIN/TICKET/DIAMOND + SFX dir Joker_Sounds/
Internal copy-pasteatlas BALLOON/BOOM/SAW-idle/boom_*
WebP EXIF authorno dc:creator / Photoshop credit
WebP C2PA21/21 dump stills carry com.anthropic.claude.provided + origin-confidence: unknown + claim_generator_info: Anthropic Files 1.0.0. Same SHA256 in job/template/axion-live. That is a stamp of a file served by Claude Files, not stock credit and not proof Claude painted the joker.
OGGsome: ENCODER=FL Studio ARTIST/TITLE empty. Others: Lavf60.16.100 + XMP CreatorTool=Adobe Audition 26.3 (Windows) dates 2026-08-24 / 2026-09-02 tz +03:00

Reverse image (SerpAPI google_lens, 2026-10-28)

JPEG probes from stills: docs/spaine/probe-joker.jpg, probe-saw.jpg, probe-bg.jpg. Raw JSON /tmp/hc-cmp/reverse-lens.json.

Probeexact_matchesvisual_matchesSame-pixel stock/slot?
Joker (zombie jester, purple/red/green hat, bells)015 generic (jester posters, Shutterstock tattoo, Etsy sticker)no
Saw (chainsaw)015 generic (chainsaw apps, Pngtree 3D, Thangs)no
BG (tent)015 generic (Vecteezy curtains, Slotmill Carnival Joker different theme, Inkration Sinister Circus other studio)no

No Craftpix / Envato / Freepik / GameArt / Join Games / Unity Asset Store hit with the same pixels.

Commercial homonyms (name ≠ this pack)

  • GameArt Circus of Horror (2019): vampire / nurse / mummy / electric chair.
  • Join Games Horror Circus (2017): devil / leather girl / bloated clown / 10 lines.
  • Relax Zombie Circus: strongman / knife thrower / acrobat / ringmaster.
  • Hacksaw Klowns: Lester/Jester, balloon cluster.

This Axion: zombie jester, slime monkey, saw, brain, balloon, bike, ticket, diamond. Different cast.

Verdict (fail-closed)

  • Not a public stock sheet with credit in the tree.
  • Yes a reskin of an Axion Joker’s Diamond template (leftover names + SFX dir). The puppet/rig was not invented for horror; the paint is of the horror theme.
  • Best supported hypothesis: studio (or private house) 2D Spine art for this bundle, not an Envato PNG pasted on. Lens 0 exact + 55-bone rig + Audition/FL Studio on SFX.
  • HOLD: cannot swear it never existed on a private marketplace / asset Discord. Lens does not index everything.
  • C2PA Anthropic: do not use as “Claude drew it.” Use as “these WebPs passed through Anthropic Files at some point in the copy pipeline.”
Absorbed

09-provenance-horrorcircus.md

Honest HOLD table

True HOLD is labelled HOLD. Fake GO is a lie. Prefer HOLD.

ItemStateWhy / what not to do
Spline OAuth hostedHOLDgrok mcp doctor spline → AuthRequired 401. Sign in. Never substitute Three.js.
Spline.app desktop MCP live on MacHOLD on Arenastdio is Darwin-only. Outbox packs are ready; the app is not on this Linux.
Full paytable stills on hplay-hc.pngHOLDScreenshot is the real board, not a complete symbol sheet. Do not invent missing cells.
Reuse Chile :9336 for extra HPlay captureFORBIDDENHeaded Grabbr Stake Chrome PID 1901346. Never kill. Never hijack the port.
Playable temporary Forge deploy this cutHOLDApply/recompile zip exists; playing dst/ with Axion RGS in browser is the next cut.
N variants + pick in Grabbr UIHOLDMockup of current board exists; N-board picker does not.
SAM / FAL per-slot sliceHOLDSAM_SERVER_URL empty. Brush/lasso work. Imagine paint GO.
Automatic Pixi captureHOLDGrabbr is built for Pragmatic/Unity. Horror Circus tree was hydrated by hand.
Genie commercial shipHOLDPolyForm NC. Lab yes; paid product needs Genielabs license.
build_spine_json.py from scratch for jokerHOLDEmits 4.2.0, humanoid hierarchy ≠ 55 bones.
Magix gem for Horror Circus pilotoNOWrong engine. 3-cut radio is not this show.
Provenance “never on a private marketplace”HOLDLens 0 exact is not omniscience.
C2PA as “Claude painted the joker”NOAnthropic Files stamp of a copy, not authorship of paint.
Imagine paintGOgen-stills AA-Joker.png measured.
ElevenLabs per cueGOgen-sfx UI_Button ogg measured.
Pipeline 13 smokeGOcatalog 8 → select AA → outbox → approve → recompile 6.1 MB.
Forge handleSpaineGOGET /spaine/health ok.
Grabbr tab + proxyGO/v1/spaine/* including outbox AA.zip 200.
Absorbed

INDEX.md, 03-que-falta.md, 11-reskin-app.md, 12-spline-mcp.md, CONTRACT.md, jokers README

What is already there vs what is missing

To reach clone level (full theme + puppets + audio director) the missing piece is not “one more mp3.” It is a factory that respects the score and lets you play the result.

Already there (do not invent)

PieceWhereReal scope
Grabbr capture + Unity unpack/opt/hallallow/apps/game-images-apiTextures, AudioClip, UHTSpine 3.7, NGUI. Public gallery.
Forge deploy / gems / RGS/opt/forgePlayable games. Magix gems, Arena, RGS.
Imagine stillsimagina.jailbroken.techSymbol, background, frame, logo.
ElevenLabssecrets/elevenlabs.envGenerates waves. Does not generate the orchestra.
Score of this slotSounds.json + Manifest.json18 cues, ladder, BN stop, 5 arias, counter 0.3.
Horror Circus templatetranslaxion horrorcircus-templateEngine already directs audio.
Cookie hall_salaecosystemUnified auth.

v1 shortcut that does feel premium

Do not generate a 55-bone clown or a new mixer. Take a slot that already has a director (this Horror Circus or another Axion/Pixi with Sounds.json) and: leave rules intact (events, priorities, durations, ladder); change drawings, atlas, oggs, texts; repack with a new id; deploy on Forge and play it; only then the zip. That is what the clone did (5×3 joker-diamond chassis → horror circus) and it is the only first cut that will sound like a provider. If the piloto ships on Magix (3-cut sounds.ogg) or Arena Zeus (9 one-shots), the game sounds flat even if ElevenLabs is pretty.

Holes

1. Product SpAIne — on disk including pipeline 13. Still open: N variants in UI, SAM slice per slot, temp deploy played in browser this cut, Spline.app desktop MCP live on the Mac.

2. Capture of the right engine. Grabbr is thought for Pragmatic/Unity. Horror Circus is Pixi + JSON + Spine 4.1 + loose oggs. Today that pack was downloaded by hand. Missing a capture that leaves a playable tree. If the zip does not boot on Forge, premium audio cannot be verified.

3. Audio — files yes, director in the factory not yet as a generator of loops/empalmes. Cue list documented. Need per-cue generator with fixed duration, splice without seam, respect ladder, character arias fitted to 4 s, do not break BN stop, mix counter 0.3, pack many ogg + Manifest not one Magix sprite. QA: a spin where you hear trigger → motor → clacks → (if BN) sting → aria + multiple theme + low counter → close. If it does not pass in the browser, it is not done.

4. Image — close, incomplete. Imagine covers stills. Missing the face set per symbol: still, spin blur, miniature, Spine atlas skins. A pretty PNG that does not enter the atlas = the puppet splits or shows the old drawing. Background + drum + logo + HUD go in the same Apply. Symbols only = a patch (original vs this clone proves it).

5. Motion — technical ceiling. Reuse bones, change skin: yes (clone path). Blur from still: yes. Spine of few bones (balloon, ticket): v1.5. Invent idle/win of 40–55 bones: no. Imagine makes video, not joker.json 4.1. Without puppets the ceiling is Joker’s Diamond: premium figurines that sit still.

6. Close the playable circle. Order closed: Apply → repack → Forge temp deploy → see and play → zip. Missing: new bundle id with originals untouched (apply already does this); temp host extending Forge (not stomping serve.mjs / Caddy); RGS of that engine actually spinning (not an mp4); two downloads. Until it spins with audio on top, it is theatre.

Not in the first cut

New audio engine, Spine from scratch, Adobe mode, cloning Magix to 3 cuts and pretending it is this.

Recommended piloto

Base: Horror Circus Axion 1.0.23 (director already exists, analysis done). Work: full-theme reskin + cue replacement, rules intact. Success: ear checklist + playable board on Forge + dual zip + original intact. Product flow in the Product chapter. Spline bridge in Pipeline.

Absorbed

03-que-falta.md, INDEX measured state

Grabbr’s role (not the whole HTTP API)

SpAIne is not implemented in Grabbr. It lives in Forge. Grabbr is the client. Living docs update with the product under /opt/forge/docs/spaine/. This HTML is the English book of those chapters.

Grabbr’s own API.en.md documents the capture/gallery HTTP API (Unity/PP jobs, image CDN, etc.). That surface is how captures enter the factory when ingest --capture= is used. It is not the SpAIne contract. Do not dump that API here. SpAIne-facing Grabbr paths are only the /v1/spaine/* proxy listed in the HTTP chapter, plus the SpAIne tab UI (chips QUÉ, CÓMO, Send to Spline).

Public host: grabbr.jailbroken.tech. Local :8790. Magix gem: no. Headed Chrome :9336: do not kill.

Absorbed

/opt/hallallow/apps/game-images-api/docs/spaine/README.md

Source map — every chapter’s parents

Spanish living docs were translated and unified, not summarised into empty headings. Plugin, runtime, and job READMEs (read-only) were folded in. Jobs under /opt/forge/spaine/jobs/** were not edited.

ChapterAbsorbed files
Cover / ProductINDEX.md, 00-producto.md, 04-puntos-producto.md
GlossaryINDEX, 00, 08, 12, PLUGIN, Grabbr README
Pipeline13-pipeline.md, cli.mjs, routes.mjs, pipeline.json (read)
CLIcli.mjs, defaults.json, 07-howto-piloto.md, SKILL.md
HTTProutes.mjs, 13-pipeline.md, Grabbr README
PortsINDEX, 11, 12, jokers README
Jokers Diamond01-original-vs-clon.md, jobs/jokers-diamond-hplay/README.md + pipeline.json
Horror Circus01, 05, job tree listing, catalog.json
Visual05-puntos-visual.md
Audio02-audio-dinamico.md, 06-puntos-audio.md
Spline12-spline-mcp.md, 13-pipeline.md
Genie11-reskin-app.md
Spine AI10-spine-animation-ai.md
Pack08-pack.md, PLUGIN, NORTHSTAR, CONTRACT, SKILL, commands, runtime README
How-to07-howto-piloto.md
Provenance09-provenance-horrorcircus.md
HOLDs / Gaps03-que-falta.md, INDEX, CONTRACT, 11, 12
Grabbrapps/game-images-api/docs/spaine/README.md (pointer only)

Runtime libs cited, not invented: apply.mjs, atlas-repack.mjs, catalog.mjs, compose-mockup.mjs, gen-sfx.mjs, gen-stills.mjs, hydrate.mjs, ingest-joker-genie.py, inventory.mjs, paths.mjs, pipeline.mjs, review.mjs, select.mjs, spline-bridge.mjs, validate-tree.mjs, zip-pack.mjs, hold-stage.mjs.

SpAIne English book · last updated 2026-10-28 · path /opt/forge/docs/spaine/SPAINE.html · print via CSS · no CDN · originals in src/ stay bit-identical · Chile :9336 never killed · Magix gem is not the Horror Circus piloto.