From 71bb2b25dabbe683666714962f0ff19345d1542d Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Tue, 2 Dec 2025 15:41:20 -0600 Subject: [PATCH] Add sun and starfield config to level config schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add StarfieldConfig interface (count, radius, brightness, pointSize) - Add scale property to SunConfig for independent x/y/z scaling - Update levelDeserializer to apply sun scale and expose starfield config - Update level1 to pass starfield config to BackgroundStars - Create SunConfigEditor.svelte for editing sun properties - Create StarfieldConfigEditor.svelte for editing starfield properties - Add Sun and Stars tabs to LevelConfigEditor 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../editor/LevelConfigEditor.svelte | 17 +++ .../editor/StarfieldConfigEditor.svelte | 127 ++++++++++++++++++ src/components/editor/SunConfigEditor.svelte | 75 +++++++++++ src/levels/config/levelConfig.ts | 15 ++- src/levels/config/levelDeserializer.ts | 13 ++ src/levels/level1.ts | 11 +- 6 files changed, 249 insertions(+), 9 deletions(-) create mode 100644 src/components/editor/StarfieldConfigEditor.svelte create mode 100644 src/components/editor/SunConfigEditor.svelte diff --git a/src/components/editor/LevelConfigEditor.svelte b/src/components/editor/LevelConfigEditor.svelte index 3b26c8c..7fdfccc 100644 --- a/src/components/editor/LevelConfigEditor.svelte +++ b/src/components/editor/LevelConfigEditor.svelte @@ -8,6 +8,8 @@ import InfoBox from '../shared/InfoBox.svelte'; import ShipConfigEditor from './ShipConfigEditor.svelte'; import BaseConfigEditor from './BaseConfigEditor.svelte'; + import SunConfigEditor from './SunConfigEditor.svelte'; + import StarfieldConfigEditor from './StarfieldConfigEditor.svelte'; import AsteroidListEditor from './AsteroidListEditor.svelte'; import PlanetListEditor from './PlanetListEditor.svelte'; @@ -29,6 +31,8 @@ const tabs = [ { id: 'ship', label: '🚀 Ship' }, { id: 'base', label: '🛬 Base' }, + { id: 'sun', label: '☀️ Sun' }, + { id: 'starfield', label: '✨ Stars' }, { id: 'asteroids', label: '☄️ Asteroids' }, { id: 'planets', label: '🪐 Planets' } ]; @@ -111,6 +115,15 @@ config.startBase = undefined; } } + + function handleStarfieldToggle(enabled: boolean) { + if (!config) return; + if (enabled && !config.starfield) { + config.starfield = {}; + } else if (!enabled) { + config.starfield = undefined; + } + }
@@ -153,6 +166,10 @@ {:else if activeTab === 'base'} + {:else if activeTab === 'sun'} + + {:else if activeTab === 'starfield'} + {:else if activeTab === 'asteroids'} {:else if activeTab === 'planets'} diff --git a/src/components/editor/StarfieldConfigEditor.svelte b/src/components/editor/StarfieldConfigEditor.svelte new file mode 100644 index 0000000..7f5b125 --- /dev/null +++ b/src/components/editor/StarfieldConfigEditor.svelte @@ -0,0 +1,127 @@ + + +
+
+ +

When disabled, uses default starfield settings.

+
+ + {#if isEnabled && config} +
+ + + Number of stars (100-10000) +
+ +
+ + + Sphere radius containing stars +
+ +
+ + + {config.minBrightness?.toFixed(2)} +
+ +
+ + + {config.maxBrightness?.toFixed(2)} +
+ +
+ + + Size of star points (0.1-5) +
+ {/if} +
+ + diff --git a/src/components/editor/SunConfigEditor.svelte b/src/components/editor/SunConfigEditor.svelte new file mode 100644 index 0000000..13bd29f --- /dev/null +++ b/src/components/editor/SunConfigEditor.svelte @@ -0,0 +1,75 @@ + + +
+ + +
+ + +
+ +
+ + +
+ +
+ +
+ + {#if hasScale && config.scale} + + {/if} +
+ + diff --git a/src/levels/config/levelConfig.ts b/src/levels/config/levelConfig.ts index a23985b..b200b69 100644 --- a/src/levels/config/levelConfig.ts +++ b/src/levels/config/levelConfig.ts @@ -82,10 +82,22 @@ interface StartBaseConfig { /** * Sun configuration */ -interface SunConfig { +export interface SunConfig { position: Vector3Array; diameter: number; intensity?: number; // Light intensity + scale?: Vector3Array; // Independent x/y/z scaling +} + +/** + * Starfield configuration + */ +export interface StarfieldConfig { + count?: number; // Number of stars (default: 4500) + radius?: number; // Sphere radius (default: 50000) + minBrightness?: number; // Min brightness 0-1 (default: 0.1) + maxBrightness?: number; // Max brightness 0-1 (default: 1.0) + pointSize?: number; // Star point size (default: 0.1) } /** @@ -142,6 +154,7 @@ export interface LevelConfig { ship: ShipConfig; startBase?: StartBaseConfig; sun: SunConfig; + starfield?: StarfieldConfig; planets: PlanetConfig[]; asteroids: AsteroidConfig[]; diff --git a/src/levels/config/levelDeserializer.ts b/src/levels/config/levelDeserializer.ts index 83d1c39..d8c13e7 100644 --- a/src/levels/config/levelDeserializer.ts +++ b/src/levels/config/levelDeserializer.ts @@ -16,6 +16,7 @@ import { ScoreEvent } from "../../ui/hud/scoreboard"; import { LevelConfig, ShipConfig, + StarfieldConfig, Vector3Array, validateLevelConfig } from "./levelConfig"; @@ -156,9 +157,21 @@ export class LevelDeserializer { sun.material = material; sun.renderingGroupId = 2; + // Apply scale if specified + if (config.scale) { + sun.scaling = this.arrayToVector3(config.scale); + } + return sun; } + /** + * Get starfield configuration for BackgroundStars + */ + public getStarfieldConfig(): StarfieldConfig | undefined { + return this.config.starfield; + } + /** * Create planets from config */ diff --git a/src/levels/level1.ts b/src/levels/level1.ts index e68d5ea..a64de32 100644 --- a/src/levels/level1.ts +++ b/src/levels/level1.ts @@ -408,14 +408,9 @@ export class Level1 implements Level { // Initialize scoreboard with asteroid count this._ship.scoreboard.setRemainingCount(this._asteroidCount); - // Create background starfield - this._backgroundStars = new BackgroundStars(DefaultScene.MainScene, { - count: 5000, - radius: 3000, - minBrightness: 0.1, - maxBrightness: 1.0, - pointSize: 1 - }); + // Create background starfield (use config if available, otherwise defaults) + const starfieldConfig = this._deserializer.getStarfieldConfig(); + this._backgroundStars = new BackgroundStars(DefaultScene.MainScene, starfieldConfig); // Set up render loop updates DefaultScene.MainScene.onBeforeRenderObservable.add(() => {