LANTERN purge B6: delete the legacy single-ability path (sockets are THE ability model)

AbilityRef, AbilityCooldown, EffectiveAbilityStats, DefaultAbility deleted.
GoInGameServerSystem seeds the per-frame 4-socket Spark loadout UNCONDITIONALLY
(was gym-only); ClassSelectReceiveSystem + DebugOp.SetClass swap FrameId +
re-seed sockets + zero SocketCooldown; ClassSwapUtil.Apply drops newAbilityId;
EquipSystem weapons become stat-sticks (GrantedAbilityId removed from the item
blob/authoring); StatRecomputeSystem folds CharacterStatsRef + sockets only;
HUD cooldown bar reads socket 0 of SocketCooldown/EffectiveSocketStats; class
HUD readers are FrameId-only (ClassForAbility/AbilityFor deleted);
DebugModifierInjectionSystem drops CycleAbility.

390 tests green; Play-verified: a non-gym spawn gets frame=2 with Sparks
[7,8,6,9] and no console errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 15:47:12 -07:00
parent b34945c2d2
commit 4a8220ad3e
27 changed files with 137 additions and 275 deletions
@@ -14,7 +14,6 @@ namespace ProjectM.Server
/// client. In-editor single-process only (client + server worlds in one process). Poke from execute_code:
/// DebugModifierInjectionSystem.AddModifier((byte)StatTarget.Damage, (byte)ModOp.Flat, 50f);
/// DebugModifierInjectionSystem.AddModifier((byte)StatTarget.MoveSpeed, (byte)ModOp.PercentAdd, 0.5f);
/// DebugModifierInjectionSystem.CycleAbility(); // Primary -> FastLight -> SlowHeavy -> Primary
/// DebugModifierInjectionSystem.ClearModifiers();
/// All applied to the first player on the next server tick.
/// </summary>
@@ -25,7 +24,6 @@ namespace ProjectM.Server
static readonly List<PendingModifier> s_Pending = new List<PendingModifier>();
static bool s_Clear;
static bool s_Cycle;
/// <summary>Queue a modifier to append to the first player on the next server tick.</summary>
public static void AddModifier(byte target, byte op, float value)
@@ -36,17 +34,15 @@ namespace ProjectM.Server
/// <summary>Clear the first player's whole modifier stack on the next server tick.</summary>
public static void ClearModifiers() => s_Clear = true;
/// <summary>Cycle the first player's primary ability id on the next server tick.</summary>
public static void CycleAbility() => s_Cycle = true;
protected override void OnUpdate()
{
if (s_Pending.Count == 0 && !s_Clear && !s_Cycle)
if (s_Pending.Count == 0 && !s_Clear)
return;
Entity player = Entity.Null;
foreach (var (abilityRef, e) in
SystemAPI.Query<RefRO<AbilityRef>>().WithAll<PlayerTag, StatModifier>().WithEntityAccess())
foreach (var (tag, e) in
SystemAPI.Query<RefRO<PlayerTag>>().WithAll<StatModifier>().WithEntityAccess())
{
player = e;
break;
@@ -70,19 +66,6 @@ namespace ProjectM.Server
}
s_Pending.Clear();
}
if (s_Cycle)
{
var abilityRef = EntityManager.GetComponentData<AbilityRef>(player);
abilityRef.Id = abilityRef.Id switch
{
(byte)AbilityId.Primary => (byte)AbilityId.FastLight,
(byte)AbilityId.FastLight => (byte)AbilityId.SlowHeavy,
_ => (byte)AbilityId.Primary,
};
EntityManager.SetComponentData(player, abilityRef);
s_Cycle = false;
}
}
}
}