Tuning Knobs

This commit is contained in:
2026-06-10 15:22:30 -07:00
parent da522efe7a
commit 08f16b689f
20 changed files with 11045 additions and 18 deletions
@@ -61,6 +61,8 @@ namespace ProjectM.Server
float dt = SystemAPI.Time.DeltaTime;
var serverTick = SystemAPI.GetSingleton<NetworkTime>().ServerTick;
uint now = serverTick.TickIndexForValidTick;
// Live feel knobs (MC-0): one read, guarded at use. Server-only — clients never simulate enemies.
var tune = SystemAPI.TryGetSingleton<TuningConfig>(out var tcfg) ? tcfg : TuningConfig.Defaults();
var ecb = new EntityCommandBuffer(Allocator.Temp);
bool havePhysics = SystemAPI.TryGetSingleton<PhysicsWorldSingleton>(out var physics);
uint envMask = SystemAPI.TryGetSingleton<WorldCollisionConfig>(out var worldCol) ? worldCol.EnvironmentMask : 0u;
@@ -165,7 +167,7 @@ namespace ProjectM.Server
}
if (ready)
{
uint windupTicks = (uint)math.max(1, Tuning.AttackWindupTicks);
uint windupTicks = (uint)math.max(1f, tune.GruntWindupTicks);
windup.ValueRW.WindUpUntilTick = TickUtil.NonZero(now + windupTicks);
}
}
@@ -173,10 +175,12 @@ namespace ProjectM.Server
// --- Charger pass: a Husk variant baked with LungeState commits to a punishable fixed-direction lunge.
// Component-presence is the discriminator; the Grunt pass above excludes these via .WithNone<LungeState>().
const float ChargerLungeSpeed = 16f; // units/s while lunging
const uint ChargerLungeDurationTicks = 18; // ~0.30 s of committed travel
const uint ChargerWindupTicks = 30; // ~0.50 s readable telegraph (>= interp delay + reaction)
const uint ChargerWhiffStaggerTicks = 36; // ~0.60 s punish window on a whiff
// Charger feel knobs — live-tunable via TuningConfig (MC-0), guarded at the read site. Server-only
// (clients never simulate Chargers); the >=1-tick floor avoids a degenerate instant/no-travel lunge.
float ChargerLungeSpeed = math.max(0f, tune.ChargerLungeSpeed); // units/s while lunging
uint ChargerLungeDurationTicks = (uint)math.max(1f, tune.ChargerLungeDurationTicks); // committed travel
uint ChargerWindupTicks = (uint)math.max(1f, tune.ChargerWindupTicks); // readable telegraph lead
uint ChargerWhiffStaggerTicks = (uint)math.max(1f, tune.ChargerWhiffStaggerTicks); // punish window
uint chargerWhiffsThisTick = 0;
foreach (var (xform, stats, cooldown, knockback, windup, lunge) in
SystemAPI.Query<RefRW<LocalTransform>, RefRO<EnemyStats>, RefRW<EnemyAttackCooldown>,