defy-rs — Open-World Wanted Escalation & Tactical Pursuit AI in Pure Rust
defy-rs is a game AI library that models open-world crime witness reporting, 1-to-6 star wanted level escalation, and coordinated police pursuit tactics. It uses line-of-sight sensory cones, last-known-position heatmaps, and interceptor roadblock spawning to drive dynamic sandbox gameplay.
$ cargo add defy-rs
Wanted Level & Dispatch Simulator
Simulate crime incidents, test witness reaction latencies, silence 911 callers, and break line-of-sight during high-speed police pursuits.
Three Core Gameplay Subsystems
Engineered from ground up with data-oriented structures, cache locality, and Bevy ECS schedule compatibility.
Wanted Level System
Progressive 1-to-6 stars system with score thresholds, unit compositions, dynamic roadblock probabilities, and line-of-sight cooldown decay.
- 1 Star: Cruiser patrol with peaceful arrest attempt
- 3 Stars: SWAT Enforcers, spikes, helicopter air support
- 6 Stars: Military martial law, Rhino tanks, shoot-on-sight
- Out-of-sight search radius bubble with progressive star decay
Crime & Witness Pipeline
Multi-modal sensory detection combining directional visual FOV cones with omnidirectional acoustic sound propagation.
- Auditory radius: gunfire (60-90m), blast explosions (200m)
- Witness shock delay before dialing 911
- Silenceable witnesses cancel reports before dispatch triggers
- Categorized severities: Minor, Moderate, Felony, Capital
Bystander AI Archetypes
Rich bystander reactions determined by psychological personality traits and proximity to gunfire, vehicle theft, and melee assaults.
- Coward: Cowers or flees screaming upon loud sounds
- AverageCitizen: Raises hands at gunpoint, calls 911 when safe
- Aggressive: Fights back against melee assaults and carjackings
- ArmedVigilante: Conceals pistol, returns fire during shootout
16 Unit Tests & Micro-Benchmarks
Every sensory check, dispatch rule, and AI transition is covered by automated integration tests.
Automated Test Matrix 16 / 16 PASSED (0.00s)
| Suite | Test Function | Status |
|---|---|---|
| wanted | test_star_progression_by_score | OK |
| wanted | test_dispatch_composition_per_star | OK |
| wanted | test_line_of_sight_and_decay_cycle | OK |
| wanted | test_reacquisition_resets_decay | OK |
| wanted | test_deadly_force_at_high_wanted_level | OK |
| wanted | test_busted_arrest_mechanic | OK |
| crime | test_crime_severities_and_scores | OK |
| crime | test_sensory_detection_audio_omnidirectional | OK |
| crime | test_sensory_detection_vision_cone | OK |
| crime | test_911_call_pipeline_and_dispatch | OK |
| crime | test_silence_witness_cancels_call | OK |
| npc | test_coward_cowers_on_gunfire | OK |
| npc | test_average_citizen_hands_up_at_gunpoint | OK |
| npc | test_aggressive_fights_back_on_melee | OK |
| npc | test_armed_vigilante_draws_weapon_on_gunfire | OK |
| npc | test_panic_timer_calms_down | OK |
Comparative Benchmarks vs Game Scripts Full Report (BENCHMARKS.md) →
| Scenario | defy-rs (Rust) | Lua / C# Script | Speedup |
|---|---|---|---|
| Police Pursuit (50 Units) | 0.20 µs (4.08 ns/u) | 25 – 60 µs | 60× – 300× |
| NPC Crowd Triage (200 NPCs) | 1.49 µs (7.47 ns/npc) | 45 – 120 µs | 13× – 80× |
| Witness Sensory Detection | 3.10 ns (322M/s) | 350 – 900 ns | 40× – 290× |
| Star Progression & Scaling | 21.55 ns (46M/s) | 800 – 2,200 ns | 12× – 100× |
| Hot Loop Heap Allocations | 0 bytes | 4 – 16 allocs | Zero GC |
Massive Crowd & Dispatch Simulation
In open-world cities with 5,000+ simultaneous NPCs and 50+ police pursuit units, defy-rs runs entire sensory sweeps and tactical coordination in under 0.05 ms per frame. Run cargo run --release --example bench_vs_original to verify.
Integrate defy-rs in Minutes
Plug directly into your Bevy ECS systems or custom engine tick.
use glam::Vec3;
use defy_rs::{
WantedLevelSystem, WantedStatus, WitnessSystem,
CrimeEvent, CrimeType, NpcEntity, NpcPersonality, NpcContext, ThreatStimulus,
};
fn main() {
// 1. Initialize Wanted Level System
let mut wanted = WantedLevelSystem::default();
wanted.add_crime_score(150, Vec3::ZERO); // 1 Star Triggered
println!("Current Wanted Stars: {}", wanted.stars);
// 2. Register Witness and 911 Call Countdown
let mut witnesses = WitnessSystem::new();
witnesses.register_witness(
1,
Vec3::new(5.0, 0.0, 5.0),
CrimeEvent {
crime_type: CrimeType::VehicleTheft,
perpetrator_id: 100,
location: Vec3::ZERO,
timestamp_sec: 0.0,
is_direct_police_view: false,
},
3.0, // 3.0s call timer
);
// Player intimidates witness before report finishes:
let silenced = witnesses.silence_witness(1);
assert!(silenced);
// 3. Simulate Bystander Reaction
let mut citizen = NpcEntity::new(10, Vec3::ZERO, NpcPersonality::AverageCitizen);
citizen.update(&NpcContext {
threats: vec![ThreatStimulus {
source_id: 100,
position: Vec3::new(0.0, 0.0, 3.0),
is_gunfire: false,
is_aimed_at_me: true,
is_melee_attack: false,
}],
delta_time: 0.016,
});
println!("Citizen reaction: {:?}", citizen.reaction); // HandsUp
}