working compile!

This commit is contained in:
2026-03-13 17:03:06 -04:00
parent 45c1c072da
commit 2bf3319181
9 changed files with 132 additions and 91 deletions

10
Cargo.lock generated
View File

@@ -300,16 +300,6 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "asset_loader_proc"
version = "0.1.0"
dependencies = [
"bevy",
"ron 0.12.0",
"serde",
"serde_json",
]
[[package]] [[package]]
name = "async-broadcast" name = "async-broadcast"
version = "0.7.2" version = "0.7.2"

View File

@@ -2,10 +2,14 @@
resolver = "2" resolver = "2"
members = [ members = [
"game/main", "game/main",
"game/buildings",
"game/shared", "game/shared",
"game/buildings",
"game/units",
"game/resources",
"engine/world_generation", "engine/world_generation",
"engine/asset_loader", "game/buildings", "game/shared", "game/units", "engine/data", "game/resources", "engine/asset_loader_proc"] "engine/asset_loader",
"engine/data",
]
# Enable a small amount of optimization in debug mode # Enable a small amount of optimization in debug mode
[profile.dev] [profile.dev]

View File

@@ -1,13 +0,0 @@
[package]
name = "asset_loader_proc"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
serde = "1.0.228"
serde_json = "1.0.149"
bevy = "0.18.0"
ron = "0.12.0"

View File

@@ -1 +0,0 @@

View File

@@ -13,8 +13,10 @@ use super::components::*;
pub struct PhosCameraPlugin; pub struct PhosCameraPlugin;
impl Plugin for PhosCameraPlugin { impl Plugin for PhosCameraPlugin
fn build(&self, app: &mut App) { {
fn build(&self, app: &mut App)
{
app.register_type::<PhosCamera>(); app.register_type::<PhosCamera>();
app.register_type::<PhosOrbitCamera>(); app.register_type::<PhosOrbitCamera>();
@@ -24,15 +26,12 @@ impl Plugin for PhosCameraPlugin {
app.add_systems(Update, init_bounds.run_if(in_state(GeneratorState::SpawnMap))); app.add_systems(Update, init_bounds.run_if(in_state(GeneratorState::SpawnMap)));
app.add_plugins(TemporalAntiAliasPlugin); // app.add_plugins(TemporalAntiAliasPlugin);
} }
} }
fn init_bounds( fn init_bounds(mut commands: Commands, mut cam: Single<(&mut Transform, Entity), With<PhosCamera>>, heightmap: Res<Map>)
mut commands: Commands, {
mut cam: Single<(&mut Transform, Entity), With<PhosCamera>>,
heightmap: Res<Map>,
) {
let (mut cam_t, cam_entity) = cam.into_inner(); let (mut cam_t, cam_entity) = cam.into_inner();
cam_t.translation = heightmap.get_center(); cam_t.translation = heightmap.get_center();
commands commands
@@ -44,7 +43,8 @@ fn init_bounds(
}); });
} }
fn setup(mut commands: Commands) { fn setup(mut commands: Commands)
{
commands commands
.spawn(( .spawn((
Camera3d::default(), Camera3d::default(),
@@ -71,7 +71,8 @@ fn orbit_camera_upate(
time: Res<Time>, time: Res<Time>,
map: Res<Map>, map: Res<Map>,
#[cfg(debug_assertions)] mut gizmos: Gizmos, #[cfg(debug_assertions)] mut gizmos: Gizmos,
) { )
{
let (mut transform, config, mut orbit, bounds) = cam_query.into_inner(); let (mut transform, config, mut orbit, bounds) = cam_query.into_inner();
let target = orbit.target; let target = orbit.target;
@@ -80,9 +81,11 @@ fn orbit_camera_upate(
//Apply Camera Dist //Apply Camera Dist
cam_pos -= orbit.forward * orbit.distance; cam_pos -= orbit.forward * orbit.distance;
if mouse.pressed(MouseButton::Middle) { if mouse.pressed(MouseButton::Middle)
{
let mut orbit_move = Vec2::ZERO; let mut orbit_move = Vec2::ZERO;
for e in mouse_motion.read() { for e in mouse_motion.read()
{
orbit_move += e.delta; orbit_move += e.delta;
} }
orbit_move *= config.pan_speed * time.delta_secs() * -1.0; orbit_move *= config.pan_speed * time.delta_secs() * -1.0;
@@ -94,39 +97,54 @@ fn orbit_camera_upate(
orbit.forward = orbit.forward.normalize(); orbit.forward = orbit.forward.normalize();
cursor_options.grab_mode = CursorGrabMode::Locked; cursor_options.grab_mode = CursorGrabMode::Locked;
cursor_options.visible = false; cursor_options.visible = false;
} else { }
else
{
cursor_options.grab_mode = CursorGrabMode::None; cursor_options.grab_mode = CursorGrabMode::None;
cursor_options.visible = true; cursor_options.visible = true;
} }
if key.pressed(KeyCode::KeyE) { if key.pressed(KeyCode::KeyE)
{
let rot = Quat::from_axis_angle(Vec3::Y, f32::to_radians(config.speed) * time.delta_secs()); let rot = Quat::from_axis_angle(Vec3::Y, f32::to_radians(config.speed) * time.delta_secs());
orbit.forward = rot * orbit.forward; orbit.forward = rot * orbit.forward;
} else if key.pressed(KeyCode::KeyQ) { }
else if key.pressed(KeyCode::KeyQ)
{
let rot = Quat::from_axis_angle(Vec3::Y, f32::to_radians(-config.speed) * time.delta_secs()); let rot = Quat::from_axis_angle(Vec3::Y, f32::to_radians(-config.speed) * time.delta_secs());
orbit.forward = rot * orbit.forward; orbit.forward = rot * orbit.forward;
} }
let mut cam_move = Vec3::ZERO; let mut cam_move = Vec3::ZERO;
if key.pressed(KeyCode::KeyA) { if key.pressed(KeyCode::KeyA)
{
cam_move.x = 1.; cam_move.x = 1.;
} else if key.pressed(KeyCode::KeyD) { }
else if key.pressed(KeyCode::KeyD)
{
cam_move.x = -1.; cam_move.x = -1.;
} }
if key.pressed(KeyCode::KeyW) { if key.pressed(KeyCode::KeyW)
{
cam_move.z = 1.; cam_move.z = 1.;
} else if key.pressed(KeyCode::KeyS) { }
else if key.pressed(KeyCode::KeyS)
{
cam_move.z = -1.; cam_move.z = -1.;
} }
let move_speed = if key.pressed(KeyCode::ShiftLeft) { let move_speed = if key.pressed(KeyCode::ShiftLeft)
{
config.speed * 2.0 config.speed * 2.0
} else { }
else
{
config.speed config.speed
}; };
if cam_move != Vec3::ZERO { if cam_move != Vec3::ZERO
{
cam_move = cam_move.normalize(); cam_move = cam_move.normalize();
let move_fwd = Vec3::new(orbit.forward.x, 0., orbit.forward.z).normalize(); let move_fwd = Vec3::new(orbit.forward.x, 0., orbit.forward.z).normalize();
let move_rot = Quat::from_rotation_arc(Vec3::NEG_Z, move_fwd); let move_rot = Quat::from_rotation_arc(Vec3::NEG_Z, move_fwd);
@@ -143,8 +161,10 @@ fn orbit_camera_upate(
} }
let mut scroll = 0.0; let mut scroll = 0.0;
for e in wheel.read() { for e in wheel.read()
match e.unit { {
match e.unit
{
MouseScrollUnit::Line => scroll += e.y * 5., MouseScrollUnit::Line => scroll += e.y * 5.,
MouseScrollUnit::Pixel => scroll += e.y, MouseScrollUnit::Pixel => scroll += e.y,
} }
@@ -166,23 +186,31 @@ fn orbit_camera_upate(
transform.look_at(target, Vec3::Y); transform.look_at(target, Vec3::Y);
} }
fn sample_ground(pos: Vec3, heightmap: &Map) -> f32 { fn sample_ground(pos: Vec3, heightmap: &Map) -> f32
{
let tile_under = HexCoord::from_world_pos(pos); let tile_under = HexCoord::from_world_pos(pos);
let neighbors = heightmap.get_neighbors(&tile_under); let neighbors = heightmap.get_neighbors(&tile_under);
let mut ground_height = if heightmap.is_in_bounds(&tile_under) { let mut ground_height = if heightmap.is_in_bounds(&tile_under)
{
heightmap.sample_height(&tile_under) heightmap.sample_height(&tile_under)
} else { }
else
{
heightmap.sealevel heightmap.sealevel
}; };
for n in neighbors { for n in neighbors
if let Some(h) = n { {
if h > ground_height { if let Some(h) = n
{
if h > ground_height
{
ground_height = h; ground_height = h;
} }
} }
} }
if ground_height < heightmap.sealevel { if ground_height < heightmap.sealevel
{
ground_height = heightmap.sealevel; ground_height = heightmap.sealevel;
} }
return ground_height; return ground_height;

View File

@@ -6,6 +6,7 @@ use bevy::prelude::*;
use bevy::window::PresentMode; use bevy::window::PresentMode;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
use bevy::window::WindowResolution; use bevy::window::WindowResolution;
use bevy_inspector_egui::bevy_egui::EguiPlugin;
use bevy_inspector_egui::quick::WorldInspectorPlugin; use bevy_inspector_egui::quick::WorldInspectorPlugin;
use phos::PhosGamePlugin; use phos::PhosGamePlugin;
@@ -17,7 +18,8 @@ mod shader_extensions;
mod ui; mod ui;
mod utlis; mod utlis;
fn main() { fn main()
{
App::new() App::new()
.add_plugins(( .add_plugins((
DefaultPlugins DefaultPlugins
@@ -47,6 +49,7 @@ fn main() {
watch_for_changes_override: Some(true), watch_for_changes_override: Some(true),
..Default::default() ..Default::default()
}), }),
EguiPlugin::default(),
WorldInspectorPlugin::new(), WorldInspectorPlugin::new(),
WireframePlugin::default(), WireframePlugin::default(),
PhosGamePlugin, PhosGamePlugin,

View File

@@ -35,8 +35,10 @@ use super::{chunk_rebuild::ChunkRebuildPlugin, render_distance_system::RenderDis
pub struct MapInitPlugin; pub struct MapInitPlugin;
impl Plugin for MapInitPlugin { impl Plugin for MapInitPlugin
fn build(&self, app: &mut App) { {
fn build(&self, app: &mut App)
{
app.insert_state(GeneratorState::Startup); app.insert_state(GeneratorState::Startup);
app.insert_state(AssetLoadState::Loading); app.insert_state(AssetLoadState::Loading);
@@ -52,7 +54,7 @@ impl Plugin for MapInitPlugin {
ChunkRebuildPlugin, ChunkRebuildPlugin,
// TerraFormingTestPlugin, // TerraFormingTestPlugin,
MaterialPlugin::<ExtendedMaterial<StandardMaterial, ChunkMaterial>>::default(), MaterialPlugin::<ExtendedMaterial<StandardMaterial, ChunkMaterial>>::default(),
MaterialPlugin::<ExtendedMaterial<StandardMaterial, WaterMaterial>> { ..Default::default() }, MaterialPlugin::<ExtendedMaterial<StandardMaterial, WaterMaterial>>::default(),
)); ));
app.configure_loading_state( app.configure_loading_state(
@@ -86,7 +88,8 @@ impl Plugin for MapInitPlugin {
fn setup_materials( fn setup_materials(
mut phos_assets: ResMut<PhosAssets>, mut phos_assets: ResMut<PhosAssets>,
mut water_materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, WaterMaterial>>>, mut water_materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, WaterMaterial>>>,
) { )
{
let water_material = water_materials.add(ExtendedMaterial { let water_material = water_materials.add(ExtendedMaterial {
base: StandardMaterial { base: StandardMaterial {
base_color: Color::srgb(0., 0.878, 1.), base_color: Color::srgb(0., 0.878, 1.),
@@ -112,7 +115,8 @@ fn finalize_biome_painter(
mut next_generator_state: ResMut<NextState<GeneratorState>>, mut next_generator_state: ResMut<NextState<GeneratorState>>,
biome_painter: Res<BiomePainterAsset>, biome_painter: Res<BiomePainterAsset>,
biomes: Res<Assets<BiomeAsset>>, biomes: Res<Assets<BiomeAsset>>,
) { )
{
let painter = biome_painter.build(&biomes); let painter = biome_painter.build(&biomes);
commands.insert_resource(painter); commands.insert_resource(painter);
next_generator_state.set(GeneratorState::GenerateHeightmap); next_generator_state.set(GeneratorState::GenerateHeightmap);
@@ -123,11 +127,14 @@ fn finalize_texture(
mut images: ResMut<Assets<Image>>, mut images: ResMut<Assets<Image>>,
mut chunk_materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, ChunkMaterial>>>, mut chunk_materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, ChunkMaterial>>>,
mut next_load_state: ResMut<NextState<AssetLoadState>>, mut next_load_state: ResMut<NextState<AssetLoadState>>,
) { )
{
let image = images.get_mut(atlas.handle.id()).unwrap(); let image = images.get_mut(atlas.handle.id()).unwrap();
let array_layers = image.height() / image.width(); let array_layers = image.height() / image.width();
image.reinterpret_stacked_2d_as_array(array_layers); image
.reinterpret_stacked_2d_as_array(array_layers)
.expect("Failed to reinterpret as array");
let chunk_material = chunk_materials.add(ExtendedMaterial { let chunk_material = chunk_materials.add(ExtendedMaterial {
base: StandardMaterial::default(), base: StandardMaterial::default(),
@@ -144,7 +151,8 @@ fn create_heightmap(
mut commands: Commands, mut commands: Commands,
mut next_state: ResMut<NextState<GeneratorState>>, mut next_state: ResMut<NextState<GeneratorState>>,
biome_painter: Res<BiomePainter>, biome_painter: Res<BiomePainter>,
) { )
{
let config = GenerationConfig { let config = GenerationConfig {
biome_blend: 32, biome_blend: 32,
biome_dither: 10., biome_dither: 10.,
@@ -215,7 +223,8 @@ fn spawn_map(
mut game_state: ResMut<NextState<MenuState>>, mut game_state: ResMut<NextState<MenuState>>,
mut gameplay_state: ResMut<NextState<GameplayState>>, mut gameplay_state: ResMut<NextState<GameplayState>>,
biome_painter: Res<BiomePainter>, biome_painter: Res<BiomePainter>,
) { )
{
paint_map(&mut heightmap, &biome_painter, &tile_assets, &tile_mappers); paint_map(&mut heightmap, &biome_painter, &tile_assets, &tile_mappers);
//Prepare Mesh Data //Prepare Mesh Data
@@ -246,7 +255,8 @@ fn spawn_map(
0., 0.,
(Chunk::SIZE / 2) as f32 * 1.5, (Chunk::SIZE / 2) as f32 * 1.5,
); );
for (chunk_mesh, water_mesh, collider, pos, index) in chunk_meshes { for (chunk_mesh, water_mesh, collider, pos, index) in chunk_meshes
{
// let mesh_handle = meshes.a // let mesh_handle = meshes.a
let chunk = commands let chunk = commands
.spawn(( .spawn((
@@ -275,7 +285,8 @@ fn spawn_map(
commands.insert_resource(registry); commands.insert_resource(registry);
generator_state.set(GeneratorState::Idle); generator_state.set(GeneratorState::Idle);
if cur_game_state.get() != &MenuState::InGame { if cur_game_state.get() != &MenuState::InGame
{
game_state.set(MenuState::InGame); game_state.set(MenuState::InGame);
gameplay_state.set(GameplayState::PlaceHQ); gameplay_state.set(GameplayState::PlaceHQ);
} }
@@ -289,8 +300,10 @@ fn despawn_map(
chunks: Query<Entity, With<PhosChunk>>, chunks: Query<Entity, With<PhosChunk>>,
mut next_state: ResMut<NextState<GeneratorState>>, mut next_state: ResMut<NextState<GeneratorState>>,
biome_painter: Res<BiomePainter>, biome_painter: Res<BiomePainter>,
) { )
for chunk in chunks.iter() { {
for chunk in chunks.iter()
{
commands.entity(chunk).despawn(); commands.entity(chunk).despawn();
} }

View File

@@ -7,35 +7,43 @@ use bevy::shader::ShaderRef;
use world_generation::consts::{ATTRIBUTE_PACKED_VERTEX_DATA, ATTRIBUTE_VERTEX_HEIGHT}; use world_generation::consts::{ATTRIBUTE_PACKED_VERTEX_DATA, ATTRIBUTE_VERTEX_HEIGHT};
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
pub struct ChunkMaterial { pub struct ChunkMaterial
{
#[texture(100, dimension = "2d_array")] #[texture(100, dimension = "2d_array")]
#[sampler(101)] #[sampler(101)]
pub array_texture: Handle<Image>, pub array_texture: Handle<Image>,
} }
impl MaterialExtension for ChunkMaterial { impl MaterialExtension for ChunkMaterial
fn fragment_shader() -> ShaderRef { {
fn fragment_shader() -> ShaderRef
{
"shaders/world/chunk.wgsl".into() "shaders/world/chunk.wgsl".into()
} }
} }
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
pub struct PackedChunkMaterial { pub struct PackedChunkMaterial
{
#[texture(100, dimension = "2d_array")] #[texture(100, dimension = "2d_array")]
#[sampler(101)] #[sampler(101)]
pub array_texture: Handle<Image>, pub array_texture: Handle<Image>,
} }
impl Material for PackedChunkMaterial { impl Material for PackedChunkMaterial
fn fragment_shader() -> ShaderRef { {
fn fragment_shader() -> ShaderRef
{
"shaders/world/chunk.wgsl".into() "shaders/world/chunk.wgsl".into()
} }
fn vertex_shader() -> ShaderRef { fn vertex_shader() -> ShaderRef
{
"shaders/world/chunk_packed.wgsl".into() "shaders/world/chunk_packed.wgsl".into()
} }
fn prepass_vertex_shader() -> ShaderRef { fn prepass_vertex_shader() -> ShaderRef
{
"shaders/world/chunk_packed.wgsl".into() "shaders/world/chunk_packed.wgsl".into()
} }
@@ -52,7 +60,8 @@ impl Material for PackedChunkMaterial {
descriptor: &mut bevy::render::render_resource::RenderPipelineDescriptor, descriptor: &mut bevy::render::render_resource::RenderPipelineDescriptor,
layout: &bevy::mesh::MeshVertexBufferLayoutRef, layout: &bevy::mesh::MeshVertexBufferLayoutRef,
key: bevy::pbr::MaterialPipelineKey<Self>, key: bevy::pbr::MaterialPipelineKey<Self>,
) -> bevy::ecs::error::Result<(), bevy::render::render_resource::SpecializedMeshPipelineError> { ) -> bevy::ecs::error::Result<(), bevy::render::render_resource::SpecializedMeshPipelineError>
{
let vertex_layout = layout.0.get_layout(&[ let vertex_layout = layout.0.get_layout(&[
// Mesh::ATTRIBUTE_POSITION.at_shader_location(0), // Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
// Mesh::ATTRIBUTE_UV_0.at_shader_location(1), // Mesh::ATTRIBUTE_UV_0.at_shader_location(1),

View File

@@ -5,23 +5,28 @@ use bevy::prelude::*;
use bevy::reflect::Reflect; use bevy::reflect::Reflect;
use bevy::render::render_resource::{AsBindGroup, ShaderType}; use bevy::render::render_resource::{AsBindGroup, ShaderType};
use bevy::shader::ShaderRef; use bevy::shader::ShaderRef;
use world_generation::consts::{ATTRIBUTE_PACKED_VERTEX_DATA, ATTRIBUTE_VERTEX_HEIGHT};
#[derive(Asset, Reflect, AsBindGroup, Debug, Clone, Default)] #[derive(Asset, Reflect, AsBindGroup, Debug, Clone, Default)]
pub struct WaterMaterial { pub struct WaterMaterial
{
#[uniform(100)] #[uniform(100)]
pub settings: WaterSettings, pub settings: WaterSettings,
} }
#[derive(Debug, Clone, ShaderType, Reflect)] #[derive(Debug, Clone, ShaderType, Reflect)]
pub struct WaterSettings { pub struct WaterSettings
{
pub offset: f32, pub offset: f32,
pub scale: f32, pub scale: f32,
pub f_power: f32, pub f_power: f32,
pub deep_color: LinearRgba, pub deep_color: LinearRgba,
} }
impl Default for WaterSettings { impl Default for WaterSettings
fn default() -> Self { {
fn default() -> Self
{
Self { Self {
offset: 0.0, offset: 0.0,
scale: 1.0, scale: 1.0,
@@ -31,18 +36,21 @@ impl Default for WaterSettings {
} }
} }
impl MaterialExtension for WaterMaterial { impl MaterialExtension for WaterMaterial
fn fragment_shader() -> ShaderRef { {
fn fragment_shader() -> ShaderRef
{
"shaders/world/water.wgsl".into() "shaders/world/water.wgsl".into()
} }
// fn specialize( // fn specialize(
// _pipeline: &bevy::pbr::MaterialExtensionPipeline, // pipeline: &bevy::pbr::MaterialExtensionPipeline,
// descriptor: &mut bevy::render::render_resource::RenderPipelineDescriptor, // descriptor: &mut bevy::render::render_resource::RenderPipelineDescriptor,
// layout: &bevy::render::mesh::MeshVertexBufferLayout, // layout: &bevy::mesh::MeshVertexBufferLayoutRef,
// _key: bevy::pbr::MaterialExtensionKey<Self>, // key: bevy::pbr::MaterialExtensionKey<Self>,
// ) -> Result<(), bevy::render::render_resource::SpecializedMeshPipelineError> { // ) -> std::result::Result<(), bevy::render::render_resource::SpecializedMeshPipelineError>
// let vertex_layout = layout.get_layout(&[ // {
// let vertex_layout = layout.0.get_layout(&[
// // Mesh::ATTRIBUTE_POSITION.at_shader_location(0), // // Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
// // Mesh::ATTRIBUTE_UV_0.at_shader_location(1), // // Mesh::ATTRIBUTE_UV_0.at_shader_location(1),
// // Mesh::ATTRIBUTE_NORMAL.at_shader_location(2), // // Mesh::ATTRIBUTE_NORMAL.at_shader_location(2),