ModernUO/Distribution/Data/Spawns/shared/ilshenar/Sorcerers.json
Kamron Batman 2f8a7afa57 chore(spawners): migrate spawn data to $type discriminator
- Rename "type" -> "$type" (first key, required for STJ polymorphism) in
  all 109 spawn JSON files (5,612 records).
- Convert "homeRange" + "location" -> "spawnBounds" object, dropping homeRange.
  Runtime keeps reading homeRange so un-migrated/external files still load.
- Add BoundsEquivalenceTests (hr=0/1/3/7) validating that the script's toBounds
  formula produces the same Rectangle3D as the runtime homeRange path.
- Add MigratedDataLoadTests loading a real migrated file as List<SpawnerDto>
  and round-tripping each DTO through ToSpawner().
- Add tools/spawner-json-migrate/migrate.mjs (offline Node script).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 16:17:35 -07:00

1114 lines
20 KiB
JSON

[
{
"$type": "Spawner",
"guid": "091c33d5-ee75-471b-aafc-78ea45d3dd66",
"name": "Spawner (309)",
"location": [
336,
48,
-28
],
"map": "Ilshenar",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 328,
"y1": 40,
"z1": -128,
"x2": 345,
"y2": 57,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "Gargoyle",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "10f6b4be-fd86-480d-b285-d00f0f55b59c",
"name": "Spawner (309)",
"location": [
155,
21,
-28
],
"map": "Ilshenar",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 145,
"y1": 11,
"z1": -128,
"x2": 166,
"y2": 32,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "Balron",
"maxCount": 2,
"probability": 100
},
{
"name": "ElderGazer",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "1fb85d78-33ef-42c5-8145-e0af0ec5bd33",
"name": "Spawner (309)",
"location": [
336,
37,
-28
],
"map": "Ilshenar",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 328,
"y1": 29,
"z1": -128,
"x2": 345,
"y2": 46,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "Gargoyle",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "20ea3ede-9733-4b69-a2a9-44312ad782df",
"name": "Spawner (309)",
"location": [
254,
20,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 249,
"y1": 15,
"z1": -128,
"x2": 260,
"y2": 26,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "BloodElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "271dd12c-8c89-4962-8766-27c6e23ab039",
"name": "Spawner (309)",
"location": [
427,
95,
-28
],
"map": "Ilshenar",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 417,
"y1": 85,
"z1": -128,
"x2": 438,
"y2": 106,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "Skeleton",
"maxCount": 4,
"probability": 100
},
{
"name": "BoneKnight",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "27540523-3186-413d-99da-3fd4ef5be98f",
"name": "Spawner (309)",
"location": [
281,
20,
-28
],
"map": "Ilshenar",
"count": 7,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 271,
"y1": 10,
"z1": -128,
"x2": 292,
"y2": 31,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "ElderGazer",
"maxCount": 1,
"probability": 100
},
{
"name": "Gazer",
"maxCount": 4,
"probability": 100
},
{
"name": "GazerLarva",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "29b9ab63-8072-4a0e-b8b2-cbdbe54a74c6",
"name": "Spawner (309)",
"location": [
462,
16,
-28
],
"map": "Ilshenar",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 457,
"y1": 11,
"z1": -128,
"x2": 468,
"y2": 22,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "HeadlessOne",
"maxCount": 2,
"probability": 100
},
{
"name": "Mongbat",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "37598c17-946c-4a0a-8e86-20d1329e4bca",
"name": "Spawner (309)",
"location": [
133,
114,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 113,
"y1": 94,
"z1": -128,
"x2": 154,
"y2": 135,
"z2": 128
},
"walkingRange": 25,
"entries": [
{
"name": "BoneKnight",
"maxCount": 1,
"probability": 100
},
{
"name": "SkeletalKnight",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "3aad6c47-815b-4713-93f2-c57156aded30",
"name": "Spawner (309)",
"location": [
305,
20,
-28
],
"map": "Ilshenar",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 295,
"y1": 10,
"z1": -128,
"x2": 316,
"y2": 31,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "DullCopperElemental",
"maxCount": 5,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "492af6a5-b034-4a8b-aa7b-923b906321e2",
"name": "Spawner (309)",
"location": [
133,
114,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 123,
"y1": 104,
"z1": -128,
"x2": 144,
"y2": 125,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "BloodElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "5bceb873-73d8-4326-8ec1-46bb48c65d60",
"name": "Spawner (309)",
"location": [
214,
67,
-28
],
"map": "Ilshenar",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 199,
"y1": 52,
"z1": -128,
"x2": 230,
"y2": 83,
"z2": 128
},
"walkingRange": 40,
"entries": [
{
"name": "Imp",
"maxCount": 4,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "5e285fc0-52a0-4f23-ad8f-bc7e90b2fcec",
"name": "Spawner (309)",
"location": [
455,
70,
-28
],
"map": "Ilshenar",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 448,
"y1": 63,
"z1": -128,
"x2": 463,
"y2": 78,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "AcidElemental",
"maxCount": 5,
"probability": 100
},
{
"name": "FireElemental",
"maxCount": 5,
"probability": 100
},
{
"name": "BloodElemental",
"maxCount": 5,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "6433de3a-a4f6-4d51-9249-0dc37a3fe107",
"name": "Spawner (309)",
"location": [
394,
69,
-28
],
"map": "Ilshenar",
"count": 7,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 384,
"y1": 59,
"z1": -128,
"x2": 405,
"y2": 80,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "Shade",
"maxCount": 2,
"probability": 100
},
{
"name": "Mongbat",
"maxCount": 5,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "65f92121-fb34-4f86-9722-4ee64ec64b61",
"name": "Spawner (309)",
"location": [
109,
44,
-28
],
"map": "Ilshenar",
"count": 7,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 94,
"y1": 29,
"z1": -128,
"x2": 125,
"y2": 60,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "BoneMagi",
"maxCount": 4,
"probability": 100
},
{
"name": "SkeletalMage",
"maxCount": 4,
"probability": 100
},
{
"name": "Mummy",
"maxCount": 3,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "72c10d82-2c9a-489b-8bad-28dac3e794c9",
"name": "Spawner (309)",
"location": [
447,
19,
-28
],
"map": "Ilshenar",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 437,
"y1": 9,
"z1": -128,
"x2": 458,
"y2": 30,
"z2": 128
},
"walkingRange": 25,
"entries": [
{
"name": "Gargoyle",
"maxCount": 3,
"probability": 100
},
{
"name": "StoneGargoyle",
"maxCount": 1,
"probability": 100
},
{
"name": "Lich",
"maxCount": 1,
"probability": 100
},
{
"name": "Shade",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "73b4ab03-1cab-4034-a3c0-9b8ba61d3600",
"name": "Spawner (309)",
"location": [
160,
59,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 150,
"y1": 49,
"z1": -128,
"x2": 171,
"y2": 70,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "BloodElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "73efa56f-434e-4fc0-8822-c028c9a83e6c",
"name": "Spawner (309)",
"location": [
431,
16,
-28
],
"map": "Ilshenar",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 426,
"y1": 11,
"z1": -128,
"x2": 437,
"y2": 22,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "HeadlessOne",
"maxCount": 2,
"probability": 100
},
{
"name": "Mongbat",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "807fd985-4f3a-4d1f-a7be-942294f1d782",
"name": "Spawner (309)",
"location": [
238,
48,
-28
],
"map": "Ilshenar",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 231,
"y1": 41,
"z1": -128,
"x2": 246,
"y2": 56,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "Balron",
"maxCount": 1,
"probability": 100
},
{
"name": "Daemon",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "818d30b9-0568-4e69-9b00-a8567e0f63b4",
"name": "Spawner (309)",
"location": [
143,
70,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 133,
"y1": 60,
"z1": -128,
"x2": 154,
"y2": 81,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "EvilMageLord",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "846a8862-f62b-4814-856b-88a6f9cb0a27",
"name": "Spawner (309)",
"location": [
350,
42,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 340,
"y1": 32,
"z1": -128,
"x2": 361,
"y2": 53,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "BloodElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "86f27a56-95cc-49ed-8483-38c07cd31de2",
"name": "Spawner (309)",
"location": [
462,
16,
-28
],
"map": "Ilshenar",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 457,
"y1": 11,
"z1": -128,
"x2": 468,
"y2": 22,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "EarthElemental",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "94e38cf9-78c0-498b-927d-f7151001f811",
"name": "Spawner (309)",
"location": [
67,
70,
-28
],
"map": "Ilshenar",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 52,
"y1": 55,
"z1": -128,
"x2": 83,
"y2": 86,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "LichLord",
"maxCount": 2,
"probability": 100
},
{
"name": "Mummy",
"maxCount": 4,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "99674640-e132-4cdd-a69e-1607e28dc5f3",
"name": "Spawner (309)",
"location": [
310,
92,
-13
],
"map": "Ilshenar",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 290,
"y1": 72,
"z1": -128,
"x2": 331,
"y2": 113,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "LichLord",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "9ce0e4a2-0318-4e8d-83a6-48933b302425",
"name": "Spawner (309)",
"location": [
336,
42,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 328,
"y1": 34,
"z1": -128,
"x2": 345,
"y2": 51,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "Lich",
"maxCount": 1,
"probability": 100
},
{
"name": "Shade",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "9cebea0f-1699-45af-a9b1-0d79d99d290e",
"name": "Spawner (309)",
"location": [
383,
29,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 378,
"y1": 24,
"z1": -128,
"x2": 389,
"y2": 35,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "BloodElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "a1b6deba-e340-4851-bba7-4f5ad2d03353",
"name": "Spawner (309)",
"location": [
146,
83,
-28
],
"map": "Ilshenar",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 136,
"y1": 73,
"z1": -128,
"x2": 157,
"y2": 94,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "BloodElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "a304cb5f-12b3-401a-96d3-104ee9f33544",
"name": "Spawner (309)",
"location": [
311,
91,
-13
],
"map": "Ilshenar",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 291,
"y1": 71,
"z1": -128,
"x2": 332,
"y2": 112,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "PoisonElemental",
"maxCount": 1,
"probability": 100
},
{
"name": "BloodElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "b6f7c48e-faa6-44a6-b59f-d0b47313a4f6",
"name": "Spawner (309)",
"location": [
278,
53,
-28
],
"map": "Ilshenar",
"count": 7,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 268,
"y1": 43,
"z1": -128,
"x2": 289,
"y2": 64,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "HellHound",
"maxCount": 6,
"probability": 100
},
{
"name": "BloodElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "bd576d60-5525-4ee3-b85f-8439e6dd38fd",
"name": "Spawner (309)",
"location": [
160,
9,
-28
],
"map": "Ilshenar",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 156,
"y1": 5,
"z1": -128,
"x2": 165,
"y2": 14,
"z2": 128
},
"walkingRange": 5,
"entries": [
{
"name": "Efreet",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "bed076f5-fb2b-4342-9423-6a3228cc1978",
"name": "Spawner (309)",
"location": [
262,
84,
-28
],
"map": "Ilshenar",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 247,
"y1": 69,
"z1": -128,
"x2": 278,
"y2": 100,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "Gargoyle",
"maxCount": 2,
"probability": 100
},
{
"name": "Wyvern",
"maxCount": 1,
"probability": 100
},
{
"name": "EvilMage",
"maxCount": 3,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "f4631bce-3338-4d0e-88c9-9faa4ba968ef",
"name": "Spawner (309)",
"location": [
262,
84,
-28
],
"map": "Ilshenar",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 247,
"y1": 69,
"z1": -128,
"x2": 278,
"y2": 100,
"z2": 128
},
"walkingRange": 25,
"entries": [
{
"name": "Shade",
"maxCount": 1,
"probability": 100
},
{
"name": "Zombie",
"maxCount": 1,
"probability": 100
},
{
"name": "DreadSpider",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "fc22ceb7-01e2-4389-a356-ffc788071f0f",
"name": "Spawner (309)",
"location": [
427,
67,
-28
],
"map": "Ilshenar",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 402,
"y1": 42,
"z1": -128,
"x2": 453,
"y2": 93,
"z2": 128
},
"walkingRange": 25,
"entries": [
{
"name": "Zombie",
"maxCount": 2,
"probability": 100
}
]
}
]