Skip to content

Update V2 plan: event-driven targeting, local embeddings, unified tag system - #7

Open
nat-bishop wants to merge 22 commits into
mainfrom
claude/implement-v3-design-lSArM
Open

Update V2 plan: event-driven targeting, local embeddings, unified tag system#7
nat-bishop wants to merge 22 commits into
mainfrom
claude/implement-v3-design-lSArM

Conversation

@nat-bishop

Copy link
Copy Markdown
Owner

Major design updates to object-system-v2.md:

  • Replace polling-based target scanning with event-driven matching
    (runs only on object spawn or tag change, not per-frame)
  • Switch from cloud embeddings (Google text-embedding-004) to local
    model (all-MiniLM-L6-v2 via ONNX, <1ms, no PyTorch)
  • Unify tag handling: all tags get TAG_PHRASES, no static/dynamic
    distinction. Any tag can change at any time (Medusa petrification)
  • Identity = name + visual_description + tag phrases for all current tags
  • Behavior priority = list order (LLM decides character through ordering)
  • Minimal implied behaviors (only default wander for living + no behaviors)
  • HOSTILE stays LLM-visible for non-seeking hostile objects
  • Remove old design-object-system-v2.md (superseded)

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

nat-bishop and others added 22 commits April 4, 2026 13:13
… system

Major design updates to object-system-v2.md:
- Replace polling-based target scanning with event-driven matching
  (runs only on object spawn or tag change, not per-frame)
- Switch from cloud embeddings (Google text-embedding-004) to local
  model (all-MiniLM-L6-v2 via ONNX, <1ms, no PyTorch)
- Unify tag handling: all tags get TAG_PHRASES, no static/dynamic
  distinction. Any tag can change at any time (Medusa petrification)
- Identity = name + visual_description + tag phrases for all current tags
- Behavior priority = list order (LLM decides character through ordering)
- Minimal implied behaviors (only default wander for living + no behaviors)
- HOSTILE stays LLM-visible for non-seeking hostile objects
- Remove old design-object-system-v2.md (superseded)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tion stages

Replace all-MiniLM-L6-v2 (384-dim ONNX) with qwen3-embedding:0.6b (1024-dim
via Ollama) for better semantic similarity. Flatten Stage 1/Stage 2 into
Backend/Godot sections, remove backward-compat shims (V1 behavior conversion),
add SIZE_PHRASES to embed strings, refine TAG_PHRASES formatting and examples.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…viors

Replace the V1 trigger/action/target behavior system with a substance/element-based
model. LLM now picks substance (16), optional element (7), 0-3 tags, and 0-4 verb
behaviors. Traits derived from substance+element automatically. Semantic targeting via
Ollama qwen3-embedding. Includes cleanup: persistent httpx client, re-embed debounce,
model_dump for substance_profile, enum-derived verb values, dead code removal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…te passthrough

- Rename LLM_VISIBLE_TAGS_V2 → LLM_VISIBLE_TAGS and all derived constants
- Strip "V2:" prefix from comments across Python and GDScript (20+ files)
- Fix _reapply_physics() no-op: runtime tag changes (HEAVY, LIGHT, FLYING,
  BOUNCY, STICKY) now actually update physics via apply_tag_modifiers()
- Eliminate PhysicsComposer.compose_physics_v2() one-line passthrough;
  call SubstancePhysics.resolve_physics() directly
- Clean up SubstanceProfile sentinel defaults (-1.0 → 0.0) and remove
  dead sentinel checks on client side

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a suite of embedding/targeting eval scripts capturing the investigation
findings (embeddings can't reliably distinguish state/tag shifts). Updates
embedding_eval.py thresholds and fixes a known-limitation test case expectation.
Adds `make ollama` target to pull qwen3-embedding and verify Ollama is running.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reflects new compiled_behaviors format, tag-filter targeting, stable identity
embeddings, and asymmetric query embedding approach.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…embeddings

Replace dynamic re-embedding with compiled behaviors that combine tag-filter
mode (require_any_tags → pure boolean check) and identity mode (embedding
dot-product). Identity embeddings are now stable (substance-based, no tags),
and behavior targets use instructed-retrieval prefix for asymmetric matching.

- Add target_tags field to BehaviorVerbSpec with ModelRetry validation
- Compile behaviors at creation into self-contained dicts (verb, target,
  target_embedding, require_any_tags, exclude_tags)
- Replace behavior_embeddings with compiled_behaviors on GameObjectBlueprint
- Remove /api/embed endpoint and client-side re-embedding on tag change
- Rename object_embedding_changed signal to object_tags_changed
- Update VerbBehaviorSystem for dual-mode targeting (tag filter vs embedding)
- Rewrite embedding evals for stable identity + instructed retrieval
- Add targeting integration test (evals/targeting_test.py)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…t_tag

Three-layer architecture: material rules (56 passive physics rules),
behaviors + categories (creature intent via boolean matching), and
planned spawn-time LLM enrichment (Phase 4, not yet built).

- Add Category enum (CREATURE, FOOD, WEAPON, PLANT, VALUABLE, VEHICLE, TOOL)
- BehaviorVerbSpec: target_tags → single target_tag from BEHAVIOR_TARGETS
- CREATURE auto-derives LIVING, destroy verb auto-derives HOSTILE
- LLM_VISIBLE_TAGS: 12 → 10 (LIVING/HOSTILE now derived-only)
- Remove embeddings.py, Ollama dependency, identity_embedding
- Remove 3 HOSTILE combat rules (VBS handles creature combat)
- VBS: collapse dual-mode to single _matches_target() boolean
- Player joins game_objects group with CREATURE category
- Remove HOSTILE from field_config FIELD_TAGS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a CanvasLayer-based post-processing system for visual style iteration.
Five fullscreen shaders (palette limiter, ordered dithering, sobel outline,
crosshatch, pencil) can be toggled (F8) and cycled (F9) at runtime.
Debug mode (F3) shows the active shader name. Materials are pre-cached
to avoid allocation churn on toggle/cycle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove obsolete embedding-based evals and targeting tests (replaced by
category system). Add gate dataset, category accuracy metric, and
benchmarking scripts. Update eval runner with --gate and --compare flags.
Clear stale pre-V2 baseline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Split design into focused docs: architecture (two interaction systems,
pairwise cache, state interaction table), engine primitives (physics,
7 states with mechanics, affordances, verbs, destruction results),
creation pipeline (call batching, budgets), and future features
(compound sprites, object evolution). Includes archived V1 doc and
inference benchmarks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…flow

- Rewrite LLM judge rubrics from 5-point generic to 3-point anchored scales
  with game-specific examples (Faithfulness, Delight, Visual Clarity)
- Move 90 eval cases from Python to YAML (dataset.yaml) with schema
- Add baseline management: --gate, --compare, --promote, --list CLI flags
- Add gate dataset (14 cases, deterministic only, no LLM judges)
- Fix judge truncation bug: remove max_tokens=300 that caused ~30-89% failures
- Increase max_concurrency from 8 to 64 (SGLang batching, no rate limits)
- Fix valid_behaviors checking wrong field name (target -> target_description)
- Delete 7 dead files (research scripts, redundant runners)
- Rename living_movement.py -> has_signature.py to match metric name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mplifications

Major design changes from review:
- Replace fixed behavior verbs with per-pair creature evaluation (staged:
  movement → action → parameters). Firefighter extinguishes fire, rescues
  people, chases arsonists — all from one creature.
- Drop state interaction table (pairwise cache handles state changes with
  lazy invalidation)
- Drop destruction results from core (death animation → remove, kept in
  future-features.md)
- Cut states from 12 to 7 (removed unspecified: blessed, cursed, weakened,
  strengthened, petrified)
- Add mechanics for each remaining state (DOT, armor reduction, etc.)
- Rename local-llm-rules.md → llm-design-patterns.md with decomposition
  patterns (fan-out, sequential seeding, fan-out/filter/fan-in)
- Add cache design, migration plan, future optimizations docs
- Add benchmark scripts (outputs gitignored)
- Delete archive directory

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add screened pairwise evaluation — single LLM call triages which
object pairs are worth fully evaluating, cutting ~70% of N² calls.

Add scene context to creature behavior prompts so creatures make
contextually-aware decisions (firefighter cares about water when
fire exists). Mark creature behavior cache as scene-local since
results depend on scene composition.

Add utility scoring priority resolution for competing creature
behaviors — discrete target selection with perception-range-normalized
distance falloff, same pattern as The Sims.

Add batch screening as pattern 5 in LLM design patterns doc.
Add triadic reasoning note to future features.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two plan variants covering the 10-phase dependency graph from V2
extraction through LLM question runner, pairwise interaction cache,
creature behavior, Godot client rewrite, and eval system rebuild.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace V2's hand-authored substances (16), tags (31), elements (7),
categories (7), behavior verbs (6), and 56 rules with:

Backend:
- Parallel 1-token LLM questions for physics (mass, friction, bounce, etc.)
- Pairwise interaction cache (LLM-evaluated at spawn, looked up at runtime)
- 7-state system (on_fire, frozen, wet, electrified, poisoned, corroded, molten)
- Creature behavior via 3-stage LLM evaluation
- CacheManager with SQLite backend for creation/pairwise/behavior caches
- New creation pipeline, pairwise evaluator, and creature behavior engine

Godot Client:
- StateManager replaces TagManager with contradiction-aware state mutations
- CollisionResolver uses pairwise cache lookup instead of rule matching
- EffectExecutor rewritten as static class for pairwise result execution
- Physics-derived visual animations (bobbing, breathing, squash/stretch)
- State-driven visual effects (particles, shaders, color shifts, lights)
- AffordanceSystem for carry/mount/climb interactions
- FieldSystem for area-of-effect interactions
- V3 blueprint format for all level seed objects and environment bodies

Cleanup:
- Delete V2 backend modules (substances, tags, rules_data, trait_deriver, agent)
- Delete V2 Godot scripts (rule_engine, tag_manager, tag_field, substance_physics)
- Delete V2-dependent tests, update integration test harnesses for V3
- Remove RuleEngine autoload from project.godot

73 backend tests pass. LLM quality gate tests require API key (manual run).

https://claude.ai/code/session_01QCnxQKnocERiqPwPeSU7G2
- Fix runtime crash: sessions/manager.py referenced removed
  `starting_durability` field, now derives durability from `hp`
- Extract cache DDL into CacheManager.ensure_schema() to remove
  duplication between main.py and cli.py
- Batch get_all_for_names() into single SQL query instead of O(n²)
  individual SELECTs
- Reuse parse_int from questions.py in pairwise.py and
  creature_behavior.py instead of inline regex
- Fix BaseException handling in asyncio.gather results (was catching
  Exception, missing BaseException subclasses)
- Remove unused VisualDescriptor import from pipeline.py
- Add 0.5s debounce to state-change re-evaluation requests in
  game_object.gd to prevent LLM API spam during cascade chains

https://claude.ai/code/session_01QCnxQKnocERiqPwPeSU7G2
…s aren't dropped

Autonomous game objects (creatures) now get a VerbBehaviorSystem child
node during init_from_blueprint(). Previously the backend would evaluate
creature behaviors via LLM and send results over WebSocket, but the
handler in backend.gd looked for a VerbBehaviorSystem child that was
never created — silently discarding all results while still paying for
the LLM calls.

https://claude.ai/code/session_01QCnxQKnocERiqPwPeSU7G2
Phase 7D: move V2-specific documentation to docs/archive/.
LEVEL_DESIGN.md, scribblenauts-deep-dive.md, and
llm-behavior-systems.md are kept as still-relevant references.

https://claude.ai/code/session_01QCnxQKnocERiqPwPeSU7G2
- Delete broken V2 eval system (14 files importing deleted modules)
- Delete unused V3Resolver (backend/app/engine/resolver.py)
- Fix Godot runtime errors: replace deleted TagColors/TagDescriptions/BehaviorDisplay with StateColors + inline logic
- Remove stale pyproject.toml ruff excludes and Makefile eval targets
- Promote design docs from docs/v3-design/ to docs/ root, remove "V3" prefixes
- Move research docs to docs/reference/
- Delete docs/archive/ and remaining V2 docs (object-system-v2.md)
- Rewrite CLAUDE.md to reflect current architecture
- Update docs-sync and code-reviewer agent definitions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants