ModernUO/Distribution/Data/Spawns/shared/felucca/TerathanKeep.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

646 lines
20 KiB
JSON

[
{
"$type": "Spawner",
"guid": "05f81bd1-8432-458d-973a-85449805e567",
"name": "Spawner (221)",
"location": [5163, 1585, -15],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "0c8d7085-680b-49cf-a8c3-be20a79f94be",
"name": "Spawner (221)",
"location": [5161, 1584, -15],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "0e911183-4be3-4c7d-878b-a7b4d97d8f14",
"name": "Spawner (221)",
"location": [5201, 1566, 0],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "140da661-2c38-4502-a8d3-a093fb672c3e",
"name": "Spawner (221)",
"location": [5363, 1709, -75],
"map": "Felucca",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "14d9a777-99d2-4e2a-92e4-98eb9ed2cc2a",
"name": "Spawner (221)",
"location": [5342, 1552, 0],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "1613210d-f099-406c-8dad-b3e6c4978ea4",
"name": "Spawner (221)",
"location": [5134, 1625, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "19a3a2ba-4466-440e-9eb8-69c30087faf0",
"name": "Spawner (221)",
"location": [5160, 1586, -15],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "56ff9b13-646b-4f60-be0b-b5aaa730d17d",
"name": "Spawner (221)",
"location": [5336, 1708, -70],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "578848ef-81b8-4528-b3e5-7819296f1441",
"name": "Spawner (221)",
"location": [5200, 1568, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "5a472619-a1fd-43b6-8ed3-876689a8b7a4",
"name": "Spawner (221)",
"location": [5343, 1551, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "628166d6-c981-4d20-bee3-f9e68ca672e4",
"name": "Spawner (221)",
"location": [5345, 1551, 0],
"map": "Felucca",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 1,
"walkingRange": 1,
"entries": [
{ "name": "TreasureChestLevel4", "maxCount": 2, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "6b1ed67b-dcfd-41a6-9b27-9f815db3e48f",
"name": "Spawner (221)",
"location": [5200, 1565, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "6db88e49-590f-4fc9-9ff2-484c0caba22d",
"name": "Spawner (221)",
"location": [5342, 1553, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "7045923d-0e54-48e2-8c61-25f4e748bb62",
"name": "Spawner (221)",
"location": [5176, 1702, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "78eb98fb-eb53-4956-919c-9b075b3a02ad",
"name": "Spawner (221)",
"location": [5348, 1552, 0],
"map": "Felucca",
"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": "877895b3-0048-42fa-943b-4246c6d0dbd1",
"name": "Spawner (221)",
"location": [5176, 1701, 2],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "8cddc6ca-33de-411d-9d6d-03f61c427acc",
"name": "Spawner (221)",
"location": [5335, 1707, -70],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "97e91add-b1d5-48e6-ae53-6dd25cb088bc",
"name": "Spawner (221)",
"location": [5270, 1695, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "9c464287-4f2e-40c2-b6cd-7110d89097eb",
"name": "Spawner (221)",
"location": [5132, 1624, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "a720dbb7-0f4e-45c8-9bac-c9b76e028c02",
"name": "Spawner (221)",
"location": [5132, 1623, 0],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "ada2362f-c030-42f1-86ce-5d983ff64a38",
"name": "Spawner (221)",
"location": [5346, 1756, -125],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "adcadb01-80d3-40a1-acf8-6a7493aeef84",
"name": "Spawner (221)",
"location": [5271, 1693, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "b1a245ac-73e5-4f51-a9b0-72a7e0aeb999",
"name": "Spawner (221)",
"location": [5177, 1700, 1],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "b3b5c6cf-915f-427b-97b1-89d49bdc440a",
"name": "Spawner (221)",
"location": [5297, 1565, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "ce1ce8c5-583f-4f67-84b6-126bc30487ff",
"name": "Spawner (221)",
"location": [5334, 1613, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "d3a73b6d-ffa1-4448-9308-6431b4f51d4b",
"name": "Spawner (221)",
"location": [5345, 1757, -125],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "d6b68ad4-a9c2-4982-9477-31a7cb202a69",
"name": "Spawner (221)",
"location": [5334, 1614, 0],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "da8f850f-a715-4ae6-9c10-47db89b3d732",
"name": "Spawner (221)",
"location": [5344, 1757, -125],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "dfb3c171-67af-4dea-8b11-1d49762b2fb2",
"name": "Spawner (221)",
"location": [5335, 1615, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "TerathanAvenger", "maxCount": 1, "probability": 100 },
{ "name": "TerathanDrone", "maxCount": 1, "probability": 100 },
{ "name": "TerathanMatriarch", "maxCount": 1, "probability": 100 },
{ "name": "TerathanWarrior", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "ebca1c72-604f-4cba-b019-c5de4a5b55c8",
"name": "Spawner (221)",
"location": [5365, 1707, -71],
"map": "Felucca",
"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": "ec99841b-c28c-4b7c-a4d3-15f2753a4184",
"name": "Spawner (221)",
"location": [5296, 1561, 0],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "f9a936c9-3c10-4029-a46d-dbbdb5494b48",
"name": "Spawner (221)",
"location": [5335, 1706, -70],
"map": "Felucca",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "Balron", "maxCount": 1, "probability": 100 },
{ "name": "Dragon", "maxCount": 1, "probability": 100 },
{ "name": "Drake", "maxCount": 1, "probability": 100 },
{ "name": "Nightmare", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "fbc340d4-cf84-410e-9764-5987bdacc4fc",
"name": "Spawner (221)",
"location": [5270, 1694, 0],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
},
{
"$type": "Spawner",
"guid": "fee1141d-1c6e-479e-9cfc-d92fed242b0a",
"name": "Spawner (221)",
"location": [5296, 1562, 0],
"map": "Felucca",
"count": 5,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"homeRange": 10,
"walkingRange": 20,
"entries": [
{ "name": "OphidianArchmage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianKnight", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMage", "maxCount": 1, "probability": 100 },
{ "name": "OphidianWarrior", "maxCount": 1, "probability": 100 },
{ "name": "OphidianMatriarch", "maxCount": 1, "probability": 100 }
]
}
]