Files
Project-M/Assets/_Project/Tests/EditMode/DebugCommandReceiveSystemTests.cs
T
kronic b34945c2d2 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>
2026-07-15 15:27:12 -07:00

131 lines
5.7 KiB
C#

using NUnit.Framework;
using ProjectM.Server;
using ProjectM.Simulation;
using Unity.Core;
using Unity.Entities;
using Unity.Mathematics;
using Unity.NetCode;
using Unity.Transforms;
namespace ProjectM.Tests
{
/// <summary>
/// Plain-Entities EditMode tests for the editor-only <see cref="DebugCommandReceiveSystem"/> — the
/// server-side dev-tools RPC dispatcher. A bare world is seeded with the relevant singletons + a
/// DebugCommandRequest (+ ReceiveRpcCommandRequest) entity. These pin that grant-resource deposits to the
/// ledger, spawn-wave arms the pending siege, end-siege forces the wave to Lull + clears pending, and a
/// sender-targeted teleport resolves the player from the source connection and flips its region.
/// </summary>
public class DebugCommandReceiveSystemTests
{
static (World world, SimulationSystemGroup group) MakeWorld(string name)
{
var world = new World(name);
var group = world.GetOrCreateSystemManaged<SimulationSystemGroup>();
group.AddSystemToUpdateList(world.GetOrCreateSystem<DebugCommandReceiveSystem>());
group.SortSystems();
world.SetTime(new TimeData(elapsedTime: 0f, deltaTime: 1f / 60f));
return (world, group);
}
static Entity MakeRequest(EntityManager em, byte op, int argA, int argB, Entity sourceConnection)
{
var e = em.CreateEntity(typeof(DebugCommandRequest), typeof(ReceiveRpcCommandRequest));
em.SetComponentData(e, new DebugCommandRequest { Op = op, ArgA = argA, ArgB = argB });
em.SetComponentData(e, new ReceiveRpcCommandRequest { SourceConnection = sourceConnection });
return e;
}
[Test]
public void GrantResource_Deposits_To_Ledger()
{
var (world, group) = MakeWorld("DebugGrantResource");
using (world)
{
var em = world.EntityManager;
var ledger = em.CreateEntity(typeof(ResourceLedger), typeof(StorageEntry));
MakeRequest(em, DebugOp.GrantResource, ResourceId.Aether, 50, Entity.Null);
group.Update();
var buf = em.GetBuffer<StorageEntry>(ledger);
int aether = 0;
for (int i = 0; i < buf.Length; i++)
if (buf[i].ItemId == ResourceId.Aether) aether = buf[i].Count;
Assert.AreEqual(50, aether, "GrantResource deposits the amount into the shared ledger.");
}
}
[Test]
public void SpawnWave_Forces_Next_Wave_Now()
{
var (world, group) = MakeWorld("DebugSpawnWave");
using (world)
{
var em = world.EntityManager;
var wave = em.CreateEntity(typeof(WaveState));
em.SetComponentData(wave, new WaveState { Phase = WavePhase.Spawning, NextActionTick = 999999, RemainingToSpawn = 0 });
MakeRequest(em, DebugOp.SpawnWave, 0, 0, Entity.Null);
group.Update();
var w = em.GetComponentData<WaveState>(wave);
Assert.AreEqual(WavePhase.Lull, w.Phase, "SpawnWave resets to a due Lull so WaveSystem starts the next wave.");
Assert.AreEqual(0u, w.NextActionTick, "SpawnWave makes the next wave due immediately.");
}
}
[Test]
public void EndSiege_Quiets_The_Arena()
{
var (world, group) = MakeWorld("DebugEndSiege");
using (world)
{
var em = world.EntityManager;
var wave = em.CreateEntity(typeof(WaveState));
em.SetComponentData(wave, new WaveState { Phase = WavePhase.Spawning, RemainingToSpawn = 3 });
for (int i = 0; i < 2; i++)
em.CreateEntity(typeof(EnemyTag));
MakeRequest(em, DebugOp.EndSiege, 0, 0, Entity.Null);
group.Update();
var w = em.GetComponentData<WaveState>(wave);
Assert.AreEqual(WavePhase.Lull, w.Phase, "EndSiege drives the wave to Lull.");
Assert.AreEqual(0, w.RemainingToSpawn, "EndSiege stops further spawning.");
Assert.AreNotEqual(0u, w.NextActionTick, "EndSiege pushes the next wave far out (quiet arena).");
using (var husks = em.CreateEntityQuery(typeof(EnemyTag)))
Assert.AreEqual(0, husks.CalculateEntityCount(), "EndSiege culls the remaining Husks.");
}
}
[Test]
public void Teleport_Resolves_Sender_Only()
{
var (world, group) = MakeWorld("DebugTeleport");
using (world)
{
var em = world.EntityManager;
var connection = em.CreateEntity(typeof(NetworkId));
em.SetComponentData(connection, new NetworkId { Value = 1 });
var player = em.CreateEntity(typeof(PlayerTag), typeof(GhostOwner), typeof(RegionTag), typeof(LocalTransform));
em.SetComponentData(player, new GhostOwner { NetworkId = 1 });
em.SetComponentData(player, new RegionTag { Region = RegionId.Base });
em.SetComponentData(player, LocalTransform.FromPosition(new float3(0, 1, 0)));
MakeRequest(em, DebugOp.Teleport, RegionId.Expedition, 0, connection);
group.Update();
Assert.AreEqual(RegionId.Expedition, em.GetComponentData<RegionTag>(player).Region,
"Teleport flips the SENDER's region.");
Assert.Greater(em.GetComponentData<LocalTransform>(player).Position.x, 500f,
"Teleport moves the sender to the expedition region (far +X).");
}
}
}
}