Separate retail client actions, ACE server commands, and ordinary chat at the shared router. Port lifestone/lif/ls from the named retail registry through a typed App controller to game action 0x0063, keep unknown verbs on ACE Talk, and cover both UI backends plus exact outbound bytes. Co-Authored-By: Codex <codex@openai.com>
3.5 KiB
3.5 KiB
Retail client-command routing and lifestone recall
Date: 2026-07-13
Scope
This note records the retail path used for chat-bar commands and the first
ported client command, @lifestone (@lif, @ls). It deliberately separates
commands the retail client executes from ACE administrator commands that the
server consumes as Talk text.
Named-retail sources
ChatInterface::ProcessCommand @ 0x004F5100ClientCommunicationSystem::OnChatCommand @ 0x00581320ClientCommunicationSystem::DoLifestone @ 0x0056FC70ClientCommunicationSystem::HelpLifestone @ 0x00578500CM_Character::Event_TeleToLifestone @ 0x006A1B90- Command-table construction at
0x005838F7through0x00583A2B - Alias data at
0x007E17E4(ls),0x007E17E8(lif), and0x007E17EC(lifestone)
Source file:
docs/research/named-retail/acclient_2013_pseudo_c.txt.
Cross-references
- ACE consumes server/admin commands such as
@cifrom the Talk game action. That is a different path from retail client commands. - acdream already has the exact lifestone action builder in
AcDream.Core.Net.Messages.InteractRequests.BuildTeleToLifestone. - holtburger's chat parser is useful for chat aliases, but the named retail command registry is authoritative for client-command ownership and aliases.
Retail pseudocode
Chat submission
ChatInterface.ProcessCommand():
text = read chat input
communicationSystem.OnChatCommand(text, currentCommandSource)
append text to input history
ClientCommunicationSystem.OnChatCommand(text, source):
allow plugin to inspect/replace the input
remember the current source and trimmed command line
if first character is '/':
replace it with '@'
return DoCommand()
if first character is '@':
return DoCommand()
if first character denotes an emote shortcut:
rewrite to '@emote ...'
return DoCommand()
otherwise:
route as ordinary speech according to the current talk focus
Lifestone command registration
register "lifestone" -> DoLifestone, HelpLifestone
register "lif" -> DoLifestone, HelpLifestone
register "ls" -> DoLifestone, HelpLifestone
The registry uses case-insensitive command keys.
Lifestone command execution
ClientCommunicationSystem.DoLifestone(argumentCount, arguments):
if argumentCount == 0:
CM_Character.Event_TeleToLifestone()
else:
add the command's usage/error text to the chat scroll
return handled
CM_Character.Event_TeleToLifestone():
sequence = Proto_UI.GetNextUICounter()
packet = OrderHdr(gameActionEnvelope, sequence, payloadLength = 12)
packet.action = 0x0063
sent = Proto_UI.SendToWeenie(packet)
if not sent:
Proto_UI.UICounterFailedSend(sequence)
return sent
Port contract
- Both
/and@prefixes are accepted for retail client commands. lifestone,lif, andlsmatch case-insensitively.- The command accepts no arguments. Invalid arguments display usage locally and send neither chat nor a game action.
- A valid command publishes a typed client action. The App layer executes it
through
WorldSession; UI code never touches the network session. - Unknown command verbs remain server commands:
/foois canonicalized to@fooand sent through Talk so ACE remains authoritative for its command set. - The wire body is the existing 12-byte game-action envelope with opcode
0x0063; no command text is sent for lifestone recall.