Merges main (the parallel parts-catalog + keyword/parametric assembler edit
path, single-context scissor tree rendering, runtime selector rework) into the
FreeLand-from-scratch / Random / draft-creature / canvas-and-nav-polish branch.
fusion_ui.py and voxel_embed.py auto-merged cleanly (the two efforts edited
disjoint regions); wiki/log.md was the only content conflict (append-only on
both sides, kept both). Two semantic artifacts the line-merge could not catch,
both fixed and verified locally:
- Canvas pan dead-zone: this branch's installCanvasPan suppressed panning when a
drag began on a node (it assumed per-node OrbitControls to rotate). main's
scissor renderer draws the tree through ONE pointer-events:none context with
auto-rotate, so node-drag rotated nothing AND no longer panned. Now a drag
anywhere pans (matches main's installTreeInteractions intent); the __buddyPanned
threshold still keeps a clean tap selecting.
- Splice Bench FAB resurrected on reveal -> Lab Back: …
feat(edit): replace small-model selector with keyword + parametric assembler
Edit path is now pure Python: an English keyword parser maps the instruction to
a catalog part plus count/scale/anchor/rotation/color, and the assembler snaps it
on deterministically (symmetric pairs first, overflow to rear; float scale rounded
to the grid; exact 90deg integer-grid rotation). Instant, no GPU. Gemma 12B stays
only for full generation, hatch fusion, and the freeform-edit safety valve.
Removes select_part, the MiniCPM selector constants/preflight/warmup bench, and
SELECT_SCHEMA/build_select_messages.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build a buddy from scratch and splice it, reworking the Lab/bench flow.
- FreeLand: landing "Build from scratch" button opens the bench with both
slots empty; each empty slot generates a freeform creature from a typed
description (runtime.generate_creature, exemplar fallback). The bench is now
the single A/B workspace: a slot is either a tree-picked creature or one
built from scratch.
- Advance relaxed from two picks to >=1: the unselected side becomes a
from-scratch panel; splice is gated until both slots are filled.
- 🎲 Random per slot: fills with a random Compendium template, kept distinct
from the other slot (no duplicate sides).
- Draft creatures: bench candidates (Random / from-scratch) are drafts hidden
from the family tree until a splice commits their two parents, so re-rolling
no longer litters the tree with orphan "ancestors" (Creature.draft, serialized).
- Bench Back returns to its origin (landing for FreeLand, Lab otherwise) via a
bench_origin State, ins…
Today edit/suggest sit behind `except: pass`, so a 0.3.19 chat-template load
failure is silently swallowed into the fallback with no log. Add an env-gated
selector preflight that prints `[selector-preflight] ok/FAILED: <err>`, and make
the production path log the exception + auto-fall to Qwen2.5-3B with a printed
line. One restart + page open tells you if MiniCPM5-1B loads and why not.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dual-path edit: keep Gemma-12B freeform for from-scratch generation and hatch
fusion (the low-frequency big moments); route in-bench edits (suggestion chips +
A/B text) to a fast template part-assembly path. A small selector (MiniCPM5-1B,
grammar-enforced, thinking off; Qwen2.5-3B fallback) outputs {part, anchor,
scale}; a deterministic assembler snaps hand-authored part geometry onto the
creature's bounding box. Additive parts only for MVP; transforms fall back to the
freeform Gemma edit. Lists the 0.3.19-load / GGUF / thinking-off / latency
verification gates.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Translate cosmetic Chinese (comments, report title, spec mockup) to English.
Keep the load-bearing CJK synonym tables in fallback.py that let the offline
interpreter recognise Chinese command input.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Consolidate the throwaway scratch/voxel-spike/ exploration (11 scripts,
scattered HTML viewers) into a tracked, reusable tool so the next model
test does not start from zero.
tools/voxel-model-eval/:
- core.py: pure base (SYS prompt, 8 themes, BOX_SCHEMA, extract_json,
voxelize, metrics); no model loading, llama_cpp never imported here.
- models.py: the editable (label, repo) list.
- exemplars.py: few-shot reference layouts for --fewshot.
- eval.py: single CLI; one model at a time (download -> grammar-enforced
test -> optional --delete-after -> merge); llama_cpp imported lazily so
the pytest suite runs without the sibling venv.
- report.html: Three.js viewer with a theme filter; live WebGL contexts
are reconciled by distance-to-viewport-center on scroll (fixes the
evict-furthest blanking bug where still-visible cards never re-mounted).
- report_data.js: committed 19-model x 8-theme sweep so the report opens
populated.
Align voxelize() to JS Math.round (round half up) so P…
Add an opt-in freeform path where the model draws raw box-layout geometry
({name, boxes:[{x,y,z,w,h,d,color}]}) instead of the recipe, so creatures can
take cross-form shapes (five arms, a house on the head) the closed recipe
vocabulary cannot express. Gemma 4 12B (the model-selection spike winner),
grammar-enforced, seeded with a hand-authored reference exemplar.
Freeform creatures are first-class: they enter the family tree and breed. A
splice routes to a Gemma "merge two creatures" call when either parent carries
boxes (freeform x freeform and freeform x recipe both yield a box child);
otherwise the recipe fuse runs. Fallbacks (fake runtime / model failure) use a
reference exemplar or a deterministic box merge, so the app never renders empty.
- genome: optional Genome.boxes + freeform_genome(); round-trips, recipe
creatures stay box-free
- prompts: BOX_SCHEMA, build_freeform_messages, build_freeform_fuse_messages
- runtime: generate_creature / fuse_creatures on Gemma via per-cal…
Rework the flat single-scroll UI into a screen-based game flow:
- Landing: an infinite drifting grid of pre-rendered transparent buddy
PNGs over a continuous gradient; each cell re-randomises as it wraps off
screen (no repeating tile), with a centered scrim keeping the copy legible.
- The Lab: the family pedigree graph is the hub. Tap nodes to stage two
creatures (A/B slots), SVG parent->child connectors, a single Splice CTA,
and a per-node detail modal with a live 3D view + genome card + AI tweak.
- Reveal: parents + newborn shown together, then back to the family.
Selection drives the existing fuse path (children fuse with children).
Splits the reveal transition from its population to avoid Gradio's
visible-toggle + write-value mount race (stuck "pending").
Adds 50 distinct transparent buddy PNGs (assets/buddies) baked by a one-off
headless export; exposes voxelsFromGenome/voxelBuildMesh on window for it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com…
feat: rebrand to Hatchimera with daytime light UI
UI / theming:
- Lock the app to Gradio's light theme (was dark); daytime palette across
the chrome — panels, genome card, family tree, command bar.
- Voxel stages now render the creature against a gradient sky background
only; removed the dark backdrop, grass/podium, clouds, bushes, and
contact shadow per design iteration. Single-creature framing per stage.
Rename:
- Buddy Splice Lab -> Hatchimera across the header H1, browser tab title,
social share text, and the README / HF Space title.
- Add a one-line subtitle: "A small local AI splices two voxel critters
into a one-of-a-kind chimera."
Input:
- Left-parent tweak runs through a typed natural-language command box
(Enter or Apply), interpreted by the model.
Docs / wiki:
- Update gradio-theme-locking (dark -> light lock; mechanism unchanged)
and append to the wiki log.
- Add brainstorming specs for the stage backdrop and the text command.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>