Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ThalissonTMora/shaiya-chat-native-re/llms.txt

Use this file to discover all available pages before exploring further.

Shaiya Core V9 ships six GM notice commands that let privileged users push messages to individual players, specific maps, entire factions, or the whole world. All commands are parsed on the client in GmCommand_Dispatch @ 0x0047FFD0 after a GM-privilege check, then packaged into 0xF90x-series opcodes and forwarded to ps_game.exe, which routes them through a dedicated jump table at 0x004833F4. Understanding the full chain — command syntax, wire layout, server handler addresses, and scope — is required for any emulator aiming at native client compatibility.

Command Overview

CommandNative alias (KR)SyntaxScope / effect
/gmnotice/운영자공지/gmnotice <msg>Global admin notice — orange text banner, all online players
/cnotice/챗공지/cnotice <mapId> <msg>Chat-box notice to a specific map
/wnotice/귓공지/wnotice <player> <msg>Whisper notice to a single named player
/notice/공지/notice <mapId> <msg>System notice type 0 to a specific map
/znotice/맵공지/znotice <mapId> <msg>Zone/map broadcast notice
/bnotice/종족공지/bnotice <빛|어둠> <mapId> <msg>Faction-specific notice (Light or Dark only)
<mapId> is an optional integer parameter. The client extracts it via FUN_0047AAF0, which parses a leading decimal integer from the argument string. If omitted, it defaults to 0.

Packet Wire Layouts

All packets below are C→S (client Game.exe → world server ps_game.exe).

/wnotice — Whisper Notice (0xF908)

Targets a single named player. The target name occupies a fixed 21-byte field (Pattern B/H layout), with an uninitialized tail after the null terminator (see Padding Simulation).
+0x00  u16      opcode = 0xF908
+0x02  char[21] target_player_name   // null-terminated; uninitialized tail bytes
+0x17  u16      unknown              // usually 0x0000
+0x19  u8       msg_len              // strlen + 1
+0x1A  char[]   message_text         // null-terminated
Plaintext size: 0x1A + msg_len

/bnotice — Faction Notice (0xF90A)

Broadcasts to all players whose faction matches faction_id.
+0x00  u16      opcode = 0xF90A
+0x02  u8       faction_id   // 0 = Light (빛), 1 = Dark (어둠)
+0x03  u16      map_id       // extracted via FUN_0047AAF0
+0x05  u8       msg_len
+0x06  char[]   message_text
Plaintext size: 0x0E + msg_len

/gmnotice — Global Admin Notice (0xF906)

No map scope; broadcast is server-wide. The map_id field is absent.
+0x00  u16      opcode = 0xF906
+0x02  u8       msg_len
+0x03  char[]   message_text
Plaintext size: 0x03 + msg_len

Standard Map-Scoped Notices (0xF907, 0xF909, 0xF90B)

/cnotice (0xF907), /znotice (0xF909), and /notice (0xF90B) share the same layout:
+0x00  u16      opcode = 0xF90x
+0x02  u8       unknown_flag   // usually 0x00
+0x03  u16      map_id
+0x05  u8       msg_len
+0x06  char[]   message_text
Plaintext size: 0x0D + msg_len

The /bnotice Parser Constraint

The /bnotice command will only accept literal Korean faction strings hardcoded in Game.exe .rdata:
.rdata VAStringFaction ID
0x0074D6F80 (Light)
0x0074D6F0어둠1 (Dark)
Executing /bnotice light ... or /bnotice dark ... causes the client to call error handler FUN_00423150 and no packet is sent.
English or romanized faction names are not supported by the stock parser. You must type (or paste) the Korean characters directly, or use an IME. Example:
/bnotice 빛 0 Announcement for the Alliance of Light
/bnotice 어둠 0 Announcement for the Union of Darkness

Server-Side Dispatch

Entry Point

Packets with opcodes in the 0xF900 series are recognized at 0x0047509F (cmp eax, 0xF900) in the main packet loop of ps_game.exe, then forwarded to router function 0x00482630.

Jump Table @ 0x004833F4

At 0x004826BA, the router indexes into the jump table to select a per-opcode sub-handler:
OpcodeHandler VAServer behavior
0xF9010x004826C1Target case
0xF9020x004833BEDefault stub (ret 4)
0xF9030x004833BEDefault stub (ret 4)
0xF9040x004828D9Admin-level action
0xF9050x00482A37Admin-level action
0xF9060x00482E53Global /gmnotice broadcast
0xF9070x00482EC0Map-based /cnotice relay
0xF9080x00482FB1Whisper /wnotice — player lookup + target send
0xF9090x004830C7Zone /znotice broadcast
0xF90A0x004831BDFaction-specific /bnotice broadcast
0xF90B0x004832C2System /notice handler
0xF90C0x00482BAAFinal sub-case
Opcodes 0xF902 and 0xF903 map to a ret 4 stub — they are recognized by the jump table but perform no action. Any emulator should silently discard packets for these opcodes.

Validation Rules and Length Limits

CommandFieldConstraintEnforcement
Allmsg_lenServer enforces maximum; client-side strlen used at send timeSub-handler validation
/wnoticetarget_player_name21-byte fixed field, null-terminatedClient copies up to 20 chars + NUL
/bnoticefaction_idMust be 0 or 1Client parser; server broadcasts to matching faction
/bnoticefaction stringMust be Korean or 어둠FUN_00423150 error on mismatch
/cnotice, /znotice, /noticemap_idOptional; defaults to 0 if omittedFUN_0047AAF0 decimal parser

Client Send Functions

CommandC→S OpcodeClient send function
/gmnotice0xF906FUN_005EE240
/cnotice0xF907FUN_005EDF70
/wnotice0xF908FUN_005EDE90
/znotice0xF909FUN_005EE020
/bnotice0xF90AFUN_005EE0D0
/notice0xF90BFUN_005EE190

Emulator Implementation Notes

Mapping these opcodes enables emulators to support fully-native client-side admin notifications without custom hook overlays.
1

Implement /wnotice (0xF908) — targeted send

Intercept 0xF908, extract target_player_name from +0x02, look up the connection, and forward the notice packet directly to that player’s session.
2

Implement /bnotice (0xF90A) — faction filter

Read faction_id from +0x02. Iterate all active sessions and send the notice only to players whose faction byte matches.
3

Implement map-scoped notices (0xF907, 0xF909, 0xF90B)

Read map_id from +0x03. Broadcast the message only to sessions whose current map matches.
4

Implement /gmnotice (0xF906) — global broadcast

No scope filtering. Send to all active connections.
5

Stub 0xF902 / 0xF903

Accept and silently discard — matching the stock ret 4 stub behavior at 0x004833BE.

Build docs developers (and LLMs) love