You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A layered decision architecture for intelligent behavior in a real-time 3D world.
10
10
@@ -24,7 +24,7 @@ A legacy 3D MMORPG emulator provided the demanding sandbox that forced this arch
24
24
25
25
## Architecture
26
26
27
-
The system is organized as a four-stage control pipeline: perception, brain, routines, and motor, with environment parsers, navigation, and observability as support layers. It runs as a single 10 Hz loop with zero runtime dependencies beyond the Python 3.14 standard library. That core is surrounded by priority rules across four modules, state-machine routines with enter/tick/exit lifecycles, swappable combat strategies, A\* pathfinding on 1-unit heightmaps, and a GOAP planner with learned cost functions.
27
+
The system is organized as a four-stage control pipeline: perception, brain, routines, and motor, with environment parsers, navigation, and observability as support layers. It runs as a single 10 Hz loop with zero runtime dependencies beyond the Python 3.14 standard library. That core is surrounded by priority rules across four modules, state-machine routines with enter/tick/exit lifecycles, swappable combat strategies, JPS/A\* pathfinding with DDA line-of-sight on 1-unit heightmaps, and a GOAP planner with learned cost functions.
28
28
29
29
Data flows through four stages in strict forward-only order:
30
30
@@ -50,7 +50,7 @@ flowchart TB
50
50
51
51
%% util/ is cross-cutting; any layer may import it, unlike eq/ and nav/.
52
52
EQ["eq/<br/>terrain · spells · zones"]
53
-
NAV["nav/<br/>A* · heightmaps · waypoints"]
53
+
NAV["nav/<br/>JPS/A* · DDA LOS · heightmaps · waypoints"]
Zone terrain is parsed from the environment's own 3D geometry into 1-unit-resolution heightmaps with walkability, water, lava, and cliff surface types. A\*searches this grid with surface-type-aware cost functions and danger-zone cost inflation. Pre-built cache files persist across sessions (~80MB per zone, ~20MB resident).
101
+
Zone terrain is parsed from the environment's own 3D geometry into 1-unit-resolution heightmaps with walkability, water, lava, cliff, and obstacle surface types. JPS (Jump Point Search) is the primary pathfinding algorithm, pruning symmetric paths on the grid for speed, with A\*as a fallback when JPS exhausts its node budget in dense terrain. Both use octile-distance heuristics, bitfield-accelerated walkability checks, Z-gradient penalties, and dynamic avoidance-zone cost inflation. Pre-built cache files persist across sessions.
102
102
103
-
For areas where 2D grid pathfinding fails (bridges, tunnels, spiral ramps, overlapping geometry), pre-recorded waypoint graphs provide known-safe routes. A zone graph with BFS computes multi-zone paths for long-distance travel.
103
+
Line-of-sight uses DDA (Amanatides-Woo) grid traversal, visiting every cell the ray crosses exactly once with no sampling gaps. Obstacle flags and interpolated ray Z are checked per cell. Movement validates the path ahead with predictive obstacle scanning and computes perpendicular detours before hitting hazards, rather than relying on stuck recovery alone.
104
+
105
+
For areas where grid pathfinding cannot resolve vertical ambiguity (bridges, tunnels, spiral ramps, overlapping geometry), pre-recorded waypoint graphs provide known-safe routes. A zone graph with BFS computes multi-zone paths for long-distance travel.
104
106
105
107
---
106
108
@@ -229,7 +231,7 @@ A legacy 3D MMORPG emulator concentrates most of the hard problems in autonomous
229
231
-**Complex 3D terrain**: cliffs, water, lava, bridges, tunnels, zone boundaries
230
232
-**Social threat**: engaging one entity can trigger others to join
Coverage is measured in CI with `pytest-cov` and enforced with a `fail_under` floor in `pyproject.toml`. The measured surface is the full 20.5K source lines with zero omissions.
20
+
Coverage is measured in CI with `pytest-cov` and enforced with a `fail_under` floor in `pyproject.toml`. The measured surface is the full source with zero omissions.
21
21
22
22
### What is covered
23
23
@@ -69,7 +69,7 @@ The remaining uncovered lines are concentrated in multi-phase routine tick handl
69
69
70
70
## Test patterns
71
71
72
-
**Zero suppressions.** The test suite has zero `type: ignore`, zero `noqa`, zero `TODO`, zero monkeypatch calls. All dependencies are constructor-injected.
72
+
**Factory-first testing.** The test suite uses factory functions and dependency injection as the primary testing strategy. `unittest.mock.patch` is used sparingly and only at system boundaries (perception I/O, file system). All domain logic is tested through constructor-injected dependencies, not mocks.
73
73
74
74
**Factory functions** (`tests/factories.py`): `make_game_state()`, `make_spawn()`, `make_plan_world_state()`, `make_mob_profile()` construct frozen dataclasses with sensible defaults. Tests override only the fields they care about.
75
75
@@ -83,4 +83,16 @@ The remaining uncovered lines are concentrated in multi-phase routine tick handl
83
83
84
84
**Stateful property tests** (`tests/test_safety_envelope.py`): a `hypothesis.stateful.RuleBasedStateMachine` exercises the Brain's safety envelope under random state sequences, verifying that emergency rules always override, locked routines are respected, and cooldowns are honored across arbitrary tick sequences.
85
85
86
+
**Session simulation** (`tests/test_session_simulation.py`): a `SessionSimulator` drives the Brain through multi-phase `GameState` sequences using `register_all()` with real rules. `ScenarioBuilder` constructs scripted scenarios (idle, damage, drain mana, recover). Tests reproduce documented behaviors from `docs/samples/` telemetry, including the forensics ring buffer skeleton-aggro incident.
87
+
88
+
**Learning invariants** (`tests/test_learning_invariants.py`): property-based tests verifying structural guarantees: gradient weight drift stays within +-20% of defaults under arbitrary fitness sequences, scorecard tuning parameters stay within declared bounds after repeated evaluation, and encounter history respects `MIN_FIGHTS_FOR_LEARNED` and `MAX_SAMPLES` contracts.
89
+
90
+
**Adversarial sequences** (`tests/test_adversarial.py`): Hypothesis-driven tests feeding arbitrary `GameState` sequences through the Brain to verify it never crashes. Includes edge cases (zero HP max, negative HP, 200-spawn lists) and timing budget assertions (single tick under 100ms).
91
+
92
+
**Observability contracts** (`tests/test_observability_contracts.py`): verifies that decision receipts cover all registered rules, forensics buffer respects capacity and eviction order, and structured events carry expected fields.
93
+
94
+
**Architecture enforcement** (`tests/test_import_dag.py`): AST-based tests verifying the forward-only import DAG: routines cannot import brain.decision, motor cannot import brain or routines, perception cannot import upper layers. Also verifies all `Point()` constructors include the z coordinate.
95
+
96
+
**Pure function tests** (`tests/test_routine_pure_functions.py`): unit tests for decision functions extracted from routines (`classify_dot_fizzle`, `verify_cast_landed`, `choose_pull_strategy`, `should_attempt_gate`, `should_cast_regen_buff`, `should_exit_rest`). No mocks, no motor, no state machines.
97
+
86
98
**RecordingMotor** (`src/motor/recording.py`): installed by conftest for all tests. Captures motor action sequences for assertion. Eliminates all `time.sleep()` calls, making the test suite run in ~5 seconds.
0 commit comments