Skip to content

Commit 332d692

Browse files
committed
Add the initial framework for megastructures
To provide something to test with, an option has been added to scatter a random assortment of horospheres throughout the world.
1 parent c42d73c commit 332d692

File tree

10 files changed

+963
-7
lines changed

10 files changed

+963
-7
lines changed

client/src/sim.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ impl Sim {
8888
local_character_id: EntityId,
8989
) -> Self {
9090
let mut graph = Graph::new(cfg.chunk_size);
91+
if cfg.horospheres_enabled {
92+
graph.enable_horospheres();
93+
}
9194
graph.ensure_node_state(NodeId::ROOT);
9295
Self {
9396
graph,

common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ license = "Apache-2.0 OR Zlib"
99
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1010

1111
[dependencies]
12+
arrayvec = "0.7.6"
1213
blake3 = "1.3.3"
1314
serde = { version = "1.0.104", features = ["derive"] }
1415
nalgebra = { workspace = true, features = ["serde-serialize"] }

common/src/graph.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::{
1616
pub struct Graph {
1717
nodes: FxHashMap<NodeId, NodeContainer>,
1818
layout: ChunkLayout,
19+
horospheres_enabled: bool,
1920
}
2021

2122
impl Graph {
@@ -25,9 +26,18 @@ impl Graph {
2526
Self {
2627
nodes,
2728
layout: ChunkLayout::new(dimension),
29+
horospheres_enabled: false,
2830
}
2931
}
3032

33+
pub fn enable_horospheres(&mut self) {
34+
self.horospheres_enabled = true;
35+
}
36+
37+
pub fn horospheres_enabled(&self) -> bool {
38+
self.horospheres_enabled
39+
}
40+
3141
#[inline]
3242
pub fn layout(&self) -> &ChunkLayout {
3343
&self.layout

common/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub mod lru_slab;
2525
mod margins;
2626
pub mod math;
2727
pub mod node;
28+
pub mod peer_traverser;
2829
mod plane;
2930
pub mod proto;
3031
mod sim_config;

common/src/node.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ use crate::collision_math::Ray;
88
use crate::dodeca::Vertex;
99
use crate::graph::{Graph, NodeId};
1010
use crate::lru_slab::SlotId;
11+
use crate::peer_traverser::PeerTraverser;
1112
use crate::proto::{BlockUpdate, Position, SerializedVoxelData};
1213
use crate::voxel_math::{ChunkDirection, CoordAxis, CoordSign, Coords};
1314
use crate::world::Material;
14-
use crate::worldgen::NodeState;
15+
use crate::worldgen::{NodeState, PartialNodeState};
1516
use crate::{Chunks, margins};
1617

1718
/// Unique identifier for a single chunk (1/20 of a dodecahedron) in the graph
@@ -28,21 +29,44 @@ impl ChunkId {
2829
}
2930

3031
impl Graph {
32+
/// Returns the PartialNodeState for the given node, panicking if it isn't initialized.
33+
#[inline]
34+
pub fn partial_node_state(&self, node_id: NodeId) -> &PartialNodeState {
35+
self[node_id].partial_state.as_ref().unwrap()
36+
}
37+
38+
/// Initializes the PartialNodeState for the given node if not already initialized,
39+
/// initializing other nodes' NodeState and PartialNodeState as necessary
40+
pub fn ensure_partial_node_state(&mut self, node_id: NodeId) {
41+
if self[node_id].partial_state.is_some() {
42+
return;
43+
}
44+
45+
for (_, parent) in self.descenders(node_id) {
46+
self.ensure_node_state(parent);
47+
}
48+
49+
let partial_node_state = PartialNodeState::new(self, node_id);
50+
self[node_id].partial_state = Some(partial_node_state);
51+
}
52+
3153
/// Returns the NodeState for the given node, panicking if it isn't initialized.
3254
#[inline]
3355
pub fn node_state(&self, node_id: NodeId) -> &NodeState {
3456
self[node_id].state.as_ref().unwrap()
3557
}
3658

37-
/// Initializes the NodeState for the given node and all its ancestors if not
38-
/// already initialized.
59+
/// Initializes the NodeState for the given node if not already initialized,
60+
/// initializing other nodes' NodeState and PartialNodeState as necessary
3961
pub fn ensure_node_state(&mut self, node_id: NodeId) {
4062
if self[node_id].state.is_some() {
4163
return;
4264
}
4365

44-
for (_, parent) in self.descenders(node_id) {
45-
self.ensure_node_state(parent);
66+
self.ensure_partial_node_state(node_id);
67+
let mut peers = PeerTraverser::new(node_id);
68+
while let Some(peer) = peers.ensure_next(self) {
69+
self.ensure_partial_node_state(peer.node());
4670
}
4771

4872
let node_state = NodeState::new(self, node_id);
@@ -211,6 +235,7 @@ impl IndexMut<ChunkId> for Graph {
211235
/// used for rendering, is stored here.
212236
#[derive(Default)]
213237
pub struct Node {
238+
pub partial_state: Option<PartialNodeState>,
214239
pub state: Option<NodeState>,
215240
/// We can only populate chunks which lie within a cube of populated nodes, so nodes on the edge
216241
/// of the graph always have some `Fresh` chunks.

0 commit comments

Comments
 (0)