//! Character creation scene. //! //! Layout / picker UI lives in [`ui`]; presets and the editable draft //! resource live in [`params`]. This module wires the Bevy plugin, owns the //! spawn / despawn lifecycle, and handles the Escape → Galaxy shortcut. //! //! Persistence is not yet wired up — on Confirm, the current draft is logged //! and the app transitions to [`AppState::StartingBaseSelection`]. The TODO is //! to persist it to SpacetimeDB once the Rust SDK is integrated. mod params; mod ui; // Public API surface for the (yet-to-be-wired) persistence layer / InGame // plugin. Currently unused outside this module — `#[allow]` keeps the names // exported so consumers can `use crate::gameplay::character_creation::Origin` // without us remembering to re-add the re-export the day they're needed. #[allow(unused_imports)] pub use params::{CharacterDraft, Origin, StartingShip, STARTING_SHIPS}; use bevy::prelude::*; use crate::state::AppState; pub struct CharacterCreationPlugin; impl Plugin for CharacterCreationPlugin { fn build(&self, app: &mut App) { app.init_resource::() .add_systems( OnEnter(AppState::CharacterCreation), ui::setup_character_creation_ui, ) .add_systems( OnExit(AppState::CharacterCreation), despawn_character_creation, ) .add_systems( Update, ( escape_to_galaxy, ui::scroll_character_creation_form, ui::picker_button_handler, ui::refresh_picker_values, ui::action_button_handler, ) .chain() .run_if(in_state(AppState::CharacterCreation)), ); } } // ── Markers ───────────────────────────────────────────────────────────────── /// Tag for everything spawned during character creation so it can be cleanly /// despawned on state exit. #[derive(Component)] pub struct CharacterCreationSpawned; #[derive(Component)] pub enum CharacterCreationButton { /// Finalize the character and begin the game. Confirm, /// Discard and return to the galaxy selection screen. Back, } // ── Lifecycle ─────────────────────────────────────────────────────────────── fn despawn_character_creation( mut commands: Commands, query: Query>, ) { for entity in &query { // Bevy 0.16: despawn() is recursive by default. commands.entity(entity).despawn(); } } // ── Input ─────────────────────────────────────────────────────────────────── fn escape_to_galaxy(keys: Res>, mut next_state: ResMut>) { if keys.just_pressed(KeyCode::Escape) { next_state.set(AppState::Galaxy); } }