sandoniette/scripts/gen-assets.sh
type-two 26921eb4ad Build-out 2: the playable loop — detection stacking, live serve, string picker, 8 days
- Sando is zone-DETECTION now: the stack = food bodies physically resting in
  the plate zone, bottom->top. Hand-stacked and harness-stacked sandos are
  judged identically (sando.kinds() is what the judge reads).
- The full live loop: Game.state + updateLive() — ticket clock with late-anger
  (1 bump/3s overdue), bow-dwell serve (hold still 0.5s over a matching
  standing sando -> scorecard), click -> next day; string cut -> ragdoll ->
  fail card -> click retries the same day with fresh strings. setupDay stages
  bread + fillings per order; sins fire live off cutter.onCut + offstage sweep.
- String unlockables: HEMP/RUBBER/CHAIN/SILK picker on the title (stiffness/
  damping multipliers, registry-persisted). Rubber visibly stretches.
- Days 6-8: Tamago (it rolls), Tofu (fragile), THE TOWER (5 layers) + tofu food.
- samurai_bow (same seed): an S serve swaps in the single approving nod.
- Battery: M1 87f/8.41u/10-10, M2 cv0 clean, M3 both, days SSSSSSSS, live
  serve commits at 31f (~0.5s), death->retry + serve->advance verified.
- Known: embedded preview pane never fires rAF (visibilityState hidden) — live
  loop freezes there by browser design; harness steps manually. Real tabs fine.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 17:06:22 +10:00

94 lines
5.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# SANDONIETTE asset generation — 2D ONLY, 100% local/free, via MODELBEAST.
# ./scripts/gen-assets.sh # generate all missing 2D assets
# Seeds fixed so every asset is re-generatable. Style token shared for coherence.
# The game NEVER blocks on these — procedural fallbacks cover every prop.
set -uo pipefail
MB_DIR="$HOME/MODELBEAST"
[ -d "$MB_DIR" ] || MB_DIR="$HOME/Documents/MODELBEAST"
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
OUT_IMG="$REPO/public/assets/img"
mkdir -p "$OUT_IMG"
cd "$MB_DIR" || exit 1
# shellcheck disable=SC1091
if [ -f data/agent.env ]; then source data/agent.env
else set -a; source "$HOME/Documents/backnforth/.env"; set +a; fi
export MB_HOST="${MB_HOST:-http://100.89.131.57:8777}"
STYLE="japanese shadow puppet theatre, flat black silhouette with cut-out details, warm washi paper backdrop, edo period, high contrast, hand-crafted paper texture"
# ponytail: m4pro venvs dead (2026-07-17) — jobs there fail in ~1s, so retry up
# to 10x with 60s pauses until a healthy node takes it. Drop once m4pro is fixed.
MB_TRIES=10 MB_PAUSE=60
run_flux() {
local seed="$1" prompt="$2" w="${3:-1024}" h="${4:-1024}" i out
for i in $(seq 1 "$MB_TRIES"); do
out=$(./mb run flux_local -p prompt="$prompt" -p model=flux2-klein-4b -p steps=4 \
-p seed="$seed" -p width="$w" -p height="$h" --wait 2>/dev/null \
| awk '/image/{print $1}' | tail -1)
[ -n "$out" ] && { echo "$out"; return; }
sleep "$MB_PAUSE"
done
}
run_cutout() {
local asset="$1" i out
for i in $(seq 1 "$MB_TRIES"); do
out=$(./mb run bg_remove_local --asset "$asset" -p resolution=2048 --wait 2>/dev/null \
| awk '/image/{print $1}' | tail -1)
[ -n "$out" ] && { echo "$out"; return; }
sleep "$MB_PAUSE"
done
}
# gen_2d <name> <seed> <prompt> [w] [h] [cut]
gen_2d() {
local name="$1" seed="$2" prompt="$3" w="${4:-1024}" h="${5:-1024}" cutout="${6:-no}"
if [ -f "$OUT_IMG/$name.png" ]; then echo " = $name.png exists, skipping"; return; fi
echo "→ [$name] flux..."
local img; img=$(run_flux "$seed" "$prompt, $STYLE" "$w" "$h")
[ -z "$img" ] && { echo " ! $name: flux failed"; return 1; }
if [ "$cutout" = "cut" ]; then
echo "→ [$name] cutout..."
local c; c=$(run_cutout "$img"); [ -n "$c" ] && img="$c"
fi
local tmp; tmp=$(mktemp -d)
./mb get "$img" -o "$tmp" >/dev/null 2>&1
local f; f=$(find "$tmp" -iname '*.png' -o -iname '*.jpg' | head -1)
[ -n "$f" ] && { mv "$f" "$OUT_IMG/$name.png"; echo "$name.png"; }
rm -rf "$tmp"
}
# ---- the samurai: SAME seed, only the expression phrase varies (judge-portrait trick) ----
SAMURAI="a seated japanese samurai looming over a kitchen, ornate armor and helmet, one hand near a katana at his hip, shown as a dramatic flat black paper-cut silhouette against a warm glowing washi paper screen"
gen_2d bg_washi 301 "empty kitchen stage, shoji paper screen backdrop lit warm from behind, wooden theatre framing, no characters, no text" 1280 768
gen_2d floor_boards 303 "seamless dark wooden stage floor boards texture, worn edo-period timber, flat even light, no objects, no text" 1024 512
gen_2d samurai_calm 320 "$SAMURAI, calm neutral expression, katana fully sheathed" 768 900 cut
gen_2d samurai_watch 320 "$SAMURAI, one eyebrow raised, watchful, hand resting on hilt" 768 900 cut
gen_2d samurai_annoyed 320 "$SAMURAI, annoyed frown, thumb pushing the katana guard, ten centimeters of blade showing" 768 900 cut
gen_2d samurai_angry 320 "$SAMURAI, angry glare, half the blade drawn and gleaming" 768 900 cut
gen_2d samurai_fury 320 "$SAMURAI, furious wide-eyed glare, katana fully drawn overhead ready to slash" 768 900 cut
gen_2d title_art 330 "the word SANDONIETTE in giant dramatic japanese calligraphy brush strokes, black sumi ink" 1024 768 cut
gen_2d ticket_paper 340 "a single blank narrow paper order ticket, faint fold marks, plain, no text" 512 640
gen_2d slash_frame 350 "one single diagonal white katana slash streak on transparent background, motion blur, sharp" 1024 1024 cut
# food faces — comical, slightly alarmed
gen_2d face_bread 360 "a comical slightly alarmed cartoon face for a slice of bread, simple cut-out paper eyes and mouth, worried" 512 512 cut
gen_2d face_tomato 362 "a comical nervous cartoon face for a round tomato, simple cut-out paper features, sweating" 512 512 cut
gen_2d face_cheese 364 "a comical dopey cartoon face for a wedge of cheese, simple cut-out paper features" 512 512 cut
gen_2d face_katsu 366 "a comical brave cartoon face for a breaded pork katsu cutlet, simple cut-out paper features" 512 512 cut
gen_2d face_egg 368 "a comical wide-eyed cartoon face for a boiled egg, simple cut-out paper features, startled" 512 512 cut
# splat decals
gen_2d splat_wet 370 "a single messy wet food splat splatter shape, flat black silhouette, on transparent background" 512 512 cut
echo "done."
# ---- build-out batch 2 (seeds 400+): serve counter, S-grade bow, cutout faces v2 ----
gen_2d samurai_bow 320 "$SAMURAI, head bowed slightly in approval, eyes closed, serene" 768 900 cut
gen_2d counter_wood 402 "a low wooden serving counter table, edo period, side view, flat black silhouette on transparent background, hand-crafted paper cut-out style" 768 384 cut
gen_2d face_cut_bread 410 "simple face cut out of black paper: two round holes for eyes and a small worried oval mouth hole, white background, minimal, high contrast, paper-cut stencil" 512 512 cut
gen_2d day_stamp 420 "a round red japanese hanko seal stamp, blank center, worn ink edges, on transparent background" 512 512 cut