Structural fix for detached disk arms. The core problem was that disk
systems generated with inner_radius=0 tried to place near the origin,
but spacing constraints blocked them (core already occupied that space),
creating a visible gap between the core and spiral arms.
Changes:
- Pass core_radius to generate_disk so arms know where the core boundary is
- When inner_radius is 0 (auto), start arms inside the core zone at
40% of core_radius, so the density peak falls inside the core sphere
and arms visually emerge from the core boundary
- Change density exponent from powf(0.62) to powf(0.45) for stronger
concentration near the inner edge (~60% of systems in inner 30% of
the radial span), creating a natural bright-core-to-faint-edge falloff
- Bias randomize_disk toward inner_radius=0 (auto) 70% of the time so
randomized galaxies always have core-anchored arms
Three fixes for circular/non-spiral galaxies produced by Randomize:
1. Raise twist range from [1.0, 6.0] to [4.0, 18.0] radians
- Old max (~0.95 turns) could barely curve; new range covers
0.6–2.9 full turns, matching real spiral galaxy morphology
- Default twist raised from 3.0 to 12.0 (~1.9 turns)
2. Scale angular scatter inversely with arm count
- Replaced hardcoded ±0.36 rad scatter with arm_scatter() that
uses 30% of the inter-arm gap (TAU / arms × 0.30)
- Single-arm disks use a generous 1.5 rad scatter
- Prevents high-arm-count disks from blurring into circles
3. Bias randomize_disk toward spiral-friendly values
- Arms weighted toward 2–4 (10%, 30%, 30%, 20%, 10% distribution)
- Twist floored at arms × 4.0 rad so multi-arm disks always wind
enough for distinct spiral structure
- Outer radius defaults to "auto" 60% of the time
- Add multi-disk support (up to 4 independent disk layers) with per-disk
arms, twist, tilt, rotation, inner/outer radius
- Add polar beams (top/bottom) with taper, gravity, thickness controls
- Implement tab-based disk selector UI with add/remove disk
- Add Randomize Settings button for full param randomization
- Add Regenerate (reseed) and Center View buttons
- Add per-system contents generation (planets, belts, stations, anomalies,
gas clouds, stargates) with orbital mechanics
- Refactor control panel into scrollable sections with value display
- Split GalaxyParams into CoreParams, DiskParams, and BeamParams sub-structs
- Add polar beam systems (top/bottom) with visual differentiation
- Add scrollable control panel with section headers for each layer
- Fix Randomize Settings button: remove explicit width (use flex auto)
and bump height from 28px to 32px to match other action buttons
- Add mouse-wheel scroll routing for the control panel
- Add 'Randomize Settings' button that randomizes all params within bounds
- Add SystemOrigin enum for per-layer tracking
- Update AGENTS.md with new module layout and plugin pattern
Promote the monolithic character_creation/mod.rs into a folder per
apps/game/AGENTS.md: lays out the picker UI in ui.rs, holds presets
and the editable CharacterDraft resource in params.rs, and keeps
mod.rs as the plugin + lifecycle shell.
Re-exports CharacterDraft / Origin / StartingShip at the module root
for the (yet-to-be-wired) persistence layer.
- Introduce ORBITAL_PERIOD_SCALE = 4.0 multiplier so planets/stations/
gas clouds/anomalies all orbit visibly slower. At inspection-scale
zoom the un-scaled periods (≈2.5s per unit of radius) made bodies
spin like tops; tuned for a calm browsing pace.
- Default Orbit angular_velocity 0.5 → 0.15 (≈40s per revolution).
- Update orbital_period unit tests for the new scale factor.
Stateless orbital system: each Orbital's local position is recomputed
each frame from phase + (TAU/period) * elapsed_secs. No per-entity
angle accumulator means no drift, trivial save/load (component data
only), and free pause/slow-mo via Bevy's time speed multiplier.
Extended to planets, stations, anomalies, gas clouds, and individual
asteroid rocks. Inner rocks orbit proportionally faster than outer
ones, producing visible belt shearing over time. Stargates stay
stationary as navigational aids. The orbital_period(orbit, jitter)
helper consolidates the period formula in one place.
10 new unit tests (7 for orbital_position, 3 for orbital_period).
All 32 tests pass.
Replace the flat-grey torus asteroid belt with a swarm of 60 individual
rocks per belt — one shared jittered-icosphere mesh asset scaled, rotated,
and palette-tinted per instance (5-entry greyscale/brown material set).
- New GeneratedAsteroid data (position/scale/rotation/material_index)
generated deterministically alongside the belt, preserving the
same-seed-same-galaxy invariant
- New build_asteroid_mesh + asteroid_material_palette helpers
- ContentAssets drops belt_material, adds asteroid_mesh + asteroid_materials
- spawn_system_contents signature simplified (no more &mut Assets<Mesh>)
- Belt entity is now a no-mesh parent (Mineable/Identifiable/...) with
rock meshes as children — sets the stage for per-asteroid mining
- Bundles the POI component/marker scaffolding (poi.rs) and per-system
contents generator (contents.rs: planets, stations, anomalies, stargates,
gas clouds) that the asteroid rendering sits on top of
- Tests: asteroid_generation_is_deterministic,
asteroid_positions_stay_inside_annulus
All three cylinders now use the same neutral grey (0.55, 0.58, 0.62) so they
read as a subtle spatial scaffold instead of competing with the colored
faction stars.
Camera (apps/game/src/camera.rs):
- Replace yaw/pitch with a single Quat rotation. Mouse drag now does
yaw-around-world-Y * rotation * pitch-around-local-X, which is gimbal-free
and allows true 360° tumbling in any direction.
- Remove pitch clamps (ORBIT_MIN_PITCH / ORBIT_MAX_PITCH).
- Add ResetOrbitCamera resource + apply_orbit_reset system that snaps the
orbit camera back to default on demand.
- OrbitCamera::reset() helper.
Galaxy scene (apps/game/src/gameplay/galaxy_creation/):
- New axes.rs: spawn_axes() draws three emissive cylinders through the
origin (X=red, Y=green, Z=blue) as children of the scene root so they
rebuild with the rest of the galaxy.
- UI adds a 'Center View' button below Regenerate that inserts
ResetOrbitCamera; handled by reset_view_button_handler.
- Help text now mentions drag/zoom/escape.
Drag down now raises the camera so the galaxy shifts down with the cursor
(content follows finger). Horizontal was already correct (drag right moves
the scene right). Matches the feel of panning a map on iOS.
- Refactor apps/game/src/main.rs into modules: state.rs, camera.rs, ui/, gameplay/
- Add gameplay/galaxy_creation.rs scaffold (stubs only, no new logic)
- Update root AGENTS.md: separate TS workspace vs Rust game commands
- Update apps/AGENTS.md: docs/game/site use two toolchains, not one
- Add apps/game/AGENTS.md: build commands, module layout, naming conventions, Plugin pattern
- Add MiniStarMap, NpcMarketPanel, ShipStatusPanel, useKeyboardShortcuts
- Add progress bars for approach/mining operations and cargo fill indicator
- Rewrite docs from spreadsheet-first to exploration-first open-world RPG
- Replace dev:db + dev:standalone with unified dev script (scripts/dev.sh)
- Add Vite chunk splitting for three.js and spacetimedb
- Fix displayName dependency in useSpacetimeConnection
- Remove stale usePlayerSession.ts
- Add AGENTS.md files across all packages