Cut 2: the dead mining path goes, and chunks get one owner

MiningTool (its Execute range-checked against nothing, since no writer ever
set AsteroidBelt/Asteroid) and Zone.MineAsteroid (mints nothing; the
SimpleCommodity drop was commented out) are deleted, per Q1=A: "Bring back
the drill, indeed." Union tag 26 is retired, not reused. ResourceScanner's
dead survey Execute and its scan-target fields go too; its authored Range/
MinimumDensity/ScanDuration stay pending Q2. PlanetSettings.MiningDifficulty
had one reader, now gone.

Chunk wear (damage, broken-until) moves off AsteroidBelt's three per-belt
dictionaries and onto Zone as the one owner (Q3=A): Zone.Wear is the only
writer, ChunkExists/ChunkRadius are the readers, and respawn is a lazy
comparison against zone time, never a per-tick loop. ChunkId is
(CultRecordKey Field, int Index) -- "Field", not "Belt", because chunks are
meant to generalize past asteroid belts to other debris fields later.

Persisted in ZonePack's new key 6 (List<ChunkWearPack>, nullable so an older
record with no key 6 loads with no wear instead of throwing), pruned of
healed, non-broken entries at pack.

The break threshold stays strictly greater-than, matching today's behaviour:
damage exactly equal to hitpoints does not yet break the chunk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-25 11:30:44 +02:00
commit 3b9f0f1d09
8 changed files with 150 additions and 224 deletions

View file

@ -35,7 +35,32 @@ public class ZonePack
[JsonProperty("time"), Key(5)]
public double Time;
// Cut 2 (docs/mining-cut.md): chunk wear (damage taken, broken-until time), keyed by chunk. Nullable, not
// defaulted to an empty list: an older record has no key 6 at all, and MessagePack fills a missing trailing
// key with nil, which a reference-typed field reads back as null. ARunWithoutKeySixLoadsWhole pins that a
// record from before this key existed loads with no wear, rather than throwing or silently reading a
// default instance.
[JsonProperty("chunkWear"), Key(6)]
public List<ChunkWearPack> ChunkWear;
}
// Cut 2 (docs/mining-cut.md): one packed wear entry for one chunk. "Field" names the body that owns the chunk
// (an asteroid belt today; the operator's ruling generalizes chunks to other kinds of debris field later), not
// "belt" -- the chunk surface itself must not bake in the one live field kind.
[MessagePackObject, JsonObject(MemberSerialization.OptIn)]
public class ChunkWearPack
{
[JsonProperty("field"), Key(0)]
public CultRecordKey Field;
[JsonProperty("index"), Key(1)]
public int Index;
[JsonProperty("damage"), Key(2)]
public float Damage;
[JsonProperty("brokenUntil"), Key(3)]
public double? BrokenUntil;
}
[JsonObject(MemberSerialization.OptIn)]