try to implement world sync, prob made some mistakes but no crash is good enough for me

This commit is contained in:
bgkillas 2025-08-20 23:01:53 -04:00
parent ec3857c6b9
commit f78070e1b5
13 changed files with 735 additions and 440 deletions

46
ewext/Cargo.lock generated
View file

@ -52,9 +52,9 @@ checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7"
[[package]]
name = "bitcode"
version = "0.6.6"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf300f4aa6e66f3bdff11f1236a88c622fe47ea814524792240b4d554d9858ee"
checksum = "648bd963d2e5d465377acecfb4b827f9f553b6bc97a8f61715779e9ed9e52b74"
dependencies = [
"arrayvec",
"bitcode_derive",
@ -65,9 +65,9 @@ dependencies = [
[[package]]
name = "bitcode_derive"
version = "0.6.5"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42b6b4cb608b8282dc3b53d0f4c9ab404655d562674c682db7e6c0458cc83c23"
checksum = "ffebfc2d28a12b262c303cb3860ee77b91bd83b1f20f0bd2a9693008e2f55a9e"
dependencies = [
"proc-macro2",
"quote",
@ -76,9 +76,9 @@ dependencies = [
[[package]]
name = "bitflags"
version = "2.9.1"
version = "2.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29"
[[package]]
name = "bytemuck"
@ -88,9 +88,9 @@ checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677"
[[package]]
name = "cfg-if"
version = "1.0.1"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "crc32fast"
@ -226,9 +226,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.174"
version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "libloading"
@ -264,7 +264,7 @@ dependencies = [
"iced-x86",
"libloading",
"noita_api_macro",
"object 0.37.2",
"object 0.37.3",
"rayon",
"rustc-hash",
"shared",
@ -293,9 +293,9 @@ dependencies = [
[[package]]
name = "object"
version = "0.37.2"
version = "0.37.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e3d0a7419f081f4a808147e845310313a39f322d7ae1f996b7f001d6cbed04"
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
dependencies = [
"flate2",
"memchr",
@ -325,9 +325,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.95"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
@ -378,9 +378,9 @@ dependencies = [
[[package]]
name = "rayon"
version = "1.10.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
dependencies = [
"either",
"rayon-core",
@ -388,9 +388,9 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.12.1"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
@ -445,9 +445,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.142"
version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [
"itoa",
"memchr",
@ -494,9 +494,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.104"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",

View file

@ -221,6 +221,7 @@ fn with_every_module(
fps_by_player: &mut state.fps_by_player,
dont_spawn: &state.dont_spawn,
camera_pos: &mut state.cam_pos,
globals: state.globals.as_mut(),
};
let mut errs = Vec::new();
for module in state.modules.iter_mut() {

View file

@ -1,6 +1,7 @@
use bimap::BiHashMap;
use eyre::Ok;
use noita_api::EntityID;
use noita_api::addr_grabber::GlobalsMut;
use rustc_hash::{FxHashMap, FxHashSet};
use shared::des::Gid;
use shared::{PeerId, WorldPos};
@ -17,6 +18,7 @@ pub(crate) struct ModuleCtx<'a> {
pub(crate) camera_pos: &'a mut FxHashMap<PeerId, WorldPos>,
pub(crate) fps_by_player: &'a mut FxHashMap<PeerId, u8>,
pub(crate) dont_spawn: &'a FxHashSet<Gid>,
pub(crate) globals: GlobalsMut,
}
impl ModuleCtx<'_> {
pub(crate) fn locate_player_within_except_me(

View file

@ -1,10 +1,11 @@
use crate::WorldSync;
use crate::modules::{Module, ModuleCtx};
use crate::{WorldSync, my_peer_id};
use eyre::{ContextCompat, eyre};
use noita_api::noita::types::{CellType, FireCell, GasCell, LiquidCell};
use noita_api::noita::world::ParticleWorldState;
use shared::NoitaOutbound;
use shared::world_sync::{
CHUNK_SIZE, ChunkCoord, CompactPixel, NoitaWorldUpdate, ProxyToWorldSync,
CHUNK_SIZE, ChunkCoord, CompactPixel, NoitaWorldUpdate, ProxyToWorldSync, WorldSyncToProxy,
};
use std::mem::MaybeUninit;
use std::ptr;
@ -13,20 +14,35 @@ impl Module for WorldSync {
self.particle_world_state = MaybeUninit::new(ParticleWorldState::new()?);
Ok(())
}
fn on_world_update(&mut self, _ctx: &mut ModuleCtx) -> eyre::Result<()> {
/*let update = NoitaWorldUpdate {
coord: ChunkCoord(0, 0),
runs: Vec::with_capacity(16384),
fn on_world_update(&mut self, ctx: &mut ModuleCtx) -> eyre::Result<()> {
let Some(ent) = ctx.player_map.get_by_left(&my_peer_id()) else {
return Ok(());
};
let mut upd = std::array::from_fn(|_| None);
unsafe {
self.particle_world_state
.assume_init_ref()
.encode_world(ChunkCoord(-2, -7), &mut upd)?;
let Some(ent) = ctx.globals.entity_manager.get_entity(ent.0.get() as usize) else {
return Ok(());
};
let mut updates = Vec::with_capacity(25);
for dx in 0..5 {
let cx = ent.transform.pos.x as i32 / CHUNK_SIZE as i32 - 2 + dx;
for dy in 0..5 {
let cy = ent.transform.pos.y as i32 / CHUNK_SIZE as i32 - 2 + dy;
let mut update = NoitaWorldUpdate {
coord: ChunkCoord(cx, cy),
pixels: std::array::from_fn(|_| None),
};
if unsafe {
self.particle_world_state
.assume_init_ref()
.encode_world(update.coord, &mut update.pixels)
}
.is_ok()
{
updates.push(update);
}
}
}
std::hint::black_box(upd);
let msg = NoitaOutbound::WorldSyncToProxy(WorldSyncToProxy::Updates(vec![update]));
ctx.net.send(&msg)?;*/
let msg = NoitaOutbound::WorldSyncToProxy(WorldSyncToProxy::Updates(updates));
ctx.net.send(&msg)?;
Ok(())
}
}
@ -35,13 +51,12 @@ impl WorldSync {
match msg {
ProxyToWorldSync::Updates(updates) => {
for chunk in updates {
let time = std::time::Instant::now();
unsafe {
self.particle_world_state
let _ = self
.particle_world_state
.assume_init_ref()
.decode_world(chunk)?
.decode_world(chunk);
}
noita_api::print!("de {}", time.elapsed().as_micros());
}
}
}
@ -94,53 +109,49 @@ impl WorldData for ParticleWorldState {
let (shift_x, shift_y) = self.get_shift::<CHUNK_SIZE>(cx, cy);
let start_x = cx * CHUNK_SIZE as isize;
let start_y = cy * CHUNK_SIZE as isize;
let mut x = 0;
let mut y = 0;
for run in chunk.runs {
for _ in 0..run.length {
let cell = pixel_array.get_mut_raw(shift_x + x, shift_y + y);
let xs = start_x + x;
let ys = start_y + y;
let mat = &self
.material_list
.get_static(run.data.material as usize)
.unwrap();
match mat.cell_type {
CellType::None => {
*cell = ptr::null_mut();
}
CellType::Liquid => {
let liquid = Box::leak(Box::new(unsafe {
LiquidCell::create(mat, self.cell_vtables.liquid(), self.world_ptr)
}));
liquid.x = xs;
liquid.y = ys;
*cell = (liquid as *mut LiquidCell).cast();
}
CellType::Gas => {
let gas = Box::leak(Box::new(unsafe {
GasCell::create(mat, self.cell_vtables.gas(), self.world_ptr)
}));
gas.x = xs;
gas.y = ys;
*cell = (gas as *mut GasCell).cast();
}
CellType::Solid => {}
CellType::Fire => {
let fire = Box::leak(Box::new(unsafe {
FireCell::create(mat, self.cell_vtables.fire(), self.world_ptr)
}));
fire.x = xs;
fire.y = ys;
*cell = (fire as *mut FireCell).cast();
}
for (i, pixel) in chunk.pixels.iter().enumerate() {
let x = (i % CHUNK_SIZE) as isize;
let y = (i / CHUNK_SIZE) as isize;
let cell = pixel_array.get_mut_raw(shift_x + x, shift_y + y);
let xs = start_x + x;
let ys = start_y + y;
let Some(pixel) = pixel else {
*cell = ptr::null_mut();
continue;
};
let mat = self
.material_list
.get_static(pixel.material() as usize)
.unwrap();
match mat.cell_type {
CellType::None => {
*cell = ptr::null_mut();
}
CellType::Liquid => {
let liquid = Box::leak(Box::new(unsafe {
LiquidCell::create(mat, self.cell_vtables.liquid(), self.world_ptr)
}));
liquid.x = xs;
liquid.y = ys;
*cell = (liquid as *mut LiquidCell).cast();
}
CellType::Gas => {
let gas = Box::leak(Box::new(unsafe {
GasCell::create(mat, self.cell_vtables.gas(), self.world_ptr)
}));
gas.x = xs;
gas.y = ys;
*cell = (gas as *mut GasCell).cast();
}
CellType::Solid => {}
CellType::Fire => {
let fire = Box::leak(Box::new(unsafe {
FireCell::create(mat, self.cell_vtables.fire(), self.world_ptr)
}));
fire.x = xs;
fire.y = ys;
*cell = (fire as *mut FireCell).cast();
}
}
if x == CHUNK_SIZE as isize {
x = 0;
y += 1;
} else {
x += 1;
}
}
Ok(())