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:
@@ -6,13 +6,12 @@ using UnityEngine;
|
||||
namespace ProjectM.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Client-only AMBIENT audio + cycle-phase stingers. A managed presentation <see cref="SystemBase"/>
|
||||
/// (<see cref="PresentationSystemGroup"/>, main thread, no Burst) that OBSERVES the replicated
|
||||
/// <see cref="CycleState"/> and never touches the simulation. On start it plays a low, seamless-looping
|
||||
/// procedural drone (asset-free, <c>AudioClip.Create</c> like <c>CombatFeedbackSystem.MakeClip</c>); each
|
||||
/// time the cycle phase changes it plays a short procedural stinger and eases the drone's intensity by phase
|
||||
/// (calmer at base, tenser during Defend / "wave incoming"). Lives only in the client world, so the server
|
||||
/// never creates audio and nothing here affects determinism. Volumes are deliberately conservative + tunable.
|
||||
/// Client-only AMBIENT audio bed + run cues. A managed presentation <see cref="SystemBase"/>
|
||||
/// (<see cref="PresentationSystemGroup"/>, main thread, no Burst) that plays a low, seamless-looping
|
||||
/// procedural drone (asset-free, <c>AudioClip.Create</c> like <c>CombatFeedbackSystem.MakeClip</c>) plus
|
||||
/// launch-countdown beeps and the boss-arrival roar — replicated-state observations only. Lives only in the
|
||||
/// client world, so the server never creates audio and nothing here affects determinism. Volumes are
|
||||
/// deliberately conservative. (The cycle-phase stingers + Core alarm retired with the siege loop — LANTERN purge.)
|
||||
/// </summary>
|
||||
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)]
|
||||
[UpdateInGroup(typeof(PresentationSystemGroup))]
|
||||
@@ -20,29 +19,17 @@ namespace ProjectM.Client
|
||||
{
|
||||
AudioSource _ambient;
|
||||
AudioClip _ambientClip;
|
||||
AudioClip _stingExpedition;
|
||||
AudioClip _stingDefend;
|
||||
AudioClip _stingBuild;
|
||||
GameObject _root;
|
||||
|
||||
byte _lastPhase;
|
||||
bool _phaseInit;
|
||||
AudioClip _stingCoreHit;
|
||||
int _lastCore = -1;
|
||||
float _coreStingCooldown;
|
||||
AudioClip _stingBeep, _stingRoar;
|
||||
int _lastCountdownSec = -1;
|
||||
bool _bossRoared;
|
||||
|
||||
const float AmbientBaseVolume = 0.10f; // low bed; Defend eases up to ~1.7x
|
||||
const float AmbientBaseVolume = 0.10f; // low ambient bed
|
||||
|
||||
protected override void OnCreate()
|
||||
{
|
||||
_ambientClip = MakeDrone();
|
||||
_stingExpedition = MakeSting(520f, 880f, 0.45f, 0.30f); // airy rising "deploy"
|
||||
_stingDefend = MakeSting(300f, 140f, 0.55f, 0.42f); // tense falling "wave incoming"
|
||||
_stingBuild = MakeSting(440f, 660f, 0.40f, 0.26f); // soft confirm
|
||||
_stingCoreHit = MakeSting(240f, 70f, 0.30f, 0.55f); // harsh falling "Core hit" alarm
|
||||
_stingBeep = MakeSting(880f, 880f, 0.09f, 0.30f); // countdown tick
|
||||
_stingRoar = MakeSting(90f, 38f, 0.90f, 0.60f); // boss-arrival roar (low falling growl)
|
||||
}
|
||||
@@ -68,36 +55,8 @@ namespace ProjectM.Client
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
if (_ambient == null) return;
|
||||
if (!SystemAPI.TryGetSingleton<CycleState>(out var cyc)) return;
|
||||
|
||||
byte phase = cyc.Phase;
|
||||
if (!_phaseInit)
|
||||
{
|
||||
_lastPhase = phase; // adopt the current phase silently (no stinger on first observe)
|
||||
_phaseInit = true;
|
||||
}
|
||||
else if (phase != _lastPhase)
|
||||
{
|
||||
PlaySting(phase);
|
||||
_lastPhase = phase;
|
||||
}
|
||||
|
||||
// Ease the drone intensity toward the phase target (tenser during Defend).
|
||||
float target = phase == CyclePhase.Siege ? AmbientBaseVolume * 1.7f : AmbientBaseVolume;
|
||||
_ambient.volume = Mathf.MoveTowards(_ambient.volume, target * GameVolume.Music, SystemAPI.Time.DeltaTime * 0.25f);
|
||||
|
||||
// Core-under-attack alarm: a falling sting on each CoreIntegrity drop (rate-limited) so a base
|
||||
// breach is AUDIBLE even when the fight has the player's eyes elsewhere.
|
||||
_coreStingCooldown -= SystemAPI.Time.DeltaTime;
|
||||
if (SystemAPI.TryGetSingleton<CoreIntegrity>(out var core))
|
||||
{
|
||||
if (_lastCore >= 0 && core.Current < _lastCore && _coreStingCooldown <= 0f)
|
||||
{
|
||||
_ambient.PlayOneShot(_stingCoreHit, 0.8f * GameVolume.Sfx);
|
||||
_coreStingCooldown = 0.7f;
|
||||
}
|
||||
_lastCore = core.Current;
|
||||
}
|
||||
_ambient.volume = Mathf.MoveTowards(_ambient.volume, AmbientBaseVolume * GameVolume.Music, SystemAPI.Time.DeltaTime * 0.25f);
|
||||
|
||||
// Launch countdown beeps (3-2-1) + the boss-arrival roar — replicated-state observations only.
|
||||
if (SystemAPI.TryGetSingleton<RunInfo>(out var runAudio))
|
||||
@@ -131,13 +90,6 @@ namespace ProjectM.Client
|
||||
}
|
||||
}
|
||||
|
||||
void PlaySting(byte phase)
|
||||
{
|
||||
AudioClip clip = phase == CyclePhase.Siege ? _stingDefend : _stingBuild;
|
||||
if (clip != null && _ambient != null)
|
||||
_ambient.PlayOneShot(clip, 0.6f * GameVolume.Music);
|
||||
}
|
||||
|
||||
// ---- Procedural audio (asset-free; mirrors CombatFeedbackSystem.MakeClip) ----
|
||||
|
||||
// A low, seamless-looping pad: each partial completes an integer number of cycles over the buffer
|
||||
@@ -176,6 +128,6 @@ namespace ProjectM.Client
|
||||
}
|
||||
|
||||
// Short one-shot tone sweeping f0->f1 with an exponential decay envelope.
|
||||
static AudioClip MakeSting(float f0, float f1, float dur, float vol) => FeedbackFx.MakeClip("sting", f0, f1, dur, vol, decay: 3.5f);
|
||||
static AudioClip MakeSting(float f0, float f1, float dur, float vol) => FeedbackFx.MakeClip("sting", f0, f1, dur, vol, decay: 3.5f);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user