ModernUO/Distribution/Data/Spawns/shared/trammel/Hythloth.json
Kamron Batman d8a64f3316
refactor(spawners): replace DynamicJson with typed SpawnerDto records (#2505)
## Summary

Removes the dated `DynamicJson` JSON helper and migrates spawner JSON (de)serialization to a polymorphic `record SpawnerDto` hierarchy. `DynamicJson` was the last remaining consumer (regions moved off it in #1400).

The key correctness improvement: **System.Text.Json deserializes plain DTO records, never a live `Item`.** Previously, deserializing directly into an `Item` meant STJ constructed world-registered objects *before* the data was validated — a malformed/hand-edited spawn file could leave orphaned spawner Items in the world save. Now a parse failure is GC-only; `dto.ToSpawner()` constructs the spawner only from a fully-validated DTO and self-cleans on failure.

## What changed

- **New:** `SpawnerDto` (abstract) + `SpawnerDataDto` / `RegionSpawnerDto` / `ProximitySpawnerDto`, each marked with a reusable `[JsonDiscoverableType]` opt-in attribute. Auto-discovered at the `Configure` phase — no manual registration list (avoids the regions `Register<T>()` footgun), open to custom spawner subtypes.
- **Symmetric mapping:** `BaseSpawner.ToDto()` (export) ⇄ `SpawnerDto.ToSpawner()` (import). `ToSpawner()` deletes-and-rethrows on any failure, so the importer can never orphan an Item.
- **`SpawnerJsonSerializer`** wires `$type` polymorphism on the `SpawnerDto` root with loud collision/constructibility validation.
- **Import/export commands** rewired to the typed DTO path (reflection `FindTypeByName`/`CreateInstance` removed).
- **Data migration:** the 109 `Distribution/Data/Spawns/**` files moved from `"type"`→`"$type"` and legacy `homeRange`→`spawnBounds`. The runtime still *reads* legacy `homeRange` for external files. The `homeRange→spawnBounds` formula is proven equivalent to the runtime conversion (`BoundsEquivalenceTests`, hr=0/1/3/7).
- **Deleted:** `Projects/Server/Json/DynamicJson.cs`.

Sparse export output matches the legacy `ToJson` (nullable DTO properties + `WhenWritingNull`). Binary world-save serialization is untouched.

## Tests

- DTO round-trip per spawner type; sparse-default omission; legacy `homeRange` read; export/import file round-trip.
- `Import_MalformedFile_LeaksNoWorldItems` — proves a mid-array parse failure constructs zero world Items.
- `AllSpawnFilesLoadTests` — every migrated spawn file deserializes and builds.
- Duplicate-discriminator validation.
- UOContent.Tests 485/485, Server.Tests 710/710, build clean.

## Follow-up (not in this PR)

`Rectangle3DConverter.Write` (in `Projects/Server/`) omits `z1/z2` when `Start.Z == -128`, so a future server-side export of a `homeRange`-style spawner round-trips depth 256→255. Pre-existing and out of scope here (Server change); the migrated data reads correctly. Worth a separate small converter PR.
2026-06-25 23:24:45 -07:00

1329 lines
33 KiB
JSON

[
{
"$type": "Spawner",
"guid": "04d3a931-3af8-4863-8989-58f6d1cae959",
"name": "Spawner (109)",
"location": [5966, 70, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "0d2d46b6-5b3a-4668-b064-34d8035b7854",
"name": "Spawner (109)",
"location": [5962, 217, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "132536ba-9f7b-47a7-bf31-be4487936235",
"name": "Spawner (109)",
"location": [6033, 199, 22],
"map": "Trammel",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Daemon", "maxCount": 2, "probability": 100 },
{ "name": "StoneGargoyle", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "159531c4-89e0-48c6-ac04-b4d67b078cae",
"name": "Spawner (109)",
"location": [5945, 78, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "176b940f-621c-490e-baee-3c2816004e14",
"name": "Spawner (109)",
"location": [5954, 225, 22],
"map": "Trammel",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 12,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 4, "probability": 100 },
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "177607bb-ea2f-484c-8e06-262edf56f6d6",
"name": "Spawner (109)",
"location": [6108, 36, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "185cd08c-716f-4255-a8aa-b9e2dbe06e44",
"name": "Spawner (109)",
"location": [6124, 159, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "1deb5cae-7cab-4b3b-91ef-a933a9836369",
"name": "Spawner (109)",
"location": [6033, 205, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "2179be82-2867-4f8e-b797-4102cc967c4c",
"name": "Spawner (109)",
"location": [5915, 91, 0],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "23a59d14-b35b-4776-9e39-c2b32a16262d",
"name": "Spawner (109)",
"location": [6108, 66, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "23ec32d7-3f5f-4d4c-b89c-2449ba45aa6e",
"name": "Spawner (109)",
"location": [6052, 156, 0],
"map": "Trammel",
"count": 7,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Daemon", "maxCount": 2, "probability": 100 },
{ "name": "Gazer", "maxCount": 3, "probability": 100 },
{ "name": "GazerLarva", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "276dda12-6154-456f-9cc9-ac111160fcb0",
"name": "Spawner (109)",
"location": [5923, 48, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 1, "probability": 100 },
{ "name": "HellHound", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "2f802063-b694-457e-8662-8c56600b28d1",
"name": "Spawner (109)",
"location": [6058, 153, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "350f7c02-4640-4932-89b6-2f4c4c4bc1b2",
"name": "Spawner (109)",
"location": [5918, 235, 44],
"map": "Trammel",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Daemon", "maxCount": 2, "probability": 100 },
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "35fc4240-bcd9-4335-b930-b2140d486cc2",
"name": "Spawner (109)",
"location": [5978, 185, 44],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "36a58f71-fb57-48db-b111-d17ec727d1aa",
"name": "Spawner (109)",
"location": [6081, 44, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "3da1531b-38a3-42f5-a69e-1f7a1aa2cb89",
"name": "Spawner (109)",
"location": [6097, 36, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "3e2dd9b5-5fc4-4308-9ae0-a8817d4fac63",
"name": "Spawner (109)",
"location": [6125, 221, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "3f509b00-f24b-4d5a-b609-ec88fe0e025d",
"name": "Spawner (109)",
"location": [5981, 84, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "4244ac16-86b4-4f39-aa2a-7474103986f5",
"name": "Spawner (109)",
"location": [5940, 107, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "443e9b08-9415-41e4-8e4e-07c813d1f687",
"name": "Spawner (109)",
"location": [6086, 178, 0],
"map": "Trammel",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 },
{ "name": "Gazer", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "4653daba-0405-4fb3-b89c-b712cf560782",
"name": "Spawner (109)",
"location": [6041, 230, 44],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "4b63bde3-f24f-407e-9d11-0eb2c04305b3",
"name": "Spawner (109)",
"location": [5918, 223, 44],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 4, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "52f85430-2e62-4e62-b548-46c1a184cf9e",
"name": "Spawner (109)",
"location": [5970, 169, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "545e00c0-3dfb-485b-9f32-dc003ad34c1c",
"name": "Spawner (109)",
"location": [5929, 77, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "5a2b323b-7048-480c-bd22-b8c557dd7571",
"name": "Spawner (109)",
"location": [5917, 93, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "5a73a11a-55be-42d7-b6d4-9db6b6e0762f",
"name": "Spawner (109)",
"location": [6094, 154, -22],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 1, "probability": 100 },
{ "name": "HellHound", "maxCount": 1, "probability": 100 },
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "5b6e1b73-46ac-46b3-b416-c1a4b5e147f1",
"name": "Spawner (109)",
"location": [5921, 81, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "5d613a12-4519-421f-afd7-dfe2d8dfc2ed",
"name": "Spawner (109)",
"location": [6099, 51, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "6524efb1-e7c2-47e4-91ad-393224529ad8",
"name": "Spawner (109)",
"location": [6060, 158, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "6598121a-66ed-4839-b985-cca9e8cb789f",
"name": "Spawner (109)",
"location": [5967, 80, 0],
"map": "Trammel",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 6,
"walkingRange": 6,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 },
{ "name": "TreasureChestLevel2", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "6638a784-d1d4-4ceb-b913-0d19c3876bd1",
"name": "Spawner (109)",
"location": [6046, 199, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "72de652f-c027-4100-ab8b-43e229bc527b",
"name": "Spawner (109)",
"location": [5997, 145, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "75f93255-3c6f-47dc-b862-3d4a61bf454a",
"name": "Spawner (109)",
"location": [6064, 96, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "760cb112-5308-4e18-9fd5-2e7dabc74fb5",
"name": "Spawner (109)",
"location": [5989, 186, 44],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "76399213-8099-47d2-b5e5-6f12d7e3ffde",
"name": "Spawner (109)",
"location": [6106, 67, 0],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "772b0b8b-373b-4859-aeb9-46d2958b0cd8",
"name": "Spawner (109)",
"location": [5946, 75, 22],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "798fd763-c76c-4656-86c3-988524cd12b6",
"name": "Spawner (109)",
"location": [5961, 169, 0],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "7bd13d82-5c43-47a4-9610-882a8dbb5800",
"name": "Spawner (109)",
"location": [5956, 145, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "7d5def22-5137-48d5-ba95-54fb10dae441",
"name": "Spawner (109)",
"location": [6113, 92, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "7e0d9ef3-4a24-44f4-bf1f-cc2c98ef3fa6",
"name": "Spawner (109)",
"location": [5979, 26, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "8254a266-263f-4f5f-b8ac-7646b42b484a",
"name": "Spawner (109)",
"location": [6054, 45, 0],
"map": "Trammel",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gazer", "maxCount": 1, "probability": 100 },
{ "name": "Imp", "maxCount": 1, "probability": 100 },
{ "name": "StoneGargoyle", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "84e31077-87fd-482c-ad78-6c7a8857b572",
"name": "Spawner (109)",
"location": [6116, 86, 0],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "FireGargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "88c01a9f-467c-4183-9e4a-ef7c47b8e5ce",
"name": "Spawner (109)",
"location": [5926, 230, 44],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "8afc042c-474c-4b81-bcc8-c05eb2d8f24e",
"name": "Spawner (109)",
"location": [5954, 26, 0],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "8d2957c0-20a9-43d6-8bc9-f1c46585f525",
"name": "Spawner (109)",
"location": [5937, 65, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "8eeb526f-8a8e-40ab-9f37-79d211549bef",
"name": "Spawner (109)",
"location": [6086, 45, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "92736344-898e-4a70-aa23-229c2b92024e",
"name": "Spawner (109)",
"location": [5970, 80, 0],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "9339a8f1-6dd9-444e-a105-3fda18569885",
"name": "Spawner (109)",
"location": [6041, 222, 44],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "93525eb9-32ec-49c8-8565-e9a1728d098b",
"name": "Spawner (109)",
"location": [5985, 36, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 2,
"walkingRange": 2,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "94814adf-f077-409f-bd7d-84ca6a68e389",
"name": "Spawner (109)",
"location": [5994, 96, 0],
"map": "Trammel",
"count": 3,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "969dad27-c44e-43c2-8456-a94c292253e1",
"name": "Spawner (109)",
"location": [5958, 65, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "9e850a41-0f8a-4411-94e0-7c6df352f6fc",
"name": "Spawner (109)",
"location": [5983, 25, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "a6d37bb4-cfe5-4a9c-a35b-c8d8a11b8ab7",
"name": "Spawner (109)",
"location": [5989, 25, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "a8ce27ea-3cc0-49b9-afd4-6f404432bec5",
"name": "Spawner (109)",
"location": [6117, 81, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "ab1c29a8-d843-4ba3-84b9-b5ef0ef2f524",
"name": "Spawner (109)",
"location": [6064, 96, 22],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Daemon", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 1, "probability": 100 },
{ "name": "Imp", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "ad9f1c34-b053-4f75-bcca-67b8d0749726",
"name": "Spawner (109)",
"location": [5972, 86, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "b0f29c64-4887-41c8-ab48-463a37a2f599",
"name": "Spawner (109)",
"location": [6081, 83, 21],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "b3501f38-bdac-418b-969f-4e0e9f7d9c42",
"name": "Spawner (109)",
"location": [6121, 166, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel2", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "b538b4b4-eba9-4854-9c66-411d622b3ed8",
"name": "Spawner (109)",
"location": [6107, 70, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "b8db6fca-406c-4fcd-951d-5108bb4ed3d2",
"name": "Spawner (109)",
"location": [5995, 62, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "FireGargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "bdf775bc-e899-44df-b7aa-36759f438e22",
"name": "Spawner (109)",
"location": [6058, 92, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "bf3d2161-79d8-402f-9e07-26ebcab8fdc2",
"name": "Spawner (109)",
"location": [5911, 55, 22],
"map": "Trammel",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 25,
"entries": [
{ "name": "Imp", "maxCount": 2, "probability": 100 },
{ "name": "TreasureChestLevel1", "maxCount": 3, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "c0b1509d-4dd2-4b7a-bd21-84c8c93347aa",
"name": "Spawner (109)",
"location": [5948, 49, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 1, "probability": 100 },
{ "name": "HellHound", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "c84dd874-d913-4a50-b681-ebe45af83d6a",
"name": "Spawner (109)",
"location": [5986, 203, 44],
"map": "Trammel",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 12,
"walkingRange": 25,
"entries": [
{ "name": "Gazer", "maxCount": 3, "probability": 100 },
{ "name": "GazerLarva", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "cb68f3ce-29a6-47ea-ad5d-c74a7bfe7ad0",
"name": "Spawner (109)",
"location": [5983, 169, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "d182489e-af6b-449d-a4d9-fd345ee98ce1",
"name": "Spawner (109)",
"location": [5990, 36, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "d3e6e31a-5547-47b2-afaa-f7f64512bdb7",
"name": "Spawner (109)",
"location": [6107, 37, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "d56d6379-f8d7-4adc-bd09-0bdb75059548",
"name": "Spawner (109)",
"location": [5914, 195, 22],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "d5b56fe5-edf3-4e8a-933c-692ff3bc752c",
"name": "Spawner (109)",
"location": [6120, 229, 22],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "df4026a4-516d-4f35-bbdd-10fb253627c1",
"name": "Spawner (109)",
"location": [6122, 170, 0],
"map": "Trammel",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "ElderGazer", "maxCount": 1, "probability": 100 },
{ "name": "Gazer", "maxCount": 3, "probability": 100 },
{ "name": "GazerLarva", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "e141c079-d2a8-43ad-a226-1cb79f87cc7d",
"name": "Spawner (109)",
"location": [6092, 187, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "e59bd560-153a-46a4-b083-8d4278b0ef2c",
"name": "Spawner (109)",
"location": [6087, 186, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel3", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "e94b0430-2565-4cdd-a7df-f87d3cb61887",
"name": "Spawner (109)",
"location": [6084, 66, 0],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "f2fcd059-3b7c-4855-a406-c419a3b46036",
"name": "Spawner (109)",
"location": [5992, 147, 0],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel1", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "f80c3502-c704-4632-ae0d-322f3f7ff388",
"name": "Spawner (109)",
"location": [5917, 156, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "f90467c3-88f7-43eb-81c2-fa882c5b62a9",
"name": "Spawner (109)",
"location": [5992, 146, 0],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Daemon", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "f9a143ac-b466-4e8f-a283-146f9cba767f",
"name": "Spawner (109)",
"location": [6119, 219, 22],
"map": "Trammel",
"count": 6,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Daemon", "maxCount": 2, "probability": 100 },
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 },
{ "name": "Gazer", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "fab57726-33f0-45bb-9aa3-28650b92d61b",
"name": "Spawner (109)",
"location": [6058, 193, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Gargoyle", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "fdf36d81-05fc-4c57-8b01-09f8de27484f",
"name": "Spawner (109)",
"location": [5945, 175, 0],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 2, "probability": 100 },
{ "name": "HellHound", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "ff350d79-2434-441a-85e9-254afcdafe5a",
"name": "Spawner (109)",
"location": [5977, 49, 22],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Imp", "maxCount": 1, "probability": 100 },
{ "name": "HellHound", "maxCount": 1, "probability": 100 }
]
}
]