You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add roaming named elites and counterplay-driven rare combat encounters #23
Architecture amendment — one authored content source (2026-08-13)
Initiative atrinik/atrinik#357 supersedes every future live-branch instruction below. atrinik/content@main is the sole mutable authored content source for replacement and Classic targets. Future authored changes land only on main; supported Classic artifacts are deterministically derived from the same immutable main revision. Do not create, restore, author, backport, validate, or publish through a live 1.x branch.
Exact historical 1.x commits, tags, releases, assets, preserved local snapshots, provenance, parity records, and comparisons remain valid immutable evidence. This amendment changes no other feature, balance, lore, compatibility, licensing, validation, or ownership acceptance criterion.
Important
The gameplay/authored-content decisions in this issue are preserved. This revision changes only the technical implementation path for the fresh MIT Go/Rust replacement program. atrinik/content remains separately/mixed licensed data; MIT engine/tooling code does not relicense the corpus.
Their physical locations remain authored, recognizable camp sites with a
stable site identity and the original family/region/level/schedule context.
The dynamic system may select safe positions within that bounded footprint,
but it must preserve the camp's local feel.
The old map-local 90/10 named-template blocks are removed. A preserved site
instead supplies a higher bounded named-variant affinity for appropriate
profiles, still subject to one authoritative global cap, reservation,
cooldown, persistence, and no-reroll rules. This is a hotspot bias, not a
guaranteed named spawn or an independent local cap.
New camp sites may use the same stable site/profile contract. Names remain
regionally and level appropriate rather than becoming a global adjective or
stat-affix lottery.
Story NPCs such as King Rhun, bespoke bosses, quest/gate actors, and named
monsters whose location-specific identity or special-key drop is required
for progression remain explicit. They are not roaming candidates merely
because they share a source archetype. Use stable semantic exclusions and
fail closed when reward ownership is uncertain.
Add camp-site classification and hotspot tuning to the audit, migration,
frequency/cap tests, and player-facing playtest evidence. Preserve exact
quest/key/unique reward behavior, and never place those objects in repeatable
roaming named loot.
Replacement implementation contract
Preserve roaming-elite scheduling, persistence, encounter, reward, disclosure,
and authored-world decisions. Use Go spawn scheduling/world persistence,
encounter ledger, common timed actions/AI, compiled content, and structured Rust
presentation rather than map Python.
Common migration gates
Stable authored identities and behavior remain the source of truth; localized/rendered text and filesystem order are never identity.
Content is parsed, validated, transacted, and compiled by released content-toolkit; production Go/Rust consumers do not add private source parsers.
Runtime authority belongs to native Go services and bounded compiled definitions/CEL; Starlark is considered only through the residual go/no-go issue.
Verification uses deterministic compiler/conformance fixtures and wrapper-managed Go-server/Rust-client scenarios.
Verified original past work by an approved MIT provenance grantor may be copied, migrated, translated, or relicensed under MIT only through the merged complete-history provenance directive; all asset/data notices remain exact.
Content release-line scope
This future feature targets content@main and the canonical replacement stack. It is not automatically backported to content@1.x; any separately approved classic maintenance uses a linked pull request under #45, preserves the same gameplay/content decision and attribution, and validates only compatible classic consumers.
Preserved product/design specification and historical implementation notes
Summary
Add a server-authoritative, data-driven system that lets an ordinary spawn-point monster be replaced by a rare named variant anywhere that monster archetype is eligible. Use Fahrgorm and Thrakir as the first roaming named minibosses, preserve the authored context of the spawn they take over, give each a readable combat mechanic, and reward the encounter with a distinctive drop.
This should create occasional "something unusual is here" moments during ordinary exploration without requiring map authors to duplicate a named template at every spawn point.
In this issue, rare named replacement describes how an encounter appears. It is separate from the veteran/elite/boss group-size rank proposed in atrinik/server#30. Fahrgorm and Thrakir should initially be soloable veteran/miniboss encounters; future roaming variants may have higher encounter ranks.
What already exists
The current maps implement almost exactly this idea, but at one fixed spawn point per monster:
maps/shattered_islands/world_3_68 at (12, 11) gives an evil treant template weight 90 and Fahrgorm weight 10.
maps/shattered_islands/world_3_69 at (4, 2) gives a night-only lost soul template weight 90 and Thrakir weight 10.
Fahrgorm embeds a rand_drop with container 25 for the Bow of Accuracy: 1/25 per Fahrgorm kill.
Thrakir embeds a rand_drop with container 30 for the Ring of the Ghost: 1/30 per Thrakir kill.
server/src/types/spawn_point.c already supplies the useful primitives:
It treats object_int1 on nested type-83 templates as a weight.
It selects one weighted template when a spawn point is empty.
It checks the selected template's spawn_time.
It copies the selected monster, generates its ordinary randomitems, copies explicit inventory, and resolves RANDOM_DROP using the object's weight_limit/container denominator.
It links the result back to the spawn point through SPAWN_POINT_INFO.
The authored world currently contains 131 treant_evil placements and 54 lost_soul placements. Copying the current 90/10 blocks into all 185 placements would be noisy, hard to rebalance, and easy for future maps to omit.
The engine also already has building blocks for more interesting fights:
monster ability objects and spell selection in server/src/types/monster.c;
multiple attack movement modes;
faction/ally signaling among nearby and linked spawn points;
attack types, protections, blocking, absorption, movement/backstab attack-roll modifiers, and status effects;
map messages, sounds, effect objects, and EVENT_DEATH hooks.
Proposed design
1. Add authored rare-variant profiles
Create a collected, validated content registry (exact syntax is an implementation choice) with stable variant IDs. A profile should describe:
stable ID and display name;
one or more eligible source archetypes, initially treant_evil and lost_soul;
replacement chance;
encounter rank and intended party size;
global active limit and respawn/cooldown policy;
relative level/stat modifiers rather than one fixed absolute level;
added abilities, behavior, visual treatment, sound, and inventory;
special-drop table;
optional region/map/difficulty constraints.
The ordinary spawn template must remain the source of contextual properties: position, authored level, spawn_time, terrain flags, faction, peaceful/aggressive state, and spawn-point ownership. Apply the named profile as an overlay after an eligible ordinary template is selected. This lets Fahrgorm replace a level-15 Eld Woods evil treant as a level-appropriate named threat instead of becoming the current fixed level-6 monster everywhere.
Unknown object fields already survive as key/value data, so a small archetype marker such as elite_pool treant and map/spawn overrides such as no_rare_variant 1 can remain data-driven. Do not identify eligibility by display name.
Migrate the inline Fahrgorm and Thrakir weighted alternatives to profiles. Their original tiles remain ordinary eligible spawn points rather than privileged hard-coded locations.
2. Define eligibility and safety rules
A replacement roll should happen only after the ordinary weighted template has been selected and found time-eligible.
Default eligibility should include spawn-point monsters whose source archetype opts into a named-variant pool. Provide explicit map, spawn-point, and template opt-outs. Automatically exclude or require explicit opt-in for:
quest/gate monsters carrying progression keys or quest containers;
one-time/script-owned encounters;
tutorial and protected settlement areas;
static monsters not owned by a spawn point;
a template already carrying a unique/named encounter identity.
Preserve the base template's schedule. Thrakir may therefore take over any eligible lost-soul spawn only while that source lost soul is allowed to exist.
3. Make named identity genuinely unique and non-exploitable
A stable variant ID should have an authoritative server-side state:
maximum active instances, initially one Fahrgorm and one Thrakir server-wide;
reservation before generation and release on death, legitimate despawn, failed insertion, or map teardown;
a configurable cooldown/window before the next appearance;
enough persisted scheduling state that a restart or repeatedly unloading/reloading maps cannot be used as a free reroll;
no second reward or duplicate reservation from multipart objects, owner indirection, or repeated death callbacks.
Do not reroll merely because a map was loaded. A genuine spawn lifecycle should consume the roll. Add debug/operator diagnostics for variant selection, rejection reason, reservation, spawn, death, and cooldown without broadcasting exact coordinates to all players by default.
4. Tune occurrence and loot as one economy
The current local design composes two rolls:
Fahrgorm: 10% named chance × 1/25 drop = 0.4% special items per generic spawn cycle at that point.
Thrakir: 10% named chance × 1/30 drop = about 0.333% per generic spawn cycle at that point.
A much smaller world-wide replacement chance followed by the unchanged 1/25 or 1/30 drop can become excessively rare. Conversely, rolling independently across 185 placements without a global limit can create many copies at once.
Set an explicit target for:
expected named encounters per active-play hour/server population;
expected named kills per special item;
maximum concurrent encounters;
minimum/maximum time between sightings.
For the MVP, retain a chance at the signature item but give every kill useful baseline value (for example a themed material, token, or above-normal treasure). Consider a tradeable component or bounded bad-luck protection later rather than making players win two opaque lotteries indefinitely.
5. Give each named variant counterplay, not only bigger stats
Each initial profile should add one signature mechanic with a clear tell, a short response window, and a meaningful failure cost that is not an unavoidable one-shot.
Suggested first encounters:
Fahrgorm — forest rally / crushing roots: on aggro or at an HP threshold, visibly warns before a directional or local-area root/slam and calls nearby allied trees. Players can step out of the marked direction/area or interrupt/stagger the windup.
Thrakir — soul-drain windup: visibly faces and warns before a drain cone/line. Players can sidestep, break line of sight, or interrupt; failure causes damage/drain but remains recoverable.
The MVP can use ordinary map text, sounds, facing, and existing effect objects/spells, avoiding a new wire command. If readable ground telegraphs cannot be represented reliably with existing effects, design one small server/client telegraph primitive and use it for all future encounters.
An authored ability description should support at least:
trigger: aggro, interval, or HP threshold;
windup duration and cue;
existing spell/effect to execute;
target/shape;
interrupt/stagger rule;
cooldown and maximum uses.
This creates a reusable base for later bosses instead of embedding one-off checks for these two names in monster.c.
Follow-on combat proposals
These should reuse the same encounter/ability data rather than become unrelated name checks:
Pack leaders and morale: rare captains rally nearby allies; killing or interrupting the leader can make remaining ordinary monsters hesitate, scatter, or lose a buff. Existing ally signaling and run_away behavior are useful starting points.
HP-threshold phases: let authored encounters change movement, vulnerabilities, or ability sets at clear thresholds. Keep early variants to one transition so the fight remains legible.
Role-based variant families: add a small curated roster such as bulwark, skirmisher, healer, summoner, and artillery, each with a visible behavior and counter. Do not create opaque random stat affixes.
Regional hunt clues: rumors, hunter NPCs, notice boards, or a command can announce the region and approximate freshness of a sighting without revealing the exact tile. This avoids requiring players to patrol hundreds of maps blindly.
Risk/reward repair: use named encounters and targeted protection drops to make dangerous caster/group routes competitive with the currently dominant passive-tree progression, as identified in the gameplay playtest notes.
Rollout
Phase 1: reusable engine primitive and two examples
Add and validate the rare-variant/profile format.
Add server-side selection, reservation, cooldown, scaling overlay, and diagnostics.
Migrate Fahrgorm and Thrakir from their map-local 90/10 templates.
Implement one telegraphed ability and one special drop profile for each.
Add a minimal regional-sighting clue.
Update the farming analyzer and Atrinik bot so roaming names are not modeled as guaranteed coordinate-local rerolls.
Phase 2: curated world roster
Audit monster families and add a small number of regionally appropriate named variants across level bands. Prefer distinctive mechanics and targeted rewards over a large combinatorial affix system.
Phase 3: broader encounter vocabulary
Generalize proven windup, interrupt, pack, and phase primitives for dungeon bosses and the encounter ranks proposed by atrinik/server#30. Add collection/achievement integration after the underlying stable IDs and kill-credit rules exist.
Acceptance criteria
A collected, validated profile can make an opted-in spawn-point archetype produce a named replacement without editing every map placement.
Fahrgorm can replace eligible evil-treant spawns and Thrakir can replace eligible time-valid lost-soul spawns across the world.
The replacement preserves the selected source template's position, schedule, level context, faction, aggression, terrain, and spawn ownership unless the profile explicitly overrides a documented field.
Each initial variant has at most one active server-wide instance and correct reservation cleanup on all success/failure/despawn/death paths.
Map unload/reload and server restart cannot be exploited for unlimited fresh rolls.
Add deterministic unit tests around spawn_point.c for eligibility, weighted-base selection, replacement probability, time windows, relative scaling, uniqueness, cooldown, failed insertion, death/despawn cleanup, and reload/restart behavior.
Test RANDOM_DROP composition and duplicate prevention, including party kills, summoned/projectile owners, and zero-XP/no-loot cases.
Add focused tests for windup timing, interrupt/stagger, line/area targeting, threshold triggers, and destroyed targets/maps during a pending ability.
Seed or inject the gameplay RNG in statistical tests; do not use flaky live randomness assertions.
Run the map checker on migrated maps, collect affected authored resources, build the server, and run focused/server checks.
Runtime-smoke low-, mid-, and high-level replacements, two simultaneous players searching/killing, map unload/reload, restart during cooldown, and each special-drop path.
Update and run tools/farming_analyzer.py, tools/atrinik_bot, and their tests for non-coordinate-local named encounters.
Relevant source/content areas
server/src/types/spawn_point.c: weighted selection, time checks, generation, random drops, spawn ownership
Architecture amendment — one authored content source (2026-08-13)
Initiative atrinik/atrinik#357 supersedes every future live-branch instruction below.
atrinik/content@mainis the sole mutable authored content source for replacement and Classic targets. Future authored changes land only onmain; supported Classic artifacts are deterministically derived from the same immutablemainrevision. Do not create, restore, author, backport, validate, or publish through a live1.xbranch.Exact historical
1.xcommits, tags, releases, assets, preserved local snapshots, provenance, parity records, and comparisons remain valid immutable evidence. This amendment changes no other feature, balance, lore, compatibility, licensing, validation, or ownership acceptance criterion.Important
The gameplay/authored-content decisions in this issue are preserved. This revision changes only the technical implementation path for the fresh MIT Go/Rust replacement program.
atrinik/contentremains separately/mixed licensed data; MIT engine/tooling code does not relicense the corpus.Camp-spot and static-actor amendment (2026-08-23)
This issue now coordinates with content#241 — preserve camp-spot identity
during dynamic spawn migration.
The earlier statement that the Fahrgorm and Thrakir tiles become merely
ordinary eligible spawn points is superseded by the following product rule:
stable site identity and the original family/region/level/schedule context.
The dynamic system may select safe positions within that bounded footprint,
but it must preserve the camp's local feel.
instead supplies a higher bounded named-variant affinity for appropriate
profiles, still subject to one authoritative global cap, reservation,
cooldown, persistence, and no-reroll rules. This is a hotspot bias, not a
guaranteed named spawn or an independent local cap.
regionally and level appropriate rather than becoming a global adjective or
stat-affix lottery.
monsters whose location-specific identity or special-key drop is required
for progression remain explicit. They are not roaming candidates merely
because they share a source archetype. Use stable semantic exclusions and
fail closed when reward ownership is uncertain.
Add camp-site classification and hotspot tuning to the audit, migration,
frequency/cap tests, and player-facing playtest evidence. Preserve exact
quest/key/unique reward behavior, and never place those objects in repeatable
roaming named loot.
Replacement implementation contract
Preserve roaming-elite scheduling, persistence, encounter, reward, disclosure,
and authored-world decisions. Use Go spawn scheduling/world persistence,
encounter ledger, common timed actions/AI, compiled content, and structured Rust
presentation rather than map Python.
Common migration gates
content-toolkit; production Go/Rust consumers do not add private source parsers.Content release-line scope
This future feature targets
content@mainand the canonical replacement stack. It is not automatically backported tocontent@1.x; any separately approved classic maintenance uses a linked pull request under #45, preserves the same gameplay/content decision and attribution, and validates only compatible classic consumers.Preserved product/design specification and historical implementation notes
Summary
Add a server-authoritative, data-driven system that lets an ordinary spawn-point monster be replaced by a rare named variant anywhere that monster archetype is eligible. Use Fahrgorm and Thrakir as the first roaming named minibosses, preserve the authored context of the spawn they take over, give each a readable combat mechanic, and reward the encounter with a distinctive drop.
This should create occasional "something unusual is here" moments during ordinary exploration without requiring map authors to duplicate a named template at every spawn point.
In this issue, rare named replacement describes how an encounter appears. It is separate from the veteran/elite/boss group-size rank proposed in atrinik/server#30. Fahrgorm and Thrakir should initially be soloable veteran/miniboss encounters; future roaming variants may have higher encounter ranks.
What already exists
The current maps implement almost exactly this idea, but at one fixed spawn point per monster:
maps/shattered_islands/world_3_68at(12, 11)gives an evil treant template weight 90 and Fahrgorm weight 10.maps/shattered_islands/world_3_69at(4, 2)gives a night-only lost soul template weight 90 and Thrakir weight 10.rand_dropwithcontainer 25for the Bow of Accuracy: 1/25 per Fahrgorm kill.rand_dropwithcontainer 30for the Ring of the Ghost: 1/30 per Thrakir kill.server/src/types/spawn_point.calready supplies the useful primitives:object_int1on nested type-83 templates as a weight.spawn_time.randomitems, copies explicit inventory, and resolvesRANDOM_DROPusing the object'sweight_limit/containerdenominator.SPAWN_POINT_INFO.The authored world currently contains 131
treant_evilplacements and 54lost_soulplacements. Copying the current 90/10 blocks into all 185 placements would be noisy, hard to rebalance, and easy for future maps to omit.The engine also already has building blocks for more interesting fights:
server/src/types/monster.c;EVENT_DEATHhooks.Proposed design
1. Add authored rare-variant profiles
Create a collected, validated content registry (exact syntax is an implementation choice) with stable variant IDs. A profile should describe:
treant_evilandlost_soul;The ordinary spawn template must remain the source of contextual properties: position, authored level,
spawn_time, terrain flags, faction, peaceful/aggressive state, and spawn-point ownership. Apply the named profile as an overlay after an eligible ordinary template is selected. This lets Fahrgorm replace a level-15 Eld Woods evil treant as a level-appropriate named threat instead of becoming the current fixed level-6 monster everywhere.Unknown object fields already survive as key/value data, so a small archetype marker such as
elite_pool treantand map/spawn overrides such asno_rare_variant 1can remain data-driven. Do not identify eligibility by display name.Migrate the inline Fahrgorm and Thrakir weighted alternatives to profiles. Their original tiles remain ordinary eligible spawn points rather than privileged hard-coded locations.
2. Define eligibility and safety rules
A replacement roll should happen only after the ordinary weighted template has been selected and found time-eligible.
Default eligibility should include spawn-point monsters whose source archetype opts into a named-variant pool. Provide explicit map, spawn-point, and template opt-outs. Automatically exclude or require explicit opt-in for:
Preserve the base template's schedule. Thrakir may therefore take over any eligible lost-soul spawn only while that source lost soul is allowed to exist.
3. Make named identity genuinely unique and non-exploitable
A stable variant ID should have an authoritative server-side state:
Do not reroll merely because a map was loaded. A genuine spawn lifecycle should consume the roll. Add debug/operator diagnostics for variant selection, rejection reason, reservation, spawn, death, and cooldown without broadcasting exact coordinates to all players by default.
4. Tune occurrence and loot as one economy
The current local design composes two rolls:
A much smaller world-wide replacement chance followed by the unchanged 1/25 or 1/30 drop can become excessively rare. Conversely, rolling independently across 185 placements without a global limit can create many copies at once.
Set an explicit target for:
For the MVP, retain a chance at the signature item but give every kill useful baseline value (for example a themed material, token, or above-normal treasure). Consider a tradeable component or bounded bad-luck protection later rather than making players win two opaque lotteries indefinitely.
5. Give each named variant counterplay, not only bigger stats
Each initial profile should add one signature mechanic with a clear tell, a short response window, and a meaningful failure cost that is not an unavoidable one-shot.
Suggested first encounters:
The MVP can use ordinary map text, sounds, facing, and existing effect objects/spells, avoiding a new wire command. If readable ground telegraphs cannot be represented reliably with existing effects, design one small server/client telegraph primitive and use it for all future encounters.
An authored ability description should support at least:
This creates a reusable base for later bosses instead of embedding one-off checks for these two names in
monster.c.Follow-on combat proposals
These should reuse the same encounter/ability data rather than become unrelated name checks:
run_awaybehavior are useful starting points.Rollout
Phase 1: reusable engine primitive and two examples
Phase 2: curated world roster
Audit monster families and add a small number of regionally appropriate named variants across level bands. Prefer distinctive mechanics and targeted rewards over a large combinatorial affix system.
Phase 3: broader encounter vocabulary
Generalize proven windup, interrupt, pack, and phase primitives for dungeon bosses and the encounter ranks proposed by atrinik/server#30. Add collection/achievement integration after the underlying stable IDs and kill-credit rules exist.
Acceptance criteria
EVENT_DEATH, faction, XP, party credit, loot/corpse, and spawn-respawn behavior remain correct.Validation
spawn_point.cfor eligibility, weighted-base selection, replacement probability, time windows, relative scaling, uniqueness, cooldown, failed insertion, death/despawn cleanup, and reload/restart behavior.RANDOM_DROPcomposition and duplicate prevention, including party kills, summoned/projectile owners, and zero-XP/no-loot cases.tools/farming_analyzer.py,tools/atrinik_bot, and their tests for non-coordinate-local named encounters.Relevant source/content areas
server/src/types/spawn_point.c: weighted selection, time checks, generation, random drops, spawn ownershipserver/src/types/monster.c: spell abilities, movement, ally signalingserver/src/server/attack.c: damage, death event, XP, faction and kill/loot creditserver/src/server/living.c: level-relative monster stat calculationserver/src/loaders/object.l: authored key/value loadingarch/special/spawn_point.arcand the new authored variant/ability sourcearch/mobs/undead/lost_soul/andarch/mobs/plants/treant/maps/shattered_islands/world_3_68andmaps/shattered_islands/world_3_69tools/farming_analyzer.py,tools/atrinik_bot/, and related tests