Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
227 commits
Select commit Hold shift + click to select a range
3d96f7b
Re-Enable Shaping of Room Affections (#265)
ahumbert Nov 17, 2025
27cecd1
RangerProg: Add option for Riposte (#264)
ahumbert Mar 19, 2026
a827e1c
Docs (#266)
Noobinabox Mar 19, 2026
f0f519c
Update Keywords for Ranfer Prog
ahumbert May 14, 2026
3223d45
Change Teleport to Level 93
ahumbert Jun 4, 2026
f8e362e
Merge pull request #268 from ahumbert/gd_perms_93
ahumbert Jun 4, 2026
f90273a
Merge pull request #267 from ahumbert/adjust_raner_keywords
ahumbert Jun 4, 2026
7533913
Merge branch 'master' into release-frodo
drelidan7 Jun 27, 2026
a8b9eb5
Bug Fix: Scripts Stuck in Memory and Repeat Last Line on Death (#270)
ahumbert Jul 8, 2026
871eb20
Whistle: attempt flee for in-combat tames (#273)
ahumbert Jul 8, 2026
dacfdb6
Handle crashes when a character's hit points go negative (#272)
ahumbert Jul 8, 2026
27ca9d8
Prac Command Update (#271)
ahumbert Jul 8, 2026
73734ee
Sanitize MSDP string values so clients can safely parse them as JSON …
ahumbert Jul 8, 2026
f26d314
Account management (#274)
Noobinabox Jul 24, 2026
48d5c4b
fix(msdp): correct inverted NOWHERE guard in msdp_room_update()
ahumbert Jul 24, 2026
2d91349
harden(msdp): sanitize MSDPSendPair/MSDPSendList and the TERRAIN field
ahumbert Jul 24, 2026
e1c3d2a
perf(net): enable TCP_NODELAY on game socket accept and both proxy legs
ahumbert Jul 24, 2026
ceccd2f
fix(net): don't disconnect on a momentary EAGAIN/EWOULDBLOCK write
ahumbert Jul 24, 2026
77e5a9a
fix(net): cap process_input()'s read-loop iterations per call
ahumbert Jul 24, 2026
79cf31a
fix(net): reap idle pre-login connections, add SO_KEEPALIVE
ahumbert Jul 24, 2026
74fe5a4
fix(ops): add 5s backoff before autorun restarts the game process
ahumbert Jul 24, 2026
1b2a06b
fix(combat): don't skip the element shifted into an erased slot
ahumbert Jul 24, 2026
796462f
fix(movement): don't double-fire ON_BEFORE_ENTER on flee/windblast
ahumbert Jul 24, 2026
65934a4
fix(movement): consume skip-trigger flag in do_move()'s ridden branch
ahumbert Jul 24, 2026
999c167
fix(combat): don't silently clobber a reentrantly-queued delay
ahumbert Jul 24, 2026
8446205
fix(scripts): stop get_next_command() from double-advancing past nest…
ahumbert Jul 24, 2026
9c1f40b
fix(review): correct EAGAIN buffer-drop and haze-reroll trigger dangle
ahumbert Jul 24, 2026
5708b22
fix(review): msdp_room_update null-desc guard/room mismatch, WAIT_STA…
ahumbert Jul 24, 2026
8ae32c9
fix(net): stop the prompt from racing ahead of buffered game text
ahumbert Jul 25, 2026
04afc58
fix(msdp): populate SERVER_ID's backing storage so SEND SERVER_ID works
ahumbert Jul 25, 2026
b2f05e1
fix(msdp): stop ROOM_EXITS/WORLD_TIME double-sends, drop redundant WE…
ahumbert Jul 25, 2026
3027ab3
docs: update manual test checklist (MSDP null-desc guard, switch/retu…
ahumbert Jul 25, 2026
c9a8dfb
chore: stop tracking autorun, gitignore it instead
ahumbert Jul 27, 2026
508bec4
fix(move): stop g_skip_next_before_enter_for from dangling into unrel…
ahumbert Jul 27, 2026
a837cd8
fix(net): restore bare_prompt_pending across EAGAIN retries and short…
ahumbert Jul 27, 2026
3c865a3
fix(proxy): don't kill connections on a failed set_nodelay call
ahumbert Jul 27, 2026
eca5e51
docs: scrub tmp-path reference from test checklist, add PR #276 revie…
ahumbert Jul 27, 2026
703cfff
docs: update PR #276 review doc with fix status and finding 3 correction
ahumbert Jul 27, 2026
8bd82c9
fix(wizset): case-insensitive field matching for `OB`
ahumbert Jul 29, 2026
df8477a
fix(docker): run container as host user, not root
ahumbert Jul 29, 2026
2f5c27d
docs: detailed writeup of the bash double-delay bug (PR #276 finding 4)
ahumbert Jul 29, 2026
75f09ac
docs: root-cause the bash double-delay bug to interrupt-check ordering
ahumbert Jul 29, 2026
db1b89f
fix(combat): let battle mages resist bash's cast interruption
ahumbert Jul 29, 2026
29114a9
docs: update manual test checklist with today's bash findings
ahumbert Jul 30, 2026
474831d
docs(review): add missing reentrancy comment to WAIT_STATE_FULL
ahumbert Jul 30, 2026
3c1b3f0
docs: close out PR #276 review -- finding 5 out of scope, all resolved
ahumbert Jul 30, 2026
27dfd74
fix(msdp): send room MSDP data on reconnect, not just fresh login
ahumbert Jul 30, 2026
b886026
fix(protocol): advertise ISO-8859-1, not UTF-8, in CHARSET negotiation
ahumbert Aug 4, 2026
0e9193e
Merge pull request #278 from ahumbert/charset-iso-8859-1
ahumbert Aug 17, 2026
a5e6c87
Merge pull request #277 from ahumbert/msdp-reconnect-parity-v2
ahumbert Aug 17, 2026
8ca8ae3
Merge pull request #276 from ahumbert/core-server-health-update
ahumbert Aug 17, 2026
c404dfc
fix(account): close the connection when logging out of the account menu
ahumbert Aug 17, 2026
e664168
Merge pull request #279 from ahumbert/fix/account-menu-logout-closes-…
ahumbert Aug 17, 2026
26c0df1
fix(db): truncate over-long player descriptions instead of failing th…
ahumbert Aug 26, 2026
7cfa801
Merge pull request #281 from ahumbert/fix/legacy-long-description-load
ahumbert Aug 26, 2026
ae19639
fix(account): unlink account characters on system deletion
ahumbert Aug 27, 2026
709d83d
Merge pull request #282 from ahumbert/fix/account-aware-character-del…
ahumbert Aug 27, 2026
4c94902
feat(msdp): report carried weight, profession levels, and specialization
ahumbert Aug 28, 2026
ff2842f
Feat/account: Reset Password (#284)
ahumbert Aug 29, 2026
eb9b167
feat(account): allow selecting a linked character by name
ahumbert Aug 31, 2026
0c61b33
Merge pull request #285 from ahumbert/feat/account-character-select-b…
ahumbert Aug 31, 2026
e65027f
Merge pull request #283 from ahumbert/feat/msdp-carried-weight-prof-l…
ahumbert Aug 31, 2026
cb89a1d
fix(msdp): stop publishing bogus, never-visited rooms (#286)
ahumbert Sep 2, 2026
a0438dd
fix(account): raise linked-character cap to 200
ahumbert Sep 3, 2026
3d3f90b
Merge pull request #289 from ahumbert/fix/account-roster-cap-200
ahumbert Sep 3, 2026
9aa2031
feat(account): add roster summary cache
ahumbert Sep 3, 2026
3543d1d
feat(account): invalidate roster summaries on character write
ahumbert Sep 3, 2026
46771ae
feat(account): order and filter the linked-character roster
ahumbert Sep 3, 2026
f22387c
test(account): strengthen roster ordering coverage per review
ahumbert Sep 3, 2026
844d4fd
feat(account): render and select from one ordered roster list
ahumbert Sep 3, 2026
c3548a9
fix(account): resolve name selection against the same ordered roster
ahumbert Sep 3, 2026
d680354
feat(account): sort and filter keys on the character roster
ahumbert Sep 3, 2026
67ec63d
fix(account): persist roster sort on selection, cut redundant writes,…
ahumbert Sep 3, 2026
699206c
fix(account): final review fixes for roster sort/filter branch
ahumbert Sep 3, 2026
dff58cd
fix(msdp): stop dropping variables dirtied while MSDP is off (#288)
ahumbert Sep 3, 2026
e6bc655
feat(color): add a separate 'mob' colour slot for NPCs (#290)
ahumbert Sep 3, 2026
5d82030
Added group data to msdp values. (#287)
Noobinabox Sep 3, 2026
8efeb01
feat(account): render the side sort as labelled sections
ahumbert Sep 3, 2026
5178e14
test(account): close side-sort roster coverage gaps
ahumbert Sep 3, 2026
358edb8
docs(help): document the 'mob' colour slot and unshadow HELP COLOR
ahumbert Sep 3, 2026
87d56ea
docs(help): restore builder data lost from the shape table
ahumbert Sep 4, 2026
3d0530f
docs: record the colour help and CMD_SEND findings
ahumbert Sep 3, 2026
ea642b7
docs(help): drop the dangling AUTOEXIT cross-reference from HELP SET
ahumbert Sep 4, 2026
df02795
Merge pull request #292 from ahumbert/docs/color-help-mob-slot
ahumbert Sep 4, 2026
e045806
Merge pull request #291 from ahumbert/feat/account-roster-sort-and-fi…
ahumbert Sep 4, 2026
6ea0458
fix(exp): report the experience actually banked on a kill (#204)
ahumbert Sep 4, 2026
df11db7
docs(ppc): design for account-level player preferred config
ahumbert Sep 5, 2026
8188fe9
docs(ppc): correct spec — do not bump the account schema version
ahumbert Sep 5, 2026
e498673
docs(ppc): implementation plan for account-level PPC
ahumbert Sep 5, 2026
ddc48c4
feat(ppc): add the PPC mask and AccountPreferences type
ahumbert Sep 5, 2026
a6e7a73
feat(ppc): expose the colour-slot encoder and parser
ahumbert Sep 5, 2026
b013d27
feat(ppc): persist preferences in account.json
ahumbert Sep 5, 2026
488294e
fix(ppc): don't let an unknown account preference name block boot
ahumbert Sep 5, 2026
5b3dd14
feat(ppc): add the account_ppc unit
ahumbert Sep 5, 2026
2cf8c13
feat(ppc): apply the account PPC at login, seeding when absent
ahumbert Sep 5, 2026
40c27fa
fix(ppc): wire the account-link enter-game gap and guard the seed
ahumbert Sep 5, 2026
c2efbb8
feat(ppc): store the PPC back to the account on save
ahumbert Sep 5, 2026
03de9b0
fix(ppc): mirror the seeding guard on save and fix a stale-RGB compar…
ahumbert Sep 5, 2026
fe8a7e1
feat(ppc): propagate a settings change to the account's other online …
ahumbert Sep 5, 2026
40ea3f5
fix(ppc): make do_color propagate on every mutating path, not just th…
ahumbert Sep 5, 2026
d3fa8a1
feat(ppc): skip the colour and latin-1 prompts once the account has a…
ahumbert Sep 5, 2026
c51b7d9
fix(ppc): never write a character's PPC to the account before it has …
ahumbert Sep 5, 2026
c5b011a
fix(ppc): survive unknown colour modes, prefer a live sibling, guard …
ahumbert Sep 5, 2026
d189a13
docs: account storage findings — no store layer, deferred as next work
ahumbert Sep 5, 2026
61345bb
fix(ppc): close the copy-path holes in the account preference invariant
ahumbert Sep 5, 2026
f8741a2
docs: park two PPC follow-ups against the account storage work
ahumbert Sep 5, 2026
b8c6fa8
docs(account): design for an indexed account store layer
ahumbert Sep 5, 2026
7db7141
docs(account): implementation plan for the account store index
ahumbert Sep 5, 2026
5ea9a62
feat(account): add a keys-only account index
ahumbert Sep 5, 2026
2743f37
feat(account): quarantine unusable account records with a boot threshold
ahumbert Sep 5, 2026
0f9e262
feat(account): build the account index at boot instead of dying on on…
ahumbert Sep 5, 2026
96bff10
fix(account): quarantine gaps and precedence in the boot index walker
ahumbert Sep 5, 2026
69900e2
feat(account): maintain the index at the account write chokepoint
ahumbert Sep 5, 2026
62f53df
feat(account): resolve accounts through the index instead of scanning
ahumbert Sep 5, 2026
c2bf663
fix(account): restore duplicate detection and remove the boot orderin…
ahumbert Sep 5, 2026
4a84db7
fix(account): refuse to create an account over a quarantined record
ahumbert Sep 5, 2026
aa6d449
feat(account): add 'account index' to inspect and verify the account …
ahumbert Sep 5, 2026
b1c212f
fix(account): stop 'account index verify' from misreporting quarantin…
ahumbert Sep 6, 2026
a08aae9
fix(account): close the remaining false-drift gaps in 'account index …
ahumbert Sep 6, 2026
cf80488
fix(account): reconcile the account subsystem with survivable quarantine
ahumbert Sep 6, 2026
5f61a4b
test(account): cover index ambiguity, quarantine reach and the write …
ahumbert Sep 6, 2026
03f84a8
Merge branch 'feat/account-store' into release-frodo
ahumbert Sep 6, 2026
53b9cee
docs: manual test checklist for the account store index
ahumbert Sep 6, 2026
7b1465a
docs: note the scripted coverage on the account index checklist
ahumbert Sep 6, 2026
efb8c57
test(account): commit the account index smoke scripts to tools/
ahumbert Sep 6, 2026
02b8955
docs: point the account index checklist at the committed smoke scripts
ahumbert Sep 6, 2026
e442f1c
fix(account): one bad character file must not lock its owner out
ahumbert Sep 6, 2026
db5091c
fix(account): self-healing contention, S_ISREG candidates, cheaper index
ahumbert Sep 6, 2026
3d0ef16
fix(account): a dangling *.json symlink must not refuse all registration
ahumbert Sep 6, 2026
23fd2f7
Merge branch 'fix/account-index-review' into release-frodo
ahumbert Sep 6, 2026
e9ebfc1
fix(account): wave 3 - five paths that failed without telling anyone
ahumbert Sep 6, 2026
d24ea33
Merge branch 'fix/account-index-wave3' into release-frodo
ahumbert Sep 6, 2026
db1b09f
style(account): undo clang-format churn in code this branch never tou…
ahumbert Sep 8, 2026
8a9adc6
refactor(account): drop the index off switch and every rollback assum…
ahumbert Sep 8, 2026
e9e7db4
refactor(account): remove 'account index verify' as excess scope
ahumbert Sep 8, 2026
a548afa
docs(account): drop the findings doc this branch duplicated from PR #294
ahumbert Sep 8, 2026
fa8d0f2
feat(account): report account records that go unreadable after boot
ahumbert Sep 8, 2026
4f29895
docs(account): say plainly that quarantine moves no files
ahumbert Sep 8, 2026
d6cd624
fix(account): stop losing character conversion and load failures in s…
ahumbert Sep 8, 2026
c62c075
feat(account): refuse a legacy conversion that would lose data
ahumbert Sep 9, 2026
22cb5cd
fix(account): mark unreadable records on the READ path, not just the …
ahumbert Sep 9, 2026
97f7ac8
fix(account): close fourteen findings from two adversarial review rounds
ahumbert Sep 9, 2026
3c19a02
docs(account): record the adversarial reviews and their live validation
ahumbert Sep 9, 2026
b832423
fix(account): renaming an account-native character destroyed it
ahumbert Sep 9, 2026
e4ae21d
merge: account-native character rename fix
ahumbert Sep 9, 2026
87844f7
fix(account): close five findings from the pre-push review
ahumbert Sep 9, 2026
f9e9b0a
merge: five findings from the pre-push review of the account index stack
ahumbert Sep 9, 2026
c422600
fix(account): report a refused rename to the immortal who asked for it
ahumbert Sep 10, 2026
dd39507
fix(world): initialize every room_data member, not six of them
ahumbert Sep 10, 2026
ab3234c
fix(account): a disputed email address is taken, not free
ahumbert Sep 10, 2026
1a3a18c
fix(account): a record that reads again stops being reported unreadable
ahumbert Sep 10, 2026
3f49b2b
docs(account): the unreadable-since-boot mark clears on a read, not o…
ahumbert Sep 10, 2026
6368b20
fix(account): never delete or overwrite a record the server has not read
ahumbert Sep 10, 2026
e1d99cd
fix(account): refuse a record the game cannot reach, and a rename wit…
ahumbert Sep 10, 2026
0b35720
fix(account): an ordinary email address must not be able to stop the …
ahumbert Sep 10, 2026
21dfc80
feat(account): name the roster's side sections Good and Evil
ahumbert Sep 11, 2026
c5a01dc
Merge pull request #296 from ahumbert/fix/roster-side-labels
ahumbert Sep 11, 2026
5ffec8c
Merge pull request #294 from ahumbert/feat/account-level-ppc
ahumbert Sep 11, 2026
6278f58
Merge pull request #293 from ahumbert/fix/xp-display-cap
ahumbert Sep 11, 2026
3955c75
fix(db): a long email address must not smash the stack on login
ahumbert Sep 12, 2026
b8a92e2
fix(account): bound the email address, the one path component nothing…
ahumbert Sep 12, 2026
c7973f4
fix(account): a failed conversion must never delete the last copy of …
ahumbert Sep 12, 2026
0666086
fix(alias): a twenty-character alias must not corrupt the heap or the…
ahumbert Sep 12, 2026
b033d8f
fix(account): quarantining a misfiled record must not take the addres…
ahumbert Sep 12, 2026
6a9e14a
fix(account): a failure after the record commits must not undo the wo…
ahumbert Sep 12, 2026
6e20f91
fix(boot): files an operator left behind must not stop the server
ahumbert Sep 12, 2026
a5096f4
fix(boot): raise the unreadable-record limit to ten
ahumbert Sep 12, 2026
eb3a577
fix(account): a conversion that fails must say so somewhere other tha…
ahumbert Sep 12, 2026
aec02a3
fix(account): prove a character's files can be read back before repla…
ahumbert Sep 12, 2026
dc73762
docs(account): say what a contested address does not heal from
ahumbert Sep 12, 2026
13fa633
test(account): pin the rule that a failed conversion leaves the legac…
ahumbert Sep 12, 2026
b607e81
feat(account): let an immortal ask what went wrong since the last reboot
ahumbert Sep 12, 2026
01484e4
perf(account): stop re-parsing every save to catch a defect the table…
ahumbert Sep 13, 2026
ff98651
fix(account): four findings from the review of this branch
ahumbert Sep 13, 2026
f675ebe
Merge upstream/release-frodo into release-frodo
ahumbert Sep 13, 2026
9d7f8f2
test(account): expect #294 to skip the creation questions on a later …
ahumbert Sep 13, 2026
d12c240
docs(build): warn in the Makefile that `make format` rewrites the who…
ahumbert Sep 13, 2026
093c36c
fix(account): list a quarantined account record in `account errors`
ahumbert Sep 14, 2026
a482ac7
Merge pull request #297 from ahumbert/feat/account-store-index
ahumbert Sep 14, 2026
b7a1003
fix(account): verify converted object and exploit files before retiri…
ahumbert Sep 14, 2026
dc5b8dc
fix(account): check that a migration's default object and exploit fil…
ahumbert Sep 14, 2026
06d5b32
fix(account): a new account character no longer inherits a leftover l…
ahumbert Sep 14, 2026
652246d
fix(help): keep #RRGGBB on the text line so HELP COLOR is not cut off
ahumbert Sep 14, 2026
cba259e
Merge pull request #298 from ahumbert/fix/help-color-hex
ahumbert Sep 14, 2026
a8d3c35
test(idle): lock in what idling out does to followers and mounts
ahumbert Sep 14, 2026
c9d6555
docs(deploy): design spec for scripts/deploy.py
ahumbert Sep 14, 2026
54cccbf
docs(deploy): implementation plan for scripts/deploy.py
ahumbert Sep 14, 2026
4f01ffb
feat(deploy): env table and command-line arguments for scripts/deploy.py
ahumbert Sep 14, 2026
6319d46
feat(deploy): pick help files to upload and check their format
ahumbert Sep 14, 2026
9fb34cf
feat(deploy): local checkout pre-flight, pull, and deploy tags
ahumbert Sep 14, 2026
ff87870
feat(deploy): remote pre-check, backup, source edit, build, and rever…
ahumbert Sep 14, 2026
66008a0
feat(deploy): run remote steps and sftp over one ssh master connection
ahumbert Sep 14, 2026
34228aa
feat(deploy): run the deploy steps in order with dry run and failure …
ahumbert Sep 14, 2026
9cd8d8e
fix(deploy): harden remote commands, dry run, login parsing, and erro…
ahumbert Sep 14, 2026
26ea2f0
fix(deploy): add a deploy-in-progress marker and a working revert
ahumbert Sep 14, 2026
44b7857
docs(deploy): record the final-review fixes in the plan and spec
ahumbert Sep 14, 2026
bd5e68a
fix(deploy): let the source edit match lines that end in CRLF
ahumbert Sep 14, 2026
a60aa65
fix(account): an idle-out no longer hands keys and NORENT items back …
ahumbert Sep 14, 2026
008d8f8
fix(objects): a floor of 1000+ objects no longer crashes the server w…
ahumbert Sep 14, 2026
ab47f77
fix(deploy): make owned read-only files writable before asking sudo
ahumbert Sep 14, 2026
f46a4f4
feat(deploy): add a revert command
ahumbert Sep 14, 2026
8b65004
fix(deploy): name the revert command when a previous deploy did not f…
ahumbert Sep 14, 2026
9ca3ba9
fix(objects): report a 1000-object floor once instead of on every drop
ahumbert Sep 14, 2026
0370103
fix(deploy): never touch files outside the port's game dir through sy…
ahumbert Sep 14, 2026
90ac21e
fix(deploy): drop chmod and chown only what is inside the folders
ahumbert Sep 15, 2026
3b03bd7
fix(deploy): build with make -j2 instead of -j6
ahumbert Sep 15, 2026
9cd38f3
docs: compile with make -j2 when deploying by hand
ahumbert Sep 15, 2026
8b88dcb
feat(deploy): let the test port deploy from a feature branch
ahumbert Sep 15, 2026
d6cf576
fix(look): list at most 100 objects on a floor so the people in the r…
ahumbert Sep 15, 2026
1b141c9
fix(output): keep wrapped text inside process_output's buffer
ahumbert Sep 15, 2026
e3ccf9c
Merge pull request #300 from ahumbert/fix/migration-verify-objects-ex…
ahumbert Sep 15, 2026
8afd233
fix(account): let existing short-named characters be linked to accounts
ahumbert Sep 15, 2026
9a9e791
fix(account): don't refuse migration over junk in profession slot 0
ahumbert Sep 15, 2026
4cde51e
feat(deploy): limit deploys to test and forge-test; add --restart for…
ahumbert Sep 15, 2026
123e497
Merge pull request #299 from ahumbert/feat/deploy-script
ahumbert Sep 15, 2026
631829b
fix(account): don't refuse migration over unnamed flag bits or affect…
ahumbert Sep 15, 2026
62b9093
docs(deploy): how to let --restart run without a second password
ahumbert Sep 15, 2026
04022d1
feat(deploy): push deploy tags to the main repo
ahumbert Sep 15, 2026
b656e72
Merge pull request #301 from ahumbert/feat/deploy-push-tags
ahumbert Sep 15, 2026
29966b9
fix(objects): load a scalp of a removed mob as an old skull
ahumbert Sep 15, 2026
a77f60e
Merge pull request #302 from returnoftheshadow/fix/account-link-short…
ahumbert Sep 15, 2026
9a668ed
feat(deploy): --password answers the ssh login prompt
ahumbert Sep 15, 2026
0480ecb
Merge pull request #303 from returnoftheshadow/feat/deploy-password
ahumbert Sep 15, 2026
5ab6fb1
fix(combat): stop mobs switching from a charmed pet to its master
ahumbert Sep 15, 2026
ffca361
Merge pull request #304 from returnoftheshadow/fix/pet-master-switch
ahumbert Sep 15, 2026
9b244da
fix(scripts): restore get_next_command()'s block-skip behaviour
ahumbert Sep 17, 2026
bf48484
Merge pull request #305 from returnoftheshadow/fix/script-skip-regres…
ahumbert Sep 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
Empty file added .claude/.no-autoformat
Empty file.
51 changes: 51 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: CI

on:
push:
branches:
- master
pull_request:
branches:
- master

permissions:
contents: read

jobs:
build-test-smoke:
name: Build, Unit Tests, and Smoke Tests
runs-on: ubuntu-24.04
timeout-minutes: 30

steps:
- name: Check out repository
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
clang-format \
cmake \
cargo \
gcc-multilib \
g++-multilib \
libc6-dev-i386 \
libcrypt-dev \
libgtest-dev \
make \
pkg-config \
python3 \
rustc

- name: Configure build tree
run: make configure

- name: Run C++ unit tests
run: make test

- name: Run account smoke flow
run: make smoke-account
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,18 @@ CVS/
old/
backup/
lib/misc/plrmail
lib/accounts/
lib/misc/maze.dat
lib/misc/mdl
lib/misc/mudlle.keys
lib/misc/oldcrimelist
lib/misc/pk*
lib/misc/repair*
lib/misc/xnames*
tools/__pycache__/
core/
*~
autorun
autorun4000
switchserver.sh
crashes
Expand All @@ -77,3 +81,8 @@ target/

# cmake
.cache
cmake_test_discovery*.json

# macOS
.DS_Store
**/.DS_Store
42 changes: 34 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,52 @@
- proxy/: Rust workspace member (`cargo` crate) for proxy/CLI utilities.
- release-notes/, game design docs/, code documentation/: Docs and release history.

## Planning Workflow
- Before starting feature work, always read `FEATURES.md` and `WIP.md` if they exist.
- Treat `FEATURES.md` as the current feature scope, breakdown, and implementation checklist.
- Treat `WIP.md` as the current execution log and update it during feature work with the current task, recent progress, and next step.
- If feature scope changes during discussion, update `FEATURES.md` before implementing.
- If active work changes during implementation, update `WIP.md` before continuing.

## Build, Test, and Development Commands
- Bootstrap data: `cd src && make setup` — creates required runtime directories/files under `lib/`, `log/`, and `bin/`.
- Build (Make): `cd src && make all` — compiles C/C++ sources to `bin/ageland`.
- Run: `cd src && make run` or `./bin/ageland -p &` — starts server in background.
- Clean: `cd src && make clean` — removes `*.o` objects.
- CMake alt build: `cmake -S src -B build && cmake --build build` (C++17).
- Configure: `make configure` — generates the CMake build tree in `build/`.
- Bootstrap data: `make setup` — creates required runtime directories/files under `lib/`, `log/`, and `bin/`.
- Build: `make build` — compiles C/C++ sources to `bin/ageland`.
- Test: `make test` — builds and runs the GoogleTest-based C++ unit tests.
- Manual smoke: `make smoke-account` — builds the game/proxy and runs the proxy-backed account smoke flow.
Use this as a required separate validation step for account/login/authentication changes because `make test` is intentionally unit-test-only.
- Run: `make run` — builds and starts the server in the foreground on port `3791`.
- Clean: `make clean` — removes build outputs from the configured tree.
- Raw CMake fallback: `cmake -S src -B build -DCMAKE_CXX_COMPILER=g++ && cmake --build build --target ageland`
- Rust proxy: `cargo build -p proxy` | `cargo test -p proxy` | `cargo run -p proxy -- --help`.

## Coding Style & Naming Conventions
- Formatter: run `cd src && make format` (WebKit style). Prefer this over local defaults; CI expects formatted diffs.
- Formatter: run `cmake --build build --target format` (or `cd src && make format`) using WebKit style. Prefer the repo-provided target over local defaults; CI expects formatted diffs.
- .clang-format: present for IDEs; indentation 4 spaces; column limit ~100.
- Filenames: lower_snake_case for `.cpp`/`.h` (e.g., `act_comm.cpp`, `protocol.h`).
- C/C++: functions/variables lower_snake_case; constants UPPER_SNAKE_CASE; types TitleCase where applicable.
- Rust (proxy): follow `rustfmt` defaults; module/file lowercase with underscores.

## Testing Guidelines
- C/C++: no formal unit tests; perform smoke tests by building and running locally. Verify server boots, accepts connections, and changed features behave as expected.
- C/C++: add or update unit tests in `src/tests/` when working in covered areas, run them via `make test`, and also perform smoke tests manually by building and running locally, typically via `make smoke-account` for the account flow. For account/login/authentication changes, treat that smoke run as a required separate validation step before finalizing. Verify server boots, accepts connections, and changed features behave as expected.
- When the user reports a bug or finding, default to adding a focused unit/regression test for it first whenever the affected area is unit-testable. If a meaningful unit test is not practical, say so explicitly and add the next-best automated coverage you can.
- C/C++ test style: prefer behavior-oriented GoogleTest names that read clearly in CTest output, such as `ReturnsConfiguredWeaponType` instead of terse names like `WeaponType`. Use readable assertions like `EXPECT_TRUE` when appropriate, and add concise failure messages that explain the expectation and include important domain values when a failure would otherwise be cryptic.
- Do not modify production code solely to accommodate tests. Prefer test fixtures, helper builders, dependency-free coverage, and existing public behavior. Only introduce a production seam for testability when it is also a legitimate design improvement, and call that out explicitly.
- New code: add unit tests for newly written code when the surrounding module supports them, and document any gaps when tests are not practical.
- When writing or expanding unit tests for non-trivial code paths, maintain a constructively adversarial test-design partner named `Bazarat`. Use `Bazarat` to challenge assumptions, look for missing edge cases, identify weak assertions, and pressure-test whether the tests would catch realistic regressions instead of only happy paths.
- Rust: write unit/integration tests in `proxy/`; run with `cargo test -p proxy` and keep coverage reasonable.

## Review Workflow
- Before finalizing any non-trivial change set, maintain two review subagents in parallel: `Magus` as the quality engineer reviewer and `Vincent` as the security engineer reviewer.
- When the change set includes meaningful unit-test work, keep `Bazarat` engaged during test design and test review as a constructively adversarial pairing partner in addition to the normal reviewer pair. `Bazarat` is not a replacement for `Magus` or `Vincent`; the role is to pressure-test test intent, edge coverage, and failure realism while the code is still being written.
- Reuse the same reviewer pair across successive changes by sending them updated diff context, instead of spawning a fresh pair for every round. Only replace a reviewer when it has been closed, becomes unavailable, or its context is no longer reliable. If either reviewer must be replaced, assign the replacement the same role name so the workflow stays consistent.
- In user-facing updates, always refer to the reviewer roles as `Magus` and `Vincent`, and the test-design partner role as `Bazarat`, even if the underlying subagent identity has changed, so the review trail stays clear and consistent.
- The quality engineer should focus on regressions, correctness, maintainability, test quality, developer ergonomics, and documentation gaps.
- The security engineer should focus on trust boundaries, unsafe execution paths, secrets or data exposure, command safety, and build/test workflow risks.
- `Bazarat` should focus on adversarial test questions such as: what assumption is unproven, what malformed input is untested, what rollback path is uncovered, what assertion is too weak, and what realistic regression would still slip through the current tests.
- Give both reviewers the relevant changed files or diff context, ask for findings first with severity, file references, and concrete recommendations, and do not treat the work as complete until their feedback has been reviewed.
- Address their findings in code or docs when appropriate, or explicitly document why a recommendation is being deferred.

## Commit & Pull Request Guidelines
- Commits: concise, imperative subject (<=72 chars). Reference issues/PRs, e.g., "ranger: fix stun timing (#255)".
- Scope small, logically grouped changes; include short body for context when needed.
Expand All @@ -36,4 +63,3 @@
## Security & Configuration
- World files live in a separate repo; keep `lib/world/` and player data out of commits.
- Never check in PII or live server logs (`log/`). Use local testing accounts and sanitized samples.

7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
# Build/run with docker compose (see docker-compose.yml) or scripts/rots-docker.sh.
FROM --platform=linux/386 i386/debian:bullseye

# g++ 10 (supports the Makefile's -std=c++1z) + make. The Makefile links no extra
# libraries, so no other build deps are needed. telnet/procps are dev conveniences.
# g++ 10 (supports -std=c++1z/c++17) + make. The CMake build (src/CMakeLists.txt) also
# needs cmake, GoogleTest (libgtest-dev) for the ageland_tests suite, and libcrypt-dev for
# the crypt() link; pkg-config is a CMake convenience. telnet/procps are dev conveniences.
RUN apt-get update && apt-get install -y --no-install-recommends \
g++ make telnet procps ca-certificates \
g++ make cmake libgtest-dev libcrypt-dev pkg-config telnet procps ca-certificates \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /rots
Expand Down
Loading
Loading