Namespace Serenity.Wave.Editor.Builder
Classes
CreateWaveWindow
Step-by-step window for creating or updating one stage's Wave asset chain (an ordered list of
UnityWaveConfigSO plus the referencing
UnityWaveSetSO) in one run. Mirrors
CreatePlayerInputWindow's shape: the window only collects input and renders results,
WaveCreator does the actual validation and generation work — this window never mutates an
asset directly.
Every dropdown option list (spawn point ids, known archetype prefabs) and both Validate(Input) / Preview(Input) results are cached off the repaint path — recomputed only on step entry and inside a field's UnityEditor.EditorGUI.BeginChangeCheck gate, mirroring StageSpawnPointProvider's own UnityEditor.EditorApplication.projectChanged invalidation for the spawn point / archetype caches this window keeps on top of it.
WaveCreator
Generates (or updates) a Wave aggregate asset chain for one stage: an ordered list of
UnityWaveConfigSO assets under <StageFolderPath>/Waves/ and one
UnityWaveSetSO directly under StageFolderPath referencing them, in the exact order
they were authored. Mirrors Serenity.InputGateway.Installation.Editor.Builder.PlayerInputCreator's
multi-asset shape (bottom-up resolve-or-create, then the referencing asset, full rollback on any failure) —
wave configs are the "leaves", the wave set is the "root" that references them, exactly like Device
Filter/Join Gate feeding Routing.
Folder convention, verified against StageSpawnPointProvider, not assumed. The
provider does not require a literal Stages path segment anywhere — it only requires the stage
prefab to sit directly in StageFolderPath and wave assets to sit in
StageFolderPath/Waves/. This engine enforces exactly that (and nothing about the folder's name),
matching what FindStagePrefab(string) and
ScanStagePrefab(string) actually scan — the …/Stages/<Name>/
naming in the cookbooks is a human convention on top of this, not a code requirement.
Spawn-point resolution intentionally bypasses StageSpawnPointProvider's cache —
FindStagePrefab(string)/ScanStagePrefab(string)
are called directly (the same raw scan the cached GetSpawnPointIds wraps) so validation is always
fresh, never stale from a scene/prefab edit the cache has not yet observed via
EditorApplication.projectChanged.
Known, deliberately unfixed semantic gap — ToConfig(). Verified by
reading the source: ToConfig() returns WaveConfig(waveIndex, spawnEntries.Count) — the
domain's TotalActors is the NUMBER OF ENTRIES, not the sum of each entry's Count. A wave
with one entry authored with count = 5 reports TotalActors == 1 at runtime (and
WaveState will consider the wave cleared after a single RecordActorRemoved(), even though
5 actors were actually spawned). This engine does not change that runtime behavior — the fix is out of
scope for this change — but never reports a per-run actor total that relies on it: Preview(Input)
exposes both EntryCount (what ToConfig() will actually use) and
ActorSum (the sum of every entry's authored Count — what a designer
most likely means by "how many actors does this wave spawn") side by side, so the gap is visible at
authoring time instead of silently surprising someone reading a HUD later.
Wiring correction versus Assets/Serenity/Scripts/Unity/Stage/README.md. That README
documents a StageRoot.WaveSet field ("Wave data sourced from StageRoot.WaveSet, fed to wave
service"). Reading the actual StageRoot (Unity/Stage/Infrastructure/Authoring/StageRoot.cs)
on this branch shows no such field — it exposes only stageId. The README is stale. The real
wiring (confirmed in Stage.md §10 step 4 and Wave.md §6) happens exclusively at the
composition root, which must call UnityWaveService.ConfigureFromWaveSet(waveSetSO) and
SetSpawnPointResolver(stageService.SpawnPointResolver) explicitly. Create(Input)'s result
always carries a warning to this effect — creating these assets never wires anything by itself.
A wizard window collecting input and rendering results ships in a separate change; every asset mutation lives here.
WaveCreator.Input
Everything needed to create or update one stage's Wave asset chain.
WaveCreator.PreviewResult
Read-only summary of what a Create(Input) call would do. Never mutates the project.
WaveCreator.Result
Outcome of a Create(Input) call.
WaveCreator.SpawnEntryInput
One authored spawn entry row.
WaveCreator.WaveInput
One authored wave, resolved-or-edited by Id within <StageFolderPath>/Waves/.
WaveCreator.WavePreview
Read-only summary of what Create(Input) would do for one wave, including both actor totals — see the type doc's TotalActors discrepancy section.
WaveCreator.WaveResult
Outcome for a single wave within a WaveCreator.Result.