chore(workspace): fix formatting and clippy warnings

This commit is contained in:
Serkyo 2026-05-16 19:05:53 +02:00
parent 61a7fb0ed5
commit 5659469e17
8 changed files with 225 additions and 66 deletions

View file

@ -81,8 +81,8 @@ impl ApplicationHandler for App {
let config_str = std::fs::read_to_string("assets/data/worldgen/default.json") let config_str = std::fs::read_to_string("assets/data/worldgen/default.json")
.expect("Failed to read worldgen config"); .expect("Failed to read worldgen config");
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
let worldgen_config: shared::generator::WorldGenConfig = serde_json::from_str(&config_str) let worldgen_config: shared::generator::WorldGenConfig =
.expect("Failed to parse worldgen config"); serde_json::from_str(&config_str).expect("Failed to parse worldgen config");
let seed = 4_813_530; let seed = 4_813_530;
@ -90,10 +90,18 @@ impl ApplicationHandler for App {
let chunk = generator.generate_chunk(shared::world::ChunkPos::new(0, 0, 0)); let chunk = generator.generate_chunk(shared::world::ChunkPos::new(0, 0, 0));
let (vertices, indices) = meshing::generate_mesh(&chunk); let (vertices, indices) = meshing::generate_mesh(&chunk);
tracing::info!("Generated Mesh with {} vertices and {} indices!", vertices.len(), indices.len()); tracing::info!(
"Generated Mesh with {} vertices and {} indices!",
vertices.len(),
indices.len()
);
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
self.renderer.as_mut().expect("Renderer initialized").update_mesh(&vertices, &indices).expect("Failed to upload terrain to GPU"); self.renderer
.as_mut()
.expect("Renderer initialized")
.update_mesh(&vertices, &indices)
.expect("Failed to upload terrain to GPU");
} }
fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) { fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {

View file

@ -1,7 +1,11 @@
use shared::world::{BlockId, CHUNK_SIZE, Chunk};
use renderer::mesh::Vertex; use renderer::mesh::Vertex;
use shared::world::{BlockId, CHUNK_SIZE, Chunk};
#[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)] #[allow(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::too_many_lines
)]
pub fn generate_mesh(chunk: &Chunk) -> (Vec<Vertex>, Vec<u32>) { pub fn generate_mesh(chunk: &Chunk) -> (Vec<Vertex>, Vec<u32>) {
let mut vertices = Vec::new(); let mut vertices = Vec::new();
let mut indices = Vec::new(); let mut indices = Vec::new();
@ -22,65 +26,176 @@ pub fn generate_mesh(chunk: &Chunk) -> (Vec<Vertex>, Vec<u32>) {
if y == CHUNK_SIZE - 1 || chunk.get(x, y + 1, z) == BlockId::AIR { if y == CHUNK_SIZE - 1 || chunk.get(x, y + 1, z) == BlockId::AIR {
let base_idx = vertices.len() as u32; let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz + 0.5], color: [0.2, 0.8, 0.2] }); vertices.push(Vertex {
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz + 0.5], color: [0.2, 0.8, 0.2] }); position: [fx - 0.5, fy + 0.5, fz + 0.5],
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz - 0.5], color: [0.2, 0.8, 0.2] }); color: [0.2, 0.8, 0.2],
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz - 0.5], color: [0.2, 0.8, 0.2] }); });
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz + 0.5],
color: [0.2, 0.8, 0.2],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz - 0.5],
color: [0.2, 0.8, 0.2],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz - 0.5],
color: [0.2, 0.8, 0.2],
});
indices.extend_from_slice(&[ indices.extend_from_slice(&[
base_idx, base_idx + 1, base_idx + 2, base_idx,
base_idx + 2, base_idx + 3, base_idx, base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]); ]);
} }
if y == 0 || chunk.get(x, y - 1, z) == BlockId::AIR { if y == 0 || chunk.get(x, y - 1, z) == BlockId::AIR {
let base_idx = vertices.len() as u32; let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz - 0.5], color: [0.1, 0.4, 0.1] }); vertices.push(Vertex {
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz - 0.5], color: [0.1, 0.4, 0.1] }); position: [fx - 0.5, fy - 0.5, fz - 0.5],
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz + 0.5], color: [0.1, 0.4, 0.1] }); color: [0.1, 0.4, 0.1],
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz + 0.5], color: [0.1, 0.4, 0.1] }); });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]); vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz - 0.5],
color: [0.1, 0.4, 0.1],
});
vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz + 0.5],
color: [0.1, 0.4, 0.1],
});
vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz + 0.5],
color: [0.1, 0.4, 0.1],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
} }
if x == CHUNK_SIZE - 1 || chunk.get(x + 1, y, z) == BlockId::AIR { if x == CHUNK_SIZE - 1 || chunk.get(x + 1, y, z) == BlockId::AIR {
let base_idx = vertices.len() as u32; let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz + 0.5], color: [0.15, 0.6, 0.15] }); vertices.push(Vertex {
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz - 0.5], color: [0.15, 0.6, 0.15] }); position: [fx + 0.5, fy - 0.5, fz + 0.5],
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz - 0.5], color: [0.15, 0.6, 0.15] }); color: [0.15, 0.6, 0.15],
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz + 0.5], color: [0.15, 0.6, 0.15] }); });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]); vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz - 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz - 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz + 0.5],
color: [0.15, 0.6, 0.15],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
} }
if x == 0 || chunk.get(x - 1, y, z) == BlockId::AIR { if x == 0 || chunk.get(x - 1, y, z) == BlockId::AIR {
let base_idx = vertices.len() as u32; let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz - 0.5], color: [0.15, 0.6, 0.15] }); vertices.push(Vertex {
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz + 0.5], color: [0.15, 0.6, 0.15] }); position: [fx - 0.5, fy - 0.5, fz - 0.5],
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz + 0.5], color: [0.15, 0.6, 0.15] }); color: [0.15, 0.6, 0.15],
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz - 0.5], color: [0.15, 0.6, 0.15] }); });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]); vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz + 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz + 0.5],
color: [0.15, 0.6, 0.15],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz - 0.5],
color: [0.15, 0.6, 0.15],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
} }
if z == CHUNK_SIZE - 1 || chunk.get(x, y, z + 1) == BlockId::AIR { if z == CHUNK_SIZE - 1 || chunk.get(x, y, z + 1) == BlockId::AIR {
let base_idx = vertices.len() as u32; let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz + 0.5], color: [0.18, 0.7, 0.18] }); vertices.push(Vertex {
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz + 0.5], color: [0.18, 0.7, 0.18] }); position: [fx - 0.5, fy - 0.5, fz + 0.5],
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz + 0.5], color: [0.18, 0.7, 0.18] }); color: [0.18, 0.7, 0.18],
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz + 0.5], color: [0.18, 0.7, 0.18] }); });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]); vertices.push(Vertex {
position: [fx + 0.5, fy - 0.5, fz + 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz + 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz + 0.5],
color: [0.18, 0.7, 0.18],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
} }
if z == 0 || chunk.get(x, y, z - 1) == BlockId::AIR { if z == 0 || chunk.get(x, y, z - 1) == BlockId::AIR {
let base_idx = vertices.len() as u32; let base_idx = vertices.len() as u32;
vertices.push(Vertex { position: [fx + 0.5, fy - 0.5, fz - 0.5], color: [0.18, 0.7, 0.18] }); vertices.push(Vertex {
vertices.push(Vertex { position: [fx - 0.5, fy - 0.5, fz - 0.5], color: [0.18, 0.7, 0.18] }); position: [fx + 0.5, fy - 0.5, fz - 0.5],
vertices.push(Vertex { position: [fx - 0.5, fy + 0.5, fz - 0.5], color: [0.18, 0.7, 0.18] }); color: [0.18, 0.7, 0.18],
vertices.push(Vertex { position: [fx + 0.5, fy + 0.5, fz - 0.5], color: [0.18, 0.7, 0.18] }); });
indices.extend_from_slice(&[base_idx, base_idx + 1, base_idx + 2, base_idx + 2, base_idx + 3, base_idx]); vertices.push(Vertex {
position: [fx - 0.5, fy - 0.5, fz - 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx - 0.5, fy + 0.5, fz - 0.5],
color: [0.18, 0.7, 0.18],
});
vertices.push(Vertex {
position: [fx + 0.5, fy + 0.5, fz - 0.5],
color: [0.18, 0.7, 0.18],
});
indices.extend_from_slice(&[
base_idx,
base_idx + 1,
base_idx + 2,
base_idx + 2,
base_idx + 3,
base_idx,
]);
} }
} }
} }

View file

@ -1,6 +1,6 @@
use crate::create_gpu_buffer; use crate::create_gpu_buffer;
use crate::{error::RendererError, mesh::Vertex};
use crate::sync::SyncPrimitives; use crate::sync::SyncPrimitives;
use crate::{error::RendererError, mesh::Vertex};
use ash::{Device, Instance, khr, vk}; use ash::{Device, Instance, khr, vk};
use gpu_allocator::vulkan::{Allocation, Allocator}; use gpu_allocator::vulkan::{Allocation, Allocator};
@ -299,7 +299,8 @@ impl Renderer {
mvp_bytes, mvp_bytes,
); );
self.device.cmd_draw_indexed(cmd, self.index_count, 1, 0, 0, 0); self.device
.cmd_draw_indexed(cmd, self.index_count, 1, 0, 0, 0);
} }
} }
@ -343,14 +344,22 @@ impl Renderer {
/// # Errors /// # Errors
/// Returns a `RendererError` if new Vulkan buffers cannot be allocated or created. /// Returns a `RendererError` if new Vulkan buffers cannot be allocated or created.
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
pub fn update_mesh(&mut self, vertices: &[Vertex], indices: &[u32]) -> Result<(), RendererError> { pub fn update_mesh(
&mut self,
vertices: &[Vertex],
indices: &[u32],
) -> Result<(), RendererError> {
unsafe { unsafe {
let _ = self.device.device_wait_idle(); let _ = self.device.device_wait_idle();
let _ = self.allocator.free(std::ptr::read(&raw const self.vertex_allocation)); let _ = self
.allocator
.free(std::ptr::read(&raw const self.vertex_allocation));
self.device.destroy_buffer(self.vertex_buffer, None); self.device.destroy_buffer(self.vertex_buffer, None);
let _ = self.allocator.free(std::ptr::read(&raw const self.index_allocation)); let _ = self
.allocator
.free(std::ptr::read(&raw const self.index_allocation));
self.device.destroy_buffer(self.index_buffer, None); self.device.destroy_buffer(self.index_buffer, None);
} }

View file

@ -8,24 +8,29 @@ pub mod world_server;
use std::fs; use std::fs;
use shared::{generator::{VoxelGenerator, WorldGenConfig}, world::ChunkPos}; use shared::{
generator::{VoxelGenerator, WorldGenConfig},
world::ChunkPos,
};
use tracing::{debug, info}; use tracing::{debug, info};
fn main() { fn main() {
tracing_subscriber::fmt() tracing_subscriber::fmt()
.with_env_filter( .with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env() tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("debug")) .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("debug")),
) )
.init(); .init();
info!("Starting Project Catalyst server"); info!("Starting Project Catalyst server");
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
let config_str = fs::read_to_string("assets/data/worldgen/default.json").expect("Failed to read worldgen config"); let config_str = fs::read_to_string("assets/data/worldgen/default.json")
.expect("Failed to read worldgen config");
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
let worldgen_config: WorldGenConfig = serde_json::from_str(&config_str).expect("Failed to parse worldgen config"); let worldgen_config: WorldGenConfig =
serde_json::from_str(&config_str).expect("Failed to parse worldgen config");
info!("Successfully loaded world configuration"); info!("Successfully loaded world configuration");
debug!("Base height: {}", worldgen_config.base_height); debug!("Base height: {}", worldgen_config.base_height);
@ -42,5 +47,8 @@ fn main() {
let spawn_chunk = world.get_chunk(ChunkPos::new(0, 0, 0)); let spawn_chunk = world.get_chunk(ChunkPos::new(0, 0, 0));
tracing::info!("Spawn chunk generated. Block at (0,0,0) is {}", spawn_chunk.get(0, 0, 0).0); tracing::info!(
"Spawn chunk generated. Block at (0,0,0) is {}",
spawn_chunk.get(0, 0, 0).0
);
} }

View file

@ -1,6 +1,9 @@
//! Authoritative chunk storage and generation logic for the server. //! Authoritative chunk storage and generation logic for the server.
use shared::{generator::VoxelGenerator, world::{Chunk, ChunkPos}}; use shared::{
generator::VoxelGenerator,
world::{Chunk, ChunkPos},
};
use std::collections::HashMap; use std::collections::HashMap;
/// The server's authoritative representation of the world. /// The server's authoritative representation of the world.
@ -21,8 +24,8 @@ impl ServerWorld {
/// Retrieves a reference to the chunk at the given position, generating it if necessary. /// Retrieves a reference to the chunk at the given position, generating it if necessary.
pub fn get_chunk(&mut self, pos: ChunkPos) -> &Chunk { pub fn get_chunk(&mut self, pos: ChunkPos) -> &Chunk {
self.chunks.entry(pos).or_insert_with(|| { self.chunks
self.generator.generate_chunk(pos) .entry(pos)
}) .or_insert_with(|| self.generator.generate_chunk(pos))
} }
} }

View file

@ -39,7 +39,11 @@ impl VoxelGenerator {
/// Generates a complete voxel chunk for the specified position. /// Generates a complete voxel chunk for the specified position.
#[must_use] #[must_use]
#[allow(clippy::cast_precision_loss, clippy::cast_possible_wrap, clippy::cast_possible_truncation)] #[allow(
clippy::cast_precision_loss,
clippy::cast_possible_wrap,
clippy::cast_possible_truncation
)]
pub fn generate_chunk(&self, pos: ChunkPos) -> Chunk { pub fn generate_chunk(&self, pos: ChunkPos) -> Chunk {
let mut chunk = Chunk::default(); let mut chunk = Chunk::default();

View file

@ -3,5 +3,5 @@
//! This crate contains data structures and constants that are used by both //! This crate contains data structures and constants that are used by both
//! the client and the server. //! the client and the server.
pub mod world;
pub mod generator; pub mod generator;
pub mod world;

View file

@ -11,7 +11,19 @@ pub const CHUNK_VOLUME: usize = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE;
/// A unique identifier representing a type of block in the world. /// A unique identifier representing a type of block in the world.
#[repr(transparent)] #[repr(transparent)]
#[derive( #[derive(
Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Pod, Zeroable, Copy,
Clone,
Debug,
Default,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
Pod,
Zeroable,
)] )]
pub struct BlockId(pub u16); pub struct BlockId(pub u16);