Project1998 · what changed

Patch Notes

Newest first. Code changes deploy with a 3-minute in-game warning; content-only changes hot-reload with no restart.

Server: Shaman's and Do's spells cast and go on sale

2026-10-26 · Essorcal · Server PRs #406, #407

For players: Shaman's spells (PR #406)

For players: Do's spells (PR #407)

Server: closing an NPC's box no longer blocks anything, teachers on the twelve PC-subpath Circles, and a one-time key for the login hand-off

2026-10-26 · Essorcal · Server PRs #402, #404, and, for operators, #403

For players: a closed NPC box no longer leaves anything waiting (PR #402)

For players: PC-subpath teachers (PR #404)

For operators: the login hand-off and the database (PR #403)

Server: the Dog ignores a PC-subpath member's cleanse, the Chapel's divorce and engagement costs stop wrapping, Ki strike and Ice bombardment can be deflected, closing an NPC's page takes nothing, and two settings for operators

2026-10-26 · Essorcal · Server PRs #396, #397, #399, #400, #401, and, for operators, #382, #383

For players: the Dog's cleanse and PC subpaths (PR #401)

For players: the Chapel's costs for very large pools (PR #400)

For testers: Ki strike and Ice bombardment can be deflected (PR #397)

Checked: closing an NPC's page takes nothing

For operators: where new characters start, a synthetic test profile, and two earlier fixes (PRs #396, #399; #382, #383)

Server: the four NPC subpaths can be joined at Baek, the Watcher's rabbit appears to unblessed players of any level in Buya's north-west field, the NPC-subpath spells have a price, and testers get aligned versions of ten Sam san spells

2026-10-24 · Essorcal · Server PRs #392, #394

For players: the four NPC subpaths can be joined at Baek, and the Watcher's rabbit appears at any level (PR #394)

For testers: aligned Sam san characters are taught their versions of ten Sam san spells (PR #392)

Server: boards and the mailbox show 20 entries at a time and load older ones as you scroll, the twelve PC subpaths can be joined, and base classes and NPC subpaths can no longer use the subpath channel

2026-10-24 · Essorcal · Server PRs #393, #395

Boards and the mailbox open on their newest 20 entries and load 20 older ones as you scroll (PR #395)

The twelve PC subpaths can be joined, and only their members can use the subpath channel (PR #393)

Server: long mail subjects and buff boxes no longer break their windows, experience stops at its cap instead of wrapping, Bon-Hwa offers the Il San trials, and testers get rank learn prices and eight subpath damage spells

2026-10-24 · Essorcal · Server PRs #387, #388, #389, #390, #391

For players: long mail subjects, buff boxes and legend lists no longer break, and experience stops at its cap (PRs #388, #391)

For testers: the Il San trials at Bon-Hwa, rank learn prices and eight subpath damage spells (PRs #389, #387, #390)

Server: a GM's mass clear of more than 255 dummies clears them all, and an over-long message-box text is cut short instead of garbled

2026-10-24 · Essorcal · Server PR #384, and, for operators, #380

A GM's mass clear of more than 255 dummies clears them all, and an over-long message-box text is cut short instead of garbled (PR #384)

Server: the first hit on a sleeping or dozing creature rounds down once, like every other hit

2026-10-23 · Essorcal · Server PR #378, and, as an internal fix, #371 (how the mentorship's lines reach the mentor; nothing players see changes)

The first hit on a sleeping or dozing creature rounds down once, like every other hit (PR #378, issue #363)

Server: a weapon proc is not cast at a player you can't attack, emotes need an ordinary player and ghosts and riders pick nothing up, the Mage's Bolt hits like Spark, Dooms Fire needs 15,275 mana, and the gap in the Buya Marketplace stall counter draws as floor

2026-10-23 · Essorcal · Server PRs #369, #370, #373, #374, #375, #376, and, as internal fixes, #372 (two rare races in Approach and Mana Steal), #377 (a protocol document) and #379 (a developer tool and an operator log line)

A weapon proc is not cast at a player you can't attack (PR #373)

Emotes need an ordinary player, and ghosts and riders pick nothing up (PR #374)

The Mage's Bolt hits like Spark: 50 + half your level, for 20 mana (PR #370, issue #200)

Dooms Fire needs 15,275 mana and waits 65 s, and Siege and Focused Blow cost what the live pages say to learn (PR #375)

The gap in the Buya Marketplace stall counter draws as floor (PR #376)

A race between a wedding and a logout is closed (PR #369)

Server: a "yes" to a proposal engages nobody if the proposer, or the player answering, is going away

2026-10-22 · Essorcal · Server PR #368

A "yes" to a proposal engages nobody if the proposer, or the player answering, is going away (PR #368)

Server: the Spirit dragon's room on Jeweled Dragon 3 is a corridor tile players can reach, and a wedding is refused for free if the engagement has ended, or a partner has left, by the fiancé's "I do"

2026-10-22 · Essorcal · Server PRs #365, #366 (a developer tool; no change in play), #367

The Spirit dragon's room on Jeweled Dragon 3 is a corridor tile players can reach (PR #367)

A wedding is refused for free if the engagement has ended, or a partner has left, by the fiancé's "I do" (PR #365)

Server: @bring, Resurrect and @rez never move, revive or heal a player who is logging out, the Leviathan's "Sworn enemy" brand is never lost to a race, and Propose is kept until a "yes", with a 20-minute wait from every cast

2026-10-22 · Essorcal · Server PRs #358, #362 (a protocol document for client builders; no change in play)

@bring, Resurrect and @rez never move, revive or heal a player who is logging out, the Leviathan's "Sworn enemy" brand is never lost to a race, and Propose is kept until a "yes", with a 20-minute wait from every cast (PR #358, issue #330)

Server: 60 bosses wait in their own rooms, the Spark spells land 50 + half your level, every hit rounds down once, a Harden Body ward blocks venom ticks, and Bolt and Freeze at nothing are free and silent on a PvP map too

2026-10-22 · Essorcal · Server PRs #357, #359, #361

60 bosses whose spawn points sat in the hidden NPC Chamber now wait in their own rooms (PR #357, issue #333)

The Spark spells land 50 + half your level, every hit rounds down once, a Harden Body ward blocks venom ticks, and Bolt and Freeze at nothing are free and silent on a PvP map too (PR #361, issues #78, #82 and #200)

A database fault at arrival or in a ban, mute or IP-ban read is logged as an error (PR #359)

Server: Bolt and Freeze charge only for a real target off a PvP map, curses refuse an NPC, Chapel answers after your partner ended the vow read that it ended, the Warrior reskins hold the 1 s cast slot, and the Inferno spells, Wind master, Siege and Focused Blow follow their sources

2026-10-22 · Essorcal · Server PRs #354, #355, #356

Bolt and Freeze charge only for a real target off a PvP map, curses refuse an NPC, and a curse or a hold keeps the target it found first (PR #356)

A Chapel answer given after your partner ended the vow reads that it ended (PR #355)

Six spell rulings: the Warrior reskins hold the 1 s cast slot, the Inferno spells need 600 mana, Wind master is refused, the Rogue's Wolf's Fury twins come at level 30, Spirit Barrier is now Spirit Body, and Siege and Focused Blow follow the Nexus Atlas (PR #354)

Server: Bolt, Venom and the other damage spells at an NPC are refused for free, a sacrifice strike at one costs what a strike at nothing costs, a Chapel confirm for a vow already ended is free, and an online partner reads that their vow ended

2026-10-20 · Essorcal · Server PRs #350, #351

A Chapel confirm for a vow your partner already ended is free, and an online partner reads that the vow ended (PR #350)

Bolt, Venom and the other damage spells at an NPC are refused for free, and a sacrifice strike at one costs what a strike at nothing costs (PR #351)

Server: Doze, Sleep, Blind and the other holds refuse for free before they roll, Drain and Kamikaze strike the victim they read and refuse an NPC, a vow your partner no longer holds ends at login, and actions on a busy player wait for them

2026-10-19 · Essorcal · Server PRs #344, #345, #348, #349

Drain and Kamikaze at an NPC are refused for free (PR #349)

A click, approach or proposal on a busy player waits for them (PR #345)

Doze, Blind and the other holds refuse for free before they roll, and Drain and Kamikaze strike the victim they read (PR #348)

A vow your partner no longer holds ends at login, and the Chapel leaves your ex's new vow alone (PR #344)

Server: damage, heals, buffs and curses aimed by id stay on your map, and Mana Steal at yourself is refused

2026-10-18 · Essorcal · Server PR #343

Damage, heals, buffs and curses aimed by id stay on your map, and Mana Steal at yourself is refused (PR #343)

Server: a map with one broken spawn entry can still be entered

2026-10-14 · Essorcal · Server PR #346

A broken spawn entry costs only its own creature, not the whole map entry (PR #346)

Server: a Dispell at another player wakes and cures them, fails free and spares GMs, and clears their spells safely

2026-10-11 · Essorcal · Server PRs #339, #340, #341, #342

Five more actions on another player change their state safely (PR #341)

A Dispell on yourself follows the same rules, and a spell aimed at a player stays on your map (PR #342)

A Dispell at another player wakes and cures them, fails free, and spares GMs (PR #340)

A Dispell on another player clears their spells safely (PR #339)

Server: the aligned furies, Serpent's and Spirit Fury, Second Sight, Barrier and Human Barrier work

2026-10-09 · Essorcal · Server PRs #338

Twenty-nine self-buffs that took their mana and did nothing now work (PR #338, issue #334)

Server: a changed kingdom, face, gender or totem stays after you log out, and Approach and Summon fizzle in areas that do not allow approaching

2026-10-08 to 2026-10-09 · Essorcal · Server PRs #336, #337

A changed kingdom, face, gender or totem stays after you log out (PR #337)

Approach and Summon fizzle in areas that do not allow approaching (PR #336)

Server: Approach and Summon work, 10- and 11-letter account names log in every time, and @kill keeps townsfolk and lets the spawn points it empties refill

2026-10-06 to 2026-10-07 · Essorcal · Server PRs #320, #315, #325, #335

Approach and Summon work (PR #325, issue #313)

10- and 11-letter account names log in every time (PR #315)

@kill keeps townsfolk, and the spawn points it empties refill (PR #320)

Review follow-ups from 2026-10-05 (PR #335)

Server: the Inferno spells take all your mana and wait 70 seconds, six Rogue spells get their cast delay, Wind dancer and the Champions recast every 8 minutes for no mana, and entering a map no longer puts a trap or a group creature on your tile

2026-10-05 · Essorcal · Server PRs #316, #317, #318, #319, #321, #322, #323, #324, #326, #327

The Inferno spells take all your mana and wait, six Rogue spells get their cast delay, and a granted Spirit Blade works (PR #322)

Wind dancer and the Champions recast every 8 minutes and cost no mana (PR #317)

Entering a map no longer puts a trap or a group creature on your tile (PR #319, issue #122)

Collecting a parcel while the database is failing answers at once (PR #318)

@reload says when a Lua edit is rejected (PR #323, issue #113)

The @class and @align help rows fit the status pane (PR #316)

Both quest maps go through QuestState, and the login close is widened as a guard (PR #321, issues #307, #308, #309)

Tooling: Serve.ps1 -Stop says why a stop signal failed, and tries PowerShell 7 (PR #327)

Tests: anything that changes the whole test process runs on its own (PR #326)

Review follow-ups from #311 and #314 (PR #324)

Server: failed logins no longer hang on the loading screen, group kills and parcel claims save safely during a re-login, PvP and divination read a consistent target, and quest state goes through one type

2026-09-29 · Essorcal · Server PRs #306, #310, #311, #312, #314

A login that fails before you reach the world no longer leaves you on the loading screen (PR #311)

Group kill credit and parcel claims save safely during a re-login (PR #312)

PvP, armor-reading spells and divination see a consistent target (PR #314)

Quest state goes through one QuestState type (PR #310, issue #51)

Review follow-ups from #301, #302 and #304 (PR #306)

Tooling

Server: new names stop at 11 letters, faces 1 to 4 create, errors at logout or re-login no longer leave you stuck, NPC abilities can be limited to particular NPCs, and Serve.ps1 stops cleanly from PowerShell 7

2026-09-27 · Essorcal · Server PRs #300, #301, #302, #303, #304, #305

New character names stop at 11 letters (PR #301, issue #299)

Picking face 1 to 4 at creation works (PR #304)

Errors at logout or re-login no longer leave you stuck (PR #303)

Review loose ends (PR #300)

NPC abilities can be limited to particular NPCs or maps (PR #302, issue #50)

Serve.ps1 -Stop works from PowerShell 7 (PR #305)

Server: an older deploy no longer replaces a newer one, a replaced login's old connection stops acting in the world, and a late group share at logout is kept

2026-09-25 to 2026-09-27 · Essorcal · Server PRs #296, #297, #298

A late group share at logout is kept, and a replaced login writes nothing (PR #298, issue #168)

The world stops acting on a replaced session (PR #297)

An older deploy no longer replaces a newer one (PR #296)

Server: trades open safely under both players' locks, one bad spawn row costs only itself, a failing heartbeat step no longer loses the beat, and back-to-back merges deploy cleanly

2026-09-25 · Essorcal · Server PRs #287 to #295

A trade opens under both players' locks and never on one who is leaving (PR #291, issues #173, #188)

One bad spawn row costs only itself (PR #292)

A failing heartbeat step costs only the rest of that step (PR #289, issues #106, #121)

@help rows checked against the pane width, and @clock's marker matches the wire (PR #290, issues #176, #159)

The Lua gate asserts no world lock is held on the way in (PR #293, issue #90)

Weapon swap and unequip frames pinned (PR #295)

The thread-start check scans all of the server (PR #294, issue #195)

Back-to-back merges no longer turn the deploy red (PR #287)

Test-Branch.ps1 -Shard k/n (PR #288)

Server: stripped gear drops its bonuses at once, failed saves are retried, @karma refuses NaN, messages reach a re-logged player, and three flaky tests fixed

2026-09-24 · Essorcal · Server PRs #278, #280 to #286

Gear taken off by the gender-change NPC or an armor-quest turn-in drops its bonuses at once (PR #286)

A spell script cannot leave a living player at 0 hp, and @clearinv drops the cleared gear's bonuses (PR #281, issues #175, #206)

Failed character saves are retried (PR #282, issues #179, #88)

Messages reach a player who has just logged in again (PR #283, issues #183, #87)

@karma refuses NaN and Infinity (PR #285)

Three flaky tests fixed (PRs #278, #280, #284, issue #187)

Server: the wire dump defaults off, a throwing creature costs the world lock a queued record, bad Tile533Map rows are refused, the send path gets counters, and the world lock's hold rule is written down

2026-09-23 · Essorcal · Server PRs #271 to #277

The game process defaults its wire dump off (PR #276)

A throwing creature costs the world lock one queued record, not a stack (PR #274)

Tile533Map rows are checked whole before they are expanded (PR #273, issue #128)

The game channel's send path gets counters (PR #275)

Locking.md: how long a world lock hold may be (PR #271)

Two flaky tests fixed (PRs #272, #277)

Server: the status document counts the viewers the tick swept, and four holds measure what the tick sweep skip does under load

2026-09-22 · Essorcal · Server PR #270

The status document says how many viewers the tick swept, not just how many beats ran (PR #270)

Measurement: what the tick sweep skip does under load (four hold assignments, PR #269's switch, no product change; laptop, Release, 400 players, tick 333 ms)

Dev process

Server: the tick skips viewers whose map has not changed, the dev launcher regenerates the runtimeconfig per branch and dumps no frames by default, the GC memory budget priced on two Release pairs and closed, a tick snapshot pool dropped on its numbers, and what a hold on the world lock costs

2026-09-21 · Essorcal · Server PRs #269, #268

The tick sweeps a viewer's viewport only when something it reads has changed (PR #269, refs the PR #266 pooling report)

The launcher builds the runtimeconfig the branch says, and dumps no frames by default (PR #268, tooling)

Load run: the GC memory budget, two Release pairs (branch pr/gc-conserve-memory, closed on its numbers; laptop)

The tick's map snapshot rents its buffers (branch pr/reconcile-snapshot-pool, dropped on its numbers)

Measurement: what a hold on World._lock costs (branch pr/lock-contention, no product change; laptop, harness in the review evidence)

Dev process (records since the workflow's review records began)

Server: a fury that lapses while you are logged off still takes its vita, the status tick stops allocating on idle beats, the server publishes where players and mobs stand and how fast they walk, the viewport rect tests go lazy, a load script whose bots stand apart, six load holds, and a profile of what one step costs

2026-09-21 · Essorcal · Server PRs #259, #260, #261, #262, #263, #265, #266, #264, #267

A Chung Ryong fury that lapses while you are logged off still takes its vita (PR #259, refs the PR #255 review)

TickSleep and TickPoison allocate nothing on the beat that does nothing (PR #260, refs PR #254)

run/viewport.json: where players and mobs actually stand, and how much of them a viewer sees (PR #261, refs the viewport profile)

The viewport rect tests run only on the branches that read them (PR #262, refs the PR #258 review)

A load script whose bots stand apart (tooling, no PR; refs the viewport profile)

Load run: the clump script against the spread script, four 400-bot holds on one head (Debug, laptop; refs #261, the viewport profile)

Load run: the same spread standing still, and the same walk on a map with no creatures (Debug, laptop; refs #261)

The viewport survey reports each map's accepted step rate beside its in-view fraction (PR #263, refs the walk-path profile)

Profile: what one player step costs (400 players, 386 mobs, one map, laptop; refs the six load holds)

Two order-sensitive tests made honest, one guard order, and four comment corrections (PR #265, refs the PR 260 to 262 reviews)

The walk step's map snapshot rents its two arrays instead of building them (PR #266, refs the walk-path profile, PR #253)

A player's step and turn go only to the clients that hold them (PR #264, refs the walk-path profile)

Load run: the move gate measured in Release, and a launcher switch to start a Release pair (Debug versus Release, laptop; refs #264)

Server: the map broadcast helpers stop allocating, the tick reads the sleep and poison timers before taking each session lock, natural regen returns to the original game's global clock, and the peer sweep decides straight off the snapshot array

2026-09-19 to 2026-09-21 · Essorcal · Server PRs #253, #254, #255, #256, #257, #258

The map broadcast helpers stop allocating: one call to 400 players goes from 45,361 bytes to 0 (PR #253, refs #250)

The world tick reads the sleep and poison timers before taking each player's session lock: the status phase goes from 6.61 to 0.23 ms per second at 400 players (PR #254, refs #250)

Natural regen is back on the original game's global 25 second clock, and the tick reads four values before taking each player's session lock for it: the regen phase goes from 7.07 to 1.66 ms per second at 400 players (PR #255, refs #254)

Load run: three matched pairs of 400-player holds, PR #254's merge against current master (refs #255)

Profile: the viewport sweep, 84% of the beat, attributed line by line (refs #245, #246, #255)

The peer sweep decides straight off the snapshot array: the viewports phase goes from 47.6 to 31.9 ms per second at 400 players (PR #256, refs #245, #246, #255)

The mob and floor-item sweeps decide off concrete arrays (PR #257, refs #256)

One drawn-state entry per entity replaces the shown/edge set pair: 17 to 19% off the viewport sweeps in Release (PR #258, refs #256, #257)

Server: the mob and item sweeps send outside the viewport lock, the phase totals become a rate, the tick stops allocating per player, two test seams, the db collection runs in parallel again, and a matched load run

2026-09-18 · Essorcal · Server PRs #246, #248, #249, #247, #250, #251, #252

The mob, item and peer sweeps decide under one viewport lock and send after releasing it (PR #246, refs #245)

Every beat adds its phases to a running total published in run/status.json, and the 1 ms floor flake is closed (PR #248, refs #243 and #245)

A test-only in-process hook for the logger's formatted line (PR #249, refs #239)

The tests that hold SQLite's write lock hold it on their own file, and the db test collection runs in parallel again (PR #247, refs #242 and #244)

The tick's per-player steps stop allocating 1,600 delegates a beat: 459 to 139 bytes per player per beat at 400 players (PR #250, refs #245)

Load run: a matched pair of 400-player holds, master against PR #245's merge (refs #246, #248, #250)

The status document says how much memory the process is holding and why (PR #251, refs #248)

Load run, row A: the 1.1 GB working set is the GC's budget, not the program's memory (measurement on master a923f93; refs #251)

Load run, row B: the working set follows the machine's free memory, so the 1.1 GB was the GC's budget (measurement on master a923f93, same server and client as row A)

The committed-bytes status field is named and documented for the last collection (PR #252, refs #251)

Server: the tick body at 400 players in three cuts, two CI reds made deterministic, one content override, and a five-second database timeout

2026-09-17 · Essorcal · Server PRs #240, #242, #241, #243, #244, #245

The viewport reconcile takes the viewer's rect once a sweep: 66 slow beats to 38 at 400 players (PR #240, load-run slice 2)

Two CI-only reds made deterministic (PR #242)

Retire the 68 per-table content path overrides; P1998_GAME_DATA is the one content override (PR #241, refs #35 and #42)

Split the viewports phase at its lock and count the ticks (PR #243)

The database connection's command timeout matches its busy timeout: a contended write fails in five seconds, not thirty (PR #244, refs #242)

The peer sweep takes one viewport lock instead of 400: slow beats 5.09% to 1.29% at 400 players (PR #245)

Server: every environment knob declared once, the last hand-prefixed log lines

2026-09-16 · Essorcal · Server PRs #235, #237, #236, #238, #239; closes #42, #199 and #57

ServerConfig, part 1: one declaration per environment knob, a generated reference, and a startup banner (PR #235, #42 part 1)

The last nine hand-prefixed diagnostics route through Log.Warn and Log.Error (PR #237, closes #199)

ServerConfig, part 2: the remaining inline reads (PR #236, #42 part 2)

One online-player resolver, one free-neighbour search, and the mute state in the moderation file (PR #238, #57 part 2)

A GmOverrides class with a @toggles readout and actor logging, and the RE probes in Session.Probes.cs (PR #239, #57 part 3, closes #57)

Server: the first bot load run, wire logs that obey their switch, and a slow tick that names its phase

2026-09-13 · Essorcal · Server PRs #234, #233; load run of 2026-09-12 against master b5bb486

The first bot load run, 25 to 400 players

Wire packet logs honor their switch, and drain facts pin the teardown gate (PR #234)

A slow tick says which phase spent the work (PR #233)

Reviews and process

Still queued

Server: one outbound for both processes, the last four peer sends under the recipient's lock, the status probe's polite close

2026-09-11 · Essorcal and brian · Server PRs #231, #230, #232; direct pushes 9e9e170, 3ffb44d

The Geomancers' five elemental orbs are obtainable (direct push 9e9e170, brian)

The Rogue's White Moon Axe can be earned at Buya's Maso (direct push 3ffb44d, brian)

The whisper, the ban's kick and the two announcements run under the recipient's monitor (PR #231, follow-up of PR #225)

One outbound for both processes: TcpOutbound moves to Shared and the login copy is retired (PR #230, follow-up of PR #226)

The status probe half-closes and drains before the socket closes (PR #232, PR #228 review F2)

Reviews and process

Still queued

Server: four more slices from the queue: peer sends under the recipient's lock, the login channel's outbound queue, Shared's doc XML and the bind line, the split status probe

2026-09-11 · Essorcal · Server PRs #225, #226, #227, #228

Nine more cross-session status-text sends run under the recipient's monitor (PR #225, follow-up of PR #219)

The login channel sends through a bounded queue and drops a peer that stops reading (PR #226, follow-up of the PR #213 review)

Shared generates its doc XML, and a listener that cannot bind names the port (PR #227, PR #224 follow-up and the PR #209 review)

A status probe split inside GET is answered, not dropped; the Parse length doc names the non-0xAA case (PR #228, PR #220 review probe (e), PR #222 review F2)

Reviews and process

Still queued

Review metrics at close

Server: the shared frame reader drops peers that stop framing, party notifications under the member's lock, the concurrency tests wait on progress

2026-09-10 · Essorcal · Server PRs #219, #220, #221, #222, #223, #224

Party notifications and the invite's dead-target check run under the member's monitor (PR #219, follow-up of the PR #210 review)

FrameReader drops a connection whose unframed buffer exceeds one maximum frame or whose head byte is not 0xAA (PR #220, follow-up 1 of the PR #213 review)

A frame whose length field is under 2 is malformed: TryParse never throws and the reader drops the peer (PR #222, follow-up of PR #220)

The concurrency tests wait on progress, not on a fixed join (PR #221, follow-up of PR #216)

The tile translation facts and the content reload fact run in one collection (PR #223)

Protocol.Tk495 generates its doc XML so the compiler checks its crefs (PR #224, PR #220 review F2)

Reviews and process

Server: one listener and one frame reader for both processes (#41 closed), party kicks under the member's monitor, two test flakes fixed

2026-09-10 · Essorcal · Server PRs #210, #209, #213, #211, #212, #217, #214, #216, #218, #215

The party kick pre-check and the removal's party read run under the member's monitor (PR #210, closes #198)

One listener for both processes: the accept loop, NoDelay, PROXY and ConnGuard move to Shared (PR #209, #41 part 2)

One frame reader for both processes: Protocol.Tk495.FrameReader with the handshake timeout, and one welcome and host parser (PR #213, closes #41)

Hand-prefixed diagnostics route through Log.Warn and Log.Error; the fatal handlers carry the exception (PR #211, refs #199)

The world-autosave thread logs one line at start-up (PR #212, closes #194)

A mob-sourced poison no longer marks the creature's id as the PvP foe (PR #217, closes #208)

The foe-mark note, comment and test doc say the monitor drop is unreachable from shipped callers (PR #214, closes #207)

The three deadlock facts in SessionActorTests fail on a stall, not on a slow machine (PR #216)

The drop-count facts read a tally the writer's overflow notice cannot zero (PR #218)

CI actions pinned to their Node.js 24 majors (PR #215, closes #201)

Issues closed without a PR

Review metrics at sprint close

Server: party roster as a snapshot, revives that save, the death sequence as one critical section, one logger for both processes

2026-09-09 · Essorcal · Server PRs #189, #203, #205, #204, #202

Party membership is an immutable snapshot swapped under a leaf lock; the invite writes the target under its monitor (PR #189, closes #167)

Revive paths persist the restored character, so a crash after a revive does not load a ghost (PR #203, closes #196)

TakeDamage marks the PvP foe after the death sequence, so the Hp write and Die() are one critical section (PR #205, closes #174)

One logger for both processes: Shared.Core.Log, with the login channel's wire dump still off by default (PR #204, #41 part 1)

The CSV open-count fact measures the content load only, so parallel collections cannot fail it (PR #202, closes #169)

Process, this session

Issues filed

Server: the death sequence closed, log headroom for warnings, World section 5, stale names, the self-test, MapEditor's package graph

2026-09-09 · Essorcal · Server PRs #184, #185, #186, #190, #191, #192, #193

Die() reconciles peers after the save, so a revive cannot land mid-death (PR #184, closes #177)

Log keeps headroom for Warn and Error under backpressure and counts drops by level (PR #190, closes #73)

TkListener starts the world's threads; World keeps what they run (PR #185, #37 section 5, the last section)

Stale member names in comments, doc crefs and Protocol.md (PR #186, closes #125, #180, #158, #161)

Self-test expectations reconciled with the sourced formulas; FAIL now exits nonzero (PR #191, closes #116)

Failed-reload identity test covers every snapshot member, public or not (PR #192, closes #120)

MapEditor no longer carries BCrypt and SQLite through Shared (PR #193, closes #126)

Process, this session

Issues filed

Server: four Nagnang quests, the crypts, World sections 3 and 4, group payouts, trade teardown, and a dead-code sweep

2026-09-07 to 2026-09-08 · project1998 and Essorcal · Server PRs #137, #138, #139, #140, #148, #151, #153, #162, #163, #164, #165, #166, #171, #172, #178, #181, #182

Nagnang: Mage's Spirit Stone quest (PR #137, closes #133, project1998)

Nagnang: Poet whip quest (PR #138, closes #134, project1998)

Nagnang: Warrior's Nagnang Shield quest (PR #139, closes #136, project1998)

Nagnang: Rogue's Dagger Uniform quest (PR #140, closes #135, project1998)

Cemetery: all nine crypts open (PR #153, closes #152, project1998)

Warps: arrivals stack on an occupied tile (PR #148, closes #99)

World: MobMovement owns the mob step primitives (PR #151, #37 section 2)

World: WorldClock and WeatherService own the calendar and the weather (PR #165, #37 section 3)

World: OnlineRegistry and AutoSaveLoop own the online slots and the sweep (PR #182, #37 section 4)

Group kill payouts run under each member's session monitor (PR #166, closes #154)

@exp kill splits across the group (PR #178, closes #155)

Trade ends when either party leaves the map or dies (PR #172, #57 part 1)

Mob tick: wander step commits through StepMobTo; detour fields dropped (PR #181, closes #149 and #150)

Dead code sweep (PR #164, closes #56)

Csv: a quoted "# ..." first field is a comment (PR #163, closes #131 and #157)

Serve.ps1: -Status remembers the last stopped pair (PR #162, closes #130)

Test-Branch.ps1 reads script headers (PR #171, closes #146 and #147)

Issues filed

Test client: bug batch, console commands and run control, persisted-state headers, task layer part 2

2026-09-07 · Essorcal · test client PRs #26, #29, #33, #39, #37, #36

Console builds against current server master, clone-layout fallback, peers labelled by nameplate (test client PR #26)

Bug batch: disposal verdict, walk bound, cast-heal MaxHp, blocked-route text (test client PR #29, issues #18, #21, #22, #24; #19 investigated and closed)

Console slice 1: a command box, typed lines, and a REPL (test client PR #33, issue #25)

Suite scripts declare the persisted state they change; relative expect hp (test client PR #39, issue #31)

Console slice 2: pause, resume, step, abort, and a per-run token (test client PR #37, issue #25)

Task layer, part 2: fight, hunt, level-up, checkpoints (test client PR #36, issue #30)

Process, tooling, and findings

Server maintenance: disconnect messages and packet handling

2026-09-06 · Server PRs #142, #143 and #144

Alongside the disconnect-message fix, protocol maintenance preserves existing behavior. No intended changes to combat balance, items, quests or emotes.

Test client: bot console, task layer, Frida observe

2026-09-04 · Essorcal

Bot console: every bot on the real map, with stats, timeline and expect results (test client PR #14, issue #12)

Hygiene: melee-kill made deterministic, the build kept out of the server checkout, and the #101 rejection probe (test client PR #15, issues #10, #11)

Task layer, part 1: guards, loops, and navigation by name (test client PR #16, issue #13)

Frida backend F1: attach to the real client and observe (test client PR #23, issue #17)

Tooling (coordination, not in either repo)

Issues filed

Sprint 5: tick isolation, atomic content reload, a real two-sender sync

2026-09-03 · Essorcal

World.Tick: per-mob AI in MobAiTick.Step, one mob throwing no longer abandons the beat (PR #108, issue #36)

Content: one immutable snapshot published with one write (PR #110, issue #33)

Test client: a real two-sender sync (Essorcal/project1998-testclient PR #9, issue #7)

Tooling (local, not on upstream)

Issues filed

Sprint 4: persistence, movement and mob state under the lock, the launcher

2026-09-03 · Essorcal

Character records upgrade explicitly and unreadable rows are protected (PR #96, issue #32)

Two players can no longer land on one tile at once (PR #97, issue #30)

Warp arrivals write position under the world lock (PR #102, issue #99, part 1)

Lock hygiene (PR #100)

Mob state under the world lock, part 2 (PR #105, issue #103)

Content.cs split by domain (PR #104, issue #34)

Dev launcher: Test-Branch.ps1 (PR #98, issue #95)

Test client PR 4: two bots in one script, melee, and the exchange window (Essorcal/project1998-testclient #4)

Test client PR 8: script guards (Essorcal/project1998-testclient #8, issues #5, #6)

Issues filed

Tooling (local, not upstream)

Sprint 3 wrap-up (early 2026-09-03)

Ops & testing commands

2026-08-31 · Essorcal

GM & tester commands

True colours & the docs site

2026-08-31 · Essorcal

Content, quests & world

Client & UI fixes

Server & infrastructure

The website

Tooling & fixes wave

2026-08-28 · Essorcal

GM & tester commands

Content, quests & world

Client & UI fixes

Dev & map tools

Forever Tree, mob AI & recovered maps

2026-08-26 · snugglezone

Content, quests & world

Combat, spells & mob AI

Login & accounts

Armor quests & alliances

2026-08-23 · snugglezone

Proximity broadcasts & fast-move

2026-08-20 · snugglezone

Buya Library Caverns & the Ice Beast

2026-08-19 · snugglezone

Known issue at the time: cavern mob stats/spawns were misconfigured — fix followed.

Multiplayer visibility & PvP

2026-08-18 · snugglezone

Multiplayer visibility & PvP

Cave ambush traps

Chat & social

Items & spells

Options, battle cries & Nagnang

2026-08-17 · snugglezone

Options menu

Combat

World & content

Social & misc