Repository navigation
Quest arc phase 0: one menu primitive for every choice (#375) - #642
Merged
Merged
Conversation
…#375) QUEST_DIALOGUE_REQUIREMENTS.md is the one-page target: goal, player flow, rules and the done-when checklist with its tests and guards. QUEST_DIALOGUE_ROADMAP.md is the route: verified facts, approach, topic structure, build order and phases 0 to 7. Brainstormed with the owner 2026-10-20. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Phase 0 spec: pure internal/menu core, non-modal game session with interrupts, modal builder session, follow-pull lines, typed-input flag, and migration of every fixed choice. Roadmap and requirements record the session's rulings (no terminal clicking, help and context.md coverage, corrected menu-parse counts). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…login (#375) Ticks and triggers queue while a menu or prompt is open (server pushes Char.Menu), the queue resumes paced after close, and nothing fires at the login prompts: tick timers are cleared on socket close and start only after the session's first Char.Automation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ueue audit (#375) Quest menu entries show the title with the player's line beneath it, and choosing any topic plays out to the room as a conversation while menus stay private. Phase 0 audits the web client action queue (front mode especially) with tests before building the pause on it; login automation stays dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Game menus resolve only numbers, Enter and exact labels, ids or aliases, so a movement or look shortcut typed mid-menu runs as a command. Builder menus opt into prefix matching and free text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n, control (#375 phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…se 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
phase 0) OpenMenu, RouteMenuInput, CloseMenu, CloseMenuForFollow, CheckMenuInterrupts and CloseMenusForRoomChange on UserRecord, gated by menuGate (dead, combat, busy, asleep, quitting, off feet, controlled). characters.BusyStateChanged lands on CheckMenuInterrupts. MenuChanged fires when the first menu or prompt opens or the last one closes; the open state is read before and after each change in the same critical section, and callbacks, SendText and the event run with sessionMu released. prompt.Prompt gains NonModal (Task 9 adds the rest). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every grapple position is off the feet, so a seized player read "as you go down". The controlled rule now comes first and stays nil-safe for a character loaded from a save, which has no Control machine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…se 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
phase 0) - events.DrainQueuedMenuChangedForTest, and tests for the MenuChanged sequences: open/close, replace, prompt/clear, clear with nothing open, one interrupt closing a menu and a non-modal prompt. - A choice holds MenuChanged until OnChoose returns, so a choice that opens the next menu never reads as closed in between. - MenuChanged is queued under sessionMu with the change it reports, so signals cannot reorder across goroutines; callbacks and SendText stay outside the lock. - StartPrompt over an open game menu closes it with CloseReplaced. - One interrupt takes the menu and a non-modal prompt in one critical section and signals once. - Table test for every menuGate rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…375 phase 0) prompt gains AskMenu, AskConfirm and Question.Resolve; a menu question answers through menu.Resolve and records LastResult. world.go gives a typed line to an open game menu first, then to the prompt through UserRecord.RoutePromptInput, and clears a finished prompt before the redraw (ClearFinishedPrompt) so Char.Menu reports it closed promptly. A queued command never answers a menu or prompt any more, which also closes the hole where a follow step could be swallowed as a builder prompt's answer. A non-modal prompt closes on a line its menu does not recognise and the line runs as a command. The exit-message requeue in go strips CmdTyped so its delayed re-run cannot answer a prompt opened in between. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#375 phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ee (#375 phase 0) Also closes a menu on the synchronous Sleep path and makes the hook's mob room-change test able to fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#375 phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hase 0) Adds cases A2-A10: front ordering, dedup, cap, rejected, deferred aging, one release per round, login hold (with setTimeout stubbed so no stray timer), front/back ordering while held, death clear. No queue defect found. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…login (#375 phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…phase 0) The leader has already left the room when the lines are spoken, so the follower, leader and room lines now use DepartureSight and a new Room.DepartureSnapshot. The party follow path breaks off before "You follow the party leader." Also updates the condition-apply allowlist line for sleep.go. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rows in the queue (#375 phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… route tests (#375 phase 0) A line a game menu consumes never reached TryCommand, so it neither stamped the last input round nor woke Idle/AFK; a player working through a menu could idle out. The wake moves to UserRecord.WakePresence (TryCommand calls it), and world.go calls NoteActivity for a consumed non-empty menu line, then redraws the prompt line so telnet players get one after a silent close. A modal builder prompt that edits the current room survived a follow step or forced move, so the next answer acted on the new room. Prompts gain RoomBound; the room container, mutator and exit builders and zone edit set it, and CloseMenusForRoomChange cancels a RoomBound prompt with an admin line. A source guard keeps every StartPrompt in those files room bound. Adds the missing RoutePromptInput tests: free-text answer and re-run, empty command, NoSuchNumber and Ambiguous refusal lines, and the menu AcceptText branch of Question.Answer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l/menu (#375 phase 0) Item type and subtype, room containers and exits, trap conditions, container recipes, room and zone mutators and server config are now AskMenu questions; the restNum parse blocks and numbered-list renders are gone. The spell list is display only and prints plain lines. Departures from the plan, both from reading the source: - optionsMenu uses an option's Id (as text) as the entry Id when it has one. Condition names are not unique (two shipped specs are "Stunned"), so Id=Name made picking the second by number select the first. optionByResponse maps an answer back to its option. - getConfigOptions keeps the full path in Id and the segment in Name, so configMenu uses Name: server_Config appends the answer to its prefix. It re-asks after each level so a number picks from the level drawn, and a bad path now redraws the current level instead of the top one. Toggle lists re-ask with updated marks so [x] shows. Choosing "new" recipe by number now creates a recipe (it used to edit recipe 0). builder_menu_test.go drives each flow by number through RoutePromptInput and the command function. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…es, subtype Enter redraws (#375 phase 0) - Trap conditions sort by name then id. Two specs are named "Stunned" and ids arrive in map order, so their numbers swapped between redraws (the toggle test failed 15 of 50 runs without the tie-break). - Condition 0 (the quit timer) is not offered as a trap condition; its id "0" collided with the toggle menus' leave answer. - menu.Menu gains LeaveAliases, checked before the number branch, so a typed "0" still finishes the trap, room mutator and zone mutator lists. LintLabels flags a leave alias that shadows an entry. - The item subtype menu has no Cancel entry again: Enter with no subtype redraws instead of ending the build. The abort branch it fed is gone (an answer can no longer be empty). - A modal menu that gets a line it cannot use, or Enter with no default and no leave, now says "Pick a number from the list." before the builder redraws (the old builders said "Invalid selection."). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l/menu (#375 phase 0) Confirms are two entries, Enter picks No, and actions that cannot be undone name the action. Player flows are non-modal, so a command typed mid-choice closes the menu and runs; builders and start stay modal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…st templates (#375 phase 0) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…side line; tests (#375 phase 0) A non-modal prompt records the interrupt rule already holding when it opens (Prompt.OpenedUnder), so mail opened while resting or picklock started in a fight is closed only by a different rule, and a rule that lifts and returns counts as new. Room changes and follow pulls still close it. Prompt.SetAsideLine is spoken whenever such a prompt closes unfinished; mail says "You set your unsent mail aside." Also: rename confirm names the action, character confirms fail safe on anything but yes, the veteran decline no longer announces the arrival twice, and driving tests for the character room alt delete, picklock, the mail set-aside line and the rename labels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The perma-gear AddCondition allowlist key moves to its new line. The refusal phrase guard already skips cmdPrompt.Ask questions because a question waiting for an answer is not a refusal; a question can now be a menu, so the skip also covers a menu.Menu Heading and the question argument of cmdPrompt.AskConfirm and menu.Confirm. Entry labels, confirm labels and Heading keys of other types are still scanned, with a test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Remove unused util.BoolYN, document Menu.LeaveAliases, scan root *.go in the menu guard, share the "no such choice" refusal line, and early-out CheckMenuInterrupts when nothing is open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings the quest arc requirements, roadmap, phase 0 spec and plan onto the implementation branch so they ship in one PR. README conflict: master's archived combat-reachability rows kept, phase 0 rows added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 tasks
Owner ruling 2026-10-20: being off their feet is not a gate for audio interactions. menuGate drops its not-standing rule; CloseOffFeet, its line and the position busy observer are removed. Combat, busy, dead, asleep, quitting and grapple control still gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Owner ruling 2026-10-20 applied (96b9253): being off your feet (sitting, prone) is not a gate for audio interactions. The menu gate no longer refuses or closes menus for position; combat, busy, dead, asleep, quitting and grapple control still gate. CloseOffFeet and its line are removed; tests prove seated and prone players can open menus and that sitting down keeps one open. |
pruuk
added a commit
that referenced
this pull request
Oct 21, 2026
Moved 2 to completed/ (the #375 phase 0 spec and plan, shipped in PR #642), 0 to abandoned/. Stayed at the top: the phase 1 spec and plan (in progress), the autosave and messaging arc specs (open follow-ups). README repointed; the relative-link check found no new breaks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Quest and dialogue arc (epic #375), phase 0: one menu primitive that every fixed choice in the game uses, plus the arc's requirements, roadmap, phase 0 spec and plan.
internal/menu): render, resolve, confirm, label lint, close reasons, interrupt and follow lines. Game menus match only a number, Enter, or an exact label, id or alias; prefix matching is builder-only (owner-approved change from the spec, sonandlstay movement and look).internal/users):OpenMenu/RouteMenuInputwith a busy gate (combat, casting/crafting/salvaging, dead, asleep, quitting, controlled, off feet). State machines gotRegisterObserver; characters push busy changes; conditions and room changes close menus.OpenMenuhas no production caller until phase 1 (talk).internal/prompt): menu questions (AskMenu,AskConfirm). Player flows (character, guild, mail, rename, picklock, auctions, deletecharacter) are non-modal: a typed command that is not a choice closes the menu and runs. They close only on a NEW interrupt (OpenedUnder), so mail while sitting still works; room changes and follow pulls always close them. Mail says "You set your unsent mail aside." when a draft is dropped. Builders andstartstay modal.events.CmdTyped. Engine-queued commands (follow steps, scripts, admincommandforcing a player, web-clientChar.Action.Try) can no longer answer a menu or prompt. A player's own macros still can.[x]toggles,0still finishes a toggle list). Room-editing builders are cancelled when the admin moves (RoomBound). Picking server config entries by number now works; "new" recipe by number now creates one.Char.Menu {open}(queued ahead of the menu text, resent on spawn). Ticks and triggers queue while a menu or prompt is open and release one per round after; nothing fires during login (timers cleared on disconnect).Char.Action.Tryrepliesdeferred / menu openas a backstop. Queue audit found no defects.numbered-listtemplates are deleted; a guard test keeps numbered-menu code insideinternal/menu.Known gaps (filed)
Controlis nil for loaded players. Added to One shared busy check: combat, activity, life, position, control, sleep, quitting #640.Test plan
go build ./...,gofmt -lcleango test ./...(all packages; root guards fixed and re-run)golangci-lint run --new-from-merge-base=origin/master: 0 issuestools/jstest/*.test.jspass (queue audit 31 checks, automation pause)Server Ready, 0 panicsEvery task had an implementer plus spec and quality reviews; review fixes are in follow-up commits.
🤖 Generated with Claude Code