192 lines
6.6 KiB
Rust
192 lines
6.6 KiB
Rust
//! Runtime game crate: FPS player, rendering, and starter world.
|
|
#![allow(clippy::type_complexity)]
|
|
|
|
pub mod editor_ext;
|
|
pub mod launch;
|
|
|
|
pub mod player {
|
|
//! Player types re-exported from the stable sim crate.
|
|
pub use sim::{CameraSensitivity, PlayerCamera};
|
|
}
|
|
|
|
pub mod rendering {
|
|
//! Rendering helpers re-exported from the hot-reloadable implementation.
|
|
pub use game_hot::{
|
|
apply_camera_render_profile, apply_project_camera_fx, camera_auto_exposure_active,
|
|
clear_viewport_camera_stack, effective_gi_path_for_camera, effective_viewport_gi_path,
|
|
effective_viewport_render_stack, has_local_shadow_lights, hdr_enabled_profile,
|
|
patch_camera_effects, resolve_viewport_camera_owner, strip_project_camera_fx,
|
|
sync_optional_rendering_fx, sync_viewport_camera_stack, world_has_local_shadow_lights,
|
|
FullscreenEffectsPlugin, SolariRaytracingSceneStats, SolariRenderingPlugin,
|
|
ViewportCameraOwner, ViewportFxSnapshot, ViewportStackApply, HDR_ENV_VAR,
|
|
};
|
|
}
|
|
|
|
use bevy::prelude::*;
|
|
use settings::ProjectSettingsPlugin;
|
|
use sim::SimPlugin;
|
|
|
|
pub use sim::{GameInputEnabled, GameInputFocused, SimEnabled};
|
|
|
|
/// When set, the in-process editor owns [`apply_project_camera_fx`] on a single camera.
|
|
#[derive(Resource, Debug, Clone, Copy, Default)]
|
|
pub struct GameRenderBootstrap {
|
|
pub defer_player_camera_fx: bool,
|
|
}
|
|
|
|
#[cfg(not(feature = "hot-reload"))]
|
|
mod systems {
|
|
pub use game_hot::{
|
|
apply_ambient_light, apply_player_intent, grab_cursor, move_and_slide,
|
|
setup_project_camera_effects, spawn_level, spawn_player, spawn_sun,
|
|
sync_player_physics_position, sync_project_sun_visibility,
|
|
sync_scene_directional_shadow_cascades, tag_player_camera, toggle_cursor_grab,
|
|
update_camera_pitch, update_eye_height, update_local_player_intent,
|
|
};
|
|
}
|
|
|
|
#[cfg(feature = "hot-reload")]
|
|
mod systems {
|
|
pub use crate::hot::{
|
|
apply_ambient_light, apply_player_intent, grab_cursor, move_and_slide,
|
|
setup_project_camera_effects, spawn_level, spawn_player, spawn_sun,
|
|
sync_player_physics_position, sync_project_sun_visibility,
|
|
sync_scene_directional_shadow_cascades, tag_player_camera, toggle_cursor_grab,
|
|
update_camera_pitch, update_eye_height, update_local_player_intent,
|
|
};
|
|
}
|
|
|
|
#[cfg(feature = "hot-reload")]
|
|
#[hot_lib_reloader::hot_module(dylib = "game_hot", lib_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/debug"))]
|
|
mod hot {
|
|
use avian3d::prelude::*;
|
|
use bevy::input::mouse::AccumulatedMouseMotion;
|
|
use bevy::light::CascadeShadowConfig;
|
|
use bevy::pbr::ScatteringMedium;
|
|
use bevy::prelude::*;
|
|
use bevy::time::Fixed;
|
|
use bevy::window::{CursorOptions, PrimaryWindow};
|
|
use game_hot::SolariRaytracingSceneStats;
|
|
use protocol::PlayerInputIntent;
|
|
use settings::{
|
|
ActiveCameraRenderProfile, ProjectRenderCamera, ProjectSettings, RenderingCapabilities,
|
|
SimTuning,
|
|
};
|
|
use shared::{InspectorOrder, LevelObject, LightDesc, ProjectSun};
|
|
use sim::{
|
|
CameraSensitivity, Crouching, GameInputEnabled, GameInputFocused, Grounded, JumpState,
|
|
Player, PlayerCamera, PlayerVelocity, PlayerYawSensitivity,
|
|
};
|
|
|
|
hot_functions_from_file!("crates/game_hot/src/sim_systems.rs"); // move_and_slide, sync_player_physics_position, apply_player_intent
|
|
hot_functions_from_file!("crates/game_hot/src/player/spawn.rs");
|
|
hot_functions_from_file!("crates/game_hot/src/player/input.rs");
|
|
hot_functions_from_file!("crates/game_hot/src/player/camera.rs");
|
|
hot_functions_from_file!("crates/game_hot/src/rendering/camera_fx.rs");
|
|
hot_functions_from_file!("crates/game_hot/src/world/mod.rs");
|
|
hot_functions_from_file!("crates/game_hot/src/world/level.rs");
|
|
hot_functions_from_file!("crates/game_hot/src/world/lighting.rs");
|
|
|
|
#[lib_change_subscription]
|
|
pub fn subscribe() -> hot_lib_reloader::LibReloadObserver {}
|
|
}
|
|
|
|
#[cfg(feature = "hot-reload")]
|
|
pub fn hot_reload_subscribe() -> hot_lib_reloader::LibReloadObserver {
|
|
hot::subscribe()
|
|
}
|
|
|
|
fn sim_enabled(enabled: Res<SimEnabled>) -> bool {
|
|
enabled.0
|
|
}
|
|
|
|
fn game_input_enabled(enabled: Res<GameInputEnabled>) -> bool {
|
|
enabled.0
|
|
}
|
|
|
|
fn register_game_systems(app: &mut App, defer_player_camera_fx: bool) {
|
|
app.add_systems(
|
|
FixedUpdate,
|
|
(
|
|
systems::apply_player_intent,
|
|
systems::move_and_slide,
|
|
systems::sync_player_physics_position,
|
|
)
|
|
.chain()
|
|
.run_if(sim_enabled),
|
|
)
|
|
.add_systems(Startup, systems::spawn_player)
|
|
.add_systems(
|
|
Startup,
|
|
systems::grab_cursor
|
|
.after(systems::spawn_player)
|
|
.run_if(game_input_enabled),
|
|
)
|
|
.add_systems(
|
|
Update,
|
|
(
|
|
systems::toggle_cursor_grab,
|
|
systems::update_local_player_intent,
|
|
systems::update_camera_pitch,
|
|
systems::update_eye_height,
|
|
)
|
|
.chain()
|
|
.run_if(game_input_enabled),
|
|
)
|
|
.add_systems(
|
|
Startup,
|
|
(
|
|
systems::apply_ambient_light,
|
|
systems::spawn_sun,
|
|
systems::spawn_level,
|
|
)
|
|
.chain(),
|
|
);
|
|
app.add_systems(
|
|
Update,
|
|
(
|
|
systems::sync_project_sun_visibility,
|
|
systems::sync_scene_directional_shadow_cascades,
|
|
),
|
|
);
|
|
|
|
if !defer_player_camera_fx {
|
|
app.add_systems(
|
|
PostStartup,
|
|
(
|
|
systems::tag_player_camera,
|
|
systems::setup_project_camera_effects,
|
|
)
|
|
.chain(),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Runtime game systems and content, without Bevy's platform/window plugins.
|
|
pub struct GamePlugin;
|
|
|
|
impl Plugin for GamePlugin {
|
|
fn build(&self, app: &mut App) {
|
|
let defer_player_camera_fx = app
|
|
.world()
|
|
.get_resource::<GameRenderBootstrap>()
|
|
.is_some_and(|bootstrap| bootstrap.defer_player_camera_fx);
|
|
|
|
app.register_type::<GameInputEnabled>()
|
|
.init_resource::<GameInputEnabled>()
|
|
.init_resource::<GameInputFocused>()
|
|
.add_plugins((ProjectSettingsPlugin, SimPlugin, bevy_ufbx::FbxPlugin))
|
|
.add_plugins(game_hot::SolariRenderingPlugin)
|
|
.add_plugins(game_hot::AutoExposureRenderingPlugin)
|
|
.add_plugins(game_hot::FullscreenEffectsPlugin)
|
|
.insert_resource(ClearColor(Color::srgb(0.0, 0.0, 0.0)));
|
|
|
|
register_game_systems(app, defer_player_camera_fx);
|
|
}
|
|
}
|
|
|
|
/// Called by the editor after swapping the hot dylib.
|
|
pub fn on_hot_reload(world: &mut World) {
|
|
game_hot::on_hot_reload(world);
|
|
}
|