Epic: #64 (AffinityEngine)
Depends on: #70 (AffinityEngine core), #73 (populate players)
What
Integration tests that validate AffinityEngine's behavior against the three failure modes it was designed to solve:
Test 1: raid_group_stays_together_across_boundary
- 2 clusters, spatial boundary at x=0
- 20 entities in tight group at x=-5 (cluster 1) with heavy mutual interactions
- Move group to x=+5 (spatial model would assign to cluster 2)
- Assert: AffinityEngine keeps all 20 on same cluster (no split during crossing)
Test 2: hysteresis_prevents_boundary_oscillation
- 2 clusters, boundary at x=0
- Entity at x=0.1 with moderate interaction weight in cluster 1
- Assert: entity stays in cluster 1 (hysteresis prevents migration)
- Give overwhelming interaction weight with cluster 2 entities
- Assert: entity migrates to cluster 2 (threshold exceeded)
- Check entity is on cooldown — moving back doesn't trigger re-migration
Test 3: isolated_entity_uses_spatial_fallback
- 2 clusters
- Single entity with no interactions near cluster 2's centroid
- Assert: assigned to cluster 2 (spatial fallback)
Test 4: valid_assignments_for_all_entities
- N entities, K clusters
- Run evaluate()
- Assert: every entity assigned to exactly one existing cluster
Test 5: drop_in_replacement
- Create ClusterManager with AffinityEngine instead of RulesEngine
- Run evaluation cycle with entities
- Assert: no panic, valid decisions returned
Acceptance criteria
- All 5 tests pass
- Tests use synthetic WorldStateView (no external dependencies)
Epic: #64 (AffinityEngine)
Depends on: #70 (AffinityEngine core), #73 (populate players)
What
Integration tests that validate AffinityEngine's behavior against the three failure modes it was designed to solve:
Test 1:
raid_group_stays_together_across_boundaryTest 2:
hysteresis_prevents_boundary_oscillationTest 3:
isolated_entity_uses_spatial_fallbackTest 4:
valid_assignments_for_all_entitiesTest 5:
drop_in_replacementAcceptance criteria