Summary
Implement AffinityEngine — an interaction-weighted, hysteresis-stabilized IClusteringModel implementation that groups entities by predicted interaction probability rather than pure spatial proximity.
This is the hand-crafted clustering baseline described in the primer as the step between the current spatial-only RulesEngine and the future ML/RL model. It solves three known failure modes of RulesEngine:
- Boundary thrashing — entities on a spatial boundary oscillate between clusters every tick
- Interaction blindness — heavily interacting entities on opposite sides of a boundary incur cross-cluster RPCs for every interaction
- No temporal awareness — the model reacts to where entities are now, not where they're going
Architecture
New crate: arcane-affinity (sibling to arcane-rules), with four internal modules:
- InteractionGraph — decaying pairwise interaction weights between entities
- ClusterScorer — scores entity-to-cluster affinity (interaction sum + spatial tiebreaker)
- MigrationState — per-entity cooldowns preventing oscillation
- AffinityConfig — all tunable parameters with sensible defaults
Plus minimal integration changes in existing crates:
- Extend
IClusteringModel trait with per-entity assignment method (default impl, backward-compatible)
- Add
snapshot_entities() to SpatialIndex (expose entity data for WorldStateView)
- Populate
WorldStateView.players in ClusterManager (currently always empty)
- Add
arcane-affinity as optional dependency in arcane-infra with feature flag
Design documents
Full specs are in arcane-engine repo on branch feat/affinity-clustering-specs:
in_08_affinity_engine.md — main component spec
in_08_01_interaction_graph.md through in_08_04_affinity_config.md — module specs
in_08_05_trait_extension.md — trait extension spec
in_08_00_integration_report.md — code change analysis
Sub-issues
New crate implementation
Integration changes (existing crates)
Testing
Dependency graph
#65 (scaffold) ─┬─→ #66 (InteractionGraph) ──┐
├─→ #67 (MigrationState) │
├─→ #68 (AffinityConfig) ─────┤
└─────────────────────────────→ #69 (ClusterScorer)
│
#66 + #67 + #68 + #69 ──────────────────────→ #70 (AffinityEngine core)
│
#70 ─────────────────────────────────────────→ #74 (infra integration)
#72 (SpatialIndex) ─────────────────────────→ #73 (populate players)
#70 + #73 ──────────────────────────────────→ #76 (integration tests)
#66 + #67 + #68 + #69 + #70 ───────────────→ #75 (unit tests)
#71 (trait extension) — independent, no deps
#72 (SpatialIndex accessor) — independent, no deps
Success criteria
AffinityEngine is better than RulesEngine if, under identical arcane-swarm workloads:
- Cross-cluster interaction count is lower
- Migration frequency is lower
- Latency is equal or better
- Throughput ceiling is equal or better
What this does NOT solve
Summary
Implement AffinityEngine — an interaction-weighted, hysteresis-stabilized
IClusteringModelimplementation that groups entities by predicted interaction probability rather than pure spatial proximity.This is the hand-crafted clustering baseline described in the primer as the step between the current spatial-only RulesEngine and the future ML/RL model. It solves three known failure modes of RulesEngine:
Architecture
New crate:
arcane-affinity(sibling toarcane-rules), with four internal modules:Plus minimal integration changes in existing crates:
IClusteringModeltrait with per-entity assignment method (default impl, backward-compatible)snapshot_entities()toSpatialIndex(expose entity data forWorldStateView)WorldStateView.playersinClusterManager(currently always empty)arcane-affinityas optional dependency inarcane-infrawith feature flagDesign documents
Full specs are in
arcane-enginerepo on branchfeat/affinity-clustering-specs:in_08_affinity_engine.md— main component specin_08_01_interaction_graph.mdthroughin_08_04_affinity_config.md— module specsin_08_05_trait_extension.md— trait extension specin_08_00_integration_report.md— code change analysisSub-issues
New crate implementation
arcane-affinitycrate scaffoldIClusteringModel::evaluate()Integration changes (existing crates)
IClusteringModeltrait withcompute_entity_assignments()snapshot_entities()toSpatialIndexWorldStateView.playersinClusterManagerarcane-affinityas optional dependency inarcane-infrawith model selectionTesting
arcane-affinitymodulesDependency graph
Success criteria
AffinityEngine is better than RulesEngine if, under identical arcane-swarm workloads:
What this does NOT solve