clockworklabs / clockworklabs/SpacetimeDB
Windows spacetime w/ rapier build rust panic
Open
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 25.2k
- Forks
- 1.1k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 46
Description
I'm on windows x64 and experimenting with a simple lib file even when I comment-out most of my code:
lib.rs
use once_cell::sync::Lazy;
use spacetimedb::{
Identity, ReducerContext, ScheduleAt, Table, Timestamp,
};
// serde imports removed as they were unused
use std::time::Duration;
mod ai;
mod common;
mod game_logic;
mod inventory_logic;
mod physics;
mod reducers;
mod tick;
pub use crate::common::*;
pub use crate::reducers::player_actions::{gather_resource, move_player};
pub use crate::reducers::ship_actions::build_ship;
pub use crate::reducers::test_actions::{
apply_force_to_player, get_player_position, list_all_players, list_all_resources,
list_all_ships, spawn_test_player, spawn_test_resource, spawn_test_ship,
};
pub use crate::tick::server_tick;
#[spacetimedb::table(name = inventory)]
#[derive(Clone, Debug)]
pub struct InventoryData {
#[primary_key]
#[auto_inc]
pub inventory_id: u64,
#[index(btree)]
pub owner_player: Option<Identity>,
#[index(btree)]
pub owner_ship: Option<u64>,
#[index(btree)]
pub owner_ai: Option<u64>,
pub capacity: u32,
}
#[spacetimedb::table(name = inventory_item)]
#[derive(Clone, Debug)]
pub struct InventoryItemData {
#[primary_key]
#[auto_inc]
pub item_id: u64,
#[index(btree)]
pub inventory_id: u64,
pub resource_type: ResourceType,
pub quantity: u32,
}
#[spacetimedb::table(name = player, public)]
#[derive(Clone, Debug)]
pub struct PlayerData {
#[primary_key]
pub identity: Identity,
pub name: Option<String>,
pub health: u32,
#[unique]
pub inventory_id: u64,
pub position: Vec3,
pub rotation: Vec3,
pub online: bool,
}
#[spacetimedb::table(name = ai_player)]
#[derive(Clone, Debug)]
pub struct AIPlayerData {
#[primary_key]
#[auto_inc]
pub ai_id: u64,
pub name: String,
pub health: u32,
#[unique]
pub inventory_id: u64,
pub position: Vec3,
pub rotation: Vec3,
pub ai_state: AIState,
pub target_position: Option<Vec3>,
}
#[spacetimedb::table(name = ship)]
#[derive(Clone, Debug)]
pub struct ShipData {
#[primary_key]
#[auto_inc]
pub ship_id: u64,
#[index(btree)]
pub owner_identity: Option<Identity>,
#[index(btree)]
pub owner_ai_id: Option<u64>,
pub name: String,
pub health: u32,
#[unique]
pub inventory_id: u64,
pub position: Vec3,
pub rotation: Vec3,
pub sail_deployment: f32,
pub anchor_deployed: bool,
}
#[spacetimedb::table(name = ship_cannon)]
#[derive(Clone, Debug)]
pub struct ShipCannonData {
#[primary_key]
#[auto_inc]
pub cannon_id: u64,
#[index(btree)]
pub ship_id: u64,
pub horizontal_angle: f32,
pub vertical_angle: f32,
pub loaded_resource: Option<ResourceType>,
pub cooldown_finish_time: Option<Timestamp>,
}
#[spacetimedb::table(name = resource_node)]
#[derive(Clone, Debug)]
pub struct ResourceNodeData {
#[primary_key]
#[auto_inc]
pub resource_node_id: u64,
pub resource_type: ResourceType,
pub position: Vec3,
pub current_amount: u32,
pub max_amount: u32,
pub respawn_cooldown_finish_time: Option<Timestamp>,
}
#[spacetimedb::table(name = server_tick_schedule, public, scheduled(server_tick_reducer))]
#[derive(Clone, Debug)]
pub struct ServerTickSchedule {
#[primary_key]
#[auto_inc]
pub schedule_id: u64,
pub scheduled_at: ScheduleAt,
}
pub static STARTUP: Lazy<()> = Lazy::new(|| {
let _ = env_logger::try_init();
spacetimedb::log::info!("Global STARTUP: Initializing Physics World...");
// Try to initialize the physics world, but don't fail if it doesn't work
match std::panic::catch_unwind(|| {
physics::init_physics_world_state();
}) {
Ok(_) => spacetimedb::log::info!("Global STARTUP: Physics World Initialized."),
Err(e) => spacetimedb::log::error!("Global STARTUP: Physics World Initialization failed: {:?}", e),
}
});
#[spacetimedb::reducer(init)]
pub fn init(ctx: &ReducerContext, _timestamp: Timestamp) -> Result<(), String> {
spacetimedb::log::info!("Forcing STARTUP");
Lazy::force(&STARTUP);
spacetimedb::log::info!("Running init reducer.");
let count = ctx.db.server_tick_schedule().count();
spacetimedb::log::info!("Server tick schedule count: {}", count);
if count == 0 {
let tick_interval_duration = Duration::from_secs_f64(1.0 / SERVER_TICK_RATE_HZ);
spacetimedb::log::info!("Tick interval: {:?}", tick_interval_duration);
if tick_interval_duration.is_zero() {
let err_msg = "Server tick rate must be positive!".to_string();
spacetimedb::log::error!("{}", err_msg);
return Err(err_msg);
}
spacetimedb::log::info!(
"Scheduling initial server tick (interval: {:?})...",
tick_interval_duration
);
let schedule = ServerTickSchedule {
schedule_id: 0,
scheduled_at: ScheduleAt::Interval(tick_interval_duration.into()),
};
spacetimedb::log::info!("Attempting to insert schedule: {:?}", schedule);
match ctx.db.server_tick_schedule().try_insert(schedule) {
Ok(row) => spacetimedb::log::info!(
"Server tick schedule inserted successfully. ID: {}",
row.schedule_id
),
Err(e) => {
let err_msg = format!("FAILED to insert server tick schedule: {}", e);
spacetimedb::log::error!("{}", err_msg);
return Err(err_msg);
}
}
} else {
spacetimedb::log::info!("Server tick already scheduled.");
}
spacetimedb::log::info!("Init reducer completed successfully.");
Ok(())
}
#[spacetimedb::reducer(client_connected)]
pub fn identity_connected(ctx: &ReducerContext) {
let player_identity = ctx.sender;
spacetimedb::log::info!("Client connected: {:?}", player_identity);
if let Some(existing_player) = ctx.db.player().identity().find(player_identity) {
spacetimedb::log::info!("PlayerData {:?} reconnected.", player_identity);
let mut updated_player = existing_player.clone();
updated_player.online = true;
ctx.db.player().identity().update(updated_player.clone());
physics::create_player_body(&updated_player);
} else {
spacetimedb::log::info!(
"New player {:?} joining. Creating character.",
player_identity
);
let inventory_insert_result = ctx.db.inventory().try_insert(InventoryData {
inventory_id: 0,
owner_player: Some(player_identity),
owner_ship: None,
owner_ai: None,
capacity: DEFAULT_PLAYER_INVENTORY_CAPACITY,
});
let inventory = match inventory_insert_result {
Ok(inv) => inv,
Err(e) => {
spacetimedb::log::error!(
"Failed to create inventory for new player {:?}: {}",
player_identity,
e
);
return;
}
};
let player_name_num = identity_to_u64_simple(&player_identity);
let player_name = format!("Pirate_{}", player_name_num % 10000);
let new_player_data = PlayerData {
identity: player_identity,
name: Some(player_name.clone()),
health: PLAYER_DEFAULT_HEALTH,
inventory_id: inventory.inventory_id,
position: PLAYER_SPAWN_POS,
rotation: Vec3 {
x: 0.0,
y: 0.0,
z: 1.0,
},
online: true,
};
match ctx.db.player().try_insert(new_player_data.clone()) {
Ok(inserted_player) => {
spacetimedb::log::info!(
"PlayerData {:?} ({}) created successfully.",
player_identity,
player_name
);
physics::create_player_body(&inserted_player);
}
Err(e) => {
spacetimedb::log::error!(
"Failed to insert new player {:?}: {}",
player_identity,
e
);
ctx.db
.inventory()
.inventory_id()
.delete(inventory.inventory_id);
}
}
}
}
#[spacetimedb::reducer(client_disconnected)]
pub fn identity_disconnected(ctx: &ReducerContext) {
let player_identity = ctx.sender;
spacetimedb::log::info!("Client disconnected: {:?}", player_identity);
if let Some(player_to_update) = ctx.db.player().identity().find(player_identity) {
let mut updated_player = player_to_update.clone();
updated_player.online = false;
ctx.db.player().identity().update(updated_player);
spacetimedb::log::info!("PlayerData {:?} marked as disconnected.", player_identity);
physics::remove_player_body(&player_identity);
} else {
spacetimedb::log::warn!(
"Disconnect event for player {:?} who was not found in the PlayerData table.",
player_identity
);
}
}
#[spacetimedb::reducer]
pub fn move_player_reducer(
ctx: &ReducerContext,
direction: Vec3,
jump: bool,
run: bool,
) -> Result<(), String> {
reducers::player_actions::move_player(ctx, direction, jump, run)
}
#[spacetimedb::reducer]
pub fn gather_resource_reducer(ctx: &ReducerContext, node_id: u64) -> Result<(), String> {
reducers::player_actions::gather_resource(ctx, node_id)
}
#[spacetimedb::reducer]
pub fn build_ship_reducer(
ctx: &ReducerContext,
name: String,
position: Vec3,
) -> Result<(), String> {
reducers::ship_actions::build_ship(ctx, name, position)
}
#[spacetimedb::reducer]
pub fn spawn_test_player_reducer(
ctx: &ReducerContext,
position: Vec3,
name: String,
) -> Result<(), String> {
reducers::test_actions::spawn_test_player(ctx, position, name)
}
#[spacetimedb::reducer]
pub fn spawn_test_ship_reducer(
ctx: &ReducerContext,
position: Vec3,
name: String,
) -> Result<(), String> {
reducers::test_actions::spawn_test_ship(ctx, position, name)
}
#[spacetimedb::reducer]
pub fn spawn_test_resource_reducer(
ctx: &ReducerContext,
position: Vec3,
resource_type: ResourceType,
amount: u32,
) -> Result<(), String> {
reducers::test_actions::spawn_test_resource(ctx, position, resource_type, amount)
}
#[spacetimedb::reducer]
pub fn apply_force_to_player_reducer(
ctx: &ReducerContext,
direction: Vec3,
jump: bool,
run: bool,
) -> Result<(), String> {
reducers::test_actions::apply_force_to_player(ctx, direction, jump, run)
}
#[spacetimedb::reducer]
pub fn get_player_position_reducer(ctx: &ReducerContext) -> Result<(), String> {
reducers::test_actions::get_player_position(ctx)
}
#[spacetimedb::reducer]
pub fn list_all_players_reducer(ctx: &ReducerContext) -> Result<(), String> {
reducers::test_actions::list_all_players(ctx)
}
#[spacetimedb::reducer]
pub fn list_all_ships_reducer(ctx: &ReducerContext) -> Result<(), String> {
reducers::test_actions::list_all_ships(ctx)
}
#[spacetimedb::reducer]
pub fn list_all_resources_reducer(ctx: &ReducerContext) -> Result<(), String> {
reducers::test_actions::list_all_resources(ctx)
}
#[spacetimedb::reducer(update)]
pub fn server_tick_reducer(
ctx: &ReducerContext,
_tick_info: ServerTickSchedule, /* Remove _prev_tick_info argument */
) -> Result<(), String> {
let current_time = ctx.timestamp;
let zero_timestamp = Timestamp::from_micros_since_unix_epoch(0);
tick::server_tick(ctx, current_time, zero_timestamp);
Ok(())
}
Server output
ule.rs:14: reducer "init" runtime error: error while executing at wasm backtrace:
0: 0x1b258e - pirates_rust.wasm!__rust_start_panic
1: 0x1b24e9 - pirates_rust.wasm!rust_panic
2: 0x1b242e - pirates_rust.wasm!std::panicking::rust_panic_with_hook::h4501cceb7dbe383d
3: 0x1b18ed - pirates_rust.wasm!std::panicking::begin_panic_handler::{{closure}}::hc2b9d3fc26dda7f9
4: 0x1b1859 - pirates_rust.wasm!std::sys::backtrace::__rust_end_short_backtrace::hf6a83a0a2155b9c0
5: 0x1b1fc3 - pirates_rust.wasm!rust_begin_unwind
6: 0x1b82c8 - pirates_rust.wasm!core::panicking::panic_fmt::h619600efce2da276
7: 0x1b9f30 - pirates_rust.wasm!core::result::unwrap_failed::h4ec8ebc0cd29f54b
8: 0xa6ef - pirates_rust.wasm!pirates_rust::init::invoke::hf8b7175ed331661d
9: 0x1a62bc - pirates_rust.wasm!__call_reducer__
2025-04-09T20:01:00.975245Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #10: __rust_start_panic
2025-04-09T20:01:00.975330Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #9: rust_panic
2025-04-09T20:01:00.975382Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #8: std::panicking::rust_panic_with_hook::h4501cceb7dbe383d
2025-04-09T20:01:00.975446Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #7: std::panicking::begin_panic_handler::{{closure}}::hc2b9d3fc26dda7f9
2025-04-09T20:01:00.975501Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #6: std::sys::backtrace::__rust_end_short_backtrace::hf6a83a0a2155b9c0
2025-04-09T20:01:00.975577Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #5: rust_begin_unwind
2025-04-09T20:01:00.975633Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #4: core::panicking::panic_fmt::h619600efce2da276
2025-04-09T20:01:00.975715Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #3: core::result::unwrap_failed::h4ec8ebc0cd29f54b
2025-04-09T20:01:00.975790Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #2: pirates_rust::init::invoke::hf8b7175ed331661d
2025-04-09T20:01:00.975849Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #1: __call_reducer__
2025-04-09T20:01:00.977058Z ERROR D:\a\SpacetimeDB\SpacetimeDB\crates\client-api\src\lib.rs:373: internal error: failed to get or launch module host: The Wasm instance encountered a fatal error.
2025-04-09T20:01:00.977239Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:202: exiting persister task
2025-04-09T20:01:04.827510Z INFO crates\core\src\auth\token_validation.rs:209: Fetching key for issuer https://auth.spacetimedb.com
2025-04-09T20:01:37.969200Z DEBUG crates\core\src\auth\token_validation.rs:231: Getting validator for issuer https://auth.spacetimedb.com
2025-04-09T20:01:37.969327Z DEBUG crates\core\src\auth\token_validation.rs:301: No key id in header. Trying all keys.
2025-04-09T20:01:37.969442Z DEBUG crates\core\src\auth\token_validation.rs:306: Trying key 0
2025-04-09T20:01:37.970619Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:98: open local durability
2025-04-09T20:01:37.971154Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:257: starting syncer task
2025-04-09T20:01:37.971226Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:182: starting persister task
2025-04-09T20:01:37.971201Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:98: open local durability
2025-04-09T20:01:37.980608Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:257: starting syncer task
2025-04-09T20:01:37.980613Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:182: starting persister task
2025-04-09T20:01:37.980806Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\core\src\db\relational_db.rs:312: [c20045e7c025414a5edb2373c9119525107dca1e28b6ed85d28d42d4f2de8082] DATABASE: durable_tx_offset is None
2025-04-09T20:01:37.980897Z INFO crates\core\src\db\relational_db.rs:463: [c20045e7c025414a5edb2373c9119525107dca1e28b6ed85d28d42d4f2de8082] DATABASE: no snapshot on disk
2025-04-09T20:01:37.981234Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\core\src\db\relational_db.rs:1213: [c20045e7c025414a5edb2373c9119525107dca1e28b6ed85d28d42d4f2de8082] DATABASE: applying transaction history...
2025-04-09T20:01:37.989490Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\core\src\db\relational_db.rs:1247: [c20045e7c025414a5edb2373c9119525107dca1e28b6ed85d28d42d4f2de8082] DATABASE: applied transaction history
2025-04-09T20:01:37.989927Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\core\src\db\relational_db.rs:1249: [c20045e7c025414a5edb2373c9119525107dca1e28b6ed85d28d42d4f2de8082] DATABASE: rebuilt state after replay
2025-04-09T20:01:37.990135Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:202: exiting persister task
2025-04-09T20:01:38.013497Z DEBUG D:\a\SpacetimeDB\SpacetimeDB\crates\core\src\host\wasm_common\module_host_actor.rs:272: init database
2025-04-09T20:01:38.016376Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:14: reducer "init" runtime error: error while executing at wasm backtrace:
0: 0x1b258e - pirates_rust.wasm!__rust_start_panic
1: 0x1b24e9 - pirates_rust.wasm!rust_panic
2: 0x1b242e - pirates_rust.wasm!std::panicking::rust_panic_with_hook::h4501cceb7dbe383d
3: 0x1b18ed - pirates_rust.wasm!std::panicking::begin_panic_handler::{{closure}}::hc2b9d3fc26dda7f9
4: 0x1b1859 - pirates_rust.wasm!std::sys::backtrace::__rust_end_short_backtrace::hf6a83a0a2155b9c0
5: 0x1b1fc3 - pirates_rust.wasm!rust_begin_unwind
6: 0x1b82c8 - pirates_rust.wasm!core::panicking::panic_fmt::h619600efce2da276
7: 0x1b9f30 - pirates_rust.wasm!core::result::unwrap_failed::h4ec8ebc0cd29f54b
8: 0xa6ef - pirates_rust.wasm!pirates_rust::init::invoke::hf8b7175ed331661d
9: 0x1a62bc - pirates_rust.wasm!__call_reducer__
2025-04-09T20:01:38.016578Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #10: __rust_start_panic
2025-04-09T20:01:38.016650Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #9: rust_panic
2025-04-09T20:01:38.016714Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #8: std::panicking::rust_panic_with_hook::h4501cceb7dbe383d
2025-04-09T20:01:38.016769Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #7: std::panicking::begin_panic_handler::{{closure}}::hc2b9d3fc26dda7f9
2025-04-09T20:01:38.016823Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #6: std::sys::backtrace::__rust_end_short_backtrace::hf6a83a0a2155b9c0
2025-04-09T20:01:38.016875Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #5: rust_begin_unwind
2025-04-09T20:01:38.016919Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #4: core::panicking::panic_fmt::h619600efce2da276
2025-04-09T20:01:38.016977Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #3: core::result::unwrap_failed::h4ec8ebc0cd29f54b
2025-04-09T20:01:38.017031Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #2: pirates_rust::init::invoke::hf8b7175ed331661d
2025-04-09T20:01:38.017101Z INFO crates\core\src\host\wasmtime\wasmtime_module.rs:18: Frame #1: __call_reducer__
2025-04-09T20:01:38.018059Z ERROR D:\a\SpacetimeDB\SpacetimeDB\crates\client-api\src\lib.rs:373: internal error: failed to get or launch module host: The Wasm instance encountered a fatal error.
2025-04-09T20:01:38.018223Z INFO D:\a\SpacetimeDB\SpacetimeDB\crates\durability\src\imp\local.rs:202: exiting persister task
Builder output
Optimising module with wasm-opt...
Could not find wasm-opt to optimise the module.
For best performance install wasm-opt from https://github.com/WebAssembly/binaryen/releases.
Continuing with unoptimised module.
Build finished successfully.
Uploading to local => http://127.0.0.1:3000
Publishing module...
Error: failed to get or launch module host: The Wasm instance encountered a fatal error.
Caused by:
HTTP status server error (500 Internal Server Error) for url (http://127.0.0.1:3000/v1/database/pirates-rust)
Cargo.toml
[package]
name = "pirates-rust"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib"]
[dependencies]
spacetimedb = "1.0.1"
log = "0.4"
rapier3d = { version = "0.22.0", features = ["serde-serialize", "wasm-bindgen"] }
nalgebra = "0.33.2"
env_logger = "0.11.8"
serde = { version = "1.0.219", features = ["derive"] }
once_cell = "1.19.0"
tracing = { version = "0.1", features = ["max_level_debug", "release_max_level_warn"] }
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the Windows x64 failure while running the init reducer from lib.rs, then inspect physics::init_physics_world_state and the truncated server output. Determine why initialization panics with the Rapier build and verify that the init reducer completes successfully on Windows without the panic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100