Windows spacetime w/ rapier build rust panic
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"] }
It is maybe happening because the wasm instance is trying to import some undefined resources, especially that wasm-bindgen feature on rapier3d crate, or other dependencies that might happen to use a std unsupported feature for spacetimedb.
You see, even if spacetime-db modules work on top of a wasm runtime, it is extremely different from the one that is used for wasm-bindgen which targets wasm runtimes underneath Javascript runtimes (like the browser, Node.js, Deno, Bun, ect...).
First, remove the wasm-bindgen feature on rapier3d.
And if the problem still persists, another work around on this is to use the non-std features on your dependencies (that once_cell is probably a potential culprit for this scenario), which prevent them from using std unsupported features.
It is maybe happening because the wasm instance is trying to import some undefined resources, especially that
wasm-bindgenfeature onrapier3dcrate, or other dependencies that might happen to use astdunsupported feature for spacetimedb.You see, even if
spacetime-dbmodules work on top of a wasm runtime, it is extremely different from the one that is used forwasm-bindgenwhich targets wasm runtimes underneath Javascript runtimes (like the browser, Node.js, Deno, Bun, ect...).First, remove the
wasm-bindgenfeature onrapier3d. And if the problem still persists, another work around on this is to use thenon-stdfeatures on your dependencies (thatonce_cellis probably a potential culprit for this scenario), which prevent them from usingstdunsupported features.
I’ll give it a try and keep you posted
couldn't get it work, I believe main blocker is rapier and its dependencies. I'll put this initiative on hold for now. thanks