Skip to content

Coordinates in chat are links that reach plugins - #224

Merged
eriknihlen merged 3 commits into
eriknihlen:mainfrom
davidc-smith:feat/chat-coordinate-links
Oct 19, 2026
Merged

eriknihlen merged 3 commits into
eriknihlen:mainfrom
davidc-smith:feat/chat-coordinate-links

Conversation

@davidc-smith

Copy link
Copy Markdown
Contributor

Summary

Coordinates in chat become links that reach plugins.

  • Typed coordinates are links. Any coordinate pair PluginChatCoordinateParser reads ("meet at 42.1N 33.5E", "Your corpse is located at (42.1N, 33.5E).") is a COORD:World link in every chat line except combat text. That covers speech, tells, channels and the server's own lines.
  • A plugin's markup is read. A line posted with PostMessage / PostSystemMessage has its <COORD:World:42.1N, 33.5E>caption<\COORD> tag shown as a link. It is read as markup only when the line holds a <TYPE:FORMAT…> tag, so a stray < is shown as written. Server text is never read as markup.
  • Clicks reach plugins. ChatWindowController.ChatLinkClicked was added in ef4cc19 but never assigned, so no coordinate click ever raised IPluginChat.LinkClicked. It is now wired through ChatRuntimeBindings.LinkClicked to the automation surface.

Changes

  • ChatCoordinateLinks (Core) splits the plain body spans of a line at coordinate pairs. Each match is validated by PluginChatCoordinateParser.TryParse, so a pair is linked exactly when the parser reads it, and a test pins that parity.
  • ChatEntry.AllowsMarkup is set only for plugin lines (RuntimeCommunicationState.AddPluginText). ChatLineWording.Format gives such a line as plain text for the log file and console, and FormatTagged keeps its markup.
  • RuntimeChatFeed.BuildLine parses a plugin's markup and links coordinates.
  • Contract: XML docs only. LinkClicked's summary described Received, and that is corrected. docs/plugin-api.md gains a "Chat links" section.

Not changed

The floating chat windows still show no links (not even a player's name), as before.

Testing

  • New tests: ChatCoordinateLinksTests, plus coordinate and markup cases in RuntimeChatFeedTests, ChatWindowControllerTests (a click raises the coordinate link) and RuntimeAutomationSurfacePluginApiTests.
  • Live-tested against a local ACE server: clicking typed coordinates in said lines, tells and channel lines, and the corpse-location line, sets a plugin's waypoint through PluginChatCoordinateLinkRouter.

https://claude.ai/code/session_01Lm9T9oP2Hi5FEjwsLmXeyN

davidc-smith and others added 3 commits October 14, 2026 15:00
A coordinate pair written in any chat line except combat text ("meet at
42.1N 33.5E", "Your corpse is located at (42.1N, 33.5E).") is now a
COORD:World link, split out by the same rule PluginChatCoordinateParser
reads. A line a plugin posts has its own <COORD:World:...> markup read as
a link; server text is never read as markup, and a plugin line with no
tag keeps its angle brackets.

Clicking a coordinate in the main chat window now raises
IPluginChat.LinkClicked. The window's ChatLinkClicked hook was never
assigned, so until now no click reached a plugin.

Contract: XML docs only (LinkClicked's summary described Received).

Claude-Session: https://claude.ai/code/session_01Lm9T9oP2Hi5FEjwsLmXeyN
…r text

A line with a clickable sender was parsed as tag markup whole, the
speaker's own words included. A player who typed
<COORD:World:0N, 0E>42.1N 33.5E<\COORD> got a green link showing one
place that reported another to every plugin listening on LinkClicked.

What players and the server write now looks as it did before this
branch: the speaker's name is still the tell link, plain coordinates are
not linked, and a COORD tag typed into a message keeps its caption as
plain text in the line colour with nothing behind a click. Only a line a
plugin posted carries coordinate links: its COORD tags and the pairs it
writes in plain text.

A plugin's line now reads only a well-formed <COORD:World:pair> closed by
<\COORD>; any other angle-bracket text ("Press <Ctrl:F>") is shown as
written instead of being swallowed as a tag.

The chat links pairs with the public parser's own matcher instead of a
copy of its pattern, and that pattern no longer matches inside words, so
"10n 20east" is neither read nor linked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…us-line captions

A plugin that reposts what a player wrote (echoing a tell, relaying a
channel) re-armed any COORD tag the player typed, because a plugin's line
is trusted as the plugin's own. PluginChatMarkup.Escape puts a backslash
before every '<'; the plugin-line reader drops that backslash and shows
the '<' as written, never as a tag. Nothing calls it implicitly; the
PostMessage/PostSystemMessage docs and the plugin guide tell plugins to
escape text they did not write.

The name a clicked coordinate is reported with was formatted with the
current culture and kept the sign: "-33,5W" on a Swedish machine. It is
now built once, invariantly, from the absolute values ("42.1N, 33.5W").

A plugin line routed to the status line, which has no links, showed the
raw tag; it now shows the caption only. The plugin surface already sends
that class to the transcript, so this guards the lower-level path.

Doc comments now say only COORD tags are read on plugin lines, the
tagged wording keeps a plugin's line as written, and ParseAll states the
word-boundary rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eriknihlen
eriknihlen merged commit 035c3a1 into eriknihlen:main Oct 19, 2026
eriknihlen added a commit that referenced this pull request Oct 19, 2026
@davidc-smith
davidc-smith deleted the feat/chat-coordinate-links branch October 20, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants