use dreamwell_attention::encoder::CausalEngineEncoder;
use dreamwell_attention::{CausalComputeKernel, InputPacket, KernelResult};
use dreamwell_engine::game_object::GameObjectScene;
use dreamwell_engine::input::particle::particle_sphere_offsets;
use dreamwell_engine::physics::simulation::SuperpositionObserver;
use dreamwell_fabric::causal_observer_lane::{causal_observer_lane_channel, CausalObserverLaneReceiver};
use dreamwell_gates::{DreamGate, GateConfig};
use dreamwell_gpu::quantum_bridge::QuantumBridge;
use dreamwell_sdk::{
decohere::{Decoherence, DecoherenceConfig, DecoherenceInputMode},
ledger_lane_channel,
loom_budgeter::LoomBudgeter,
loom_limiter::LoomLimiter,
LedgerLaneReceiver, Oracle, OracleConfig,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SimulationMode {
Preview,
Published,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RuntimeReadiness {
Pending,
Syncing,
Ready,
Failed,
}
#[derive(Debug, Clone)]
pub struct SimulationJournalEntry {
pub frame: u64,
pub kind: String,
pub detail: String,
}
pub struct SimulationService {
pub scene: GameObjectScene,
pub kernel: Option<CausalComputeKernel>,
pub encoder: Option<CausalEngineEncoder>,
pub bridge: Option<QuantumBridge>,
pub last_bridge_packet: Option<dreamwell_gpu::quantum_bridge::BridgePacket>,
pub decoherence: Option<Decoherence>,
pub oracle: Option<Oracle>,
pub decoherence_fields: Vec<dreamwell_quantum::DecoherenceField>,
pub last_result: Option<KernelResult>,
pub last_descriptor: Option<dreamwell_attention::SuperBodyFrameDescriptor>,
pub player_object_id: u64,
pub particle_offsets: Vec<[f32; 3]>,
pub observer: SuperpositionObserver,
pub journal: Vec<SimulationJournalEntry>,
pub console: Vec<String>,
pub mode: SimulationMode,
pub readiness: RuntimeReadiness,
pub frame: u64,
pub tick: u64,
pub quantum_cull_radius: f32,
pub elapsed_time: f32,
pub gate: Option<DreamGate>,
pub limiter: Option<LoomLimiter>,
pub budgeter: Option<LoomBudgeter>,
pub ledger_rx: Option<LedgerLaneReceiver>,
pub causal_observer_rx: Option<CausalObserverLaneReceiver>,
pub causal_observer_tx: Option<dreamwell_fabric::CausalObserverLaneSender>,
pub active_zone_index: usize,
pub metaphor_profile: dreamwell_metaphors::MetaphorProfile,
pub active_particle_count: f32,
pub coherence_target: f32,
pub coherence_current: f32,
pub gather_active: bool,
pub emit_strength: f32,
pub universe_snapshot_rx: Option<crossbeam_channel::Receiver<dreamwell_universe::FieldSnapshot>>,
pub universe_update_tx: Option<crossbeam_channel::Sender<dreamwell_universe::ClientUpdate>>,
pub universe_client_id: u64,
pub universe_connected: bool,
}
impl SimulationService {
pub const DEFAULT_QUANTUM_CULL_RADIUS: f32 = 9.14;
pub fn new(scene_name: &str, mode: SimulationMode) -> Self {
Self {
scene: GameObjectScene::new(scene_name.into()),
kernel: None,
encoder: None,
bridge: None,
last_bridge_packet: None,
decoherence: None,
oracle: None,
decoherence_fields: Vec::new(),
last_result: None,
last_descriptor: None,
player_object_id: 0,
particle_offsets: Vec::new(),
observer: SuperpositionObserver::new([0.0; 3], Self::DEFAULT_QUANTUM_CULL_RADIUS),
journal: Vec::new(),
console: Vec::new(),
mode,
readiness: RuntimeReadiness::Pending,
frame: 0,
tick: 0,
quantum_cull_radius: Self::DEFAULT_QUANTUM_CULL_RADIUS,
elapsed_time: 0.0,
gate: None,
limiter: None,
budgeter: None,
ledger_rx: None,
causal_observer_rx: None,
causal_observer_tx: None,
active_zone_index: 9,
metaphor_profile: dreamwell_metaphors::MetaphorProfile::wave(),
active_particle_count: dreamwell_metaphors::DEFAULT_PARTICLE_COUNT as f32,
coherence_target: 1.0,
coherence_current: 1.0,
gather_active: false,
emit_strength: 0.0,
universe_snapshot_rx: None,
universe_update_tx: None,
universe_client_id: 0,
universe_connected: false,
}
}
pub fn input_enabled(&self) -> bool {
self.readiness == RuntimeReadiness::Ready && self.encoder.is_some()
}
pub fn connect_universe(&mut self) -> crossbeam_channel::Sender<()> {
let config = dreamwell_universe::UniverseConfig::default();
let (shutdown_tx, shutdown_rx) = crossbeam_channel::bounded(1);
let mut field = dreamwell_universe::QuantumField::new(&config);
let mut connections = dreamwell_universe::ConnectionProtocol::new(config.max_clients);
let (client_id, snapshot_rx, update_tx) = connections
.connect(&mut field, 9)
.expect("Failed to connect to universe");
self.universe_snapshot_rx = Some(snapshot_rx);
self.universe_update_tx = Some(update_tx);
self.universe_client_id = client_id;
self.universe_connected = true;
log::info!("Connected to universe on layer 9 (client_id={})", client_id);
let config_clone = config.clone();
std::thread::Builder::new()
.name("dreamwell-universe".into())
.spawn(move || {
let mut kernel = dreamwell_universe::UniverseKernel {
config: config_clone.clone(),
field,
connections,
metrics: dreamwell_universe::metrics::UniverseMetrics::new(),
shutdown_rx,
};
kernel.run();
})
.expect("Failed to spawn universe thread");
shutdown_tx
}
pub fn set_coherence_target(&mut self, t: f32) {
self.coherence_target = t.clamp(0.0, 1.0);
}
pub fn set_gather(&mut self, active: bool) {
self.gather_active = active;
}
pub fn set_emit_strength(&mut self, s: f32) {
self.emit_strength = s.clamp(0.0, 1.0);
}
pub fn initialize(
&mut self,
scene: GameObjectScene,
spawn_pos: [f32; 3],
particle_count: u32,
) -> Result<(), String> {
self.scene = scene;
self.journal.push(SimulationJournalEntry {
frame: 0,
kind: "mount_braid".into(),
detail: format!("scene: {}, objects: {}", self.scene.name, self.scene.objects.len()),
});
self.console.push(format!(
"[Info] Braid mounted from Chronoshift checkpoint (tick: {}).",
self.tick,
));
if self.scene.objects.is_empty() {
self.readiness = RuntimeReadiness::Failed;
return Err("reality_check: empty scene".into());
}
self.console.push("[Info] Reality check: all phases passed.".into());
let obj_count = self.scene.objects.len();
self.console
.push(format!("[Info] Scene instantiated: {obj_count} objects."));
let kernel = CausalComputeKernel::new(spawn_pos, particle_count);
self.kernel = Some(kernel);
self.encoder = Some(CausalEngineEncoder::new(spawn_pos, particle_count, 42));
let mut bridge = QuantumBridge::new(particle_count);
bridge.set_metaphor_profile(self.metaphor_profile.clone());
self.bridge = Some(bridge);
let decoherence = Decoherence::with_config(DecoherenceConfig {
input_mode: DecoherenceInputMode::Particle,
..DecoherenceConfig::default()
});
self.decoherence = Some(decoherence);
let mut oracle = Oracle::new(OracleConfig::default());
let (tx, rx) = ledger_lane_channel();
oracle.connect_ledger(tx);
oracle.begin_frame(0);
self.oracle = Some(oracle);
self.ledger_rx = Some(rx);
let (causal_observer_tx, causal_observer_rx) = causal_observer_lane_channel();
self.causal_observer_tx = Some(causal_observer_tx);
self.causal_observer_rx = Some(causal_observer_rx);
let hw = dreamwell_sdk::loom_budgeter::HardwareProfile::mid_range();
let budgeter = LoomBudgeter::from_hardware(hw);
let mut limiter = LoomLimiter::default();
budgeter.apply_to_limiter(&mut limiter);
let gate = DreamGate::new(GateConfig::from_services(&limiter, &budgeter));
self.gate = Some(gate);
self.limiter = Some(limiter);
self.budgeter = Some(budgeter);
self.particle_offsets = particle_sphere_offsets(particle_count);
self.player_object_id = self
.scene
.objects
.iter()
.find(|o| {
o.property_tags
.iter()
.any(|t| t == "isInputReceiver" || t == "isPlayer")
})
.map(|o| o.id)
.unwrap_or(1);
let starting_layer = self
.scene
.objects
.iter()
.filter(|o| o.property_tags.iter().any(|t| t == "isInputReceiver"))
.flat_map(|o| o.property_tags.iter())
.find_map(|t| {
t.strip_prefix("isStartingOnTopologyLayer")
.and_then(|v| v.parse::<u8>().ok())
})
.unwrap_or(9);
if let Some(ref mut k) = self.kernel {
k.active_topology_layer = starting_layer;
}
if let Some(ref mut enc) = self.encoder {
enc.kernel_mut().active_topology_layer = starting_layer;
}
self.active_zone_index = starting_layer as usize;
self.observer.position = spawn_pos;
self.observer.active_radius = self.quantum_cull_radius;
self.console.push(format!(
"[Info] CausalComputeKernel mounted at [{:.1}, {:.1}, {:.1}] ({particle_count} particles).",
spawn_pos[0], spawn_pos[1], spawn_pos[2],
));
self.journal.push(SimulationJournalEntry {
frame: 0,
kind: "avatar_init".into(),
detail: format!("particles: {particle_count}, pos: {spawn_pos:?}, sdk: active"),
});
self.console.push("[Info] GPU resources synced.".into());
if self.encoder.is_none() || self.scene.objects.is_empty() {
self.readiness = RuntimeReadiness::Failed;
return Err("stitch: render graph validation failed".into());
}
self.readiness = RuntimeReadiness::Syncing;
self.console
.push("[Info] Stitch passed: render graph validated.".into());
self.readiness = RuntimeReadiness::Ready;
self.console
.push("[Info] Seer is happy, reality rendered without concern.".into());
self.console
.push("[Info] Input controls attached to CausalComputeKernel.".into());
self.console.push(format!(
"[Info] Quantum pipeline: {} particles, density matrix 5×5, adaptive Hamiltonian (Model 1).",
particle_count,
));
self.console
.push("[Info] Couplings will adapt to movement patterns via parameter shift gradient.".into());
log::info!(
"Quantum locomotion active: {} particles, F(12)={}, adaptive Hamiltonian learning enabled",
particle_count,
particle_count == 144,
);
let _universe_shutdown = self.connect_universe();
self.console
.push("[Info] Universe connected: persistent quantum field at 1618Hz (φ-scaled).".into());
if let (Some(ref decoherence), Some(ref mut gate)) = (&self.decoherence, &mut self.gate) {
let weave = decoherence.build_session_begin_weave(0);
gate.submit(weave, 100);
}
Ok(())
}
pub fn tick(&mut self, packet: &InputPacket) -> Option<KernelResult> {
if !self.input_enabled() {
return None;
}
self.frame += 1;
self.tick += 1;
self.elapsed_time += packet.dt;
let coherence_rate = 6.0_f32;
let coherence_t = 1.0 - (-coherence_rate * packet.dt).exp();
self.coherence_current += (self.coherence_target - self.coherence_current) * coherence_t;
let gate = self.gate.as_mut()?;
let tick = self.tick;
gate.begin_frame(tick);
if let Some(ref mut limiter) = self.limiter {
limiter.begin_frame(tick);
}
if let Some(ref mut decoherence) = self.decoherence {
let actions = packet.actions_as_u8();
let movement = packet.movement;
let look = [packet.camera_yaw, 0.0];
let input_weave = decoherence.build_input_weave(tick, actions, movement, look, 0.0);
gate.submit(input_weave, 100);
}
let encoder = self.encoder.as_mut()?;
let mut enc_packet = packet.clone();
enc_packet.grounded = encoder.kernel().grounded;
enc_packet.timestamp = self.elapsed_time as f64;
enc_packet.coherence_target = self.coherence_current;
let encode_result = encoder.encode_frame(&enc_packet, &self.decoherence_fields);
if self.frame % 2 == 0 {
let kernel = encoder.kernel_mut();
let bias = kernel.quantum.hamiltonian.bias;
let couplings = kernel.quantum.hamiltonian.couplings;
let moving = kernel.velocity[0].abs() > 0.01 || kernel.velocity[2].abs() > 0.01;
let sprinting = enc_packet.sprint && moving;
let input_bias = [
if !moving { 2.0 } else { 0.0 },
if moving && !sprinting { 2.0 } else { 0.0 },
if enc_packet.jump { 3.0 } else { 0.0 },
if kernel.landing_timer > 0.0 { 2.0 } else { 0.0 },
if sprinting { 2.0 } else { 0.0 },
];
let shift = std::f32::consts::FRAC_PI_2;
let lr = 0.005_f32;
let mut new_couplings = couplings;
for k in 0..5 {
let mut c_plus = couplings;
c_plus[k] = (c_plus[k] + shift).min(2.0);
let f_plus = kernel.quantum.rho.free_energy(&bias, &input_bias, &c_plus);
let mut c_minus = couplings;
c_minus[k] = (c_minus[k] - shift).max(0.1);
let f_minus = kernel.quantum.rho.free_energy(&bias, &input_bias, &c_minus);
let grad = (f_plus - f_minus) / 2.0;
new_couplings[k] = (new_couplings[k] - lr * grad).clamp(0.1, 2.0);
}
kernel.quantum.hamiltonian.couplings = new_couplings;
if self.frame % 120 == 0 {
log::info!(
"Adaptive Hamiltonian: couplings=[{:.3}, {:.3}, {:.3}, {:.3}, {:.3}] F={:.4}",
new_couplings[0],
new_couplings[1],
new_couplings[2],
new_couplings[3],
new_couplings[4],
kernel.quantum.rho.free_energy(&bias, &input_bias, &new_couplings),
);
}
}
let pos = encode_result.kernel_result.position;
if let Some(ref mut k) = self.kernel {
k.position = pos;
k.velocity = encoder.kernel().velocity;
k.grounded = encoder.kernel().grounded;
k.facing_yaw = encoder.kernel().facing_yaw;
}
if let Some(ref mut decoherence) = self.decoherence {
let facing_yaw = encoder.kernel().facing_yaw;
let obs_weave = decoherence.build_observe_weave(tick, pos, facing_yaw);
gate.submit(obs_weave, 100);
if let Some(ref prev) = self.last_result {
if encode_result.kernel_result.locomotion_mode != prev.locomotion_mode {
let loco_state = match encode_result.kernel_result.locomotion_mode {
0 => dreamwell_sdk::decohere::LocomotionState::Idle,
1 => dreamwell_sdk::decohere::LocomotionState::Walking,
2 => dreamwell_sdk::decohere::LocomotionState::Running,
3 => dreamwell_sdk::decohere::LocomotionState::Jumping,
4 => dreamwell_sdk::decohere::LocomotionState::Falling,
_ => dreamwell_sdk::decohere::LocomotionState::Idle,
};
let loco_weave = decoherence.build_locomotion_weave(tick, loco_state);
gate.submit(loco_weave, 90);
}
}
if encode_result.kernel_result.layer_changed {
self.active_zone_index = encode_result.kernel_result.topology_layer as usize;
}
}
if let Some(ref mut oracle) = self.oracle {
let (_accepted, _rejected, _mutations) = gate.dispatch_through_oracle(oracle, &mut self.scene);
oracle.end_frame();
oracle.begin_frame(self.tick);
}
if let Some(ref causal_observer_rx) = self.causal_observer_rx {
let gpu_events = causal_observer_rx.drain();
if !gpu_events.is_empty() {
log::trace!("causal_observer_lane: drained {} GPU frame events", gpu_events.len());
}
}
let tag_frame = self.evaluate_tag_influences(pos);
if let Some(ref mut bridge) = self.bridge {
bridge.set_tag_frame(tag_frame);
let (bp, _validation) = bridge.bridge(&encode_result, packet.dt, self.elapsed_time);
self.last_bridge_packet = Some(bp);
}
self.update_particle_siphon(pos, packet.dt);
self.observer.position = pos;
let result = encode_result.kernel_result;
self.last_result = Some(KernelResult {
position: result.position,
locomotion_mode: result.locomotion_mode,
form: result.form,
coherence: result.coherence,
populations: result.populations,
entropy: result.entropy,
purity: result.purity,
active_clip: String::new(),
moved: result.moved,
coalesce_events: Vec::new(),
topology_layer: result.topology_layer,
layer_changed: false,
});
if self.universe_connected {
if let Some(ref tx) = self.universe_update_tx {
if let Some(ref enc) = self.encoder {
let k = enc.kernel();
let update = dreamwell_universe::ClientUpdate {
client_id: self.universe_client_id,
populations: k.quantum.rho.populations(),
coherences: k.quantum.rho.off_diagonal_pairs(),
position: k.position,
layer: self.active_zone_index as u8,
frame: self.frame,
};
let _ = tx.try_send(update);
}
}
if let Some(ref rx) = self.universe_snapshot_rx {
if let Ok(snapshot) = rx.try_recv() {
if let Some(ref mut enc) = self.encoder {
let layer = self.active_zone_index;
let channel = &snapshot.channels[layer];
let coupling_eps = 0.03 * packet.dt;
let field_coh = channel.coherence_magnitude;
let rho = &mut enc.kernel_mut().quantum.rho;
for i in 0..5 {
for j in 0..5 {
if i != j {
let retain = 1.0 - coupling_eps * (1.0 - field_coh);
rho.entries[i * 5 + j] = rho.entries[i * 5 + j].scale(retain.max(0.0));
}
}
}
if self.frame % 300 == 0 {
log::info!(
"Universe sync: tick={} field_coh={:.4} field_F={:.4}",
snapshot.tick,
field_coh,
channel.free_energy,
);
}
}
}
}
}
Some(result)
}
fn observer_position(&self) -> Option<[f32; 3]> {
self.encoder
.as_ref()
.map(|e| e.kernel().position)
.or_else(|| self.kernel.as_ref().map(|k| k.position))
}
pub fn check_collisions(&self, threshold: f32) -> Vec<(u64, f32)> {
let pos = match self.observer_position() {
Some(p) => p,
None => return Vec::new(),
};
self.scene
.objects
.iter()
.filter_map(|o| {
let is_collider = o.property_tags.iter().any(|t| t == "isWall" || t == "isCollider");
if !is_collider {
return None;
}
let dx = o.transform.position[0] - pos[0];
let dy = o.transform.position[1] - pos[1];
let dz = o.transform.position[2] - pos[2];
let dist = (dx * dx + dy * dy + dz * dz).sqrt();
if dist <= threshold {
Some((o.id, dist))
} else {
None
}
})
.collect()
}
pub fn check_poi_proximity(&self, radius: f32) -> Vec<(u64, f32)> {
let pos = match self.observer_position() {
Some(p) => p,
None => return Vec::new(),
};
self.scene
.objects
.iter()
.filter_map(|o| {
let is_poi = o.property_tags.iter().any(|t| t == "poi" || t == "isInteractable");
if !is_poi {
return None;
}
let dx = o.transform.position[0] - pos[0];
let dy = o.transform.position[1] - pos[1];
let dz = o.transform.position[2] - pos[2];
let dist = (dx * dx + dy * dy + dz * dz).sqrt();
if dist <= radius {
Some((o.id, dist))
} else {
None
}
})
.collect()
}
pub fn tick_poi_interactions(&mut self) {
let pois = self.check_poi_proximity(5.0);
if pois.is_empty() {
return;
}
let gate = match &mut self.gate {
Some(g) => g,
None => return,
};
let decoherence = match &self.decoherence {
Some(d) => d,
None => return,
};
let tick = self.tick;
for (poi_id, dist) in &pois {
if *dist < 2.0 {
let weave = decoherence.build_interaction_weave(tick, *poi_id);
gate.submit(weave, 80);
}
}
}
pub fn tick_collisions(&mut self) {
let collisions = self.check_collisions(2.0);
if collisions.is_empty() {
return;
}
let kernel = if let Some(ref mut enc) = self.encoder {
enc.kernel_mut()
} else if let Some(ref mut k) = self.kernel {
k
} else {
return;
};
for (obj_id, dist) in &collisions {
if let Some(obj) = self.scene.find(*obj_id) {
if *dist < 0.01 {
continue;
}
let push_str = (1.0 - dist / 2.0).max(0.0) * 0.5;
let dx = kernel.position[0] - obj.transform.position[0];
let dz = kernel.position[2] - obj.transform.position[2];
let len = (dx * dx + dz * dz).sqrt().max(0.001);
kernel.position[0] += (dx / len) * push_str;
kernel.position[2] += (dz / len) * push_str;
}
}
}
fn evaluate_tag_influences(&self, pos: [f32; 3]) -> dreamwell_metaphors::TagInfluenceFrame {
let mut frame = dreamwell_metaphors::TagInfluenceFrame::empty();
let aoi_radius = self.quantum_cull_radius;
for obj in &self.scene.objects {
let is_poi = obj
.property_tags
.iter()
.any(|t| t == "isPointOfInterest" || t == "poi" || t == "isInteractable");
if !is_poi {
continue;
}
let dx = obj.transform.position[0] - pos[0];
let dy = obj.transform.position[1] - pos[1];
let dz = obj.transform.position[2] - pos[2];
let dist = (dx * dx + dy * dy + dz * dz).sqrt();
if dist > aoi_radius {
continue;
}
let coupling = (1.0 - dist / aoi_radius).max(0.0);
let siphon_eligible = obj.property_tags.iter().any(|t| t == "isSiphon" || t == "isFractal");
frame.poi_couplings.push(dreamwell_metaphors::PoiCoupling {
poi_id: obj.id,
distance: dist,
coupling,
siphon_eligible,
});
}
for obj in &self.scene.objects {
let is_zone = obj
.property_tags
.iter()
.any(|t| t.starts_with("isTopologyTransition") || t == "isDecoherenceZone");
if !is_zone {
continue;
}
let dx = obj.transform.position[0] - pos[0];
let dz = obj.transform.position[2] - pos[2];
let dist = (dx * dx + dz * dz).sqrt();
if dist > aoi_radius {
continue;
}
let proximity = (1.0 - dist / aoi_radius).max(0.0);
frame.zone_biases.push(dreamwell_metaphors::ZoneBias {
zone_id: obj.id,
morph_bias: proximity * 0.3,
coherence_bias: -proximity * 0.2, });
}
frame
}
fn update_particle_siphon(&mut self, pos: [f32; 3], dt: f32) {
let default_count = dreamwell_metaphors::DEFAULT_PARTICLE_COUNT as f32;
let siphon_rate = 30.0; let regen_rate = 10.0;
let mut total_siphon = 0.0f32;
for obj in &self.scene.objects {
let is_siphon = obj.property_tags.iter().any(|t| t == "isSiphon" || t == "isFractal");
if !is_siphon {
continue;
}
let dx = obj.transform.position[0] - pos[0];
let dy = obj.transform.position[1] - pos[1];
let dz = obj.transform.position[2] - pos[2];
let dist = (dx * dx + dy * dy + dz * dz).sqrt();
let coupling = (1.0 - dist / self.quantum_cull_radius).max(0.0);
if coupling > 0.1 {
total_siphon += coupling;
}
}
if total_siphon > 0.0 {
self.active_particle_count -= siphon_rate * total_siphon * dt;
} else if self.active_particle_count < default_count {
self.active_particle_count += regen_rate * dt;
}
self.active_particle_count = self.active_particle_count.clamp(16.0, default_count);
}
pub fn set_metaphor_profile(&mut self, profile: dreamwell_metaphors::MetaphorProfile) {
self.metaphor_profile = profile.clone();
if let Some(ref mut bridge) = self.bridge {
bridge.set_metaphor_profile(profile);
}
}
pub fn cycle_metaphor(&mut self) -> &'static str {
let new = dreamwell_metaphors::cycle_next(self.metaphor_profile.name);
let name = new.name;
self.set_metaphor_profile(new);
name
}
pub fn end_session(&mut self) {
if let (Some(ref decoherence), Some(ref mut oracle), Some(ref mut gate)) =
(&self.decoherence, &mut self.oracle, &mut self.gate)
{
let weave = decoherence.build_session_end_weave(self.tick);
gate.submit(weave, 100);
let _ = gate.dispatch_through_oracle(oracle, &mut self.scene);
}
self.readiness = RuntimeReadiness::Pending;
self.kernel = None;
self.encoder = None;
self.bridge = None;
self.last_bridge_packet = None;
self.decoherence = None;
self.oracle = None;
self.causal_observer_rx = None;
self.causal_observer_tx = None;
self.decoherence_fields.clear();
self.last_result = None;
self.last_descriptor = None;
self.console.push("[Info] Client closing.. Chronoshift success.".into());
self.console
.push("[Info] Reality checked and loaded. Editor session restored.".into());
self.journal.push(SimulationJournalEntry {
frame: self.frame,
kind: "end_session".into(),
detail: "play".into(),
});
}
}
#[cfg(test)]
mod tests {
use super::*;
fn test_scene() -> GameObjectScene {
let mut s = GameObjectScene::new("test".into());
s.spawn("Avatar Start".into()).unwrap();
s.objects[0].property_tags.push("isPlayer".into());
s.objects[0].property_tags.push("isInputReceiver".into());
s.objects[0].transform.position = [0.0, 0.5, 0.0];
s.spawn("Ground".into()).unwrap();
s.objects[1].property_tags.push("isStatic".into());
s.objects[1].property_tags.push("isGround".into());
s
}
#[test]
fn simulation_new() {
let sim = SimulationService::new("test", SimulationMode::Preview);
assert_eq!(sim.readiness, RuntimeReadiness::Pending);
assert!(!sim.input_enabled());
}
#[test]
fn simulation_initialize_7_steps() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
let scene = test_scene();
let result = sim.initialize(scene, [0.0, 0.5, 0.0], 128);
assert!(result.is_ok(), "init should succeed: {:?}", result.err());
assert_eq!(sim.readiness, RuntimeReadiness::Ready);
assert!(sim.input_enabled());
assert!(sim.kernel.is_some());
assert!(sim.encoder.is_some());
assert!(sim.bridge.is_some());
assert!(sim.decoherence.is_some());
assert!(sim.oracle.is_some());
assert!(sim.console.iter().any(|m| m.contains("Seer is happy")));
assert!(sim.console.iter().any(|m| m.contains("CausalComputeKernel")));
}
#[test]
fn simulation_input_gated_before_ready() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
let packet = InputPacket {
movement: [0.0, 1.0],
..InputPacket::idle(1.0 / 60.0, 0)
};
let result = sim.tick(&packet);
assert!(result.is_none(), "input should be gated before init");
}
#[test]
fn simulation_tick_moves_player() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
sim.initialize(test_scene(), [0.0, 0.5, 0.0], 128).unwrap();
let packet = InputPacket {
movement: [0.0, 1.0],
..InputPacket::idle(1.0 / 60.0, 1)
};
let result = sim.tick(&packet);
assert!(result.is_some());
let r = result.unwrap();
assert!(r.position != [0.0, 0.5, 0.0], "player should move after forward input");
}
#[test]
fn simulation_collision_detection() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
let mut scene = test_scene();
scene.spawn("Wall".into()).unwrap();
let wall_idx = scene.objects.len() - 1;
scene.objects[wall_idx].property_tags.push("isWall".into());
scene.objects[wall_idx].property_tags.push("isCollider".into());
scene.objects[wall_idx].transform.position = [0.5, 0.5, 0.0];
sim.initialize(scene, [0.0, 0.5, 0.0], 128).unwrap();
let collisions = sim.check_collisions(1.0);
assert!(!collisions.is_empty());
}
#[test]
fn simulation_poi_proximity() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
let mut scene = test_scene();
scene.spawn("POI".into()).unwrap();
let poi_idx = scene.objects.len() - 1;
scene.objects[poi_idx].property_tags.push("isInteractable".into());
scene.objects[poi_idx].transform.position = [0.0, 0.5, -1.0];
sim.initialize(scene, [0.0, 0.5, 0.0], 128).unwrap();
let pois = sim.check_poi_proximity(2.0);
assert!(!pois.is_empty());
}
#[test]
fn simulation_end_session() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
sim.initialize(test_scene(), [0.0, 0.5, 0.0], 128).unwrap();
sim.end_session();
assert_eq!(sim.readiness, RuntimeReadiness::Pending);
assert!(!sim.input_enabled());
assert!(sim.kernel.is_none());
assert!(sim.encoder.is_none());
assert!(sim.bridge.is_none());
assert!(sim.decoherence.is_none());
assert!(sim.oracle.is_none());
assert!(sim.console.iter().any(|m| m.contains("Chronoshift success")));
}
#[test]
fn simulation_empty_scene_fails() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
let scene = GameObjectScene::new("empty".into());
let result = sim.initialize(scene, [0.0; 3], 128);
assert!(result.is_err());
assert_eq!(sim.readiness, RuntimeReadiness::Failed);
}
#[test]
fn simulation_mode_variants() {
assert_ne!(SimulationMode::Preview, SimulationMode::Published);
}
#[test]
fn cycle_metaphor_changes_profile() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
sim.initialize(test_scene(), [0.0, 0.5, 0.0], 128).unwrap();
assert_eq!(sim.metaphor_profile.name, "wave");
let name = sim.cycle_metaphor();
assert_eq!(name, "keynote_fibonacci");
assert_eq!(sim.metaphor_profile.name, "keynote_fibonacci");
let name = sim.cycle_metaphor();
assert_eq!(name, "cohered_stream");
let name = sim.cycle_metaphor();
assert_eq!(name, "wave");
}
#[test]
fn default_profile_is_wave() {
let sim = SimulationService::new("test", SimulationMode::Preview);
assert_eq!(sim.metaphor_profile.name, "wave");
}
#[test]
fn simulation_quantum_cull_radius() {
let sim = SimulationService::new("test", SimulationMode::Preview);
assert!((sim.quantum_cull_radius - SimulationService::DEFAULT_QUANTUM_CULL_RADIUS).abs() < 0.01);
}
#[test]
fn simulation_observer_position_updates() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
sim.initialize(test_scene(), [0.0, 0.5, 0.0], 128).unwrap();
let packet = InputPacket {
movement: [0.0, 1.0],
..InputPacket::idle(1.0, 1)
};
sim.tick(&packet);
assert!(
sim.observer.position != [0.0, 0.5, 0.0],
"observer should follow kernel position"
);
}
#[test]
fn simulation_journal_records_lifecycle() {
let mut sim = SimulationService::new("test", SimulationMode::Preview);
sim.initialize(test_scene(), [0.0, 0.5, 0.0], 128).unwrap();
assert!(sim.journal.iter().any(|e| e.kind == "mount_braid"));
assert!(sim.journal.iter().any(|e| e.kind == "avatar_init"));
sim.end_session();
assert!(sim.journal.iter().any(|e| e.kind == "end_session"));
}
}