diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2026-08-18 22:22:27 -0700 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2026-08-18 22:22:27 -0700 |
| commit | 2640f91e36558650bb988dcc82b5148ee71f3eb0 (patch) | |
| tree | 5f67c648569109c84736b11b39cb6d2cd6b67e4d /src/sim/cell_sim | |
| parent | 92dd02d7cc4d9fc930760d26d81edbe2197a3fc0 (diff) | |
optimize with settlement counter
Diffstat (limited to 'src/sim/cell_sim')
| -rw-r--r-- | src/sim/cell_sim/chunk.rs | 9 | ||||
| -rw-r--r-- | src/sim/cell_sim/sim.rs | 32 |
2 files changed, 26 insertions, 15 deletions
diff --git a/src/sim/cell_sim/chunk.rs b/src/sim/cell_sim/chunk.rs index c7d619b..85d2c09 100644 --- a/src/sim/cell_sim/chunk.rs +++ b/src/sim/cell_sim/chunk.rs @@ -1,7 +1,10 @@ use crate::{ config::{CELLS_IN_CHUNK, CHUNK_SIZE}, sim::{ - cell::{cell::Cell, materials::MaterialId}, + cell::{ + cell::Cell, + materials::{MaterialForm, MaterialId}, + }, lib::marching_squares::Marchable, }, }; @@ -36,7 +39,9 @@ impl Marchable for Chunk { if x < 0 || x >= CHUNK_SIZE || y < 0 || y >= CHUNK_SIZE { false } else { - self.get_cell_at_local_position(x as u8, y as u8).material != MaterialId::Void + // we only build a path for solid cells or settled powder cells + let cell = self.get_cell_at_local_position(x as u8, y as u8); + cell.material.def().form == MaterialForm::Solid || cell.settled() > 4 } } fn size(&self) -> (i32, i32) { diff --git a/src/sim/cell_sim/sim.rs b/src/sim/cell_sim/sim.rs index 8831bb4..4b9f05f 100644 --- a/src/sim/cell_sim/sim.rs +++ b/src/sim/cell_sim/sim.rs @@ -5,14 +5,10 @@ use rand::{Rng, SeedableRng, rngs::SmallRng}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use crate::{ - config::{CELLS_IN_CHUNK, CHUNK_SIZE}, + config::CHUNK_SIZE, sim::{ - cell::{ - cell::Cell, - materials::{MaterialDef, MaterialId}, - }, + cell::{cell::Cell, materials::MaterialDef}, cell_sim::{chunk::Chunk, world::World}, - rb_sim::{RbSimManager, rb_entity::RbEntity}, }, }; @@ -87,6 +83,7 @@ pub struct UpdateCtx<'a, 'b, 'c> { pub material: &'c MaterialDef, pub rng: &'c mut dyn Rng, + swapped: bool, } impl UpdateCtx<'_, '_, '_> { @@ -99,8 +96,8 @@ impl UpdateCtx<'_, '_, '_> { pub fn set_cell(&mut self, dx: i32, dy: i32, cell: Cell) { // cannot move out of the neighbourhood, but also cannot move to the edge of the neighbourhood // as this would wake a chunk outside of the neighbourhood - debug_assert!(dx > -15 && dx < 15); - debug_assert!(dy > -15 && dy < 15); + debug_assert!(dx > -CHUNK_SIZE + 1 && dx < CHUNK_SIZE - 1); + debug_assert!(dy > -CHUNK_SIZE + 1 && dy < CHUNK_SIZE - 1); let x = self.x + dx; let y = self.y + dy; set_cell(self.chunks, x, y, cell); @@ -113,10 +110,14 @@ impl UpdateCtx<'_, '_, '_> { pub fn candidates_swap(&mut self, candidates: &[(i32, i32)]) -> bool { for &(dx, dy) in candidates { - let candidate_cell = self.get_cell(dx, dy); - if candidate_cell.is_some_and(|c| c.material.def().density < self.material.density) { - self.set_cell(0, 0, candidate_cell.unwrap()); + if let Some(mut candidate_cell) = self.get_cell(dx, dy) + && candidate_cell.material.def().density < self.material.density + { + candidate_cell.reset_settled(); + self.cell.reset_settled(); + self.set_cell(0, 0, candidate_cell); self.set_cell(dx, dy, *self.cell); + self.swapped = true; return true; } } @@ -145,8 +146,6 @@ pub fn sim_tick_chunk(chunks: &mut [Option<&mut Chunk>; 9], seqno: u64) { && cell.parity() == seqno_parity { cell.flip_parity(); - // apply the flipped parity in case the sim target doesn't - set_cell(chunks, x, y, cell); let mut update_ctx = UpdateCtx { chunks, @@ -160,9 +159,16 @@ pub fn sim_tick_chunk(chunks: &mut [Option<&mut Chunk>; 9], seqno: u64) { // TODO this is platform-dependent, will break for multiplayer rng: &mut rng, + swapped: false, }; update(&mut update_ctx); + + if !update_ctx.swapped { + // the cell didn't move, so it's more settled, and we also need to update its state for parity + cell.increment_settled(); + set_cell(chunks, x, y, cell); + } } } } |
