Repository navigation
Ask GMCP/MSDP games for data and show it - #70
Merged
HarryCordewener merged 1 commit intoOct 26, 2026
Merged
HarryCordewener merged 1 commit into
HarryCordewener merged 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
The client now introduces itself over GMCP once the server agrees (Core.Hello, Core.Supports.Set) and asks MSDP games to REPORT what the status row reads. Game data is held per session in GameDataStore and shown three ways: status-row meters (F7 meters), Ctrl+P > Show game data, and Lua gmcp.get / msdp.get / gmcp.send. F5 gains a per-world gmcp modules field. GmcpStats, which collected nine keys nothing drew, is removed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY
HarryCordewener
force-pushed
the
claude/project-thread-hgawpe-1b
branch
from
October 26, 2026 20:25
fa6a2d8 to
80fc2e6
Compare
HarryCordewener
merged commit Oct 26, 2026
fc8da74
into
claude/project-thread-hgawpe-1a
1 check passed
HarryCordewener
added a commit
that referenced
this pull request
Oct 26, 2026
…s name (#69) * Run Lua: load each session's script files and call the functions rules name Every rule kind with a script field (trigger, alias, timer, macro) now raises WorldSession.ScriptRequested with the match and its groups. SessionScripts builds a ScriptHost per session from the trigger sets' ScriptFiles, read from <config>/scripts only, and rebuilds it when the file list changes or on Ctrl+P > Reload scripts. Errors go to the session's window and the client messages. F5 gains a scripts field on each trigger set. Lua runs on the thread that raised the request, under the host's lock. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY * Run script-only macros from a key press; count loaded scripts DispatchMacro required a command, so a macro naming only a Lua function never reached HandleKeyAsync and the key fell through to the command line. The reload notice counted the files named rather than the files that loaded, so a missing file was followed by "1 script loaded". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY * Ask GMCP/MSDP games for data and show it (#70) The client now introduces itself over GMCP once the server agrees (Core.Hello, Core.Supports.Set) and asks MSDP games to REPORT what the status row reads. Game data is held per session in GameDataStore and shown three ways: status-row meters (F7 meters), Ctrl+P > Show game data, and Lua gmcp.get / msdp.get / gmcp.send. F5 gains a per-world gmcp modules field. GmcpStats, which collected nine keys nothing drew, is removed. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Put content format, emoji and on-disconnect on F5 (#71) Three settings existed only in config.json. F5's world row gains content (auto/ansi/mxp/pueblo) and emoji (off/emoticons/shortcodes/ both); the character form gains disconnect under on connect. ContentFormat gains AnsiOnly, appended so a stored "Ansi" keeps meaning the automatic default. OnDisconnect was saved and never sent; it now goes out before the client closes a connection itself, bounded by a one-second timeout. Emoji switches are re-read on each connect. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Negotiate Pueblo and decode its ANSI colour (#72) Register TelnetNegotiationCore's PuebloProtocol. A server's hello is answered with PUEBLOCLIENT 2.50 when the world is auto or pueblo and MXP is not already on; the server's start sequence switches an auto world to PuebloParser. The parser swap is shared with MXP and only happens off the plain ANSI parser, so the first markup negotiated keeps the connection. Both handshake lines are cleared from the pending prompt buffer. PuebloParser gains the escape state machine MxpParser has, decoding SGR through SgrCodes and consuming every other sequence. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Add the map model, store and path finder (#73) Core/Mapping holds a world's rooms and areas (Mudlet's model: exits by direction and by command, room and exit weights, locks), a per-endpoint JSON store under maps/ that is memory-only without a directory, never overwrites a newer client's file and moves an unreadable one aside, and a Dijkstra path finder that returns the walk as commands. Nothing uses it yet; room sources and the map window follow. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Record a map from GMCP rooms and text patterns (#74) Room sources report where the character is: GmcpRoomSource reads Room.Info in the IRE/Aardwolf shape (through TNC's typed RoomInfo) and MUME's (object exits, Room.UpdateExits); TextRoomSource matches a world's room-name and exits patterns. MapRecorder applies each report on the UI thread, links it to the room walked from (WorldSession now raises CommandSent for player commands, never the login line), places rooms without server coordinates one step along the direction walked with a nudge on collision, and recognises text rooms by the way back. The app keeps one recorder per session and writes maps under maps/ on disconnect and exit. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Add the map window, click-to-walk and speedwalk (#75) Ctrl+P > Show map opens the focused connection's map as a tab. A click on a room, or /walk <room>, walks there one step at a time; the walk stops off the path, on the world's walk-fail pattern, after 8 s with no room, or on disconnect. /map lock keeps walks out of a room. F5 gains the map room, map exits and walk fail patterns, and Lua gets map.current/path/walk. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Add the media queue and cache for game sound (#76) MCMP's Client.Media messages become MediaCommands, and a MediaQueue per connection applies the specification's priority, key, continue and pause rules to an IAudioOutput the host will supply. MediaCache fetches http(s) files by a hash of their URL with name, extension and size limits, and fetches nothing without a root. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Play game sound through a desktop audio device (#77) SharpMUTerm.Audio opens the device with SoundFlow (miniaudio) on the first MCMP command and decodes OGG with NVorbis. Each connection gets a media queue; F7 has a SOUND section (on/off, three levels, captions), F5 a per-world download switch, and Ctrl+P mutes for the run. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Read MSP sound triggers on connections that agreed MSP (#78) A line that is exactly !!SOUND(...) or !!MUSIC(...) becomes a media command with MSP's defaults, but only while the telnet session reports option 90 agreed. Inert until TelnetNegotiationCore ships MSPProtocol. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Install packages of trigger sets, scripts and sounds (#79) A package is a .zip read through a review that says what it adds and who it applies to; nothing is written until Enter. Installed packages apply their sets to characters on the games they name. F10 / Ctrl+P lists them, switches one off, copies its sets into the player's own, and removes it. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Browse a package index and check its SHA-256 before the review (#80) * Browse a package index and check its SHA-256 before the review Ctrl+P > Browse packages fetches the index only when opened, lists the focused game's packages first, and refuses an archive whose hash, id or version is not the one the index names. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY * Read MXP definitions, entities, gauges, sounds and frames (#81) * Offer every command of an MXP SEND menu A <SEND> with several commands sends the first on a click and offers all of them on a right-click: in the window's own menu, and in a terminal in a small chooser. &text; in a command is filled in with the element's text. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY * Read MXP definitions, entities, gauges, sounds and frames <!ELEMENT> and <!ENTITY> definitions, <VAR>, <GAUGE>/<STAT> meters on the status row, <SOUND>/<MUSIC> through the MSP media path, and <FRAME>/<DEST> spawn windows. All are secure tags; an element expands with the trust of the tag that opened it, and every expansion is capped. Room flags feed the automapper. A tag now ends only at a '>' outside a quoted value, and an unfinished one is abandoned as text at the line boundary. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY --------- Co-authored-by: Claude <noreply@anthropic.com> * Edit MOO verbs in the composer over MCP 2.1 (#82) A MOO that speaks MCP opens @edit buffers in the F1 composer, and Ctrl+S saves them back line for line (dns-org-mud-moo-simpleedit). The client sends its name, version and window size (dns-com-vmoo-client) and shows the MOO's status text (dns-com-awns-status). A prompt is now read from the interpreter's own partial line, so a line the library consumes can no longer be printed as the prompt after it. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Put a MUSH's edit grab on the command line (#83) A world's edit grab prefix (F5, empty by default; AresMUSH uses FugueEdit >) takes a matching line out of the output and puts its text on that character's command line. Nothing is sent for the player, the grab never lands on another character's bar, and a line being typed is kept in history. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Complete the last word on the command line with Tab (#84) Tab at the end of the command line completes the word being typed from the game's recent output, with the names GMCP reports (room players, channel members and talkers) first. Tab again cycles through the matches and back to what was typed. With no completion, Tab keeps its old meaning and moves to the second command line. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Let Lua scripts keep values between sessions (#85) store.get, store.set and store.keys read and write one JSON file per character in script-data/ beside config.json. The store is bounded at the door (1,024 keys, 256 KB), written through a rename, survives a script reload, and is memory-only in tests and snapshots. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Log in over GMCP Char.Login where a world opts in (#86) A world with F5 ▸ gmcp login set to "if offered" asks for Char.Login 1 and holds back its connect line. A server that offers password-credentials is sent the character's name and saved password over GMCP. Any other answer, or none within five seconds, gets the connect line as before. The password goes only to the wire. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Answer NEW-ENVIRON with the client's MNES identity (#87) A server that asks over NEW-ENVIRON is told CLIENT_NAME, CLIENT_VERSION, TERMINAL_TYPE and MTTS, taken from the TTYPE list so the two agree. The MTTS flags now claim MNES. Nothing about the machine is sent, and nothing is offered to a server that does not ask. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Send one line to several characters (#88) Two or more open characters can be put in a send group from ⌃P; the rail marks members with a diamond in the dot's cell. "Send the command line to the group" sends the typed line once to each connected member and names any that are not connected. Lua gains world.sendTo(name, cmd). Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Show a game's Discord status when its world opts in (#89) A world with F5 ▸ discord set to "show status" asks for External.Discord 1, and the game's Info and Status go to the Discord app on this computer over its local IPC while that world's window is in front. Switching away, disconnecting or a world that has not opted in clears it. The host supplies the presence; snapshots and tests have none. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Support screen readers with --plain and the window's live regions (#90) The client announces each line of output, its own messages and the window brought forward to the host's announcer. sharpmuterm --plain runs the same client as plain text on stdout and sends each line read from stdin. The desktop window passes announcements to the screen reader through live regions. A busy window can be kept quiet from ⌃P. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> * Check spelling in the F1 composer (#91) Hunspell dictionaries through WeCantSpell.Hunspell, found beside config.json or in the system folders and chosen by the POSIX locale. Unknown words are painted in the warning colour through the editor's syntax-highlighting hook, and Alt+W adds the word at the caret to the player's own list. The header names the dictionary, or says there is none. Claude-Session: https://claude.ai/code/session_01WXyHEoxwX8GurTHxwPinQY Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <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.
Requested by Grave · project thread
Item 1b of the implementation plan. Stacked on 1a (#69).
What changed
Core.HelloandCore.Supports.Set(Char, Char.Skills, Char.Items, Room, Comm.Channel) once GMCP is agreed; MSDPREPORTs for the variables the status row reads. F5gmcp modulesadds more per world.GameDataStoreper session; status-row meters (F7 ▸meters); ⌃P ▸ Show game data; Luagmcp.get,msdp.get,gmcp.send.Decisions
IAC DO MSDPis spotted on the write path and the reports follow it.Char.Vitals). MSDP variables are stored asMSDP.NAME, so one path syntax reads both.Generated by Claude Code