refactor: None means custom; the type list resolves only at construction

The None -> type list -> Medium chain was construction-time defaulting
(so creatures without a bucket or a SetSpeed call never spawn at 0/0),
not a live semantic. The constructor now resolves it once into
_speedClass itself, so at runtime a concrete bucket means table-backed
and None means the creature's own speeds are authoritative - which is
what SpeedLevel.Custom was; it is removed. Runtime entry resolution
collapses to a single level lookup, and the SpeedClass byte still
elides by comparing against the (cached) resolved type default.

Legacy loads guess the type default and demote to None when the loaded
speeds do not conform, so pre-codegen customized creatures (SetSpeed
vendors) come out honestly labeled. A constructor guard keeps a missing
speed table loud instead of spawning 0-delay creatures that spin their
AI timers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kamron Batman 2026-08-23 13:13:46 -07:00
parent 4238980c6d
commit cdcf82cfd8
No known key found for this signature in database
GPG key ID: 7D81DF26D9A5D94A
3 changed files with 54 additions and 27 deletions

View file

@ -85,7 +85,7 @@ public class BaseCreatureSerializationTests : IDisposable
Assert.Equal(0.3, copy.ActiveSpeed);
Assert.Equal(0.6, copy.PassiveSpeed);
Assert.Equal(0.6, copy.CurrentSpeed);
Assert.Equal(0.6, copy.ActiveMoveSpeed); // pulled from the table, not the wire
Assert.Equal(0.6, copy.ActiveMoveSpeed); // class None (no table in tests): restored from the wire
Assert.Equal(1.2, copy.PassiveMoveSpeed);
Assert.Equal(100, copy.PhysicalDamage);
Assert.Equal(BaseCreature.MaxLoyalty, copy.Loyalty);
@ -238,7 +238,7 @@ public class BaseCreatureSerializationTests : IDisposable
bc.ActiveSpeed = 0.25; // one tuned value customizes the whole block
Assert.Equal(SpeedLevel.Custom, bc.SpeedClass); // the bucket label never lies
Assert.Equal(SpeedLevel.None, bc.SpeedClass); // the bucket label never lies
var writer = new BufferWriter(true);
bc.Serialize(writer);
@ -252,7 +252,7 @@ public class BaseCreatureSerializationTests : IDisposable
// All four persisted raw - no value is left silently tracking the table.
Assert.Equal(buffer.Length, reader.Position);
Assert.Equal(SpeedLevel.Custom, copy.SpeedClass);
Assert.Equal(SpeedLevel.None, copy.SpeedClass);
Assert.Equal(0.25, copy.ActiveSpeed);
Assert.Equal(0.4, copy.PassiveSpeed);
Assert.Equal(0.3, copy.ActiveMoveSpeed);