This project implements a simulated spider with a modular brain, explicit predator pressure, standardized neural interfaces, online learning, deterministic behavioral scenarios, and reproducible evaluation workflows.
The current version centers on three structural changes:
- explicit predator instances inside the world, with a backward-compatible primary
lizard - a primitive locomotion output space instead of high-level semantic actions
- standardized input and output interfaces for each center or cortex to reduce excessive coupling between networks
That core has since been extended with:
- reward profiles (
classic,ecological,austere) - explicit shelter geometry with entrance, interior, and deep zones
- predator profiles for visual and olfactory hunters, including multi-predator worlds
- a richer lizard state machine (
PATROL,ORIENT,INVESTIGATE,CHASE,WAIT,RECOVER) - lizard working memory for investigate targets, ambush windows, chase streaks, and recovery
- explicit spider memory for food, predator, safe shelter, and escape route
- optional recurrent memory inside selected proposer modules
- map templates and deterministic scenarios for behavioral evaluation
- behavioral scorecards, ablations, learning-evidence workflows, reward audits, and offline analysis
The system still uses small NumPy neural networks, online learning, and independent modules, but the current architecture is closer to a simplified organism under ecological constraints.
Probabilistic nighttime danger was replaced by a concrete predator in the environment.
The lizard:
- occupies a real grid cell
- has limited vision
- moves more slowly than the spider
- cannot enter the shelter
- causes pain and health loss on contact
- can be escaped if the spider keeps moving effectively
The motor system no longer chooses semantic actions such as MOVE_TO_FOOD or MOVE_TO_SHELTER.
The action space is now:
MOVE_UPMOVE_DOWNMOVE_LEFTMOVE_RIGHTSTAY
That keeps the simulator closer to basic locomotion control instead of scripted behavior verbs.
Because the motor output is now limited to locomotion, feeding and rest emerge from spatial context:
- when the spider reaches food, feeding happens automatically
- when the spider reaches shelter under fatigue or night pressure, recovery happens automatically
- staying still can still help feeding or rest, but it is no longer a rigid prerequisite
The brain now contains five proposer modules plus action_center and motor_cortex:
visual_cortexsensory_cortexhunger_centersleep_centeralert_centeraction_centermotor_cortex
The first five networks propose locomotion in the same output space. action_center applies valence-based priority gating before final arbitration, and motor_cortex acts as the final locomotor executor or corrector.
The current architecture also includes:
- fixed, named interfaces per module
- module dropout during training
- local reflexes per module, defined from the module's own interface
- auxiliary per-module targets ("reflex targets") to reduce coadaptation
- optional recurrent proposer state for selected modules through
BrainAblationConfig.recurrent_modules - explicit contribution metrics in
action_centerfor dominance, agreement, and effective proposer count - the
local_credit_onlyablation, which preserves current inference but removes global policy-gradient broadcast during modular training
Recurrent memory is opt-in per proposer. Set BrainAblationConfig(recurrent_modules=(...)) to make selected modules stateful within an episode, or use the canonical modular_recurrent and modular_recurrent_all ablation variants when comparing recurrent and feed-forward architectures. Hidden state resets at episode boundaries, so recurrence helps with within-episode temporal context rather than cross-episode carryover. Evaluation guidance and variant definitions live in docs/ablation_workflow.md.
Layer responsibilities:
spider_cortex_sim/world.py: ecological dynamics, body state, and explicit observable memoryspider_cortex_sim/interfaces.py: named contracts between world and brainspider_cortex_sim/modules.py: proposer networks onlyspider_cortex_sim/agent.py: local reflexes, auxiliary targets, valence gating, and final motor correction
The generated contract documentation lives in docs/interfaces.md. The short topology note for the newer arbitration chain lives in docs/action_center_design.md.
The 2D grid world contains:
- shelter or burrow (
H) - shelter spatial roles (
entrance,inside,deep) - walls or blocked cells (
#) - clutter terrain (
:) - food (
F) - spider (
A) - predator lizard or hunter instances (
L) - day/night cycle
- limited vision
- food and predator smell fields
- homeostatic pressures from hunger, fatigue, health, pain, and contact
If the spider and lizard occupy the same ASCII-rendered cell, the renderer shows X.
Predators are configured with PredatorProfile values in spider_cortex_sim/predator.py. A profile defines the predator name, visual range, smell range, detection style, move interval, and detection threshold.
Built-in profiles:
DEFAULT_LIZARD_PROFILE: backward-compatible single-predator behavior matching the classic lizard parametersVISUAL_HUNTER_PROFILE: long visual range, short smell range,detection_style="visual"OLFACTORY_HUNTER_PROFILE: short visual range, long smell range,detection_style="olfactory"
SpiderWorld.reset() accepts predator_profiles=[...]. Passing one profile preserves the old single-predator API; passing several profiles spawns one predator per profile and creates one controller per predator. The compatibility helpers still work:
world.lizardandworld.lizard_pos()refer to the first predatorworld.predators,world.predator_positions(),world.predator_count, andworld.get_predator(index)expose the full predator set
Scenario setup code can also assign explicit LizardState(profile=...) instances when a benchmark needs hand-placed predators.
neuro_modular_sim/
├── README.md
├── docs/
│ ├── ablation_workflow.md
│ ├── action_center_design.md
│ └── interfaces.md
├── spider_cortex_sim/
│ ├── __main__.py
│ ├── agent.py
│ ├── bus.py
│ ├── cli.py
│ ├── gui.py
│ ├── interfaces.py
│ ├── modules.py
│ ├── nn.py
│ ├── predator.py # PredatorProfile, DEFAULT_LIZARD_PROFILE, VISUAL_HUNTER_PROFILE, OLFACTORY_HUNTER_PROFILE
│ ├── simulation.py
│ └── world.py
└── tests/
Create and activate a virtual environment:
python3 -m venv venv
source venv/bin/activateInstall dependencies:
pip install -r requirements.txtNotes:
numpyis requiredpygame-ceis optional and only needed for the graphical interface (--gui)
Run a standard training and evaluation session:
PYTHONPATH=. python3 -m spider_cortex_sim --episodes 120 --eval-episodes 3 --max-steps 90Save a summary and trace:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 120 \
--eval-episodes 1 \
--max-steps 90 \
--summary spider_summary.json \
--trace spider_trace.jsonlRender the final evaluation episode in ASCII:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 120 \
--eval-episodes 1 \
--max-steps 90 \
--render-evalTrain with the ecological profile and an alternate map:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 120 \
--eval-episodes 3 \
--max-steps 90 \
--reward-profile ecological \
--map-template side_burrowAvailable map templates:
central_burrowside_burrowcorridor_escapetwo_sheltersexposed_feeding_groundentrance_funnel
Map notes:
corridor_escapeusesNARROWterrain, representing a constrained passagetwo_sheltersintroduces two deep shelters competing with a central transition zoneexposed_feeding_groundconcentrates food in open terrain with more exposed approach pathsentrance_funnelcompresses the shelter entrance through a bottleneck that favors blocking and ambush
Reward profiles:
classic: more guided, best for quick training and baseline runsecological: less direct shaping and more pressure from world dynamicsaustere: minimal-progress baseline for shaping audits and contrast
Run a single scenario:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 0 \
--eval-episodes 0 \
--scenario night_restRun the full scenario suite:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 0 \
--eval-episodes 0 \
--scenario-suiteAvailable scenarios:
night_restpredator_edgeentrance_ambushopen_field_foragingshelter_blockaderecover_after_failed_chasecorridor_gauntlettwo_shelter_tradeoffexposed_day_foragingfood_deprivationvisual_olfactory_pincerolfactory_ambushvisual_hunter_open_fieldfood_vs_predator_conflictsleep_vs_exploration_conflict
Scenario-to-map specializations include:
entrance_ambush,shelter_blockade, andrecover_after_failed_chaseuseentrance_funnelopen_field_foragingandexposed_day_foraginguseexposed_feeding_groundvisual_olfactory_pincerandvisual_hunter_open_fielduseexposed_feeding_groundolfactory_ambushusesentrance_funnelcorridor_gauntletusescorridor_escapetwo_shelter_tradeoffusestwo_shelters
Multi-predator scenario intent:
visual_olfactory_pincer: the spider starts between a visible visual hunter in front and an olfactory hunter behind and downwind; it tests dual-threat perception and module specializationolfactory_ambush: an olfactory hunter waits near a shelter entrance where the spider can smell danger without seeing it; it targets sensory-cortex-led responsevisual_hunter_open_field: a fast visual hunter pressures the spider in open terrain; it targets visual-cortex-led response under exposed conditions
Run the full behavioral suite with explicit scorecards:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 0 \
--eval-episodes 0 \
--behavior-suite \
--full-summaryRun one behavioral scenario and export flat CSV:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 0 \
--eval-episodes 0 \
--behavior-scenario night_rest \
--behavior-csv spider_behavior.csv \
--full-summarysummary["behavior_evaluation"] includes:
suite: aggregated scenario scorecards withsuccess_rate,checks,behavior_metrics,diagnostics, andfailuressummary: overall suite success and detected regressionscomparisons: optional profile/map/seed comparison matrices when behavioral comparison flags are usedlearning_evidence: optional comparison between a trained checkpoint and controls such asrandom_init,reflex_only,freeze_half_budget, andtrained_long_budgetclaim_tests: optional experiment-of-record synthesis that composes the canonical learning-evidence, ablation, and noise-robustness primitives into per-claim pass/fail results
Weak-signal scenarios now publish scenario-owned interpretation metadata:
diagnostic_focussuccess_interpretationfailure_interpretationbudget_note
The scenario diagnostics block also summarizes:
primary_outcomeoutcome_distributionpartial_progress_ratedied_without_contact_rate
The scientific question in this repository is narrower than "does the score go up?" The emergence hypothesis is that the modular cortex learns reusable threat-sensitive behavior that remains present when privileged supports are removed, stays coherent under disturbance, and differentiates between predator types rather than collapsing into one generic escape reflex.
The supporting workflows still matter, but they are no longer the experiment-of-record by themselves:
- ablations isolate which modules and memory pathways matter
- learning-evidence comparisons separate trained behavior from initialization or reflex-only baselines
- the noise matrix checks whether behavior survives train/eval mismatch
Those workflows provide the raw evidence. The claim test suite is the formal gate that reads them together and decides whether the core scientific claims actually hold.
Run the canonical claim suite and write the full experiment record to JSON:
PYTHONPATH=. python3 -m spider_cortex_sim \
--claim-test-suite \
--summary results.jsonThe five canonical claim tests are:
-
learning_without_privileged_signalsHypothesis: trained behavior still beats an untrained policy after privileged reflex support is removed. Protocol: learning-evidence comparison fromrandom_inittotrained_without_reflex_supportacrossnight_rest,predator_edge,entrance_ambush,shelter_blockade, andtwo_shelter_tradeoff, with the leakage audit enforced. Success criterion:trained_without_reflex_supportmust improvescenario_success_rateoverrandom_initby at least0.15and the leakage audit must report zero unresolved privileged-signal findings. -
escape_without_reflex_supportHypothesis: predator escape remains learned behavior rather than a reflex-only artifact. Protocol: learning-evidence comparison fromreflex_onlytotrained_without_reflex_supportoverpredator_edge,entrance_ambush, andshelter_blockade. Success criterion:trained_without_reflex_supportmust reach predator-responsescenario_success_rate >= 0.60and exceedreflex_onlyby at least0.10. -
memory_improves_shelter_returnHypothesis: recurrent memory improves delayed shelter return and shelter trade-off behavior. Protocol: ablation comparison ofmodular_recurrentversusmodular_fullonnight_restandtwo_shelter_tradeoff. Success criterion:modular_recurrentmust improve shelter-returnscenario_success_rateby at least0.10. -
noise_preserves_threat_valenceHypothesis: threat-sensitive arbitration survives train/eval noise mismatch instead of working only on the diagonal. Protocol: canonical noise-robustness matrix, comparing diagonal and off-diagonal aggregate scores over the threat-response scenarios. Success criterion: the off-diagonal threat-response score must stay at least0.60, and the diagonal-minus-off-diagonal gap must stay at most0.15. -
specialization_emerges_with_multiple_predatorsHypothesis: multiple predator ecologies produce predator-type specialization instead of one undifferentiated threat pathway. Protocol: predator-type ablation comparison acrossvisual_olfactory_pincer,olfactory_ambush, andvisual_hunter_open_field, paired with type-specific cortex engagement checks in the full modular policy. Success criterion:drop_visual_cortexmust drivevisual_minus_olfactory_success_rate <= -0.10,drop_sensory_cortexmust drivevisual_minus_olfactory_success_rate >= 0.10, and the reference policy must show the expected cortex engagement in at least2of the3specialization scenarios.
Generic benchmarks such as the ablation suite and the noise matrix still provide the supporting detail, but the claim tests are the scientific nucleus: they are the concise pass/fail record for whether the main emergence story survives contact with the actual measurements.
PYTHONPATH=. python3 -m spider_cortex_sim \
--gui \
--episodes 120 \
--eval-episodes 3 \
--max-steps 90 \
--reward-profile classic \
--map-template central_burrowThe GUI displays:
- the predator lizard on the grid
- shelter roles and terrain types
- contact, sighting, and escape counters
- lizard position, mode, and current target
- explicit spider memory and sleep debt
- recent reward components
- nighttime shelter-role distribution and predator-state occupancy
Useful shortcuts:
V: toggle visibility overlayM: toggle smell heatmap
Train and save:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 120 --eval-episodes 3 --max-steps 90 \
--save-brain spider_brainLoad and continue training:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 60 --eval-episodes 3 --max-steps 90 \
--load-brain spider_brain \
--save-brain spider_brainLoad only selected modules:
PYTHONPATH=. python3 -m spider_cortex_sim \
--episodes 60 --eval-episodes 3 --max-steps 90 \
--load-brain spider_brain \
--load-modules visual_cortex hunger_centerCompatibility notes:
- the current architecture uses an explicit interface signature
- older saves predating the current interface standardization are rejected with explicit incompatibility errors
- older checkpoints predating
sleep_phase,rest_streak,sleep_debt, shelter-role signals, certainty/occlusion signals, explicit memory, or oriented perception are also incompatible with the current architecture - the versioned interface registry and generated contract docs are in docs/interfaces.md
Because interface descriptions are part of the current fingerprinted metadata, this English translation pass also changes interface and architecture fingerprints. Older checkpoints may therefore fail compatibility checks even though behavior and identifiers were not intentionally refactored.
Run the full suite:
PYTHONPATH=. python3 -m unittest discover -s tests -vThe tests cover:
- standardized interface shapes and generated interface docs
- contextual feeding and rest
- auditable reward decomposition
- sleep progression
SETTLING -> RESTING -> DEEP_SLEEP, sleep debt, and interruptions - predator contact with real damage
- shelter geometry and occlusion
- explicit spider memory
- map templates and reachability
- deterministic scenario regressions
- memory-guided escape and foraging after loss of sight
- scenario runners and deterministic predator-response latency
- online parameter updates
- lightweight trainability checks across reward profiles, comparisons, and alternate maps
The summary and trace include:
- per-step
reward_components reward_audit, including component inventory, shaping categories, and leakage candidates- nighttime shelter occupancy and nighttime stillness
- nighttime shelter-role distribution (
outside,entrance,inside,deep) - predator-response latency
- predator contacts, escapes, and response latency by predator type
- dominant module response by predator type
reward_profileandmap_templateconfig.operational_profile, including active thresholds and operational weightsconfig.budget, including resolved profile, benchmark strength, seeds, and explicit overridescheckpointingwhen--checkpoint-selection bestis used- explicit certainty and occlusion fields per visual channel
- world-owned
headingand decayed percept traces in trace metadata - explicit
predator_motion_salience - normalized memory vectors in trace metadata
- predator occupancy by state (
PATROL,ORIENT,INVESTIGATE,CHASE,WAIT,RECOVER) - predator state transitions and dominant predator state per episode or scenario
- food and shelter distance deltas
event_logstages per tick- behavioral scorecards per scenario in
behavior_evaluation - diagnostic per-episode bands such as
progress_bandandoutcome_band - explicit
action_centerarbitration outputs such aswinning_valence,valence_scores,module_gates,suppressed_modules, andevidence
When --debug-trace is combined with --trace, each tick also includes:
- serialized observations before and after transition
- reward components
- normalized memory vectors
- per-module logits before reflex, reflex delta, and post-reflex logits
- logits after valence gating, per-module
gate_weight, anddebug.arbitration effective_reflex_scale,module_reflex_override,module_reflex_dominance, andfinal_reflex_override- full predator internal state
Use --full-summary to print the complete JSON summary to stdout.
Specialization metrics compare how modules respond when visual versus olfactory predators are the primary threat. A high predator-type specialization score means response distributions differ by predator type, such as stronger visual_cortex dominance for visual hunters and stronger sensory_cortex dominance for olfactory hunters. A low score means the same modules respond similarly to both predator types, which can be useful as a baseline but does not show sensory-niche specialization.
The CLI exposes explicit budget profiles:
smoke: quick sanity or CI profile (6episodes,1evaluation run,60steps, seed7)dev: short reproducible local benchmark (12episodes,2evaluation runs,90steps, seeds7/17/29)report: stronger reporting workflow (24episodes,4evaluation runs,120steps,2repetitions per scenario, seeds7/17/29/41/53)
Canonical commands:
# smoke: sanity / CI
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile smoke \
--behavior-suite --full-summary
# dev: fast local benchmark
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile dev \
--ablation-suite --full-summary
# report: stronger benchmark + automatic checkpoint selection
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile report \
--checkpoint-selection best \
--ablation-suite --full-summaryWithout --budget-profile, the run still works in custom mode and records the effective values and overrides in summary["config"]["budget"].
Compare reward profiles on the current map:
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile dev \
--compare-profiles --full-summaryCompare maps under the current reward profile:
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile dev \
--reward-profile ecological \
--compare-maps --full-summaryCompare the behavioral suite across profiles:
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile dev \
--behavior-compare-profiles --full-summaryCompare the behavioral suite across maps and export CSV:
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile dev \
--reward-profile ecological \
--behavior-compare-maps \
--behavior-csv spider_behavior_compare.csv \
--full-summaryThe shaping audit uses austere as the minimal baseline and records deltas against it under summary["behavior_evaluation"]["shaping_audit"].
The project includes a separate runner that transforms summary.json, trace.jsonl, and behavior_csv into an offline analysis bundle:
PYTHONPATH=. python3 -m spider_cortex_sim.offline_analysis \
--summary spider_summary_compare.json \
--trace spider_trace_debug.jsonl \
--behavior-csv spider_behavior_compare.csv \
--output-dir offline_analysisRules:
--output-diris required- at least one of
--summary,--trace, or--behavior-csvis required - the report is always emitted, even with partial input
- missing blocks are reported in
report.mdandreport.jsoninstead of aborting execution
Compare the modular reference against the canonical ablation suite:
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile dev \
--ablation-suite \
--behavior-csv spider_ablation_rows.csv \
--full-summaryRun the learning_evidence suite under the smoke budget:
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile smoke \
--learning-evidence \
--behavior-scenario night_rest \
--behavior-csv spider_learning_evidence_rows.csv \
--full-summaryRun the canonical short-vs-long learning-evidence comparison:
PYTHONPATH=. python3 -m spider_cortex_sim \
--budget-profile smoke \
--learning-evidence \
--learning-evidence-long-budget-profile report \
--behavior-suite \
--summary spider_learning_evidence_summary.json \
--behavior-csv spider_learning_evidence_rows.csv \
--full-summaryThe detailed ablation workflow, variant definitions, and canonical check-in table live in docs/ablation_workflow.md.
- The system is biologically inspired, not biologically faithful
- The "return vector to shelter" is a simplified form of proprioception or minimal spatial memory
- Explicit memory is perception-grounded: data sources are limited to local visual perception, contact events, and movement history. The environment pipeline maintains mechanics such as aging and TTL expiration, but it cannot inject information the spider has not perceived.
- Local per-module reflexes act like innate behavior that online learning later refines
- There is no giant fallback center that integrates everything; each proposer receives only its own interface and emits only standardized locomotion proposals
- implemented: multiple predators with different sensory niches
- model a more strongly oriented field of view rather than a short omnidirectional one
- separate locomotion into gait, speed, and body orientation
- migrate the networks to PyTorch while preserving the same modular interface signature