ModernUO/Distribution/Data/Spawns/shared/trammel/PrismOfLight.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

698 lines
12 KiB
JSON

[
{
"$type": "Spawner",
"guid": "19d77ed8-3a64-4317-9570-c8a19dc885ed",
"name": "Spawner (116)",
"location": [
6536,
79,
-10
],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6532,
"y1": 75,
"z1": -128,
"x2": 6541,
"y2": 84,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "CrystalDaemon",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "2b5f366f-9197-4fb0-842c-d7e50f9d3395",
"name": "Spawner (116)",
"location": [
6478,
174,
4
],
"map": "Trammel",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6468,
"y1": 164,
"z1": -128,
"x2": 6489,
"y2": 185,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "Wisp",
"maxCount": 6,
"probability": 100
},
{
"name": "CrystalWisp",
"maxCount": 6,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "2bdadfea-e542-43dd-8391-a0a55761bd09",
"name": "Spawner (116)",
"location": [
6509,
176,
0
],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6505,
"y1": 172,
"z1": -128,
"x2": 6514,
"y2": 181,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "UnfrozenMummy",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "3ad2e27a-0fe6-44eb-9a7e-1840e2333414",
"name": "Spawner (116)",
"location": [
6572,
89,
0
],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6568,
"y1": 85,
"z1": -128,
"x2": 6577,
"y2": 94,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "CrystalHydra",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "3ce801dd-1e54-4eb6-b908-d095fc3ac3d6",
"name": "Spawner (116)",
"location": [
6521,
139,
-20
],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6517,
"y1": 135,
"z1": -128,
"x2": 6526,
"y2": 144,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "Wisp",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "44ede0db-e4a9-4fc2-bbd4-41741dc3a138",
"name": "Spawner (116)",
"location": [
6552,
155,
0
],
"map": "Trammel",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6537,
"y1": 140,
"z1": -128,
"x2": 6568,
"y2": 171,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "Wisp",
"maxCount": 5,
"probability": 100
},
{
"name": "CrystalWisp",
"maxCount": 5,
"probability": 100
},
{
"name": "TreasureChestLevel2",
"maxCount": 5,
"probability": 100
},
{
"name": "TreasureChestLevel2",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "4664466b-b753-46bf-8d9a-4c66246ed060",
"name": "Spawner (116)",
"location": [
6553,
157,
0
],
"map": "Trammel",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6545,
"y1": 149,
"z1": -128,
"x2": 6562,
"y2": 166,
"z2": 128
},
"walkingRange": 8,
"entries": [
{
"name": "CrystalLatticeSeeker",
"maxCount": 3,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "500789a1-6c13-4c8c-94c4-d7290a6d9238",
"name": "Spawner (116)",
"location": [
6576,
91,
0
],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6572,
"y1": 87,
"z1": -128,
"x2": 6581,
"y2": 96,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "CrystalSeaSerpent",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "57899529-d774-4c8f-a5b3-263237a5cb74",
"name": "Spawner (116)",
"location": [
6507,
151,
0
],
"map": "Trammel",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6502,
"y1": 146,
"z1": -128,
"x2": 6513,
"y2": 157,
"z2": 128
},
"walkingRange": 5,
"entries": [
{
"name": "Protector",
"maxCount": 3,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "5a151ef4-7184-49a1-b516-e2e5ba7973f4",
"name": "Spawner (116)",
"location": [
6566,
120,
0
],
"map": "Trammel",
"count": 7,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6551,
"y1": 105,
"z1": -128,
"x2": 6582,
"y2": 136,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "CrystalVortex",
"maxCount": 7,
"probability": 100
},
{
"name": "IceElemental",
"maxCount": 7,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "5e2e128a-5312-4afc-858f-4ee70783f6c8",
"name": "Spawner (116)",
"location": [
6534,
178,
0
],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6530,
"y1": 174,
"z1": -128,
"x2": 6539,
"y2": 183,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "CrystalWisp",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "68fe4e5a-136b-4f9d-8b23-1289f26cbfb3",
"name": "Spawner (116)",
"location": [
6547,
91,
-10
],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6543,
"y1": 87,
"z1": -128,
"x2": 6552,
"y2": 96,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "CrystalDaemon",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "6c1abed9-6d57-4f20-a0e6-1598ab7b0602",
"name": "Spawner (116)",
"location": [
6504,
181,
0
],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6503,
"y1": 180,
"z1": -128,
"x2": 6506,
"y2": 183,
"z2": 128
},
"walkingRange": 1,
"entries": [
{
"name": "TreasureChestLevel4",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "6d47bfa4-0820-4805-865d-7a7f3e54e159",
"name": "Spawner (116)",
"location": [
6510,
171,
0
],
"map": "Trammel",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6502,
"y1": 163,
"z1": -128,
"x2": 6519,
"y2": 180,
"z2": 128
},
"walkingRange": 8,
"entries": [
{
"name": "Protector",
"maxCount": 3,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "70250ff2-f75d-4f6a-adcd-e32d3f8c05e4",
"name": "Spawner (116)",
"location": [
6474,
74,
-34
],
"map": "Trammel",
"count": 9,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6470,
"y1": 70,
"z1": -128,
"x2": 6479,
"y2": 79,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "Rat",
"maxCount": 9,
"probability": 100
},
{
"name": "IceSnake",
"maxCount": 9,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "9e39061c-b9fa-4988-abef-2eac1f2344f3",
"name": "Spawner (116)",
"location": [
6578,
183,
31
],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6573,
"y1": 178,
"z1": -128,
"x2": 6584,
"y2": 189,
"z2": 128
},
"walkingRange": 5,
"entries": [
{
"name": "Ferret",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "cb0719bf-0812-4551-a287-3fe92e6dd66b",
"name": "Spawner (116)",
"location": [
6475,
101,
-44
],
"map": "Trammel",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6470,
"y1": 96,
"z1": -128,
"x2": 6481,
"y2": 107,
"z2": 128
},
"walkingRange": 5,
"entries": [
{
"name": "ShadowWisp",
"maxCount": 5,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "d4e26c54-212c-4dc9-bbb8-a6e2ecd02d55",
"name": "Spawner (116)",
"location": [
6530,
139,
-20
],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6526,
"y1": 135,
"z1": -128,
"x2": 6535,
"y2": 144,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "Wisp",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "d8d2b685-7458-494d-a596-90baea5763c8",
"name": "Spawner (116)",
"location": [
6535,
179,
0
],
"map": "Trammel",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6520,
"y1": 164,
"z1": -128,
"x2": 6551,
"y2": 195,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "CrystalWisp",
"maxCount": 5,
"probability": 100
},
{
"name": "CrystalLatticeSeeker",
"maxCount": 5,
"probability": 100
},
{
"name": "TreasureChestLevel2",
"maxCount": 5,
"probability": 100
},
{
"name": "TreasureChestLevel2",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "dbdcaa33-dad3-447b-be16-737b98732315",
"name": "Spawner (116)",
"location": [
6532,
79,
-10
],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6528,
"y1": 75,
"z1": -128,
"x2": 6537,
"y2": 84,
"z2": 128
},
"walkingRange": 4,
"entries": [
{
"name": "CrystalDaemon",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "ed761287-3375-4732-be78-2277dec45e2e",
"name": "Spawner (116)",
"location": [
6502,
120,
-10
],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6502,
"y1": 120,
"z1": -10,
"x2": 6503,
"y2": 121,
"z2": -10
},
"walkingRange": 0,
"entries": [
{
"name": "TreasureChestLevel3",
"maxCount": 1,
"probability": 100
}
]
}
]