content(sim): rotating clip pools + progressive tracked labels & emotions
Content-pipeline Increment 2, part 1 (the experience). Implements design §11 (docs/superpowers/specs/2026-06-24-content-pipeline-design.md): - Rotating pool (§11.1): each ring scale references a POOL of vetted clips (docs/content-candidate-pool.md); the player picks a random member on landing. player.ring.Scale gains `pool` + pure `pick_clip_id(scale, r)` (injected randomness); the pick happens at the API boundary (random.random()), a delta=0 advance is the initial/re-roll pick. clips.py parses/exposes the pool; the client lands on move.target_clip_id. Back-compat: a scale with only clip_id is a pool of one. - Rename ring scale forest -> coast (new land<->sea scale, orbit..reef); ring order cosmos -> orbit -> coast -> reef -> abyss -> wrap. Cleanup: dropped the leftover local media (cosmos_traverse, orbit_westcoast, old forest/reef, the Increment-1 orbit/abyss single bases); new coast-edge transition placeholders. - Time-windowed tracked labels (§11.2): annotations gain appear/disappear (loop-normalized, wraps across the seam); a label shows only while on screen and its box tracks the subject. abyss + reef pools authored as test material. - Progressive LEFT detail tiers (§11.3): per-object `salience` (first shows at Left 5-salience) + tiered strings (general -> specific -> scientific -> +fact) escalating with the Left knob; replaces flat min_level gating. Strings may be a tier list or a static string (back-compat). No engine change (client reads overlay.level). - Progressive RIGHT emotion tiers (§11.4): affect vocabulary escalates basic -> compound with the Right knob (dream.strength); appearance still gated by min(left,right). No engine change. New simulator/build_pool_manifest.py holds the hand-authored content and emits the 19-clip pool manifest (the reproducible baseline). setup_scales_media.py marked superseded. 251 passed / 4 skipped (+ ring pool + API pool/window tests). By-eye visual review deferred to the operator (no Chrome on this box). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+13
-2
@@ -9,6 +9,7 @@ from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
import random
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
@@ -26,7 +27,12 @@ from player.alteration import (
|
||||
)
|
||||
from player.content import resolve_content
|
||||
from player.controls import CONTENT_POSITIONS
|
||||
from player.ring import DEFAULT_FAST_SPIN_THRESHOLD, advance_ring
|
||||
from player.ring import (
|
||||
DEFAULT_FAST_SPIN_THRESHOLD,
|
||||
advance_ring,
|
||||
pick_clip_id,
|
||||
scale_at,
|
||||
)
|
||||
from simulator.clips import load_manifest, load_ring, ring_move_to_dict, ring_to_dict
|
||||
|
||||
STATIC_DIR = Path(__file__).parent / "static"
|
||||
@@ -145,7 +151,12 @@ def create_app(manifest_path: Optional[Path] = None) -> FastAPI:
|
||||
req.delta,
|
||||
fast_spin_threshold=DEFAULT_FAST_SPIN_THRESHOLD,
|
||||
)
|
||||
return ring_move_to_dict(move, app.state.ring)
|
||||
# Rotating pool: pick a random member of the LANDED scale (content-pipeline
|
||||
# §11.1). A delta=0 advance is the initial / re-roll pick (a no-op move that
|
||||
# still yields a fresh random clip). The pure pick takes injected randomness.
|
||||
landed = scale_at(app.state.ring, move.to_index)
|
||||
chosen = pick_clip_id(landed, random.random())
|
||||
return ring_move_to_dict(move, app.state.ring, chosen)
|
||||
|
||||
@app.middleware("http")
|
||||
async def _no_cache(request, call_next):
|
||||
|
||||
Reference in New Issue
Block a user