Summary
Cosmetic nit, follow-up to #199 (PR #201, round 2 — commit 015fe9b): on the man0l1 Sisipu escort ("Treasures of the Main", Limsa Lominsa MSQ #2), the ambush announcements in the General log now carry the mob name — but with wrong formatting:
- Actual:
Ankle Biter: is engaged. / Ankle Biter: is defeated.
- Expected:
Ankle Biter is engaged. / Ankle Biter is defeated.
The name renders as a chat-style sender prefix (Ankle Biter: ), while the row's inline <displayName> token still resolves blank — note the double space after the colon: the line is "Ankle Biter:" + " " + "<blank> is engaged.".
(Screenshot from the 2026-07-05 ~18:06 PT playtest session shows both lines in the General log; drag-drop available from the reporting session. The same screenshot incidentally confirms two #199 round-2 fixes working live: "The target is too far away." feedback in the Battle log, and EXP chains paying out.)
Where this comes from
Round 2 of PR #201 switched the engage/defeat sends in scripts/lua/content/SimpleContentMan0l101.lua from
owner:SendGameMessage(GetWorldMaster(), TEXT_MOB_ENGAGED, 0x20, mob.actorId) -- rendered " is engaged." (blank subject)
to
owner:SendGameMessageLocalizedDisplayName(GetWorldMaster(), TEXT_MOB_ENGAGED, 0x20, ANKLE_BITER_DISPLAY_ID) -- ANKLE_BITER_DISPLAY_ID = 3205603
riding the DispId-sender wire family (0x0161–0x0165, mirror of pmeteor Player.SendGameMessageDisplayIDSender). Text rows: TEXT_MOB_ENGAGED = 30120, TEXT_MOB_DEFEATED = 30121 (scripts/lua/quests/man/man0l1.lua:174-175, decoded from the client text-sheet DAT; byte-identical dup rows 30122/30123/30125 exist as fallbacks — see the escort-leg notes).
What the live test established about the client's semantics: for the DispId-sender family the client renders the display-name id as the message sender ("Ankle Biter: …"), exactly like pmeteor's only in-tree usage (PopulaceCaravanGuide.lua:64 — SendGameMessageDisplayIDSender(npc, 6, MESSAGE_TYPE_SAY, npc.displayNameId), a say-line where a sender prefix is correct). It does not feed the in-row <displayName> token — that token's subject comes from somewhere else, still unidentified.
So we've had two wrong param plumbings in a row for rows 30120/30121:
| Send |
Rendered |
runtime mob.actorId as LuaParam (pre-round-2) |
" is engaged." (blank subject, no prefix) |
| displayNameId 3205603 via DispId-sender (round 2) |
"Ankle Biter: is engaged." (prefix + blank subject) |
Fix directions (needs a small RE probe)
- Find what actually feeds
<displayName> in rows 30120/30121. Candidates, cheapest first:
- Plain
SendGameMessage(GetWorldMaster(), 30120, 0x20, <param>) with the displayNameId (3205603) as the LuaParam instead of the runtime actor id — i.e. the subject may be a name-sheet-id param, not a DispId sender. (The pre-round-2 attempt passed a runtime actor id, which is a different numeric space; a static name-sheet id in the param slot was never tried.)
- The LuaParam type nibble may matter: the client may only resolve the token from an actor-id-typed param (pmeteor
LuaUtils distinguishes them) rather than a plain Int32. Worth testing mob.actorId marshalled as an actor-reference param if the binding supports it.
- Try the dup rows 30122/30123/30125 — byte-identical text, but their param-decode tables may differ.
- Check the log type. Retail's equivalent " is engaged/defeated" lines are guildleve-content messages; the leve log type is
0x23 (MESSAGE_TYPE_LEVE), not 0x20. The client formats sender prefixes per log type — the right type may both drop the prefix and enable token substitution.
- Ground truth: grep the retail pcaps (
ffxiv_traces/*.pcapng, 56 plaintext captures) for textId 30120/30121 (LE 0x75A8/0x75A9) or the leve equivalents — one retail hit gives the exact packet family, log type, and param bytes to mirror. Alternatively decode the 30120 row's param-type table from the client DAT (the row text itself was already recovered via the XOR-0x73 cell decode).
- Whatever wins, drop the sender-prefix DispId send — the prefix is wrong for a system/duty line regardless.
Acceptance
General log during the escort ambushes reads exactly:
Ankle Biter is engaged.
Ankle Biter is defeated.
(no sender prefix, no double space, subject filled), for both the player-engaged and Sisipu-engaged waves.
Summary
Cosmetic nit, follow-up to #199 (PR #201, round 2 — commit
015fe9b): on the man0l1 Sisipu escort ("Treasures of the Main", Limsa Lominsa MSQ #2), the ambush announcements in the General log now carry the mob name — but with wrong formatting:Ankle Biter: is engaged./Ankle Biter: is defeated.Ankle Biter is engaged./Ankle Biter is defeated.The name renders as a chat-style sender prefix (
Ankle Biter:), while the row's inline<displayName>token still resolves blank — note the double space after the colon: the line is"Ankle Biter:" + " " + "<blank> is engaged.".(Screenshot from the 2026-07-05 ~18:06 PT playtest session shows both lines in the General log; drag-drop available from the reporting session. The same screenshot incidentally confirms two #199 round-2 fixes working live: "The target is too far away." feedback in the Battle log, and EXP chains paying out.)
Where this comes from
Round 2 of PR #201 switched the engage/defeat sends in
scripts/lua/content/SimpleContentMan0l101.luafromto
riding the DispId-sender wire family (0x0161–0x0165, mirror of pmeteor
Player.SendGameMessageDisplayIDSender). Text rows:TEXT_MOB_ENGAGED = 30120,TEXT_MOB_DEFEATED = 30121(scripts/lua/quests/man/man0l1.lua:174-175, decoded from the client text-sheet DAT; byte-identical dup rows 30122/30123/30125 exist as fallbacks — see the escort-leg notes).What the live test established about the client's semantics: for the DispId-sender family the client renders the display-name id as the message sender ("Ankle Biter: …"), exactly like pmeteor's only in-tree usage (
PopulaceCaravanGuide.lua:64—SendGameMessageDisplayIDSender(npc, 6, MESSAGE_TYPE_SAY, npc.displayNameId), a say-line where a sender prefix is correct). It does not feed the in-row<displayName>token — that token's subject comes from somewhere else, still unidentified.So we've had two wrong param plumbings in a row for rows 30120/30121:
mob.actorIdas LuaParam (pre-round-2)" is engaged."(blank subject, no prefix)"Ankle Biter: is engaged."(prefix + blank subject)Fix directions (needs a small RE probe)
<displayName>in rows 30120/30121. Candidates, cheapest first:SendGameMessage(GetWorldMaster(), 30120, 0x20, <param>)with the displayNameId (3205603) as the LuaParam instead of the runtime actor id — i.e. the subject may be a name-sheet-id param, not a DispId sender. (The pre-round-2 attempt passed a runtime actor id, which is a different numeric space; a static name-sheet id in the param slot was never tried.)LuaUtilsdistinguishes them) rather than a plain Int32. Worth testingmob.actorIdmarshalled as an actor-reference param if the binding supports it.0x23(MESSAGE_TYPE_LEVE), not0x20. The client formats sender prefixes per log type — the right type may both drop the prefix and enable token substitution.ffxiv_traces/*.pcapng, 56 plaintext captures) for textId 30120/30121 (LE0x75A8/0x75A9) or the leve equivalents — one retail hit gives the exact packet family, log type, and param bytes to mirror. Alternatively decode the 30120 row's param-type table from the client DAT (the row text itself was already recovered via the XOR-0x73 cell decode).Acceptance
General log during the escort ambushes reads exactly:
(no sender prefix, no double space, subject filled), for both the player-engaged and Sisipu-engaged waves.