LANTERN purge B3+B5: delete the cycle/core/win-lose spine + onboarding; save epoch v7
Deletes CyclePhaseSystem, GoalReachedSystem, CoreDamage/CoreRestore, ThreatDirector, CoreIntegrity/GoalProgress/RunPhase/RunOutcome/ThreatState components, CoreVisualFeedbackSystem, and the whole Client/Onboarding slice (+6 test files). Keepers reworked: RunDirectorSystem (UpdateBefore attr + launch guard + goal/threat bank removed; sole SaveRequest raiser now), CycleDirectorSpawnSystem (ledger/meta host only), WaveSystem UNGATED (waves run wherever a WaveDirector is baked), EnemyAISystem core-fallback stripped, AmbientAudioSystem reworked (bed + run cues; no CycleState gate), MusicSystem RunInfo-only, HudSystem big trim (goal meter, core bar, siege banner, terminal banner, outcome flash, onboarding hook all gone), MetaShop/ClassPrep/AimReticle siege gates dropped, DebugOverlay/ops re-meant (SpawnWave=force next wave, EndSiege=quiet arena; SetCalm/AdvanceGoal/SetHeat retired, bytes reserved), TuningConfig Core knobs retired (ids 20-23 reserved), StorageMath.DrainFraction deleted, HowToPlay copy rewritten. Save epoch v7 (fresh epoch, operator-approved): SaveData drops goal/core/outcome + conveyor/machine-IO fields; MinLoadableVersion=7; PendingSave/PendingStructure trimmed; RollTerminalCampaignForward deleted; SaveStructureScan signature slimmed. 390 tests green; Play world-creation clean (player + waves live, no exceptions). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,9 +11,8 @@ namespace ProjectM.Client
|
||||
/// every AudioSource starts the same frame with loop=true and identical clip length, and per-bar amplitude
|
||||
/// envelopes reach ~zero at each bar boundary so both the chord changes and the loop point are click-free
|
||||
/// (the <c>AmbientAudioSystem.Snap</c> trick generalized to enveloped segments). The MIX is the state
|
||||
/// machine: layer volumes ease toward targets chosen from replicated state only — <see cref="RunInfo"/>
|
||||
/// lifecycle (staging / combat / boss / reward lull), <see cref="CycleState"/> siege, and the terminal
|
||||
/// <see cref="RunOutcome"/> (one-shot victory/defeat sting + aftermath bed). Observe-only presentation
|
||||
/// machine: layer volumes ease toward targets chosen from replicated state only — the <see cref="RunInfo"/>
|
||||
/// lifecycle (staging / launch / combat / boss / reward lull / return). Observe-only presentation
|
||||
/// system: no sim writes, no determinism surface; asset-free per the project convention. Sits under SFX at
|
||||
/// <see cref="MasterVolume"/> × <see cref="GameVolume.Music"/>; the low <c>AmbientAudioSystem</c> drone
|
||||
/// (vol 0.10) remains as texture beneath it.
|
||||
@@ -43,7 +42,6 @@ namespace ProjectM.Client
|
||||
GameObject _root;
|
||||
AudioSource _bass, _pad, _arp, _pulse;
|
||||
float _vBass, _vPad, _vArp, _vPulse; // current smoothed volumes (pre-master)
|
||||
byte _outcomePlayed; // which terminal outcome's sting has fired (0 = none)
|
||||
|
||||
protected override void OnStartRunning()
|
||||
{
|
||||
@@ -80,27 +78,7 @@ namespace ProjectM.Client
|
||||
// ---- pick the mix from replicated state (defaults = quiet staging bed) ----
|
||||
float tBass = 0.50f, tPad = 0.55f, tArp = 0.12f, tPulse = 0f;
|
||||
|
||||
bool haveRun = SystemAPI.TryGetSingleton<RunInfo>(out var run);
|
||||
SystemAPI.TryGetSingleton<CycleState>(out var cyc);
|
||||
bool siege = cyc.Phase == CyclePhase.Siege;
|
||||
bool finalSiege = siege && SystemAPI.TryGetSingleton<GoalProgress>(out var goal)
|
||||
&& goal.Target > 0 && goal.Charge >= goal.Target;
|
||||
|
||||
byte outcome = SystemAPI.TryGetSingleton<RunOutcome>(out var oc) ? oc.Value : RunOutcomeId.InProgress;
|
||||
if (outcome != RunOutcomeId.InProgress)
|
||||
{
|
||||
if (_outcomePlayed != outcome)
|
||||
{
|
||||
_outcomePlayed = outcome;
|
||||
PlayOutcomeSting(outcome == RunOutcomeId.Victory);
|
||||
}
|
||||
tBass = 0.20f; tPad = 0.45f; tArp = 0f; tPulse = 0f; // aftermath bed under the banner
|
||||
}
|
||||
else if (siege)
|
||||
{
|
||||
tBass = 0.70f; tPad = 0.40f; tArp = 0.60f; tPulse = finalSiege ? 0.90f : 0.65f;
|
||||
}
|
||||
else if (haveRun)
|
||||
if (SystemAPI.TryGetSingleton<RunInfo>(out var run))
|
||||
{
|
||||
switch (run.Lifecycle)
|
||||
{
|
||||
@@ -138,15 +116,7 @@ namespace ProjectM.Client
|
||||
_pulse.volume = _vPulse * master;
|
||||
}
|
||||
|
||||
void PlayOutcomeSting(bool victory)
|
||||
{
|
||||
// Victory: rising A-minor->major-feel arpeggio; defeat: falling minor third crawl.
|
||||
float[] notes = victory
|
||||
? new[] { 220f, 277.18f, 329.63f, 440f } // A3 C#4 E4 A4 (picardy lift)
|
||||
: new[] { 220f, 207.65f, 174.61f, 146.83f }; // A3 Ab3 F3 D3
|
||||
var clip = BuildStingClip(notes, victory ? 0.16f : 0.28f, victory ? 0.45f : 0.40f);
|
||||
if (_pad != null) _pad.PlayOneShot(clip, 0.9f * GameVolume.Music);
|
||||
}
|
||||
|
||||
|
||||
// ================= clip builders (deterministic, asset-free) =================
|
||||
|
||||
@@ -263,23 +233,6 @@ namespace ProjectM.Client
|
||||
return clip;
|
||||
}
|
||||
|
||||
static AudioClip BuildStingClip(float[] notes, float noteLen, float vol)
|
||||
{
|
||||
int len = (int)(notes.Length * noteLen * SampleRate) + SampleRate / 2; // + half-second tail
|
||||
var clip = AudioClip.Create("music_sting", len, 1, SampleRate, false);
|
||||
var data = new float[len];
|
||||
for (int n = 0; n < notes.Length; n++)
|
||||
{
|
||||
int start = (int)(n * noteLen * SampleRate);
|
||||
int dur = (int)(SampleRate * (noteLen + (n == notes.Length - 1 ? 0.5f : 0.05f)));
|
||||
for (int i = 0; i < dur && start + i < len; i++)
|
||||
{
|
||||
float tn = i / (float)SampleRate;
|
||||
data[start + i] += Mathf.Sin(2f * Mathf.PI * notes[n] * tn) * Mathf.Exp(-4.5f * tn) * vol;
|
||||
}
|
||||
}
|
||||
clip.SetData(data, 0);
|
||||
return clip;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user