@crowdedkingdoms/crowdyjs 8.22.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/MIGRATION.md +44 -0
  2. package/README.md +74 -3
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/live-coding/assets/browser-authoring-index.json +1 -0
  7. package/dist/live-coding/assets/manifest.json +19 -0
  8. package/dist/live-coding/assets/tree-sitter-rust.wasm +0 -0
  9. package/dist/live-coding/assets/web-tree-sitter.wasm +0 -0
  10. package/dist/live-coding/browser-authoring-index.generated.d.ts +2 -0
  11. package/dist/live-coding/browser-authoring-index.generated.d.ts.map +1 -0
  12. package/dist/live-coding/browser-authoring-index.generated.js +5127 -0
  13. package/dist/live-coding/ide.d.ts +14 -7
  14. package/dist/live-coding/ide.d.ts.map +1 -1
  15. package/dist/live-coding/ide.js +296 -181
  16. package/dist/live-coding/index.d.ts +8 -0
  17. package/dist/live-coding/index.d.ts.map +1 -0
  18. package/dist/live-coding/index.js +7 -0
  19. package/dist/live-coding/lsp-protocol.d.ts +98 -0
  20. package/dist/live-coding/lsp-protocol.d.ts.map +1 -0
  21. package/dist/live-coding/lsp-protocol.js +70 -0
  22. package/dist/live-coding/monaco-services.d.ts +22 -0
  23. package/dist/live-coding/monaco-services.d.ts.map +1 -0
  24. package/dist/live-coding/monaco-services.js +69 -0
  25. package/dist/live-coding/platform-index.d.ts +29 -0
  26. package/dist/live-coding/platform-index.d.ts.map +1 -0
  27. package/dist/live-coding/platform-index.js +281 -0
  28. package/dist/live-coding/rust-analysis.d.ts +24 -0
  29. package/dist/live-coding/rust-analysis.d.ts.map +1 -0
  30. package/dist/live-coding/rust-analysis.js +312 -0
  31. package/dist/live-coding/rust-lsp-server.d.ts +43 -0
  32. package/dist/live-coding/rust-lsp-server.d.ts.map +1 -0
  33. package/dist/live-coding/rust-lsp-server.js +455 -0
  34. package/dist/live-coding/rust-lsp.worker.d.ts +2 -0
  35. package/dist/live-coding/rust-lsp.worker.d.ts.map +1 -0
  36. package/dist/live-coding/rust-lsp.worker.js +26 -0
  37. package/dist/live-coding/vfs.d.ts +41 -0
  38. package/dist/live-coding/vfs.d.ts.map +1 -0
  39. package/dist/live-coding/vfs.js +174 -0
  40. package/dist/live-coding/worker-transport.d.ts +60 -0
  41. package/dist/live-coding/worker-transport.d.ts.map +1 -0
  42. package/dist/live-coding/worker-transport.js +204 -0
  43. package/package.json +18 -6
@@ -0,0 +1 @@
1
+ {"schemaVersion":2,"rustVersion":"1.97.1","sdkVersion":"0.1.5","abiVersion":0,"contentHash":"3f5f39d46f732a346033aaf2435528a183e2ab0d0e3691f29c3fa3ecada18ffb","crates":[{"name":"alloc","version":"1.97.1","sourceHash":"7386c02231ab279f515a3768adc6662d2f043ef8ab3a9f88af6b38c1c226a7eb"},{"name":"core","version":"1.97.1","sourceHash":"7386c02231ab279f515a3768adc6662d2f043ef8ab3a9f88af6b38c1c226a7eb"},{"name":"crowdy-compute-sdk","version":"0.1.5","sourceHash":"a43147b89a4ec0ca03cc1e7d15a7cc858df36faa2f1f486cb536342155615852"},{"name":"crowdy-game-kit-ai","version":"0.1.0","sourceHash":"2b79f93f0d7369ceb0aae6cf32cf6bab614170e63a389fbd5da5a1e7266ad5a0"},{"name":"crowdy-game-kit-core","version":"0.1.0","sourceHash":"9750b5294348076d2b75cc67229cdb9e198ed6c2fbc4d76adc063e7124c9e84d"},{"name":"crowdy-game-kit-econ","version":"0.1.0","sourceHash":"01745622dea7ef772bba6d1b0360b7cf289b54a90635de13fe38559dc4a01fed"},{"name":"crowdy-game-kit-play","version":"0.1.0","sourceHash":"90f6eb0336be680c1eb901ae471ce3c2ab657d46dd3d186adfde25eb1c938c15"},{"name":"crowdy-game-kit-sim","version":"0.1.0","sourceHash":"21ed84dc3f7422970c42a3e4a0824cd52b787d4c7a266bec3ccd19bfa45641ab"}],"symbols":[{"module":"alloc","name":"format","kind":"macro","signature":"format!(format_string, ...)","docs":"Creates a formatted String."},{"module":"alloc","name":"vec","kind":"macro","signature":"vec![values...]","docs":"Creates a Vec from values or a repeated value."},{"module":"alloc::boxed","name":"Box","kind":"struct","signature":"pub struct Box<T>","docs":"An owned heap allocation."},{"module":"alloc::string","name":"String","kind":"struct","signature":"pub struct String","docs":"A UTF-8 encoded growable string."},{"module":"alloc::vec","name":"Vec","kind":"struct","signature":"pub struct Vec<T>","docs":"A contiguous growable array."},{"module":"core","name":"assert","kind":"macro","signature":"assert!(condition[, message])","docs":"Panics when a condition is false."},{"module":"core","name":"assert_eq","kind":"macro","signature":"assert_eq!(left, right[, message])","docs":"Panics when two expressions are not equal."},{"module":"core","name":"matches","kind":"macro","signature":"matches!(expression, pattern [if guard])","docs":"Checks whether an expression matches a pattern."},{"module":"core","name":"panic","kind":"macro","signature":"panic!([message])","docs":"Terminates the current execution with an error."},{"module":"core::mem","name":"drop","kind":"function","signature":"pub fn drop<T>(_x: T)","docs":"Consumes and drops a value."},{"module":"core::mem","name":"forget","kind":"function","signature":"pub const fn forget<T>(t: T)","docs":"Consumes a value without running its destructor."},{"module":"core::prelude::v1","name":"Clone","kind":"trait","signature":"pub trait Clone { fn clone(&self) -> Self; }","docs":"Explicitly duplicates a value."},{"module":"core::prelude::v1","name":"Copy","kind":"trait","signature":"pub trait Copy: Clone","docs":"Marks values duplicated by assignment."},{"module":"core::prelude::v1","name":"Default","kind":"trait","signature":"pub trait Default { fn default() -> Self; }","docs":"Constructs a useful default value."},{"module":"core::prelude::v1","name":"Err","kind":"variant","signature":"Err(E) -> Result<T, E>","docs":"Constructs an error Result value."},{"module":"core::prelude::v1","name":"IntoIterator","kind":"trait","signature":"pub trait IntoIterator { type Item; type IntoIter: Iterator<Item = Self::Item>; }","docs":"Converts a value into an iterator."},{"module":"core::prelude::v1","name":"Iterator","kind":"trait","signature":"pub trait Iterator { type Item; fn next(&mut self) -> Option<Self::Item>; }","docs":"Produces a sequence of values."},{"module":"core::prelude::v1","name":"None","kind":"variant","signature":"None -> Option<T>","docs":"Constructs an absent Option value."},{"module":"core::prelude::v1","name":"Ok","kind":"variant","signature":"Ok(T) -> Result<T, E>","docs":"Constructs a successful Result value."},{"module":"core::prelude::v1","name":"Option","kind":"enum","signature":"pub enum Option<T> { None, Some(T) }","docs":"An optional value."},{"module":"core::prelude::v1","name":"Result","kind":"enum","signature":"pub enum Result<T, E> { Ok(T), Err(E) }","docs":"A success value or an error."},{"module":"core::prelude::v1","name":"Some","kind":"variant","signature":"Some(T) -> Option<T>","docs":"Constructs a present Option value."},{"module":"core::slice","name":"from_raw_parts","kind":"function","signature":"pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]","docs":"Forms a slice from a pointer and element count."},{"module":"crowdy_compute_sdk","name":"ABI_VERSION","kind":"const","signature":"pub const ABI_VERSION: u32 = 0;","docs":""},{"module":"crowdy_compute_sdk","name":"HostError","kind":"struct","signature":"pub struct HostError { pub kind: String, #[serde(default)] pub message: Option<String>, }","docs":"A structured error from the host API."},{"module":"crowdy_compute_sdk","name":"HostError::fmt","kind":"method","signature":"fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result","docs":""},{"module":"crowdy_compute_sdk","name":"HostError::kind","kind":"field","signature":"pub kind: String","docs":""},{"module":"crowdy_compute_sdk","name":"HostError::message","kind":"field","signature":"pub message: Option<String>","docs":""},{"module":"crowdy_compute_sdk","name":"api","kind":"module","signature":"pub mod api","docs":"Typed wrappers over the v1 host API. Everything is scoped to the module's own app by the host; ids are stringified where they may exceed 2^53."},{"module":"crowdy_compute_sdk","name":"ck_alloc","kind":"function","signature":"pub extern \"C\" fn ck_alloc(len: u32) -> *mut u8","docs":"Allocate a buffer the host can write into before calling an export."},{"module":"crowdy_compute_sdk","name":"ck_free","kind":"function","signature":"pub unsafe extern \"C\" fn ck_free(ptr: *mut u8, len: u32)","docs":"Release a buffer previously handed across the boundary. # Safety `ptr`/`len` must come from `ck_alloc` or a packed return value."},{"module":"crowdy_compute_sdk","name":"host","kind":"module","signature":"pub mod host","docs":"Host imports (module namespace `ck`)."},{"module":"crowdy_compute_sdk","name":"host_call","kind":"function","signature":"pub fn host_call( fn_name: &str, args: serde_json::Value, ) -> Result<serde_json::Value, HostError>","docs":"Call a host API function with JSON args; returns the `data` payload."},{"module":"crowdy_compute_sdk","name":"input_slice","kind":"function","signature":"pub unsafe fn input_slice<'a>(ptr: *const u8, len: u32) -> &'a [u8]","docs":"View a host-provided buffer. # Safety `ptr`/`len` must describe a live buffer in guest memory."},{"module":"crowdy_compute_sdk","name":"log","kind":"function","signature":"pub fn log(level: u32, msg: &str)","docs":""},{"module":"crowdy_compute_sdk","name":"now_ms","kind":"function","signature":"pub fn now_ms() -> u64","docs":""},{"module":"crowdy_compute_sdk","name":"pack_return","kind":"function","signature":"pub fn pack_return(bytes: Vec<u8>) -> u64","docs":"Leak `bytes` and pack its (ptr, len) into the u64 return convention."},{"module":"crowdy_compute_sdk","name":"random_bytes","kind":"function","signature":"pub fn random_bytes(len: usize) -> Vec<u8>","docs":"Host-seeded random bytes (via the deterministic WASI stub)."},{"module":"crowdy_compute_sdk","name":"register_module","kind":"macro","signature":"macro_rules! register_module { (init: $init:path, tick: $tick:path, invoke: $invoke:path $(,)?) => { $crate::__register_module_core!($init, $tick, $invoke); }; (init: $init:path, tick: $tick:path, invoke: $invoke:path, event: $event:path $(,)?) => { $crate::__register_module_core!($init, $tick, $invoke); #[export_name = \"on_event\"] pub extern \"C\" fn __ck_export_on_event(ptr: *const u8, len: u32) { let input = unsafe { $crate::input_slice(ptr, len) }; $event(input); } }; }","docs":"Wires user functions to the ABI exports the host calls: `init()`, `tick(dt_ms)`, `handle_invoke(ptr, len) -> packed u64`, and (4-arg form) `on_event(ptr, len)` for event triggers. Modules registered with the 3-arg form export no `on_event`; the host skips event dispatch."},{"module":"crowdy_compute_sdk","name":"state_get","kind":"function","signature":"pub fn state_get() -> Vec<u8>","docs":"Read the module's durable state blob (empty vec when unset)."},{"module":"crowdy_compute_sdk","name":"state_set","kind":"function","signature":"pub fn state_set(bytes: &[u8]) -> bool","docs":"Replace the module's durable state blob. Returns false when over the cap."},{"module":"crowdy_compute_sdk::api","name":"Predicate","kind":"struct","signature":"pub struct Predicate { pub key: String, pub op: String, pub value: Value, }","docs":"One property predicate for `containers_list_where` (the automation selector shape): compare `key` against a JSON `value` with `==`, `!=`, `<`, `>`, `<=` or `>=`. Missing properties fall back to the type default."},{"module":"crowdy_compute_sdk::api","name":"Predicate::key","kind":"field","signature":"pub key: String","docs":""},{"module":"crowdy_compute_sdk::api","name":"Predicate::new","kind":"method","signature":"pub fn new(key: &str, op: &str, value: Value) -> Self","docs":""},{"module":"crowdy_compute_sdk::api","name":"Predicate::op","kind":"field","signature":"pub op: String","docs":""},{"module":"crowdy_compute_sdk::api","name":"Predicate::value","kind":"field","signature":"pub value: Value","docs":""},{"module":"crowdy_compute_sdk::api","name":"WorldWrite","kind":"struct","signature":"pub struct WorldWrite { pub chunk: (i64, i64, i64), pub voxel: (u8, u8, u8), pub voxel_type: i32, /// Optional voxel state blob (base64). pub state_base64: Option<String>, }","docs":"One atomic voxel write carried by `model_invoke_with_world` (the same shape `voxel_set` takes; committed on the Model transaction)."},{"module":"crowdy_compute_sdk::api","name":"WorldWrite::chunk","kind":"field","signature":"pub chunk: (i64, i64, i64)","docs":""},{"module":"crowdy_compute_sdk::api","name":"WorldWrite::state_base64","kind":"field","signature":"pub state_base64: Option<String>","docs":"Optional voxel state blob (base64)."},{"module":"crowdy_compute_sdk::api","name":"WorldWrite::voxel","kind":"field","signature":"pub voxel: (u8, u8, u8)","docs":""},{"module":"crowdy_compute_sdk::api","name":"WorldWrite::voxel_type","kind":"field","signature":"pub voxel_type: i32","docs":""},{"module":"crowdy_compute_sdk::api","name":"actors_list","kind":"function","signature":"pub fn actors_list(x: i64, y: i64, z: i64) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"actors_list_radius","kind":"function","signature":"pub fn actors_list_radius( x: i64, y: i64, z: i64, radius_xz: u8, radius_y: u8, ) -> Result<Value, HostError>","docs":"Actors in a chunk box around (x,y,z): radiusXz clamped to 3, radiusY to 1 host-side; rows include chunk coords. One db-op. Requires SDK 0.1.2+ on the host."},{"module":"crowdy_compute_sdk::api","name":"avatar_state_get","kind":"function","signature":"pub fn avatar_state_get(avatar_id: &str) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"chunk_get","kind":"function","signature":"pub fn chunk_get(x: i64, y: i64, z: i64) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"container_create","kind":"function","signature":"pub fn container_create( type_name: &str, session_id: Option<&str>, properties: Value, ) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"container_create_for","kind":"function","signature":"pub fn container_create_for( type_name: &str, display_name: &str, session_id: Option<&str>, owner_user_id: Option<&str>, properties: Value, ) -> Result<Value, HostError>","docs":"Create a container with explicit display name / owner. The module is a trusted app-scoped writer; use this for referee-created reward stacks and other durable rows that must participate in owner-gated Model transactions."},{"module":"crowdy_compute_sdk::api","name":"container_delete","kind":"function","signature":"pub fn container_delete(container_id: &str) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"container_get","kind":"function","signature":"pub fn container_get(container_id: &str) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"container_get_batch","kind":"function","signature":"pub fn container_get_batch(container_ids: &[&str]) -> Result<Value, HostError>","docs":"Batched container_get: up to 32 ids -> [{container, properties}] in one db-op. Requires SDK 0.1.2+ on the host."},{"module":"crowdy_compute_sdk::api","name":"containers_list","kind":"function","signature":"pub fn containers_list( type_name: Option<&str>, session_id: Option<&str>, ) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"containers_list_where","kind":"function","signature":"pub fn containers_list_where( type_name: Option<&str>, session_id: Option<&str>, wher: &[Predicate], limit: Option<u32>, offset: Option<u32>, ) -> Result<Value, HostError>","docs":"Filtered/paged container list: up to 8 AND-combined property predicates evaluated host-side (requires `type_name`), then offset/limit over the stable created-at ordering (limit clamps to 200). Charges 2 data ops when predicates are present (list + property batch), 1 otherwise. Requires SDK 0.1.5+ on the host."},{"module":"crowdy_compute_sdk::api","name":"edge_add","kind":"function","signature":"pub fn edge_add( from_container_id: &str, to_container_id: &str, relationship_type: &str, ) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"edge_delete","kind":"function","signature":"pub fn edge_delete( from_container_id: &str, to_container_id: &str, relationship_type: &str, ) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"emit_channel","kind":"function","signature":"pub fn emit_channel(channel_id: &str, payload_base64: &str) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"emit_event","kind":"function","signature":"pub fn emit_event(name: &str, payload: Value) -> Result<Value, HostError>","docs":"Emit a compute event other modules (or this one) can subscribe to via an on_event=compute_event trigger. Cascade depth is host-bounded."},{"module":"crowdy_compute_sdk::api","name":"emit_spatial","kind":"function","signature":"pub fn emit_spatial( kind: &str, chunk: (i64, i64, i64), uuid_hex: &str, payload_base64: &str, distance: u8, decay: u8, ) -> Result<Value, HostError>","docs":"kind: \"actor\" | \"voxel\" | \"client_event\" | \"server_event\" (host maps to the inject opcode). uuid_hex: 64 hex chars (32 bytes); payload <= 1024B."},{"module":"crowdy_compute_sdk::api","name":"grid_permission_check","kind":"function","signature":"pub fn grid_permission_check( user_id: &str, grid_id: &str, permission_key: &str, ) -> Result<bool, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"grid_state_get","kind":"function","signature":"pub fn grid_state_get(grid_id: &str) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"grid_state_set","kind":"function","signature":"pub fn grid_state_set(grid_id: &str, state_base64: &str) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"model_invoke","kind":"function","signature":"pub fn model_invoke( function_name: &str, self_container_id: &str, params: Value, session_id: Option<&str>, caller_user_id: Option<&str>, ) -> Result<Value, HostError>","docs":"Invoke an autonomous-invocable Model function transactionally from a trusted compute module. With `caller_user_id`, the Model invoke policy is evaluated as that gameplay user (callerKind=automation); `None` uses the trusted server path. The returned value is the ordinary GmInvokeResult JSON shape."},{"module":"crowdy_compute_sdk::api","name":"model_invoke_with_world","kind":"function","signature":"pub fn model_invoke_with_world( function_name: &str, self_container_id: &str, params: Value, session_id: Option<&str>, caller_user_id: Option<&str>, world_writes: &[WorldWrite], ) -> Result<Value, HostError>","docs":"`model_invoke` with atomic world writes: the voxel writes and the Model function's mutations commit in ONE transaction — if either side fails, both roll back. Use for referee actions that change the world and the ledger together (mine/place). Up to 16 writes per call; each write charges a db op. Requires SDK 0.1.4+ on the host."},{"module":"crowdy_compute_sdk::api","name":"property_set","kind":"function","signature":"pub fn property_set( container_id: &str, key: &str, value_type: &str, value: Value, ) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"sessions_list","kind":"function","signature":"pub fn sessions_list(status: Option<&str>) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"user_state_get","kind":"function","signature":"pub fn user_state_get(user_id: &str) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"user_state_set","kind":"function","signature":"pub fn user_state_set(user_id: &str, state_base64: &str) -> Result<Value, HostError>","docs":"state is base64-encoded bytes."},{"module":"crowdy_compute_sdk::api","name":"voxel_set","kind":"function","signature":"pub fn voxel_set( chunk: (i64, i64, i64), voxel: (u8, u8, u8), voxel_type: i32, state_base64: Option<&str>, ) -> Result<Value, HostError>","docs":""},{"module":"crowdy_compute_sdk::api","name":"voxels_list","kind":"function","signature":"pub fn voxels_list(x: i64, y: i64, z: i64) -> Result<Value, HostError>","docs":"List the voxels recorded in one chunk (capped host-side; voxelType + optional stateBase64 per voxel). Requires SDK 0.1.1+ on the host."},{"module":"crowdy_compute_sdk::host","name":"host_call","kind":"function","signature":"pub fn host_call(ptr: *const u8, len: u32) -> u64;","docs":"Synchronous host API gateway: JSON request in guest memory, returns packed (resp_ptr << 32 | resp_len); the guest frees the response buffer. Carries a fuel surcharge per call + byte."},{"module":"crowdy_compute_sdk::host","name":"log","kind":"function","signature":"pub fn log(level: u32, ptr: *const u8, len: u32);","docs":"level: 0=debug 1=info 2=warn 3=error"},{"module":"crowdy_compute_sdk::host","name":"now_ms","kind":"function","signature":"pub fn now_ms() -> u64;","docs":"Host-controlled clock (ms). Deterministic from the guest's view."},{"module":"crowdy_compute_sdk::host","name":"state_get","kind":"function","signature":"pub fn state_get(dest: *mut u8, cap: u32) -> u32;","docs":"Copy up to `cap` bytes of the module's durable state blob into `dest`. Returns the blob's full length (call with cap=0 to size)."},{"module":"crowdy_compute_sdk::host","name":"state_set","kind":"function","signature":"pub fn state_set(ptr: *const u8, len: u32) -> u32;","docs":"Replace the module's durable state blob. Returns 0 on success, 1 when the blob exceeds the platform cap."},{"module":"crowdy_game_kit_ai","name":"brain","kind":"module","signature":"pub mod brain;","docs":""},{"module":"crowdy_game_kit_ai","name":"core","kind":"reexport","signature":"pub use crowdy_game_kit_core as core;","docs":""},{"module":"crowdy_game_kit_ai","name":"flow","kind":"module","signature":"pub mod flow;","docs":""},{"module":"crowdy_game_kit_ai","name":"path","kind":"module","signature":"pub mod path;","docs":""},{"module":"crowdy_game_kit_ai","name":"steering","kind":"module","signature":"pub mod steering;","docs":""},{"module":"crowdy_game_kit_ai","name":"turn","kind":"module","signature":"pub mod turn;","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"AgentMemory","kind":"struct","signature":"pub struct AgentMemory { pub target: Option<(f32, f32)>, pub retarget_at_ms: u64, pub patrol_index: usize, pub pause_until_ms: u64, }","docs":"Per-agent mutable memory the tree reads/writes across ticks (serde-able into engine state)."},{"module":"crowdy_game_kit_ai::brain","name":"AgentMemory::patrol_index","kind":"field","signature":"pub patrol_index: usize","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"AgentMemory::pause_until_ms","kind":"field","signature":"pub pause_until_ms: u64","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"AgentMemory::retarget_at_ms","kind":"field","signature":"pub retarget_at_ms: u64","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"AgentMemory::target","kind":"field","signature":"pub target: Option<(f32, f32)>","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"Decision","kind":"enum","signature":"pub enum Decision { Idle, /// Move by this bounded step. Step(Vec2), /// Nothing matched / tree invalid — caller may fall back. None, }","docs":"What the agent decided to do this tick."},{"module":"crowdy_game_kit_ai::brain","name":"Decision::Idle","kind":"variant","signature":"Idle","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"Decision::None","kind":"variant","signature":"None","docs":"Nothing matched / tree invalid — caller may fall back."},{"module":"crowdy_game_kit_ai::brain","name":"Decision::Step","kind":"variant","signature":"Step(Vec2)","docs":"Move by this bounded step."},{"module":"crowdy_game_kit_ai::brain","name":"Perception","kind":"struct","signature":"pub struct Perception { pub pos: Vec2, pub home: Vec2, /// Nearest player position, when one is visible. pub nearest_player: Option<Vec2>, /// Owner position (pets), when known. pub owner: Option<Vec2>, pub is_night: bool, pub speed: f32, pub dt: f32, pub now_ms: u64, /// Two uniform rolls in [0,1) for this tick (from the engine's seeded RNG). pub roll: (f32, f32), /// World half-extent for wander clamping. pub bounds: f32, }","docs":"Everything a tree evaluation may look at (the engine fills this in)."},{"module":"crowdy_game_kit_ai::brain","name":"Perception::bounds","kind":"field","signature":"pub bounds: f32","docs":"World half-extent for wander clamping."},{"module":"crowdy_game_kit_ai::brain","name":"Perception::dt","kind":"field","signature":"pub dt: f32","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"Perception::home","kind":"field","signature":"pub home: Vec2","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"Perception::is_night","kind":"field","signature":"pub is_night: bool","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"Perception::nearest_player","kind":"field","signature":"pub nearest_player: Option<Vec2>","docs":"Nearest player position, when one is visible."},{"module":"crowdy_game_kit_ai::brain","name":"Perception::now_ms","kind":"field","signature":"pub now_ms: u64","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"Perception::owner","kind":"field","signature":"pub owner: Option<Vec2>","docs":"Owner position (pets), when known."},{"module":"crowdy_game_kit_ai::brain","name":"Perception::pos","kind":"field","signature":"pub pos: Vec2","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"Perception::roll","kind":"field","signature":"pub roll: (f32, f32)","docs":"Two uniform rolls in [0,1) for this tick (from the engine's seeded RNG)."},{"module":"crowdy_game_kit_ai::brain","name":"Perception::speed","kind":"field","signature":"pub speed: f32","docs":""},{"module":"crowdy_game_kit_ai::brain","name":"builtin_tree","kind":"function","signature":"pub fn builtin_tree(name: &str) -> Option<Value>","docs":"Canonical trees for the built-in behavior names games store on defs (BWF's `wander_passive` / `wander_hostile` / `chase_hostile` strings finally mean something)."},{"module":"crowdy_game_kit_ai::brain","name":"evaluate","kind":"function","signature":"pub fn evaluate(tree: &Value, p: &Perception, memory: &mut AgentMemory) -> Decision","docs":""},{"module":"crowdy_game_kit_ai::flow","name":"FlowField","kind":"struct","signature":"pub struct FlowField { pub min_x: i32, pub min_z: i32, pub width: i32, pub height: i32, /// Distance to the nearest goal per cell; u32::MAX = unreachable/blocked. distances: Vec<u32>, }","docs":"A baked distance field over a bounded grid window. Serde-able so engines can persist it, but rebuilding from the provider is usually cheaper than storing it durably."},{"module":"crowdy_game_kit_ai::flow","name":"FlowField::build","kind":"method","signature":"pub fn build( provider: &impl CostProvider, window: (i32, i32, i32, i32), // min_x, min_z, width, height goals: &[(i32, i32)], max_cells: usize, ) -> Self","docs":"Build the field inside the window from the goal cells outward, respecting the provider's blocked cells. Cost = uniform 1 per step (weighted providers still gate walkability; weighting the descent is deliberately v2). `max_cells` caps the BFS for fuel safety."},{"module":"crowdy_game_kit_ai::flow","name":"FlowField::distance","kind":"method","signature":"pub fn distance(&self, x: i32, z: i32) -> Option<u32>","docs":"Distance to the nearest goal (None outside the window or unreachable)."},{"module":"crowdy_game_kit_ai::flow","name":"FlowField::height","kind":"field","signature":"pub height: i32","docs":""},{"module":"crowdy_game_kit_ai::flow","name":"FlowField::min_x","kind":"field","signature":"pub min_x: i32","docs":""},{"module":"crowdy_game_kit_ai::flow","name":"FlowField::min_z","kind":"field","signature":"pub min_z: i32","docs":""},{"module":"crowdy_game_kit_ai::flow","name":"FlowField::step","kind":"method","signature":"pub fn step(&self, x: i32, z: i32) -> Option<(i32, i32)>","docs":"The descending step from (x, z): the 4-neighbor with the smallest distance, when strictly smaller than here. None at goals/unreachable."},{"module":"crowdy_game_kit_ai::flow","name":"FlowField::walk","kind":"method","signature":"pub fn walk(&self, mut x: i32, mut z: i32, max_steps: usize) -> Vec<(i32, i32)>","docs":"Follow the field from (x, z) for up to `max_steps`, returning the walked cells (excluding the start). Agents usually take 1 per tick; this helper powers tests and catch-up moves."},{"module":"crowdy_game_kit_ai::flow","name":"FlowField::width","kind":"field","signature":"pub width: i32","docs":""},{"module":"crowdy_game_kit_ai::path","name":"CostProvider","kind":"trait","signature":"pub trait CostProvider","docs":"Walkability/cost source. Implement over your world representation (obstacle grids, voxel columns, nav data in module state)."},{"module":"crowdy_game_kit_ai::path","name":"CostProvider::cost","kind":"method","signature":"fn cost(&self, x: i32, z: i32) -> Option<u32>;","docs":"Cost to ENTER (x, z); `None` = blocked. Uniform worlds return Some(1)."},{"module":"crowdy_game_kit_ai::path","name":"GridProvider","kind":"struct","signature":"pub struct GridProvider<'a> { pub width: i32, pub height: i32, pub blocked: &'a dyn Fn(i32, i32) -> bool, }","docs":"A grid of booleans (true = blocked) — the simplest provider, also the test fixture."},{"module":"crowdy_game_kit_ai::path","name":"GridProvider::blocked","kind":"field","signature":"pub blocked: &'a dyn Fn(i32, i32) -> bool","docs":""},{"module":"crowdy_game_kit_ai::path","name":"GridProvider::cost","kind":"method","signature":"fn cost(&self, x: i32, z: i32) -> Option<u32>","docs":""},{"module":"crowdy_game_kit_ai::path","name":"GridProvider::height","kind":"field","signature":"pub height: i32","docs":""},{"module":"crowdy_game_kit_ai::path","name":"GridProvider::width","kind":"field","signature":"pub width: i32","docs":""},{"module":"crowdy_game_kit_ai::path","name":"PathCache","kind":"struct","signature":"pub struct PathCache { generation: u64, entries: std::collections::HashMap<((i32, i32), (i32, i32)), (u64, Vec<(i32, i32)>)>, }","docs":"A generation-keyed path cache: repeated queries between the same cells reuse the stored path until the world changes (`invalidate()` on any voxel/tower edit bumps the generation and lazily discards entries)."},{"module":"crowdy_game_kit_ai::path","name":"PathCache::get","kind":"method","signature":"pub fn get( &mut self, provider: &impl CostProvider, from: (i32, i32), to: (i32, i32), config: &PathConfig, ) -> Vec<(i32, i32)>","docs":"Cached path or compute-and-store via [`a_star`]."},{"module":"crowdy_game_kit_ai::path","name":"PathCache::invalidate","kind":"method","signature":"pub fn invalidate(&mut self)","docs":"Drop every cached path (world changed)."},{"module":"crowdy_game_kit_ai::path","name":"PathCache::new","kind":"method","signature":"pub fn new() -> Self","docs":""},{"module":"crowdy_game_kit_ai::path","name":"PathConfig","kind":"struct","signature":"pub struct PathConfig { /// Max nodes expanded before giving up (the fuel guard). ~4x the /// manhattan distance is plenty for sane worlds. pub max_expanded: usize, }","docs":""},{"module":"crowdy_game_kit_ai::path","name":"PathConfig::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_ai::path","name":"PathConfig::max_expanded","kind":"field","signature":"pub max_expanded: usize","docs":"Max nodes expanded before giving up (the fuel guard). ~4x the manhattan distance is plenty for sane worlds."},{"module":"crowdy_game_kit_ai::path","name":"a_star","kind":"function","signature":"pub fn a_star( provider: &impl CostProvider, from: (i32, i32), to: (i32, i32), config: &PathConfig, ) -> Vec<(i32, i32)>","docs":"4-connected A*. Returns the path INCLUDING both endpoints, or empty when unreachable / budget-exhausted / endpoints blocked."},{"module":"crowdy_game_kit_ai::steering","name":"Vec2","kind":"struct","signature":"pub struct Vec2 { pub x: f32, pub z: f32, }","docs":""},{"module":"crowdy_game_kit_ai::steering","name":"Vec2::clamped","kind":"method","signature":"pub fn clamped(self, max: f32) -> Vec2","docs":"Clamp this displacement to at most `max` length."},{"module":"crowdy_game_kit_ai::steering","name":"Vec2::dist","kind":"method","signature":"pub fn dist(&self, other: Vec2) -> f32","docs":""},{"module":"crowdy_game_kit_ai::steering","name":"Vec2::len","kind":"method","signature":"pub fn len(&self) -> f32","docs":""},{"module":"crowdy_game_kit_ai::steering","name":"Vec2::new","kind":"method","signature":"pub fn new(x: f32, z: f32) -> Self","docs":""},{"module":"crowdy_game_kit_ai::steering","name":"Vec2::to","kind":"method","signature":"pub fn to(self, other: Vec2) -> Vec2","docs":""},{"module":"crowdy_game_kit_ai::steering","name":"Vec2::x","kind":"field","signature":"pub x: f32","docs":""},{"module":"crowdy_game_kit_ai::steering","name":"Vec2::yaw","kind":"method","signature":"pub fn yaw(&self) -> f32","docs":""},{"module":"crowdy_game_kit_ai::steering","name":"Vec2::z","kind":"field","signature":"pub z: f32","docs":""},{"module":"crowdy_game_kit_ai::steering","name":"arrive","kind":"function","signature":"pub fn arrive(pos: Vec2, target: Vec2, speed: f32, dt: f32, slow_radius: f32) -> Vec2","docs":"Seek that decelerates inside `slow_radius` (smooth stops)."},{"module":"crowdy_game_kit_ai::steering","name":"flee","kind":"function","signature":"pub fn flee(pos: Vec2, threat: Vec2, speed: f32, dt: f32) -> Vec2","docs":"Step directly away from `threat`."},{"module":"crowdy_game_kit_ai::steering","name":"leash","kind":"function","signature":"pub fn leash(pos: Vec2, home: Vec2, leash_radius: f32, speed: f32, dt: f32) -> Option<Vec2>","docs":"Return-home pull when beyond `leash_radius`; `None` inside the leash."},{"module":"crowdy_game_kit_ai::steering","name":"seek","kind":"function","signature":"pub fn seek(pos: Vec2, target: Vec2, speed: f32, dt: f32, stop_at: f32) -> Vec2","docs":"Step toward `target` at up to `speed*dt`, stopping within `stop_at`."},{"module":"crowdy_game_kit_ai::steering","name":"separate","kind":"function","signature":"pub fn separate(pos: Vec2, neighbors: &[Vec2], min_dist: f32, speed: f32, dt: f32) -> Vec2","docs":"Push away from any neighbor closer than `min_dist` (crowd separation)."},{"module":"crowdy_game_kit_ai::steering","name":"wander_target","kind":"function","signature":"pub fn wander_target(anchor: Vec2, range: f32, roll_x: f32, roll_z: f32, bounds: f32) -> Vec2","docs":"A wander target picker: a point within `range` of `anchor`, clamped to `bounds` (half-extent box around origin). Pure — feed it your RNG rolls."},{"module":"crowdy_game_kit_ai::turn","name":"Candidate","kind":"struct","signature":"pub struct Candidate { pub x: i32, pub z: i32, /// Movement cost spent to reach it. pub cost: u32, }","docs":"One candidate destination for a turn move."},{"module":"crowdy_game_kit_ai::turn","name":"Candidate::cost","kind":"field","signature":"pub cost: u32","docs":"Movement cost spent to reach it."},{"module":"crowdy_game_kit_ai::turn","name":"Candidate::x","kind":"field","signature":"pub x: i32","docs":""},{"module":"crowdy_game_kit_ai::turn","name":"Candidate::z","kind":"field","signature":"pub z: i32","docs":""},{"module":"crowdy_game_kit_ai::turn","name":"TurnMove","kind":"struct","signature":"pub struct TurnMove { pub to: (i32, i32), pub score: f32, }","docs":"The chosen move for a turn."},{"module":"crowdy_game_kit_ai::turn","name":"TurnMove::score","kind":"field","signature":"pub score: f32","docs":""},{"module":"crowdy_game_kit_ai::turn","name":"TurnMove::to","kind":"field","signature":"pub to: (i32, i32)","docs":""},{"module":"crowdy_game_kit_ai::turn","name":"approach_scorer","kind":"function","signature":"pub fn approach_scorer(targets: Vec<(i32, i32)>) -> impl FnMut(&Candidate) -> f32","docs":"The classic melee-enemy heuristic: get adjacent to the closest target, preferring cells that minimize distance to ANY target. Returns a score function for [`best_move`]."},{"module":"crowdy_game_kit_ai::turn","name":"best_move","kind":"function","signature":"pub fn best_move( provider: &impl CostProvider, from: (i32, i32), move_points: u32, max_expanded: usize, mut score: impl FnMut(&Candidate) -> f32, ) -> Option<TurnMove>","docs":"Pick the best reachable cell under `move_points` by `score` (higher wins; ties prefer cheaper movement, then stable coordinate order). Returns None only when even standing still is impossible (blocked origin)."},{"module":"crowdy_game_kit_ai::turn","name":"reachable","kind":"function","signature":"pub fn reachable( provider: &impl CostProvider, from: (i32, i32), move_points: u32, max_expanded: usize, ) -> Vec<Candidate>","docs":"Enumerate the cells reachable from `from` with at most `move_points` total entry cost (BFS/Dijkstra-lite over the provider, 4-connected), including standing still. Expansion stops at `max_expanded` cells."},{"module":"crowdy_game_kit_core","name":"b64","kind":"module","signature":"pub mod b64;","docs":""},{"module":"crowdy_game_kit_core","name":"clock","kind":"module","signature":"pub mod clock;","docs":""},{"module":"crowdy_game_kit_core","name":"egress","kind":"module","signature":"pub mod egress;","docs":""},{"module":"crowdy_game_kit_core","name":"events","kind":"module","signature":"pub mod events;","docs":""},{"module":"crowdy_game_kit_core","name":"invoke","kind":"module","signature":"pub mod invoke;","docs":""},{"module":"crowdy_game_kit_core","name":"model","kind":"module","signature":"pub mod model;","docs":""},{"module":"crowdy_game_kit_core","name":"presence","kind":"module","signature":"pub mod presence;","docs":""},{"module":"crowdy_game_kit_core","name":"rng","kind":"module","signature":"pub mod rng;","docs":""},{"module":"crowdy_game_kit_core","name":"sdk","kind":"reexport","signature":"pub use crowdy_compute_sdk as sdk;","docs":""},{"module":"crowdy_game_kit_core","name":"space","kind":"module","signature":"pub mod space;","docs":""},{"module":"crowdy_game_kit_core","name":"state","kind":"module","signature":"pub mod state;","docs":""},{"module":"crowdy_game_kit_core","name":"wire","kind":"module","signature":"pub mod wire;","docs":""},{"module":"crowdy_game_kit_core::b64","name":"decode","kind":"function","signature":"pub fn decode(s: &str) -> Option<Vec<u8>>","docs":""},{"module":"crowdy_game_kit_core::b64","name":"encode","kind":"function","signature":"pub fn encode(data: &[u8]) -> String","docs":""},{"module":"crowdy_game_kit_core::clock","name":"Cooldown","kind":"struct","signature":"pub struct Cooldown { pub until_ms: u64, }","docs":"A one-shot cooldown (\"spawn cooldown 20 s\", \"contact damage per player\")."},{"module":"crowdy_game_kit_core::clock","name":"Cooldown::active","kind":"method","signature":"pub fn active(&self, now_ms: u64) -> bool","docs":""},{"module":"crowdy_game_kit_core::clock","name":"Cooldown::start","kind":"method","signature":"pub fn start(&mut self, now_ms: u64, duration_ms: u64)","docs":""},{"module":"crowdy_game_kit_core::clock","name":"Cooldown::try_consume","kind":"method","signature":"pub fn try_consume(&mut self, now_ms: u64, duration_ms: u64) -> bool","docs":"Try to consume: starts the cooldown and returns true when not active."},{"module":"crowdy_game_kit_core::clock","name":"Cooldown::until_ms","kind":"field","signature":"pub until_ms: u64","docs":""},{"module":"crowdy_game_kit_core::clock","name":"Every","kind":"struct","signature":"pub struct Every { pub period_ms: u64, pub last_ms: u64, }","docs":"Fires at most once per period (\"adopt every 15 s\", \"durable sync every 12 s\"). First call fires immediately."},{"module":"crowdy_game_kit_core::clock","name":"Every::last_ms","kind":"field","signature":"pub last_ms: u64","docs":""},{"module":"crowdy_game_kit_core::clock","name":"Every::new","kind":"method","signature":"pub fn new(period_ms: u64) -> Self","docs":""},{"module":"crowdy_game_kit_core::clock","name":"Every::period_ms","kind":"field","signature":"pub period_ms: u64","docs":""},{"module":"crowdy_game_kit_core::clock","name":"Every::ready","kind":"method","signature":"pub fn ready(&mut self, now_ms: u64) -> bool","docs":""},{"module":"crowdy_game_kit_core::egress","name":"Budget","kind":"struct","signature":"pub struct Budget { pub max_msgs_per_min: u32, pub max_bytes_per_min: u64, window_start_ms: u64, msgs: u32, bytes: u64, }","docs":""},{"module":"crowdy_game_kit_core::egress","name":"Budget::max_bytes_per_min","kind":"field","signature":"pub max_bytes_per_min: u64","docs":""},{"module":"crowdy_game_kit_core::egress","name":"Budget::max_msgs_per_min","kind":"field","signature":"pub max_msgs_per_min: u32","docs":""},{"module":"crowdy_game_kit_core::egress","name":"Budget::new","kind":"method","signature":"pub fn new(max_msgs_per_min: u32, max_bytes_per_min: u64) -> Self","docs":"Mirror the app policy, ideally with headroom (e.g. 90% of the real ceiling) so racing engines on the same app don't clip each other."},{"module":"crowdy_game_kit_core::egress","name":"Budget::try_charge","kind":"method","signature":"pub fn try_charge(&mut self, now_ms: u64, bytes: usize) -> bool","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_ABILITY","kind":"const","signature":"pub const EVENT_ABILITY: u16 = 94;","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_CONTACT_DAMAGE","kind":"const","signature":"pub const EVENT_CONTACT_DAMAGE: u16 = 77;","docs":"Platform-reserved server-event types (mirrored by the SDK kit/wire parsers). 77 = contact damage (kit-play referee), 90 = weather (kit-sim), 91 = turn changed (kit-play turns), 92 = score/summary (kit-play score), 93 = match proposal (matchmaking → matches handoff), 94 = ability cast/impact (kit-play abilities), 95 = movement violation (warden), 96 = control-point state (territory), 97 = race timing (kit-play timing), 98 = zone change (kit-sim zones)."},{"module":"crowdy_game_kit_core::events","name":"EVENT_CONTROL_POINT","kind":"const","signature":"pub const EVENT_CONTROL_POINT: u16 = 96;","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_MOVEMENT_VIOLATION","kind":"const","signature":"pub const EVENT_MOVEMENT_VIOLATION: u16 = 95;","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_PROPOSAL","kind":"const","signature":"pub const EVENT_PROPOSAL: u16 = 93;","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_RACE_TIMING","kind":"const","signature":"pub const EVENT_RACE_TIMING: u16 = 97;","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_SCORE","kind":"const","signature":"pub const EVENT_SCORE: u16 = 92;","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_TURN","kind":"const","signature":"pub const EVENT_TURN: u16 = 91;","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_WEATHER","kind":"const","signature":"pub const EVENT_WEATHER: u16 = 90;","docs":""},{"module":"crowdy_game_kit_core::events","name":"EVENT_ZONE_CHANGE","kind":"const","signature":"pub const EVENT_ZONE_CHANGE: u16 = 98;","docs":""},{"module":"crowdy_game_kit_core::events","name":"decode_event","kind":"function","signature":"pub fn decode_event(payload: &[u8]) -> Option<(u16, &[u8])>","docs":""},{"module":"crowdy_game_kit_core::events","name":"emit_compute_event","kind":"function","signature":"pub fn emit_compute_event(name: &str, payload: Value) -> Result<Value, HostError>","docs":"Emit a compute event for other modules' `compute_event` triggers."},{"module":"crowdy_game_kit_core::events","name":"emit_server_event","kind":"function","signature":"pub fn emit_server_event( chunk: (i64, i64, i64), uuid_hex: &str, event_type: u16, state: &Value, distance: u8, ) -> Result<Value, HostError>","docs":"Emit a server event (JSON state) at a chunk, attributed to `uuid_hex` (64 hex chars — see `wire::ActorUuid::ascii_hex`)."},{"module":"crowdy_game_kit_core::events","name":"encode_event","kind":"function","signature":"pub fn encode_event(event_type: u16, state: &[u8]) -> Vec<u8>","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"InvokeCtx","kind":"struct","signature":"pub struct InvokeCtx { pub export: String, pub params: Value, pub caller_user_id: String, }","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"InvokeCtx::caller_user_id","kind":"field","signature":"pub caller_user_id: String","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"InvokeCtx::export","kind":"field","signature":"pub export: String","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"InvokeCtx::params","kind":"field","signature":"pub params: Value","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"Router","kind":"struct","signature":"pub struct Router { handlers: Vec<(String, Handler)>, }","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"Router::dispatch","kind":"method","signature":"pub fn dispatch(&self, input: &[u8]) -> Vec<u8>","docs":"Dispatch raw `handle_invoke` input bytes; always returns JSON bytes."},{"module":"crowdy_game_kit_core::invoke","name":"Router::new","kind":"method","signature":"pub fn new() -> Self","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"Router::on","kind":"method","signature":"pub fn on(mut self, export: &str, handler: impl Fn(&InvokeCtx) -> Value + 'static) -> Self","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"fail","kind":"function","signature":"pub fn fail(reason: &str) -> Value","docs":""},{"module":"crowdy_game_kit_core::invoke","name":"ok","kind":"function","signature":"pub fn ok(data: Value) -> Value","docs":""},{"module":"crowdy_game_kit_core::model","name":"Catalog","kind":"struct","signature":"pub struct Catalog<T> { type_name: String, ttl_ms: u64, loaded_at: u64, parse: fn(&Container) -> Option<T>, pub items: Vec<T>, }","docs":"TTL-refreshed catalog of definition containers parsed into `T` (MobDef, AbilityDef, WaveDef, ...). Refresh failures keep the previous snapshot."},{"module":"crowdy_game_kit_core::model","name":"Catalog::ensure","kind":"method","signature":"pub fn ensure(&mut self, now_ms: u64) -> bool","docs":"Refresh when stale; returns true when items are available."},{"module":"crowdy_game_kit_core::model","name":"Catalog::items","kind":"field","signature":"pub items: Vec<T>","docs":""},{"module":"crowdy_game_kit_core::model","name":"Catalog::new","kind":"method","signature":"pub fn new(type_name: &str, ttl_ms: u64, parse: fn(&Container) -> Option<T>) -> Self","docs":""},{"module":"crowdy_game_kit_core::model","name":"Container","kind":"struct","signature":"pub struct Container { pub id: String, pub type_name: String, pub display_name: String, pub owner_user_id: Option<String>, pub properties: Value, }","docs":"A container with its property map (the `container_get_batch` shape)."},{"module":"crowdy_game_kit_core::model","name":"Container::display_name","kind":"field","signature":"pub display_name: String","docs":""},{"module":"crowdy_game_kit_core::model","name":"Container::id","kind":"field","signature":"pub id: String","docs":""},{"module":"crowdy_game_kit_core::model","name":"Container::owner_user_id","kind":"field","signature":"pub owner_user_id: Option<String>","docs":""},{"module":"crowdy_game_kit_core::model","name":"Container::properties","kind":"field","signature":"pub properties: Value","docs":""},{"module":"crowdy_game_kit_core::model","name":"Container::type_name","kind":"field","signature":"pub type_name: String","docs":""},{"module":"crowdy_game_kit_core::model","name":"load_with_props","kind":"function","signature":"pub fn load_with_props(type_name: &str) -> Result<Vec<Container>, HostError>","docs":"List all containers of a type WITH their properties: one `containers_list` plus `container_get_batch` calls of ≤32 ids (2 db-ops for ≤32 containers — the pattern that replaced BWF's ~20-op adopt cycle)."},{"module":"crowdy_game_kit_core::model","name":"load_with_props_in","kind":"function","signature":"pub fn load_with_props_in( type_name: &str, session_id: Option<&str>, ) -> Result<Vec<Container>, HostError>","docs":"Session-scoped variant of [`load_with_props`] (session games: matches, battles, instances)."},{"module":"crowdy_game_kit_core::model","name":"prop_bool","kind":"function","signature":"pub fn prop_bool(props: &Value, key: &str) -> bool","docs":""},{"module":"crowdy_game_kit_core::model","name":"prop_f32","kind":"function","signature":"pub fn prop_f32(props: &Value, key: &str) -> f32","docs":""},{"module":"crowdy_game_kit_core::model","name":"prop_i64","kind":"function","signature":"pub fn prop_i64(props: &Value, key: &str) -> i64","docs":""},{"module":"crowdy_game_kit_core::model","name":"prop_str","kind":"function","signature":"pub fn prop_str(props: &Value, key: &str) -> String","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerActor","kind":"struct","signature":"pub struct PlayerActor { pub uuid: String, pub user_id: String, pub x: f32, pub y: f32, pub z: f32, /// True when the position came from a decoded pose (vs chunk centre). pub precise: bool, }","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerActor::precise","kind":"field","signature":"pub precise: bool","docs":"True when the position came from a decoded pose (vs chunk centre)."},{"module":"crowdy_game_kit_core::presence","name":"PlayerActor::user_id","kind":"field","signature":"pub user_id: String","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerActor::uuid","kind":"field","signature":"pub uuid: String","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerActor::x","kind":"field","signature":"pub x: f32","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerActor::y","kind":"field","signature":"pub y: f32","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerActor::z","kind":"field","signature":"pub z: f32","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker","kind":"struct","signature":"pub struct PlayerTracker { pub center: (i64, i64, i64), pub radius_xz: u8, pub radius_y: u8, pub chunk_size: i64, pub players: Vec<PlayerActor>, }","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::by_user","kind":"method","signature":"pub fn by_user(&self, user_id: &str) -> Option<&PlayerActor>","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::center","kind":"field","signature":"pub center: (i64, i64, i64)","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::chunk_size","kind":"field","signature":"pub chunk_size: i64","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::nearest","kind":"method","signature":"pub fn nearest(&self, x: f32, z: f32) -> Option<&PlayerActor>","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::new","kind":"method","signature":"pub fn new(center: (i64, i64, i64), radius_xz: u8, radius_y: u8) -> Self","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::players","kind":"field","signature":"pub players: Vec<PlayerActor>","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::radius_xz","kind":"field","signature":"pub radius_xz: u8","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::radius_y","kind":"field","signature":"pub radius_y: u8","docs":""},{"module":"crowdy_game_kit_core::presence","name":"PlayerTracker::refresh","kind":"method","signature":"pub fn refresh(&mut self) -> &[PlayerActor]","docs":"Refresh the snapshot (one db-op). Host errors keep the last snapshot. A user with several actor rows (alts, stale test actors, ghosts) contributes only their FRESHEST row (by `updatedAt`, ISO-sortable)."},{"module":"crowdy_game_kit_core::rng","name":"Rng","kind":"struct","signature":"pub struct Rng { state: u64, }","docs":""},{"module":"crowdy_game_kit_core::rng","name":"Rng::f32","kind":"method","signature":"pub fn f32(&mut self) -> f32","docs":"Uniform in [0, 1)."},{"module":"crowdy_game_kit_core::rng","name":"Rng::from_host","kind":"method","signature":"pub fn from_host() -> Self","docs":"Seed from the host (deterministic per module instance)."},{"module":"crowdy_game_kit_core::rng","name":"Rng::next_u64","kind":"method","signature":"pub fn next_u64(&mut self) -> u64","docs":""},{"module":"crowdy_game_kit_core::rng","name":"Rng::pick","kind":"method","signature":"pub fn pick<'a, T>(&mut self, items: &'a [T]) -> Option<&'a T>","docs":""},{"module":"crowdy_game_kit_core::rng","name":"Rng::range_i64","kind":"method","signature":"pub fn range_i64(&mut self, lo: i64, hi: i64) -> i64","docs":"Uniform integer in [lo, hi] (inclusive)."},{"module":"crowdy_game_kit_core::rng","name":"Rng::seeded","kind":"method","signature":"pub fn seeded(seed: u64) -> Self","docs":""},{"module":"crowdy_game_kit_core::space","name":"DEFAULT_CHUNK_SIZE","kind":"const","signature":"pub const DEFAULT_CHUNK_SIZE: i64 = 16;","docs":""},{"module":"crowdy_game_kit_core::space","name":"block_world","kind":"function","signature":"pub fn block_world(chunk: (i64, i64, i64), local: (i64, i64, i64), chunk_size: i64) -> (i64, i64, i64)","docs":""},{"module":"crowdy_game_kit_core::space","name":"chunk_box","kind":"function","signature":"pub fn chunk_box( center: (i64, i64, i64), radius_xz: i64, radius_y: i64, ) -> impl Iterator<Item = (i64, i64, i64)>","docs":"Iterate a chunk box around a center (inclusive radii), y-band clamped."},{"module":"crowdy_game_kit_core::space","name":"chunk_center","kind":"function","signature":"pub fn chunk_center(chunk: (i64, i64, i64), chunk_size: i64) -> (f32, f32, f32)","docs":""},{"module":"crowdy_game_kit_core::space","name":"chunk_of_block","kind":"function","signature":"pub fn chunk_of_block(x: i64, y: i64, z: i64, chunk_size: i64) -> (i64, i64, i64)","docs":""},{"module":"crowdy_game_kit_core::space","name":"dist3","kind":"function","signature":"pub fn dist3(a: (f32, f32, f32), b: (f32, f32, f32)) -> f32","docs":""},{"module":"crowdy_game_kit_core::space","name":"dist_xz","kind":"function","signature":"pub fn dist_xz(ax: f32, az: f32, bx: f32, bz: f32) -> f32","docs":""},{"module":"crowdy_game_kit_core::space","name":"world_to_chunk","kind":"function","signature":"pub fn world_to_chunk(x: f32, y: f32, z: f32, chunk_size: i64) -> (i64, i64, i64)","docs":""},{"module":"crowdy_game_kit_core::space","name":"world_to_local","kind":"function","signature":"pub fn world_to_local(x: i64, y: i64, z: i64, chunk_size: i64) -> (u8, u8, u8)","docs":""},{"module":"crowdy_game_kit_core::state","name":"Partitioned","kind":"struct","signature":"pub struct Partitioned<T> { pub parts: HashMap<String, T>, }","docs":"Many logical states under one blob, keyed by string (instance ids, run ids). One module serves many instances (game-kit-program 02 B6)."},{"module":"crowdy_game_kit_core::state","name":"Partitioned::approx_bytes","kind":"method","signature":"pub fn approx_bytes(&self) -> usize","docs":"Serialized size in bytes — engines guard against the platform's 256 KB module-state cap before admitting new partitions."},{"module":"crowdy_game_kit_core::state","name":"Partitioned::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_core::state","name":"Partitioned::evict","kind":"method","signature":"pub fn evict(&mut self, mut expired: impl FnMut(&str, &T) -> bool) -> Vec<String>","docs":"Evict partitions selected by `expired` (completed runs, idle tables); returns the evicted keys. Engines call this every tick — durable results must already live on model containers (the D5 contract)."},{"module":"crowdy_game_kit_core::state","name":"Partitioned::get_or_default","kind":"method","signature":"pub fn get_or_default(&mut self, key: &str) -> &mut T","docs":""},{"module":"crowdy_game_kit_core::state","name":"Partitioned::has_room","kind":"method","signature":"pub fn has_room(&self, budget_bytes: usize) -> bool","docs":"Whether admitting another partition is safe under `budget_bytes` (leaves headroom for the new partition to grow to the size of the current largest one)."},{"module":"crowdy_game_kit_core::state","name":"Partitioned::parts","kind":"field","signature":"pub parts: HashMap<String, T>","docs":""},{"module":"crowdy_game_kit_core::state","name":"Partitioned::remove","kind":"method","signature":"pub fn remove(&mut self, key: &str) -> Option<T>","docs":""},{"module":"crowdy_game_kit_core::state","name":"Persisted","kind":"struct","signature":"pub struct Persisted<T> { pub value: T, version: u8, dirty: bool, }","docs":""},{"module":"crowdy_game_kit_core::state","name":"Persisted::load","kind":"method","signature":"pub fn load(version: u8) -> Self","docs":"Load the blob (or defaults). `version` guards schema evolution: a blob with a different version byte is discarded in favor of defaults."},{"module":"crowdy_game_kit_core::state","name":"Persisted::mark_dirty","kind":"method","signature":"pub fn mark_dirty(&mut self)","docs":""},{"module":"crowdy_game_kit_core::state","name":"Persisted::save","kind":"method","signature":"pub fn save(&mut self) -> bool","docs":"Persist now (unconditionally)."},{"module":"crowdy_game_kit_core::state","name":"Persisted::save_if_dirty","kind":"method","signature":"pub fn save_if_dirty(&mut self) -> bool","docs":"Persist only when marked dirty (call at the end of every tick)."},{"module":"crowdy_game_kit_core::state","name":"Persisted::value","kind":"field","signature":"pub value: T","docs":""},{"module":"crowdy_game_kit_core::state","name":"STATE_CAP_BYTES","kind":"const","signature":"pub const STATE_CAP_BYTES: usize = 256 * 1024;","docs":"The platform module-state cap (see the compute docs): engines size partition budgets against this."},{"module":"crowdy_game_kit_core::wire","name":"ActorUuid","kind":"struct","signature":"pub struct ActorUuid(String);","docs":"A 32-char ASCII actor id (the platform wire form)."},{"module":"crowdy_game_kit_core::wire","name":"ActorUuid::as_str","kind":"method","signature":"pub fn as_str(&self) -> &str","docs":""},{"module":"crowdy_game_kit_core::wire","name":"ActorUuid::ascii_hex","kind":"method","signature":"pub fn ascii_hex(&self) -> String","docs":"emit_spatial wants the hex of the 32 ASCII octets (64 hex chars)."},{"module":"crowdy_game_kit_core::wire","name":"ActorUuid::normalize","kind":"method","signature":"pub fn normalize(candidate: &str, fallback: &str) -> Self","docs":"Accept a well-formed uuid, or derive one from fallback material (hex-filtered, zero-padded) — mirrors the client normalizeUuid."},{"module":"crowdy_game_kit_core::wire","name":"FLAG_GROUNDED","kind":"const","signature":"pub const FLAG_GROUNDED: u8 = 0b0001;","docs":"Flag-bit registry. Bits 0-3 are platform-reserved; games may use 4-7."},{"module":"crowdy_game_kit_core::wire","name":"FLAG_MOB","kind":"const","signature":"pub const FLAG_MOB: u8 = 0b0010;","docs":""},{"module":"crowdy_game_kit_core::wire","name":"FLAG_NPC","kind":"const","signature":"pub const FLAG_NPC: u8 = 0b0100;","docs":""},{"module":"crowdy_game_kit_core::wire","name":"FLAG_RESERVED3","kind":"const","signature":"pub const FLAG_RESERVED3: u8 = 0b1000;","docs":""},{"module":"crowdy_game_kit_core::wire","name":"POSE_BYTES","kind":"const","signature":"pub const POSE_BYTES: usize = 48;","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose","kind":"struct","signature":"pub struct Pose { pub x: f32, pub y: f32, pub z: f32, pub yaw: f32, pub pitch: f32, pub vel_x: f32, pub vel_y: f32, pub vel_z: f32, pub flags: u8, pub held: u8, pub updated_at_ms: f64, }","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::at","kind":"method","signature":"pub fn at(x: f32, y: f32, z: f32) -> Self","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::decode","kind":"method","signature":"pub fn decode(bytes: &[u8]) -> Option<Self>","docs":"Decode the leading 48 bytes; tolerates longer payloads (suffix data)."},{"module":"crowdy_game_kit_core::wire","name":"Pose::encode","kind":"method","signature":"pub fn encode(&self) -> [u8; POSE_BYTES]","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::flags","kind":"field","signature":"pub flags: u8","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::held","kind":"field","signature":"pub held: u8","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::pitch","kind":"field","signature":"pub pitch: f32","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::suffix","kind":"method","signature":"pub fn suffix(bytes: &[u8]) -> Option<String>","docs":"The UTF-8 suffix after the pose (mob/npc container ids), if any."},{"module":"crowdy_game_kit_core::wire","name":"Pose::updated_at_ms","kind":"field","signature":"pub updated_at_ms: f64","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::vel_x","kind":"field","signature":"pub vel_x: f32","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::vel_y","kind":"field","signature":"pub vel_y: f32","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::vel_z","kind":"field","signature":"pub vel_z: f32","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::x","kind":"field","signature":"pub x: f32","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::y","kind":"field","signature":"pub y: f32","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::yaw","kind":"field","signature":"pub yaw: f32","docs":""},{"module":"crowdy_game_kit_core::wire","name":"Pose::z","kind":"field","signature":"pub z: f32","docs":""},{"module":"crowdy_game_kit_core::wire","name":"emit_actor","kind":"function","signature":"pub fn emit_actor( uuid: &ActorUuid, pose: &Pose, suffix: Option<&str>, distance: u8, chunk_size: i64, ) -> Result<Value, HostError>","docs":"Emit an actor-pose update (optionally with a suffix) at the pose's chunk."},{"module":"crowdy_game_kit_econ","name":"boards","kind":"module","signature":"pub mod boards;","docs":""},{"module":"crowdy_game_kit_econ","name":"core","kind":"reexport","signature":"pub use crowdy_game_kit_core as core;","docs":""},{"module":"crowdy_game_kit_econ","name":"loot","kind":"module","signature":"pub mod loot;","docs":""},{"module":"crowdy_game_kit_econ","name":"market","kind":"module","signature":"pub mod market;","docs":""},{"module":"crowdy_game_kit_econ","name":"production","kind":"module","signature":"pub mod production;","docs":""},{"module":"crowdy_game_kit_econ::boards","name":"Board","kind":"struct","signature":"pub struct Board { pub scores: HashMap<String, i64>, }","docs":"A score book for one board. Submit through trusted paths only."},{"module":"crowdy_game_kit_econ::boards","name":"Board::page","kind":"method","signature":"pub fn page(&self, page: usize, per_page: usize) -> Vec<RankedEntry>","docs":"One page of the ranking (0-based `page` of `per_page` rows)."},{"module":"crowdy_game_kit_econ::boards","name":"Board::rank_of","kind":"method","signature":"pub fn rank_of(&self, subject_id: &str) -> Option<RankedEntry>","docs":"One subject's ranked row (None when unranked)."},{"module":"crowdy_game_kit_econ::boards","name":"Board::ranking","kind":"method","signature":"pub fn ranking(&self) -> Vec<RankedEntry>","docs":"The full ranking, best first (ties share rank; stable by id)."},{"module":"crowdy_game_kit_econ::boards","name":"Board::scores","kind":"field","signature":"pub scores: HashMap<String, i64>","docs":""},{"module":"crowdy_game_kit_econ::boards","name":"Board::submit","kind":"method","signature":"pub fn submit(&mut self, subject_id: &str, score: i64, improve_only: bool) -> i64","docs":"Record a score (higher wins; `improve_only` keeps personal bests)."},{"module":"crowdy_game_kit_econ::boards","name":"RankedEntry","kind":"struct","signature":"pub struct RankedEntry { pub subject_id: String, pub score: i64, /// 1-based; ties share a rank (competition ranking: 1, 1, 3). pub rank: u32, /// Percentile of entries at-or-below this score, in [0, 100]. pub percentile: f32, }","docs":""},{"module":"crowdy_game_kit_econ::boards","name":"RankedEntry::percentile","kind":"field","signature":"pub percentile: f32","docs":"Percentile of entries at-or-below this score, in [0, 100]."},{"module":"crowdy_game_kit_econ::boards","name":"RankedEntry::rank","kind":"field","signature":"pub rank: u32","docs":"1-based; ties share a rank (competition ranking: 1, 1, 3)."},{"module":"crowdy_game_kit_econ::boards","name":"RankedEntry::score","kind":"field","signature":"pub score: i64","docs":""},{"module":"crowdy_game_kit_econ::boards","name":"RankedEntry::subject_id","kind":"field","signature":"pub subject_id: String","docs":""},{"module":"crowdy_game_kit_econ::boards","name":"SeasonSnapshot","kind":"struct","signature":"pub struct SeasonSnapshot { pub season: String, pub taken_at_ms: u64, pub entries: Vec<RankedEntry>, }","docs":"A frozen end-of-season ranking."},{"module":"crowdy_game_kit_econ::boards","name":"SeasonSnapshot::entries","kind":"field","signature":"pub entries: Vec<RankedEntry>","docs":""},{"module":"crowdy_game_kit_econ::boards","name":"SeasonSnapshot::season","kind":"field","signature":"pub season: String","docs":""},{"module":"crowdy_game_kit_econ::boards","name":"SeasonSnapshot::taken_at_ms","kind":"field","signature":"pub taken_at_ms: u64","docs":""},{"module":"crowdy_game_kit_econ::boards","name":"roll_season","kind":"function","signature":"pub fn roll_season(board: &mut Board, season: &str, now_ms: u64) -> SeasonSnapshot","docs":"Freeze the board into a snapshot and reset live scores."},{"module":"crowdy_game_kit_econ::loot","name":"LootBook","kind":"struct","signature":"pub struct LootBook { pub rolls: u64, pub pity_counters: HashMap<String, u32>, /// (roll number, item id) — last N rolls for dispute audits. pub audit: Vec<(u64, String)>, }","docs":"Per-subject roll memory: pity counters + a rolling audit log."},{"module":"crowdy_game_kit_econ::loot","name":"LootBook::audit","kind":"field","signature":"pub audit: Vec<(u64, String)>","docs":"(roll number, item id) — last N rolls for dispute audits."},{"module":"crowdy_game_kit_econ::loot","name":"LootBook::pity_counters","kind":"field","signature":"pub pity_counters: HashMap<String, u32>","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootBook::rolls","kind":"field","signature":"pub rolls: u64","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootEntry","kind":"struct","signature":"pub struct LootEntry { pub item_id: String, pub weight: u32, /// Entries sharing a pity group tick that group's counter. pub pity_group: Option<String>, }","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootEntry::item_id","kind":"field","signature":"pub item_id: String","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootEntry::pity_group","kind":"field","signature":"pub pity_group: Option<String>","docs":"Entries sharing a pity group tick that group's counter."},{"module":"crowdy_game_kit_econ::loot","name":"LootEntry::weight","kind":"field","signature":"pub weight: u32","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootRoll","kind":"struct","signature":"pub struct LootRoll { pub item_id: String, pub pity_triggered: bool, pub roll_no: u64, }","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootRoll::item_id","kind":"field","signature":"pub item_id: String","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootRoll::pity_triggered","kind":"field","signature":"pub pity_triggered: bool","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootRoll::roll_no","kind":"field","signature":"pub roll_no: u64","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootTable","kind":"struct","signature":"pub struct LootTable { pub entries: Vec<LootEntry>, /// pity group -> guaranteed within this many rolls. pub pity_within: HashMap<String, u32>, }","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootTable::entries","kind":"field","signature":"pub entries: Vec<LootEntry>","docs":""},{"module":"crowdy_game_kit_econ::loot","name":"LootTable::pity_within","kind":"field","signature":"pub pity_within: HashMap<String, u32>","docs":"pity group -> guaranteed within this many rolls."},{"module":"crowdy_game_kit_econ::loot","name":"roll","kind":"function","signature":"pub fn roll(table: &LootTable, book: &mut LootBook, rng: &mut Rng) -> Option<LootRoll>","docs":"Roll once. Pity: when a group's counter reaches its `pity_within` threshold, the next roll is forced from that group (rarest-first by weight) and the counter resets. Rolling the group naturally also resets."},{"module":"crowdy_game_kit_econ::market","name":"Fill","kind":"struct","signature":"pub struct Fill { pub buyer_id: String, pub seller_id: String, pub buy_order_id: u64, pub sell_order_id: u64, pub price: i64, pub quantity: i64, }","docs":"One trade produced by matching: `quantity` units at `price`, buyer pays `price * quantity` to the seller. The engine settles both legs."},{"module":"crowdy_game_kit_econ::market","name":"Fill::buy_order_id","kind":"field","signature":"pub buy_order_id: u64","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Fill::buyer_id","kind":"field","signature":"pub buyer_id: String","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Fill::price","kind":"field","signature":"pub price: i64","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Fill::quantity","kind":"field","signature":"pub quantity: i64","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Fill::sell_order_id","kind":"field","signature":"pub sell_order_id: u64","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Fill::seller_id","kind":"field","signature":"pub seller_id: String","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Order","kind":"struct","signature":"pub struct Order { pub order_id: u64, pub user_id: String, pub side: Side, /// Limit price per unit. pub price: i64, pub quantity: i64, pub placed_at_ms: u64, }","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Order::order_id","kind":"field","signature":"pub order_id: u64","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Order::placed_at_ms","kind":"field","signature":"pub placed_at_ms: u64","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Order::price","kind":"field","signature":"pub price: i64","docs":"Limit price per unit."},{"module":"crowdy_game_kit_econ::market","name":"Order::quantity","kind":"field","signature":"pub quantity: i64","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Order::side","kind":"field","signature":"pub side: Side","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Order::user_id","kind":"field","signature":"pub user_id: String","docs":""},{"module":"crowdy_game_kit_econ::market","name":"OrderBook","kind":"struct","signature":"pub struct OrderBook { pub bids: Vec<Order>, pub asks: Vec<Order>, next_order_id: u64, }","docs":"The book for ONE item/commodity. Bids sorted best (highest) first, asks best (lowest) first; ties by placement time (price-time priority)."},{"module":"crowdy_game_kit_econ::market","name":"OrderBook::asks","kind":"field","signature":"pub asks: Vec<Order>","docs":""},{"module":"crowdy_game_kit_econ::market","name":"OrderBook::best_ask","kind":"method","signature":"pub fn best_ask(&self) -> Option<&Order>","docs":""},{"module":"crowdy_game_kit_econ::market","name":"OrderBook::best_bid","kind":"method","signature":"pub fn best_bid(&self) -> Option<&Order>","docs":""},{"module":"crowdy_game_kit_econ::market","name":"OrderBook::bids","kind":"field","signature":"pub bids: Vec<Order>","docs":""},{"module":"crowdy_game_kit_econ::market","name":"OrderBook::cancel","kind":"method","signature":"pub fn cancel(&mut self, order_id: u64, user_id: &str) -> Option<Order>","docs":"Cancel a resting order (owner only). Returns it for escrow refund."},{"module":"crowdy_game_kit_econ::market","name":"OrderBook::depth","kind":"method","signature":"pub fn depth(&self, side: Side, levels: usize) -> Vec<(i64, i64)>","docs":"Depth summary: (price, total quantity) per level, best first."},{"module":"crowdy_game_kit_econ::market","name":"OrderBook::place","kind":"method","signature":"pub fn place( &mut self, user_id: &str, side: Side, price: i64, quantity: i64, now_ms: u64, ) -> Result<(u64, Vec<Fill>), &'static str>","docs":"Place a limit order, matching immediately against the far side. Returns (order id, fills). Any unfilled remainder rests on the book. Maker price wins (the resting order's limit is the trade price)."},{"module":"crowdy_game_kit_econ::market","name":"Side","kind":"enum","signature":"pub enum Side { Buy, Sell, }","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Side::Buy","kind":"variant","signature":"Buy","docs":""},{"module":"crowdy_game_kit_econ::market","name":"Side::Sell","kind":"variant","signature":"Sell","docs":""},{"module":"crowdy_game_kit_econ::production","name":"Producer","kind":"struct","signature":"pub struct Producer { pub node_id: String, /// (resource, amount per cycle) consumed. pub inputs: Vec<(String, i64)>, /// (resource, amount per cycle) produced. pub outputs: Vec<(String, i64)>, pub rate_per_min: f64, /// Fractional cycles carried between advances. pub cycle_progress: f64, }","docs":"One production node: consumes inputs, produces outputs, at `rate_per_min` cycles per minute, bounded by input stock and output capacity."},{"module":"crowdy_game_kit_econ::production","name":"Producer::cycle_progress","kind":"field","signature":"pub cycle_progress: f64","docs":"Fractional cycles carried between advances."},{"module":"crowdy_game_kit_econ::production","name":"Producer::inputs","kind":"field","signature":"pub inputs: Vec<(String, i64)>","docs":"(resource, amount per cycle) consumed."},{"module":"crowdy_game_kit_econ::production","name":"Producer::node_id","kind":"field","signature":"pub node_id: String","docs":""},{"module":"crowdy_game_kit_econ::production","name":"Producer::outputs","kind":"field","signature":"pub outputs: Vec<(String, i64)>","docs":"(resource, amount per cycle) produced."},{"module":"crowdy_game_kit_econ::production","name":"Producer::rate_per_min","kind":"field","signature":"pub rate_per_min: f64","docs":""},{"module":"crowdy_game_kit_econ::production","name":"ProductionChain","kind":"struct","signature":"pub struct ProductionChain { pub producers: Vec<Producer>, pub stock: HashMap<String, i64>, /// Per-resource storage caps (absent = unlimited). pub capacity: HashMap<String, i64>, pub last_advanced_ms: u64, }","docs":""},{"module":"crowdy_game_kit_econ::production","name":"ProductionChain::advance","kind":"method","signature":"pub fn advance(&mut self, now_ms: u64) -> HashMap<String, i64>","docs":"Advance the whole chain to `now_ms` (offline catch-up in one call). Producers run in declaration order — upstream nodes first lets a night of idle time flow through multi-stage chains."},{"module":"crowdy_game_kit_econ::production","name":"ProductionChain::capacity","kind":"field","signature":"pub capacity: HashMap<String, i64>","docs":"Per-resource storage caps (absent = unlimited)."},{"module":"crowdy_game_kit_econ::production","name":"ProductionChain::last_advanced_ms","kind":"field","signature":"pub last_advanced_ms: u64","docs":""},{"module":"crowdy_game_kit_econ::production","name":"ProductionChain::producers","kind":"field","signature":"pub producers: Vec<Producer>","docs":""},{"module":"crowdy_game_kit_econ::production","name":"ProductionChain::stock","kind":"field","signature":"pub stock: HashMap<String, i64>","docs":""},{"module":"crowdy_game_kit_play","name":"abilities","kind":"module","signature":"pub mod abilities;","docs":""},{"module":"crowdy_game_kit_play","name":"cards","kind":"module","signature":"pub mod cards;","docs":""},{"module":"crowdy_game_kit_play","name":"core","kind":"reexport","signature":"pub use crowdy_game_kit_core as core;","docs":""},{"module":"crowdy_game_kit_play","name":"referee","kind":"module","signature":"pub mod referee;","docs":""},{"module":"crowdy_game_kit_play","name":"score","kind":"module","signature":"pub mod score;","docs":""},{"module":"crowdy_game_kit_play","name":"timing","kind":"module","signature":"pub mod timing;","docs":""},{"module":"crowdy_game_kit_play","name":"turns","kind":"module","signature":"pub mod turns;","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"AbilityKind","kind":"enum","signature":"pub enum AbilityKind { /// Immediate hit on a target in range (hitscan). Instant { damage: i64 }, /// A stepped projectile along a direction; first actor within /// `hit_radius` takes the damage. Projectile { speed: f32, damage: i64, max_range: f32, hit_radius: f32 }, /// A delayed explosion at a target point; damage within `radius`, /// optionally scaled down linearly with distance. Aoe { radius: f32, damage: i64, delay_ms: u64, falloff: bool }, }","docs":"What a cast does once validated."},{"module":"crowdy_game_kit_play::abilities","name":"AbilityKind::Aoe","kind":"variant","signature":"Aoe { radius: f32, damage: i64, delay_ms: u64, falloff: bool }","docs":"A delayed explosion at a target point; damage within `radius`, optionally scaled down linearly with distance."},{"module":"crowdy_game_kit_play::abilities","name":"AbilityKind::Instant","kind":"variant","signature":"Instant { damage: i64 }","docs":"Immediate hit on a target in range (hitscan)."},{"module":"crowdy_game_kit_play::abilities","name":"AbilityKind::Projectile","kind":"variant","signature":"Projectile { speed: f32, damage: i64, max_range: f32, hit_radius: f32 }","docs":"A stepped projectile along a direction; first actor within `hit_radius` takes the damage."},{"module":"crowdy_game_kit_play::abilities","name":"AbilitySpec","kind":"struct","signature":"pub struct AbilitySpec { pub ability_id: String, pub cooldown_ms: u64, pub resource_cost: i64, /// Max cast distance (target point / initial direction anchor). pub range: f32, pub kind: AbilityKind, }","docs":"One ability's rules (usually parsed from an `AbilityDef` container)."},{"module":"crowdy_game_kit_play::abilities","name":"AbilitySpec::ability_id","kind":"field","signature":"pub ability_id: String","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"AbilitySpec::cooldown_ms","kind":"field","signature":"pub cooldown_ms: u64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"AbilitySpec::kind","kind":"field","signature":"pub kind: AbilityKind","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"AbilitySpec::range","kind":"field","signature":"pub range: f32","docs":"Max cast distance (target point / initial direction anchor)."},{"module":"crowdy_game_kit_play::abilities","name":"AbilitySpec::resource_cost","kind":"field","signature":"pub resource_cost: i64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"CasterBook","kind":"struct","signature":"pub struct CasterBook { /// ability id -> earliest next cast (ms). pub ready_at: HashMap<String, u64>, pub resource: i64, pub resource_max: i64, /// Resource points regenerated per second. pub regen_per_sec: i64, pub last_regen_ms: u64, }","docs":"Per-caster server-held book: cooldown stamps + a regenerating resource pool. One book per user, serde in module state."},{"module":"crowdy_game_kit_play::abilities","name":"CasterBook::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"CasterBook::last_regen_ms","kind":"field","signature":"pub last_regen_ms: u64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"CasterBook::ready_at","kind":"field","signature":"pub ready_at: HashMap<String, u64>","docs":"ability id -> earliest next cast (ms)."},{"module":"crowdy_game_kit_play::abilities","name":"CasterBook::regen","kind":"method","signature":"pub fn regen(&mut self, now_ms: u64)","docs":"Apply resource regeneration up to `now_ms`."},{"module":"crowdy_game_kit_play::abilities","name":"CasterBook::regen_per_sec","kind":"field","signature":"pub regen_per_sec: i64","docs":"Resource points regenerated per second."},{"module":"crowdy_game_kit_play::abilities","name":"CasterBook::resource","kind":"field","signature":"pub resource: i64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"CasterBook::resource_max","kind":"field","signature":"pub resource_max: i64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe","kind":"struct","signature":"pub struct PendingAoe { pub ability_id: String, pub caster_id: String, pub x: f32, pub z: f32, pub radius: f32, pub damage: i64, pub falloff: bool, pub detonate_at_ms: u64, }","docs":"A delayed area effect awaiting detonation."},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::ability_id","kind":"field","signature":"pub ability_id: String","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::caster_id","kind":"field","signature":"pub caster_id: String","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::damage","kind":"field","signature":"pub damage: i64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::detonate_at_ms","kind":"field","signature":"pub detonate_at_ms: u64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::falloff","kind":"field","signature":"pub falloff: bool","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::from_cast","kind":"method","signature":"pub fn from_cast( spec: &AbilitySpec, caster_id: &str, cast: &ValidCast, now_ms: u64, ) -> Option<Self>","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::radius","kind":"field","signature":"pub radius: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::ready","kind":"method","signature":"pub fn ready(&self, now_ms: u64) -> bool","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::resolve","kind":"method","signature":"pub fn resolve(&self, victims: &[(String, (f32, f32))]) -> Vec<(String, i64)>","docs":"Damage per victim inside the radius (linear falloff to 25% at the edge when enabled). Victims = (id, position); the caster is exempt."},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::x","kind":"field","signature":"pub x: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"PendingAoe::z","kind":"field","signature":"pub z: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile","kind":"struct","signature":"pub struct Projectile { pub ability_id: String, pub caster_id: String, pub x: f32, pub z: f32, pub dir: (f32, f32), pub speed: f32, pub damage: i64, pub hit_radius: f32, pub traveled: f32, pub max_range: f32, pub launched_at_ms: u64, }","docs":"A live projectile stepped by the engine each tick."},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::ability_id","kind":"field","signature":"pub ability_id: String","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::caster_id","kind":"field","signature":"pub caster_id: String","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::damage","kind":"field","signature":"pub damage: i64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::dir","kind":"field","signature":"pub dir: (f32, f32)","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::hit_radius","kind":"field","signature":"pub hit_radius: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::launch","kind":"method","signature":"pub fn launch( spec: &AbilitySpec, caster_id: &str, from: (f32, f32), cast: &ValidCast, now_ms: u64, ) -> Option<Self>","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::launched_at_ms","kind":"field","signature":"pub launched_at_ms: u64","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::max_range","kind":"field","signature":"pub max_range: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::speed","kind":"field","signature":"pub speed: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::step","kind":"method","signature":"pub fn step( &mut self, dt_ms: u64, hit_test: &mut impl FnMut(f32, f32, f32) -> Option<String>, blocked: &mut impl FnMut(f32, f32) -> bool, ) -> ProjectileStep","docs":"Advance `dt_ms`, sub-stepping so tick-rate simulation cannot tunnel through targets (tolerance window = hit_radius per sub-step). `hit_test(x, z, radius)` returns a hit target (never the caster) or None; `blocked(x, z)` marks walls."},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::traveled","kind":"field","signature":"pub traveled: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::x","kind":"field","signature":"pub x: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"Projectile::z","kind":"field","signature":"pub z: f32","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"ProjectileStep","kind":"enum","signature":"pub enum ProjectileStep { /// Still flying (new position recorded on the projectile). Flying, /// Hit `target_id` at the recorded position; despawn. Hit { target_id: String }, /// Ran out of range or was blocked; despawn. Expired, }","docs":"The outcome of one projectile step."},{"module":"crowdy_game_kit_play::abilities","name":"ProjectileStep::Expired","kind":"variant","signature":"Expired","docs":"Ran out of range or was blocked; despawn."},{"module":"crowdy_game_kit_play::abilities","name":"ProjectileStep::Flying","kind":"variant","signature":"Flying","docs":"Still flying (new position recorded on the projectile)."},{"module":"crowdy_game_kit_play::abilities","name":"ProjectileStep::Hit","kind":"variant","signature":"Hit { target_id: String }","docs":"Hit `target_id` at the recorded position; despawn."},{"module":"crowdy_game_kit_play::abilities","name":"ValidCast","kind":"struct","signature":"pub struct ValidCast { pub ability_id: String, /// Normalized aim direction (projectiles). pub dir: (f32, f32), /// Clamped target point (instant/AoE). pub target: (f32, f32), }","docs":"A validated cast, ready for the engine to act on."},{"module":"crowdy_game_kit_play::abilities","name":"ValidCast::ability_id","kind":"field","signature":"pub ability_id: String","docs":""},{"module":"crowdy_game_kit_play::abilities","name":"ValidCast::dir","kind":"field","signature":"pub dir: (f32, f32)","docs":"Normalized aim direction (projectiles)."},{"module":"crowdy_game_kit_play::abilities","name":"ValidCast::target","kind":"field","signature":"pub target: (f32, f32)","docs":"Clamped target point (instant/AoE)."},{"module":"crowdy_game_kit_play::abilities","name":"validate_cast","kind":"function","signature":"pub fn validate_cast( spec: &AbilitySpec, book: &mut CasterBook, caster_pos: (f32, f32), target: (f32, f32), now_ms: u64, ) -> Result<ValidCast, &'static str>","docs":"Validate a cast against the book: cooldown, resource, range. On success the cooldown is armed and the resource deducted (the cast is committed)."},{"module":"crowdy_game_kit_play::cards","name":"CardId","kind":"type","signature":"pub type CardId = String;","docs":""},{"module":"crowdy_game_kit_play::cards","name":"CardTable","kind":"struct","signature":"pub struct CardTable { pub draw: Pile, pub discard: Pile, pub hands: HashMap<String, Vec<CardId>>, /// Named public zones (battlefield, trick, melds, ...), in play order. pub zones: HashMap<String, Vec<(String, CardId)>>, pub seed: u64, }","docs":"The full table: draw pile, discard, per-actor hidden hands, and named public zones. Everything serde — one `CardTable` per match partition."},{"module":"crowdy_game_kit_play::cards","name":"CardTable::clear_zone","kind":"method","signature":"pub fn clear_zone(&mut self, zone: &str) -> Vec<(String, CardId)>","docs":"Move every card in a zone to the discard (trick taken, turn over)."},{"module":"crowdy_game_kit_play::cards","name":"CardTable::deal","kind":"method","signature":"pub fn deal(&mut self, actors: &[String], count: usize)","docs":"Deal `count` cards to each actor (round-robin, deterministic order)."},{"module":"crowdy_game_kit_play::cards","name":"CardTable::discard","kind":"field","signature":"pub discard: Pile","docs":""},{"module":"crowdy_game_kit_play::cards","name":"CardTable::draw","kind":"field","signature":"pub draw: Pile","docs":""},{"module":"crowdy_game_kit_play::cards","name":"CardTable::draw_to_hand","kind":"method","signature":"pub fn draw_to_hand(&mut self, actor_id: &str) -> Option<CardId>","docs":"Draw one card into an actor's hidden hand. Recycles the discard (reshuffled with the table seed + draw count) when the deck empties."},{"module":"crowdy_game_kit_play::cards","name":"CardTable::hand","kind":"method","signature":"pub fn hand(&self, actor_id: &str) -> &[CardId]","docs":"The caller's own hand (the ONLY read path for hidden cards)."},{"module":"crowdy_game_kit_play::cards","name":"CardTable::hand_sizes","kind":"method","signature":"pub fn hand_sizes(&self) -> HashMap<String, usize>","docs":""},{"module":"crowdy_game_kit_play::cards","name":"CardTable::hands","kind":"field","signature":"pub hands: HashMap<String, Vec<CardId>>","docs":""},{"module":"crowdy_game_kit_play::cards","name":"CardTable::new","kind":"method","signature":"pub fn new(catalog: impl IntoIterator<Item = CardId>, seed: u64) -> Self","docs":"Build a table from a card catalog and shuffle with the given seed."},{"module":"crowdy_game_kit_play::cards","name":"CardTable::play","kind":"method","signature":"pub fn play(&mut self, actor_id: &str, card: &str, zone: &str) -> Result<(), &'static str>","docs":"Play (reveal) a card from a hand into a public zone. Fails when the caller does not hold the card — the legality floor every game gets."},{"module":"crowdy_game_kit_play::cards","name":"CardTable::public_json","kind":"method","signature":"pub fn public_json(&self) -> Value","docs":"The public view (zones + counts, NEVER hidden cards) for model sync and spectator events."},{"module":"crowdy_game_kit_play::cards","name":"CardTable::seed","kind":"field","signature":"pub seed: u64","docs":""},{"module":"crowdy_game_kit_play::cards","name":"CardTable::zones","kind":"field","signature":"pub zones: HashMap<String, Vec<(String, CardId)>>","docs":"Named public zones (battlefield, trick, melds, ...), in play order."},{"module":"crowdy_game_kit_play::cards","name":"Pile","kind":"struct","signature":"pub struct Pile { /// Top of the pile is the END of the vec (pop to draw). pub cards: Vec<CardId>, }","docs":"A pile with hidden order (draw deck / discard)."},{"module":"crowdy_game_kit_play::cards","name":"Pile::cards","kind":"field","signature":"pub cards: Vec<CardId>","docs":"Top of the pile is the END of the vec (pop to draw)."},{"module":"crowdy_game_kit_play::cards","name":"Pile::draw","kind":"method","signature":"pub fn draw(&mut self) -> Option<CardId>","docs":""},{"module":"crowdy_game_kit_play::cards","name":"Pile::is_empty","kind":"method","signature":"pub fn is_empty(&self) -> bool","docs":""},{"module":"crowdy_game_kit_play::cards","name":"Pile::len","kind":"method","signature":"pub fn len(&self) -> usize","docs":""},{"module":"crowdy_game_kit_play::cards","name":"Pile::put","kind":"method","signature":"pub fn put(&mut self, card: CardId)","docs":""},{"module":"crowdy_game_kit_play::cards","name":"Pile::shuffle","kind":"method","signature":"pub fn shuffle(&mut self, rng: &mut Rng)","docs":"Seeded Fisher-Yates shuffle."},{"module":"crowdy_game_kit_play::cards","name":"standard_52","kind":"function","signature":"pub fn standard_52() -> Vec<CardId>","docs":"Build a standard 52-card catalog (\"AS\", \"2S\", ..., \"KC\") — handy for examples and tests; real games usually feed `DeckDef` container catalogs."},{"module":"crowdy_game_kit_play::referee","name":"ContactBook","kind":"struct","signature":"pub struct ContactBook { pub contact_at_ms: HashMap<String, u64>, }","docs":"Per-victim contact-damage memory (persist in module state)."},{"module":"crowdy_game_kit_play::referee","name":"ContactBook::contact_at_ms","kind":"field","signature":"pub contact_at_ms: HashMap<String, u64>","docs":""},{"module":"crowdy_game_kit_play::referee","name":"ContactBook::try_contact","kind":"method","signature":"pub fn try_contact( &mut self, victim_uuid: &str, victim_pos: (f32, f32, f32), attacker_pos: (f32, f32, f32), rules: &ContactRules, now_ms: u64, chunk_size: i64, ) -> Option<ContactHit>","docs":"Decide whether `attacker_pos` (a hostile mob) contacts the victim at `victim` this tick. Consumes the victim's cooldown when it does."},{"module":"crowdy_game_kit_play::referee","name":"ContactHit","kind":"struct","signature":"pub struct ContactHit { pub victim_uuid: String, pub victim_chunk: (i64, i64, i64), }","docs":""},{"module":"crowdy_game_kit_play::referee","name":"ContactHit::victim_chunk","kind":"field","signature":"pub victim_chunk: (i64, i64, i64)","docs":""},{"module":"crowdy_game_kit_play::referee","name":"ContactHit::victim_uuid","kind":"field","signature":"pub victim_uuid: String","docs":""},{"module":"crowdy_game_kit_play::referee","name":"ContactRules","kind":"struct","signature":"pub struct ContactRules { pub range: f32, /// Per-victim cooldown between contact hits. pub cooldown_ms: u64, }","docs":""},{"module":"crowdy_game_kit_play::referee","name":"ContactRules::cooldown_ms","kind":"field","signature":"pub cooldown_ms: u64","docs":"Per-victim cooldown between contact hits."},{"module":"crowdy_game_kit_play::referee","name":"ContactRules::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_play::referee","name":"ContactRules::range","kind":"field","signature":"pub range: f32","docs":""},{"module":"crowdy_game_kit_play::referee","name":"DamageOutcome","kind":"struct","signature":"pub struct DamageOutcome { pub health: i64, pub killed: bool, }","docs":""},{"module":"crowdy_game_kit_play::referee","name":"DamageOutcome::health","kind":"field","signature":"pub health: i64","docs":""},{"module":"crowdy_game_kit_play::referee","name":"DamageOutcome::killed","kind":"field","signature":"pub killed: bool","docs":""},{"module":"crowdy_game_kit_play::referee","name":"EVENT_CONTACT_DAMAGE","kind":"const","signature":"pub const EVENT_CONTACT_DAMAGE: u16 = 77;","docs":"The platform convention for contact-damage server events."},{"module":"crowdy_game_kit_play::referee","name":"Health","kind":"struct","signature":"pub struct Health { pub current: i64, pub max: i64, }","docs":""},{"module":"crowdy_game_kit_play::referee","name":"Health::alive","kind":"method","signature":"pub fn alive(&self) -> bool","docs":""},{"module":"crowdy_game_kit_play::referee","name":"Health::apply","kind":"method","signature":"pub fn apply(&mut self, amount: i64) -> DamageOutcome","docs":""},{"module":"crowdy_game_kit_play::referee","name":"Health::current","kind":"field","signature":"pub current: i64","docs":""},{"module":"crowdy_game_kit_play::referee","name":"Health::heal","kind":"method","signature":"pub fn heal(&mut self, amount: i64)","docs":""},{"module":"crowdy_game_kit_play::referee","name":"Health::max","kind":"field","signature":"pub max: i64","docs":""},{"module":"crowdy_game_kit_play::referee","name":"Health::new","kind":"method","signature":"pub fn new(max: i64) -> Self","docs":""},{"module":"crowdy_game_kit_play::referee","name":"HitBook","kind":"struct","signature":"pub struct HitBook { pub last_hit_ms: HashMap<String, u64>, }","docs":"Per-attacker hit-rate memory (persist in module state)."},{"module":"crowdy_game_kit_play::referee","name":"HitBook::last_hit_ms","kind":"field","signature":"pub last_hit_ms: HashMap<String, u64>","docs":""},{"module":"crowdy_game_kit_play::referee","name":"HitRules","kind":"struct","signature":"pub struct HitRules { /// Max distance between the attacker's actor and the target. pub range: f32, /// Per-attacker minimum interval between accepted hits. pub cooldown_ms: u64, /// Damage clamp. pub min_amount: i64, pub max_amount: i64, /// Accept chunk-level proximity when the attacker has no pose heartbeat /// yet (the tracker's `precise: false` rows). BWF's lag-tolerant default. pub allow_imprecise: bool, }","docs":""},{"module":"crowdy_game_kit_play::referee","name":"HitRules::allow_imprecise","kind":"field","signature":"pub allow_imprecise: bool","docs":"Accept chunk-level proximity when the attacker has no pose heartbeat yet (the tracker's `precise: false` rows). BWF's lag-tolerant default."},{"module":"crowdy_game_kit_play::referee","name":"HitRules::cooldown_ms","kind":"field","signature":"pub cooldown_ms: u64","docs":"Per-attacker minimum interval between accepted hits."},{"module":"crowdy_game_kit_play::referee","name":"HitRules::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_play::referee","name":"HitRules::max_amount","kind":"field","signature":"pub max_amount: i64","docs":""},{"module":"crowdy_game_kit_play::referee","name":"HitRules::min_amount","kind":"field","signature":"pub min_amount: i64","docs":"Damage clamp."},{"module":"crowdy_game_kit_play::referee","name":"HitRules::range","kind":"field","signature":"pub range: f32","docs":"Max distance between the attacker's actor and the target."},{"module":"crowdy_game_kit_play::referee","name":"KillRecord","kind":"struct","signature":"pub struct KillRecord { pub killer_user_id: String, pub at_ms: u64, pub respawn_at_ms: u64, }","docs":""},{"module":"crowdy_game_kit_play::referee","name":"KillRecord::at_ms","kind":"field","signature":"pub at_ms: u64","docs":""},{"module":"crowdy_game_kit_play::referee","name":"KillRecord::killer_user_id","kind":"field","signature":"pub killer_user_id: String","docs":""},{"module":"crowdy_game_kit_play::referee","name":"KillRecord::respawn_at_ms","kind":"field","signature":"pub respawn_at_ms: u64","docs":""},{"module":"crowdy_game_kit_play::referee","name":"RespawnBook","kind":"struct","signature":"pub struct RespawnBook { pub kills: HashMap<String, KillRecord>, }","docs":"Kill credit + respawn timers, keyed by the victim's id (slot container, player uuid, ...). Persist in module state."},{"module":"crowdy_game_kit_play::referee","name":"RespawnBook::due","kind":"method","signature":"pub fn due(&mut self, now_ms: u64) -> Vec<String>","docs":"Ids whose respawn timer elapsed (removed from the book)."},{"module":"crowdy_game_kit_play::referee","name":"RespawnBook::is_down","kind":"method","signature":"pub fn is_down(&self, victim_id: &str) -> bool","docs":"A victim currently down (dead, waiting on respawn)?"},{"module":"crowdy_game_kit_play::referee","name":"RespawnBook::kills","kind":"field","signature":"pub kills: HashMap<String, KillRecord>","docs":""},{"module":"crowdy_game_kit_play::referee","name":"RespawnBook::record_kill","kind":"method","signature":"pub fn record_kill(&mut self, victim_id: &str, killer_user_id: &str, now_ms: u64, respawn_ms: u64)","docs":""},{"module":"crowdy_game_kit_play::referee","name":"ValidHit","kind":"struct","signature":"pub struct ValidHit { pub amount: i64, }","docs":""},{"module":"crowdy_game_kit_play::referee","name":"ValidHit::amount","kind":"field","signature":"pub amount: i64","docs":""},{"module":"crowdy_game_kit_play::referee","name":"contact_event_body","kind":"function","signature":"pub fn contact_event_body(victim_uuid: &str, damage: i64, mob_id: &str, mob_name: &str) -> Value","docs":"The type-77 event body clients apply to their own stats (BWF shape)."},{"module":"crowdy_game_kit_play::referee","name":"hit_response","kind":"function","signature":"pub fn hit_response(outcome: &DamageOutcome) -> Value","docs":"The invoke response for an accepted hit (the `{success, health, killed}` envelope BWF clients already speak)."},{"module":"crowdy_game_kit_play::referee","name":"validate_hit","kind":"function","signature":"pub fn validate_hit( caller_user_id: &str, amount: i64, target_pos: (f32, f32, f32), target_alive: bool, tracker: &PlayerTracker, rules: &HitRules, book: &mut HitBook, now_ms: u64, ) -> Result<ValidHit, &'static str>","docs":"Validate an attack from `caller_user_id` against a target at `target_pos`. The tracker must be freshly refreshed (it is the presence referee)."},{"module":"crowdy_game_kit_play::score","name":"MatchSummary","kind":"struct","signature":"pub struct MatchSummary { pub winner_id: Option<String>, pub standings: Vec<Standing>, pub rounds_played: u32, pub decided_by: String, }","docs":"The published result of a decided match."},{"module":"crowdy_game_kit_play::score","name":"MatchSummary::decided_by","kind":"field","signature":"pub decided_by: String","docs":""},{"module":"crowdy_game_kit_play::score","name":"MatchSummary::rounds_played","kind":"field","signature":"pub rounds_played: u32","docs":""},{"module":"crowdy_game_kit_play::score","name":"MatchSummary::standings","kind":"field","signature":"pub standings: Vec<Standing>","docs":""},{"module":"crowdy_game_kit_play::score","name":"MatchSummary::winner_id","kind":"field","signature":"pub winner_id: Option<String>","docs":""},{"module":"crowdy_game_kit_play::score","name":"ScoreBook","kind":"struct","signature":"pub struct ScoreBook { pub scores: HashMap<String, i64>, /// Actors still in the running (forfeits/eliminations remove). pub active: Vec<String>, pub decided: Option<MatchSummary>, }","docs":""},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::active","kind":"field","signature":"pub active: Vec<String>","docs":"Actors still in the running (forfeits/eliminations remove)."},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::award","kind":"method","signature":"pub fn award(&mut self, actor_id: &str, points: i64) -> i64","docs":"Add points (engines call this from validated moves only)."},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::decided","kind":"field","signature":"pub decided: Option<MatchSummary>","docs":""},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::eliminate","kind":"method","signature":"pub fn eliminate(&mut self, actor_id: &str)","docs":"Remove an actor from contention (death/forfeit/disconnect)."},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::evaluate","kind":"method","signature":"pub fn evaluate( &mut self, condition: &WinCondition, rounds_played: u32, now_ms: u64, ) -> Option<&MatchSummary>","docs":"Evaluate the condition; the first decision sticks (idempotent after)."},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::new","kind":"method","signature":"pub fn new(actors: impl IntoIterator<Item = String>) -> Self","docs":""},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::score","kind":"method","signature":"pub fn score(&self, actor_id: &str) -> i64","docs":""},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::scores","kind":"field","signature":"pub scores: HashMap<String, i64>","docs":""},{"module":"crowdy_game_kit_play::score","name":"ScoreBook::standings","kind":"method","signature":"pub fn standings(&self) -> Vec<Standing>","docs":"Standings ordered by score desc (stable; rank is 1-based, ties share the earlier rank's position order but distinct ranks — simple v1)."},{"module":"crowdy_game_kit_play::score","name":"Standing","kind":"struct","signature":"pub struct Standing { pub actor_id: String, pub score: i64, pub rank: u32, }","docs":""},{"module":"crowdy_game_kit_play::score","name":"Standing::actor_id","kind":"field","signature":"pub actor_id: String","docs":""},{"module":"crowdy_game_kit_play::score","name":"Standing::rank","kind":"field","signature":"pub rank: u32","docs":""},{"module":"crowdy_game_kit_play::score","name":"Standing::score","kind":"field","signature":"pub score: i64","docs":""},{"module":"crowdy_game_kit_play::score","name":"WinCondition","kind":"enum","signature":"pub enum WinCondition { /// First to reach `target` points. ScoreReached { target: i64 }, /// Highest score when round `final_round` completes. BestOfRounds { final_round: u32 }, /// Last active participant standing (driven by forfeits/eliminations). LastStanding, /// Survive until the timer: highest score at `ends_at_ms`. TimeLimit { ends_at_ms: u64 }, }","docs":"When is the match decided?"},{"module":"crowdy_game_kit_play::score","name":"WinCondition::BestOfRounds","kind":"variant","signature":"BestOfRounds { final_round: u32 }","docs":"Highest score when round `final_round` completes."},{"module":"crowdy_game_kit_play::score","name":"WinCondition::LastStanding","kind":"variant","signature":"LastStanding","docs":"Last active participant standing (driven by forfeits/eliminations)."},{"module":"crowdy_game_kit_play::score","name":"WinCondition::ScoreReached","kind":"variant","signature":"ScoreReached { target: i64 }","docs":"First to reach `target` points."},{"module":"crowdy_game_kit_play::score","name":"WinCondition::TimeLimit","kind":"variant","signature":"TimeLimit { ends_at_ms: u64 }","docs":"Survive until the timer: highest score at `ends_at_ms`."},{"module":"crowdy_game_kit_play::score","name":"summary_json","kind":"function","signature":"pub fn summary_json(summary: &MatchSummary) -> Value","docs":"The summary as the JSON shape clients/events consume."},{"module":"crowdy_game_kit_play::timing","name":"Course","kind":"struct","signature":"pub struct Course { pub gates: Vec<Gate>, pub laps: u32, }","docs":"A course: ordered gates; a lap = passing every gate in order (gate 0 is the start/finish line)."},{"module":"crowdy_game_kit_play::timing","name":"Course::gates","kind":"field","signature":"pub gates: Vec<Gate>","docs":""},{"module":"crowdy_game_kit_play::timing","name":"Course::laps","kind":"field","signature":"pub laps: u32","docs":""},{"module":"crowdy_game_kit_play::timing","name":"GHOST_MAX_FRAMES","kind":"const","signature":"pub const GHOST_MAX_FRAMES: usize = 600;","docs":"Ghost tracks are capped so a long run cannot blow the state budget."},{"module":"crowdy_game_kit_play::timing","name":"Gate","kind":"struct","signature":"pub struct Gate { pub x: f32, pub z: f32, pub radius: f32, }","docs":"One ordered gate on a course."},{"module":"crowdy_game_kit_play::timing","name":"Gate::radius","kind":"field","signature":"pub radius: f32","docs":""},{"module":"crowdy_game_kit_play::timing","name":"Gate::x","kind":"field","signature":"pub x: f32","docs":""},{"module":"crowdy_game_kit_play::timing","name":"Gate::z","kind":"field","signature":"pub z: f32","docs":""},{"module":"crowdy_game_kit_play::timing","name":"GhostTrack","kind":"struct","signature":"pub struct GhostTrack { pub frames: Vec<(u32, f32, f32, f32, f32)>, pub started_at_ms: u64, }","docs":"A compact recorded pose track: (offset ms, x, y, z, yaw). Sampled at the recorder's cadence, replayed with linear interpolation."},{"module":"crowdy_game_kit_play::timing","name":"GhostTrack::duration_ms","kind":"method","signature":"pub fn duration_ms(&self) -> u32","docs":""},{"module":"crowdy_game_kit_play::timing","name":"GhostTrack::frame_at","kind":"method","signature":"pub fn frame_at(&self, offset_ms: u32) -> Option<(f32, f32, f32, f32)>","docs":"Interpolated pose at `offset_ms` into the replay (clamped to ends)."},{"module":"crowdy_game_kit_play::timing","name":"GhostTrack::frames","kind":"field","signature":"pub frames: Vec<(u32, f32, f32, f32, f32)>","docs":""},{"module":"crowdy_game_kit_play::timing","name":"GhostTrack::record","kind":"method","signature":"pub fn record(&mut self, now_ms: u64, x: f32, y: f32, z: f32, yaw: f32)","docs":"Record one frame (call per sample while the run is live)."},{"module":"crowdy_game_kit_play::timing","name":"GhostTrack::started_at_ms","kind":"field","signature":"pub started_at_ms: u64","docs":""},{"module":"crowdy_game_kit_play::timing","name":"RunTimer","kind":"struct","signature":"pub struct RunTimer { pub next_gate: usize, pub lap: u32, pub started_at_ms: u64, pub lap_started_at_ms: u64, pub splits_ms: Vec<u64>, pub best_lap_ms: u64, pub finished: bool, pub total_ms: u64, }","docs":"One racer's live run state."},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::best_lap_ms","kind":"field","signature":"pub best_lap_ms: u64","docs":""},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::feed","kind":"method","signature":"pub fn feed(&mut self, course: &Course, pos: (f32, f32), now_ms: u64) -> Vec<TimingEvent>","docs":"Feed one pose sample; returns the timing events it produced. The run starts when the racer first touches gate 0."},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::finished","kind":"field","signature":"pub finished: bool","docs":""},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::lap","kind":"field","signature":"pub lap: u32","docs":""},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::lap_started_at_ms","kind":"field","signature":"pub lap_started_at_ms: u64","docs":""},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::next_gate","kind":"field","signature":"pub next_gate: usize","docs":""},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::splits_ms","kind":"field","signature":"pub splits_ms: Vec<u64>","docs":""},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::started_at_ms","kind":"field","signature":"pub started_at_ms: u64","docs":""},{"module":"crowdy_game_kit_play::timing","name":"RunTimer::total_ms","kind":"field","signature":"pub total_ms: u64","docs":""},{"module":"crowdy_game_kit_play::timing","name":"TimingEvent","kind":"enum","signature":"pub enum TimingEvent { Started { at_ms: u64 }, Checkpoint { gate: usize, split_ms: u64 }, LapCompleted { lap: u32, lap_ms: u64, best: bool }, Finished { total_ms: u64, best_lap_ms: u64 }, }","docs":"Events produced by feeding poses through a run timer."},{"module":"crowdy_game_kit_play::timing","name":"TimingEvent::Checkpoint","kind":"variant","signature":"Checkpoint { gate: usize, split_ms: u64 }","docs":""},{"module":"crowdy_game_kit_play::timing","name":"TimingEvent::Finished","kind":"variant","signature":"Finished { total_ms: u64, best_lap_ms: u64 }","docs":""},{"module":"crowdy_game_kit_play::timing","name":"TimingEvent::LapCompleted","kind":"variant","signature":"LapCompleted { lap: u32, lap_ms: u64, best: bool }","docs":""},{"module":"crowdy_game_kit_play::timing","name":"TimingEvent::Started","kind":"variant","signature":"Started { at_ms: u64 }","docs":""},{"module":"crowdy_game_kit_play::turns","name":"RevealRound","kind":"struct","signature":"pub struct RevealRound { pub expected: Vec<String>, pub submissions: Vec<(String, serde_json::Value)>, pub deadline_ms: u64, }","docs":"Collects one hidden submission per actor, then resolves when everyone (or the deadline) is in. Submissions stay module-side until reveal."},{"module":"crowdy_game_kit_play::turns","name":"RevealRound::complete","kind":"method","signature":"pub fn complete(&self) -> bool","docs":""},{"module":"crowdy_game_kit_play::turns","name":"RevealRound::deadline_ms","kind":"field","signature":"pub deadline_ms: u64","docs":""},{"module":"crowdy_game_kit_play::turns","name":"RevealRound::expected","kind":"field","signature":"pub expected: Vec<String>","docs":""},{"module":"crowdy_game_kit_play::turns","name":"RevealRound::new","kind":"method","signature":"pub fn new(expected: Vec<String>, now_ms: u64, window_ms: u64) -> Self","docs":""},{"module":"crowdy_game_kit_play::turns","name":"RevealRound::ready","kind":"method","signature":"pub fn ready(&self, now_ms: u64) -> bool","docs":"Ready to reveal: everyone submitted, or the window closed."},{"module":"crowdy_game_kit_play::turns","name":"RevealRound::reveal","kind":"method","signature":"pub fn reveal(self) -> Vec<(String, serde_json::Value)>","docs":"Consume and return all submissions (the reveal)."},{"module":"crowdy_game_kit_play::turns","name":"RevealRound::submissions","kind":"field","signature":"pub submissions: Vec<(String, serde_json::Value)>","docs":""},{"module":"crowdy_game_kit_play::turns","name":"RevealRound::submit","kind":"method","signature":"pub fn submit(&mut self, actor_id: &str, payload: serde_json::Value) -> Result<(), &'static str>","docs":"Record a submission. Duplicates and strangers are rejected."},{"module":"crowdy_game_kit_play::turns","name":"TimeoutPolicy","kind":"enum","signature":"pub enum TimeoutPolicy { /// The actor's turn is skipped (turn passes on). Skip, /// The actor forfeits and is removed from the order. Forfeit, /// Nothing happens automatically (a human host decides). Wait, }","docs":"What happens when a turn timer expires."},{"module":"crowdy_game_kit_play::turns","name":"TimeoutPolicy::Forfeit","kind":"variant","signature":"Forfeit","docs":"The actor forfeits and is removed from the order."},{"module":"crowdy_game_kit_play::turns","name":"TimeoutPolicy::Skip","kind":"variant","signature":"Skip","docs":"The actor's turn is skipped (turn passes on)."},{"module":"crowdy_game_kit_play::turns","name":"TimeoutPolicy::Wait","kind":"variant","signature":"Wait","docs":"Nothing happens automatically (a human host decides)."},{"module":"crowdy_game_kit_play::turns","name":"TimeoutPolicy::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnActor","kind":"struct","signature":"pub struct TurnActor { /// Stable id (user id, unit container id, ...). pub id: String, /// Higher acts first; ties keep insertion order (stable sort). pub initiative: i64, /// Forfeited/dead actors stay recorded but are skipped. pub active: bool, }","docs":"One participant in the order."},{"module":"crowdy_game_kit_play::turns","name":"TurnActor::active","kind":"field","signature":"pub active: bool","docs":"Forfeited/dead actors stay recorded but are skipped."},{"module":"crowdy_game_kit_play::turns","name":"TurnActor::id","kind":"field","signature":"pub id: String","docs":"Stable id (user id, unit container id, ...)."},{"module":"crowdy_game_kit_play::turns","name":"TurnActor::initiative","kind":"field","signature":"pub initiative: i64","docs":"Higher acts first; ties keep insertion order (stable sort)."},{"module":"crowdy_game_kit_play::turns","name":"TurnEvent","kind":"enum","signature":"pub enum TurnEvent { TurnStarted { actor_id: String, round: u32, turn_in_round: u32 }, RoundStarted { round: u32 }, ActorSkipped { actor_id: String }, ActorForfeited { actor_id: String }, /// One (or zero) active actors remain. OrderExhausted, }","docs":"An event the engine should announce (turn changed, round advanced, ...)."},{"module":"crowdy_game_kit_play::turns","name":"TurnEvent::ActorForfeited","kind":"variant","signature":"ActorForfeited { actor_id: String }","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnEvent::ActorSkipped","kind":"variant","signature":"ActorSkipped { actor_id: String }","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnEvent::OrderExhausted","kind":"variant","signature":"OrderExhausted","docs":"One (or zero) active actors remain."},{"module":"crowdy_game_kit_play::turns","name":"TurnEvent::RoundStarted","kind":"variant","signature":"RoundStarted { round: u32 }","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnEvent::TurnStarted","kind":"variant","signature":"TurnStarted { actor_id: String, round: u32, turn_in_round: u32 }","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder","kind":"struct","signature":"pub struct TurnOrder { pub actors: Vec<TurnActor>, /// Index into `actors` of the current turn holder. pub current: usize, pub round: u32, pub turn_in_round: u32, /// Current turn deadline (0 = no timer). pub deadline_ms: u64, pub turn_duration_ms: u64, pub timeout_policy: TimeoutPolicy, started: bool, }","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::active_count","kind":"method","signature":"pub fn active_count(&self) -> usize","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::actors","kind":"field","signature":"pub actors: Vec<TurnActor>","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::advance","kind":"method","signature":"pub fn advance(&mut self, now_ms: u64) -> Vec<TurnEvent>","docs":"Advance to the next active actor (call when the current turn ends)."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::current","kind":"field","signature":"pub current: usize","docs":"Index into `actors` of the current turn holder."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::current_actor","kind":"method","signature":"pub fn current_actor(&self) -> Option<&TurnActor>","docs":"The current turn holder (None before start / after exhaustion)."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::deadline_ms","kind":"field","signature":"pub deadline_ms: u64","docs":"Current turn deadline (0 = no timer)."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::forfeit","kind":"method","signature":"pub fn forfeit(&mut self, actor_id: &str, now_ms: u64) -> Vec<TurnEvent>","docs":"Remove an actor from the running order (death, rage-quit). Advances the turn when it was theirs."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::new","kind":"method","signature":"pub fn new( actors: impl IntoIterator<Item = (String, i64)>, turn_duration_ms: u64, timeout_policy: TimeoutPolicy, ) -> Self","docs":"Build an order from (id, initiative) pairs; sorts by initiative descending (stable — ties keep the given order)."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::remaining_ms","kind":"method","signature":"pub fn remaining_ms(&self, now_ms: u64) -> Option<u64>","docs":"Milliseconds left on the current turn (None = no timer / not started)."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::round","kind":"field","signature":"pub round: u32","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::start","kind":"method","signature":"pub fn start(&mut self, now_ms: u64) -> Vec<TurnEvent>","docs":"Begin round 1, turn 1. Returns the announce events."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::tick","kind":"method","signature":"pub fn tick(&mut self, now_ms: u64) -> Vec<TurnEvent>","docs":"Apply the timeout policy if the current turn's deadline passed."},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::timeout_policy","kind":"field","signature":"pub timeout_policy: TimeoutPolicy","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::turn_duration_ms","kind":"field","signature":"pub turn_duration_ms: u64","docs":""},{"module":"crowdy_game_kit_play::turns","name":"TurnOrder::turn_in_round","kind":"field","signature":"pub turn_in_round: u32","docs":""},{"module":"crowdy_game_kit_sim","name":"core","kind":"reexport","signature":"pub use crowdy_game_kit_core as core;","docs":""},{"module":"crowdy_game_kit_sim","name":"daycycle","kind":"module","signature":"pub mod daycycle;","docs":""},{"module":"crowdy_game_kit_sim","name":"grow","kind":"module","signature":"pub mod grow;","docs":""},{"module":"crowdy_game_kit_sim","name":"nodes","kind":"module","signature":"pub mod nodes;","docs":""},{"module":"crowdy_game_kit_sim","name":"terrain","kind":"module","signature":"pub mod terrain;","docs":""},{"module":"crowdy_game_kit_sim","name":"waves","kind":"module","signature":"pub mod waves;","docs":""},{"module":"crowdy_game_kit_sim","name":"weather","kind":"module","signature":"pub mod weather;","docs":""},{"module":"crowdy_game_kit_sim","name":"zones","kind":"module","signature":"pub mod zones;","docs":""},{"module":"crowdy_game_kit_sim::daycycle","name":"DEFAULT_DAY_LENGTH_MS","kind":"const","signature":"pub const DEFAULT_DAY_LENGTH_MS: u64 = 1_200_000;","docs":""},{"module":"crowdy_game_kit_sim::daycycle","name":"DayCycle","kind":"struct","signature":"pub struct DayCycle { pub day_length_ms: u64, }","docs":""},{"module":"crowdy_game_kit_sim::daycycle","name":"DayCycle::day_index","kind":"method","signature":"pub fn day_index(&self, now_ms: u64) -> u64","docs":"Day number since epoch (season math, daily resets)."},{"module":"crowdy_game_kit_sim::daycycle","name":"DayCycle::day_length_ms","kind":"field","signature":"pub day_length_ms: u64","docs":""},{"module":"crowdy_game_kit_sim::daycycle","name":"DayCycle::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_sim::daycycle","name":"DayCycle::is_night","kind":"method","signature":"pub fn is_night(&self, now_ms: u64) -> bool","docs":"The BWF convention: night when sin(phase*TAU) dips below -0.05."},{"module":"crowdy_game_kit_sim::daycycle","name":"DayCycle::new","kind":"method","signature":"pub fn new(day_length_ms: u64) -> Self","docs":""},{"module":"crowdy_game_kit_sim::daycycle","name":"DayCycle::phase","kind":"method","signature":"pub fn phase(&self, now_ms: u64) -> f32","docs":"Phase in [0, 1): 0 = day start, 0.5 = day/night boundary region."},{"module":"crowdy_game_kit_sim::daycycle","name":"DayCycle::sun","kind":"method","signature":"pub fn sun(&self, now_ms: u64) -> f32","docs":"Sun height in [-1, 1] (drive lighting / spawn weights)."},{"module":"crowdy_game_kit_sim::grow","name":"GrowthRule","kind":"struct","signature":"pub struct GrowthRule { pub from_block: i64, pub grow_seconds: f64, pub structure: Vec<Placement>, /// Whether the planter uuid is stamped onto hard placements' state. pub keep_planter: bool, }","docs":"A growth rule: voxels of `from_block` older than `grow_seconds` become `structure` (relative to the plant position)."},{"module":"crowdy_game_kit_sim::grow","name":"GrowthRule::from_block","kind":"field","signature":"pub from_block: i64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"GrowthRule::grow_seconds","kind":"field","signature":"pub grow_seconds: f64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"GrowthRule::keep_planter","kind":"field","signature":"pub keep_planter: bool","docs":"Whether the planter uuid is stamped onto hard placements' state."},{"module":"crowdy_game_kit_sim::grow","name":"GrowthRule::structure","kind":"field","signature":"pub structure: Vec<Placement>","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"Placement","kind":"struct","signature":"pub struct Placement { pub dx: i64, pub dy: i64, pub dz: i64, pub block: i32, /// Soft placements (canopy leaves) skip positions with a player edit; /// hard ones (trunk) always write. pub soft: bool, }","docs":"One relative voxel write of a grown structure."},{"module":"crowdy_game_kit_sim::grow","name":"Placement::block","kind":"field","signature":"pub block: i32","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"Placement::dx","kind":"field","signature":"pub dx: i64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"Placement::dy","kind":"field","signature":"pub dy: i64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"Placement::dz","kind":"field","signature":"pub dz: i64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"Placement::soft","kind":"field","signature":"pub soft: bool","docs":"Soft placements (canopy leaves) skip positions with a player edit; hard ones (trunk) always write."},{"module":"crowdy_game_kit_sim::grow","name":"RipePlant","kind":"struct","signature":"pub struct RipePlant { pub chunk: (i64, i64, i64), pub local: (i64, i64, i64), pub planter_uuid: Option<String>, pub rule_index: usize, }","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"RipePlant::chunk","kind":"field","signature":"pub chunk: (i64, i64, i64)","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"RipePlant::local","kind":"field","signature":"pub local: (i64, i64, i64)","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"RipePlant::planter_uuid","kind":"field","signature":"pub planter_uuid: Option<String>","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"RipePlant::rule_index","kind":"field","signature":"pub rule_index: usize","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"ScanBand","kind":"struct","signature":"pub struct ScanBand { pub radius_xz: i64, pub y_min: i64, pub y_max: i64, }","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"ScanBand::radius_xz","kind":"field","signature":"pub radius_xz: i64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"ScanBand::ring","kind":"method","signature":"pub fn ring(&self) -> Vec<(i64, i64, i64)>","docs":"The band's chunks in the stable cursor order."},{"module":"crowdy_game_kit_sim::grow","name":"ScanBand::y_max","kind":"field","signature":"pub y_max: i64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"ScanBand::y_min","kind":"field","signature":"pub y_min: i64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"ScanCursor","kind":"struct","signature":"pub struct ScanCursor { pub cursor: u64, }","docs":"Round-robin cursor over a fixed chunk band (x/z square, y band) — persists in module state so scanning survives re-lease."},{"module":"crowdy_game_kit_sim::grow","name":"ScanCursor::cursor","kind":"field","signature":"pub cursor: u64","docs":""},{"module":"crowdy_game_kit_sim::grow","name":"build","kind":"function","signature":"pub fn build(plant: &RipePlant, rule: &GrowthRule, chunk_size: i64)","docs":"Build the rule's structure at the plant. Soft placements skip positions with a recorded non-air voxel edit (player builds are never overwritten; procedural base terrain is invisible to modules and tolerated)."},{"module":"crowdy_game_kit_sim::grow","name":"scan","kind":"function","signature":"pub fn scan( band: &ScanBand, cursor: &mut ScanCursor, rules: &[GrowthRule], now_seconds: f64, chunks_per_tick: usize, ) -> Option<RipePlant>","docs":"Scan up to `chunks_per_tick` chunks for the first ripe plant matching any rule. Advances the cursor; one db-op per scanned chunk."},{"module":"crowdy_game_kit_sim::grow","name":"stage","kind":"function","signature":"pub fn stage(planted_seconds: f64, now_seconds: f64, grow_seconds: f64, stages: u32) -> u32","docs":"Pure growth-stage math for client-side rendering parity: which stage of `stages` a plant with `planted_seconds` is in at `now_seconds`, given the full cycle takes `grow_seconds`."},{"module":"crowdy_game_kit_sim::grow","name":"tree_structure","kind":"function","signature":"pub fn tree_structure(wood: i32, leaves: i32) -> Vec<Placement>","docs":"The classic BWF tree: 4-block trunk (wood 4) + manhattan canopy (leaves 5) — byte-identical to the bwf-world-tick original."},{"module":"crowdy_game_kit_sim::nodes","name":"HarvestOutcome","kind":"struct","signature":"pub struct HarvestOutcome { pub harvested: bool, pub depleted: bool, }","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"HarvestOutcome::depleted","kind":"field","signature":"pub depleted: bool","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"HarvestOutcome::harvested","kind":"field","signature":"pub harvested: bool","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"Node","kind":"struct","signature":"pub struct Node { pub phase: NodePhase, /// Remaining harvests before depletion (0 = infinite until depleted /// explicitly). pub charges: u32, }","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"Node::charges","kind":"field","signature":"pub charges: u32","docs":"Remaining harvests before depletion (0 = infinite until depleted explicitly)."},{"module":"crowdy_game_kit_sim::nodes","name":"Node::phase","kind":"field","signature":"pub phase: NodePhase","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"NodePhase","kind":"enum","signature":"pub enum NodePhase { Ready, /// Depleted; respawns at the embedded time. Respawning { at_ms: u64 }, }","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"NodePhase::Ready","kind":"variant","signature":"Ready","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"NodePhase::Respawning","kind":"variant","signature":"Respawning { at_ms: u64 }","docs":"Depleted; respawns at the embedded time."},{"module":"crowdy_game_kit_sim::nodes","name":"NodePhase::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"NodePool","kind":"struct","signature":"pub struct NodePool { pub nodes: HashMap<String, Node>, }","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"NodePool::ensure","kind":"method","signature":"pub fn ensure(&mut self, id: &str, charges: u32) -> &mut Node","docs":"Register a node (idempotent; keeps existing state)."},{"module":"crowdy_game_kit_sim::nodes","name":"NodePool::harvest","kind":"method","signature":"pub fn harvest(&mut self, id: &str, now_ms: u64, respawn_ms: u64) -> HarvestOutcome","docs":"Attempt a harvest. Depletes when charges run out."},{"module":"crowdy_game_kit_sim::nodes","name":"NodePool::is_ready","kind":"method","signature":"pub fn is_ready(&self, id: &str) -> bool","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"NodePool::nodes","kind":"field","signature":"pub nodes: HashMap<String, Node>","docs":""},{"module":"crowdy_game_kit_sim::nodes","name":"NodePool::tick","kind":"method","signature":"pub fn tick(&mut self, now_ms: u64, recharge: u32) -> Vec<String>","docs":"Tick respawns: returns ids that just came back (re-arm charges)."},{"module":"crowdy_game_kit_sim::terrain","name":"TerrainCache","kind":"struct","signature":"pub struct TerrainCache { chunk_size: i64, ttl_ms: u64, max_fetches_per_tick: u32, fetches_this_tick: u32, chunks: HashMap<(i64, i64, i64), CachedChunk>, }","docs":""},{"module":"crowdy_game_kit_sim::terrain","name":"TerrainCache::begin_tick","kind":"method","signature":"pub fn begin_tick(&mut self, now: u64)","docs":"Call once at the top of each tick: resets the fetch budget and evicts expired entries (so edits players make show up within `ttl_ms`)."},{"module":"crowdy_game_kit_sim::terrain","name":"TerrainCache::block_at","kind":"method","signature":"pub fn block_at(&mut self, x: i64, y: i64, z: i64, now: u64) -> Option<u8>","docs":"The block byte at a world position; `None` = unknown (unloaded chunk, fetch budget exhausted, or host error)."},{"module":"crowdy_game_kit_sim::terrain","name":"TerrainCache::ground_y","kind":"method","signature":"pub fn ground_y(&mut self, x: f32, z: f32, scan_top: i64, now: u64) -> Option<f32>","docs":"The walk height for column (x, z): one block above the first solid block scanning down from `scan_top`. `None` = terrain unknown — callers should keep the agent's current height (fail-soft)."},{"module":"crowdy_game_kit_sim::terrain","name":"TerrainCache::new","kind":"method","signature":"pub fn new(chunk_size: i64, ttl_ms: u64, max_fetches_per_tick: u32) -> Self","docs":""},{"module":"crowdy_game_kit_sim::waves","name":"WaveDef","kind":"struct","signature":"pub struct WaveDef { /// Entries: (unit id, count). pub units: Vec<(String, u32)>, /// Delay after the previous wave clears (or starts, for timed mode). pub delay_ms: u64, }","docs":""},{"module":"crowdy_game_kit_sim::waves","name":"WaveDef::delay_ms","kind":"field","signature":"pub delay_ms: u64","docs":"Delay after the previous wave clears (or starts, for timed mode)."},{"module":"crowdy_game_kit_sim::waves","name":"WaveDef::units","kind":"field","signature":"pub units: Vec<(String, u32)>","docs":"Entries: (unit id, count)."},{"module":"crowdy_game_kit_sim::waves","name":"WaveEvent","kind":"enum","signature":"pub enum WaveEvent { /// Spawn this wave's units now. Start(usize), Finished, }","docs":""},{"module":"crowdy_game_kit_sim::waves","name":"WaveEvent::Finished","kind":"variant","signature":"Finished","docs":""},{"module":"crowdy_game_kit_sim::waves","name":"WaveEvent::Start","kind":"variant","signature":"Start(usize)","docs":"Spawn this wave's units now."},{"module":"crowdy_game_kit_sim::waves","name":"WavePhase","kind":"enum","signature":"pub enum WavePhase { /// Before wave `next` starts; starts at the embedded time. Countdown { next: usize, starts_at_ms: u64 }, /// Wave `index` is live. Active { index: usize }, /// All waves done. Complete, }","docs":""},{"module":"crowdy_game_kit_sim::waves","name":"WavePhase::Active","kind":"variant","signature":"Active { index: usize }","docs":"Wave `index` is live."},{"module":"crowdy_game_kit_sim::waves","name":"WavePhase::Complete","kind":"variant","signature":"Complete","docs":"All waves done."},{"module":"crowdy_game_kit_sim::waves","name":"WavePhase::Countdown","kind":"variant","signature":"Countdown { next: usize, starts_at_ms: u64 }","docs":"Before wave `next` starts; starts at the embedded time."},{"module":"crowdy_game_kit_sim::waves","name":"WaveSchedule","kind":"struct","signature":"pub struct WaveSchedule { pub phase: WavePhase, }","docs":""},{"module":"crowdy_game_kit_sim::waves","name":"WaveSchedule::default","kind":"method","signature":"fn default() -> Self","docs":""},{"module":"crowdy_game_kit_sim::waves","name":"WaveSchedule::phase","kind":"field","signature":"pub phase: WavePhase","docs":""},{"module":"crowdy_game_kit_sim::waves","name":"WaveSchedule::start","kind":"method","signature":"pub fn start(waves: &[WaveDef], now_ms: u64) -> Self","docs":"Arm the schedule from wave 0 with the first delay."},{"module":"crowdy_game_kit_sim::waves","name":"WaveSchedule::step","kind":"method","signature":"pub fn step(&mut self, waves: &[WaveDef], now_ms: u64, active_cleared: bool) -> Option<WaveEvent>","docs":"Advance. `active_cleared` = the live wave's units are all dead."},{"module":"crowdy_game_kit_sim::weather","name":"EVENT_WEATHER","kind":"const","signature":"pub const EVENT_WEATHER: u16 = 90;","docs":"The platform-reserved server-event type for weather/season transitions."},{"module":"crowdy_game_kit_sim::weather","name":"Transition","kind":"struct","signature":"pub struct Transition { pub from: String, pub to: String, pub until_ms: u64, }","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"Transition::from","kind":"field","signature":"pub from: String","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"Transition::to","kind":"field","signature":"pub to: String","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"Transition::until_ms","kind":"field","signature":"pub until_ms: u64","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"WeatherKind","kind":"struct","signature":"pub struct WeatherKind { pub id: String, /// Relative pick weight (0 disables). pub weight: u32, pub min_ms: u64, pub max_ms: u64, }","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"WeatherKind::id","kind":"field","signature":"pub id: String","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"WeatherKind::max_ms","kind":"field","signature":"pub max_ms: u64","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"WeatherKind::min_ms","kind":"field","signature":"pub min_ms: u64","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"WeatherKind::weight","kind":"field","signature":"pub weight: u32","docs":"Relative pick weight (0 disables)."},{"module":"crowdy_game_kit_sim::weather","name":"WeatherState","kind":"struct","signature":"pub struct WeatherState { pub current: String, pub since_ms: u64, pub until_ms: u64, }","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"WeatherState::current","kind":"field","signature":"pub current: String","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"WeatherState::since_ms","kind":"field","signature":"pub since_ms: u64","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"WeatherState::until_ms","kind":"field","signature":"pub until_ms: u64","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"default_kinds","kind":"function","signature":"pub fn default_kinds() -> Vec<WeatherKind>","docs":""},{"module":"crowdy_game_kit_sim::weather","name":"emit_transition","kind":"function","signature":"pub fn emit_transition( chunk: (i64, i64, i64), uuid_hex: &str, state: &WeatherState, now_ms: u64, distance: u8, ) -> Result<Value, HostError>","docs":"Broadcast a transition as a type-90 server event at `chunk`."},{"module":"crowdy_game_kit_sim::weather","name":"front_json","kind":"function","signature":"pub fn front_json(state: &WeatherState, now_ms: u64) -> Value","docs":"The client-facing JSON for a front (both the event body and `forecast`)."},{"module":"crowdy_game_kit_sim::weather","name":"step","kind":"function","signature":"pub fn step( state: &mut WeatherState, kinds: &[WeatherKind], now_ms: u64, rng: &mut Rng, ) -> Option<Transition>","docs":"Advance the front. Returns the transition when the front changed (emit it to clients), `None` while the current front holds."},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkPhase","kind":"struct","signature":"pub struct ShrinkPhase { /// The radius this phase shrinks TO. pub radius: f32, /// How long the zone HOLDS before shrinking (the warning window). pub hold_ms: u64, /// How long the shrink itself takes (radius interpolates linearly). pub shrink_ms: u64, }","docs":"One phase of a shrinking-zone schedule."},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkPhase::hold_ms","kind":"field","signature":"pub hold_ms: u64","docs":"How long the zone HOLDS before shrinking (the warning window)."},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkPhase::radius","kind":"field","signature":"pub radius: f32","docs":"The radius this phase shrinks TO."},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkPhase::shrink_ms","kind":"field","signature":"pub shrink_ms: u64","docs":"How long the shrink itself takes (radius interpolates linearly)."},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone","kind":"struct","signature":"pub struct ShrinkingZone { pub center: (f32, f32), pub initial_radius: f32, pub phases: Vec<ShrinkPhase>, pub started_at_ms: u64, /// Last phase-progress marker events were emitted for (phase, stage). announced: Vec<(usize, u8)>, }","docs":"A battle-royale circle: fixed center, radius stepping down a schedule. Pure clock math — feed it `now_ms`, read `radius()` and drain events."},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::center","kind":"field","signature":"pub center: (f32, f32)","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::contains","kind":"method","signature":"pub fn contains(&self, pos: (f32, f32), now_ms: u64) -> bool","docs":"Is a position inside the live circle?"},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::done","kind":"method","signature":"pub fn done(&self, now_ms: u64) -> bool","docs":"Every phase fully settled?"},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::initial_radius","kind":"field","signature":"pub initial_radius: f32","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::phases","kind":"field","signature":"pub phases: Vec<ShrinkPhase>","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::poll","kind":"method","signature":"pub fn poll(&mut self, now_ms: u64) -> Vec<ZoneEvent>","docs":"Advance the announcer: returns the events newly due at `now_ms` (warning at hold start, shrinking at shrink start, settled at end, final once after the last phase)."},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::radius","kind":"method","signature":"pub fn radius(&self, now_ms: u64) -> f32","docs":"The circle's radius at `now_ms` (linear interpolation during shrinks)."},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::start","kind":"method","signature":"pub fn start(center: (f32, f32), initial_radius: f32, phases: Vec<ShrinkPhase>, now_ms: u64) -> Self","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"ShrinkingZone::started_at_ms","kind":"field","signature":"pub started_at_ms: u64","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"Zone","kind":"struct","signature":"pub struct Zone { pub id: String, pub rule: String, pub min: (f32, f32, f32), pub max: (f32, f32, f32), }","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"Zone::contains","kind":"method","signature":"pub fn contains(&self, pos: (f32, f32, f32)) -> bool","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"Zone::id","kind":"field","signature":"pub id: String","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"Zone::max","kind":"field","signature":"pub max: (f32, f32, f32)","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"Zone::min","kind":"field","signature":"pub min: (f32, f32, f32)","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"Zone::rule","kind":"field","signature":"pub rule: String","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"ZoneEvent","kind":"enum","signature":"pub enum ZoneEvent { /// A hold began: the zone will start shrinking to `to_radius` at `at_ms`. Warning { phase: usize, to_radius: f32, shrink_starts_at_ms: u64 }, /// The shrink began. Shrinking { phase: usize, to_radius: f32 }, /// The phase's target radius was reached. Settled { phase: usize, radius: f32 }, /// Every phase is done (the final circle). Final { radius: f32 }, }","docs":"Announcements a shrinking zone produces as time advances."},{"module":"crowdy_game_kit_sim::zones","name":"ZoneEvent::Final","kind":"variant","signature":"Final { radius: f32 }","docs":"Every phase is done (the final circle)."},{"module":"crowdy_game_kit_sim::zones","name":"ZoneEvent::Settled","kind":"variant","signature":"Settled { phase: usize, radius: f32 }","docs":"The phase's target radius was reached."},{"module":"crowdy_game_kit_sim::zones","name":"ZoneEvent::Shrinking","kind":"variant","signature":"Shrinking { phase: usize, to_radius: f32 }","docs":"The shrink began."},{"module":"crowdy_game_kit_sim::zones","name":"ZoneEvent::Warning","kind":"variant","signature":"Warning { phase: usize, to_radius: f32, shrink_starts_at_ms: u64 }","docs":"A hold began: the zone will start shrinking to `to_radius` at `at_ms`."},{"module":"crowdy_game_kit_sim::zones","name":"ZoneSet","kind":"struct","signature":"pub struct ZoneSet { pub zones: Vec<Zone>, }","docs":""},{"module":"crowdy_game_kit_sim::zones","name":"ZoneSet::at","kind":"method","signature":"pub fn at(&self, pos: (f32, f32, f32)) -> Vec<&Zone>","docs":"All zones containing the position."},{"module":"crowdy_game_kit_sim::zones","name":"ZoneSet::has_rule","kind":"method","signature":"pub fn has_rule(&self, pos: (f32, f32, f32), rule: &str) -> bool","docs":"Does any zone with this rule cover the position?"},{"module":"crowdy_game_kit_sim::zones","name":"ZoneSet::zones","kind":"field","signature":"pub zones: Vec<Zone>","docs":""}]}
@@ -0,0 +1,19 @@
1
+ {
2
+ "assets": [
3
+ {
4
+ "name": "web-tree-sitter.wasm",
5
+ "bytes": 201037,
6
+ "provenance": "web-tree-sitter@0.26.11"
7
+ },
8
+ {
9
+ "name": "tree-sitter-rust.wasm",
10
+ "bytes": 1113644,
11
+ "provenance": "@vscode/tree-sitter-wasm@0.3.1 (VS Code generated Rust grammar)"
12
+ },
13
+ {
14
+ "name": "browser-authoring-index.json",
15
+ "bytes": 140085,
16
+ "provenance": "cks-game-api generated browser authoring index"
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,2 @@
1
+ export declare const GENERATED_BROWSER_AUTHORING_INDEX: unknown;
2
+ //# sourceMappingURL=browser-authoring-index.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-authoring-index.generated.d.ts","sourceRoot":"","sources":["../../src/live-coding/browser-authoring-index.generated.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,iCAAiC,EAAE,OAqgK/C,CAAC"}