From RuneWiki
Revision as of 16:19, 9 July 2021 by Pazaz (talk | contribs) (→‎Client Opcodes)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Login Screen

Revision 317 of RuneScape 2 came out around May 5th, 2005, just after Barrows was released.

Welcome Screen
Game World using 319 cache

There is no known 317 cache available -- the popular ones that claim to be 317 are typically 333, 369, or 377. 317 did not have farming, so if you see farming in your skill interfaces, that would be an immediate indicator.

There are 84 client opcodes and 73 server opcodes in this revision.

Reading and Writing Bytes

RuneScape uses a big endian order by default. The original client packet obfuscation process transformed packets. They had their opcode scrambled and their parameters were turned into a mix of big, middle, middle inverse, and little endian with various transformations.

Packets will always start with an unsigned byte. Variable-length packets then have one to two bytes following the opcode that should be the size of the remaining bytes.

There are only a few data types, and nearly all can adjust their endianness and apply transformations.

Data Types

Type Bytes
Byte 1
Word 2
DWord 4
QWord 8
String Variable length, ends in a newline
Base37 8

Data types should be constructed by shifting data an appropriate number of bytes.

Bit masks are used here to access specific bits out of a value and discard

Changing Endianness

Endianness Byte Order
Big Endian 4, 3, 2, 1
Middle Endian 2, 1, 4, 3
Middle-Inverse Endian 3, 4, 2, 1
Little Endian 1, 2, 3, 4

Byte order is shown based off DWord to provide an example, extrapolate for other data types. Word will not have a middle endian.

Applying Transformations

Transformation Read Write
Add byte - 128 byte + 128
Subtract byte + 128 byte - 128
Negate -byte -byte

Only the last byte read (in order) should have the transformation applied to it.


Opcode Purpose
14 Login handshake
15 On-demand
16 Login exchange
18 Reconnection exchange


Client Opcodes

Opcode Name Purpose Type Bytes
0 Keepalive Sent if no other packets have been sent. This notifies the server the connection is still active Fixed 0
3 Client focus Client has lost user's focus Fixed 1
4 Public chat Public chat message Variable Byte N/A
14 Item on Player Item used on another player Fixed 8
16 Item option 3 Item option 3 selected Fixed 6
17 NPC action 3 NPC action 3 performed Fixed 2
18 NPC action 5 NPC action 5 performed Fixed 2
21 NPC action 4 NPC action 4 performed Fixed 2
23 unknown-1 TODO Fixed 6
25 Item on Ground Item Item used on ground item Fixed 12
35 Magic on Object Magic spell used on object Fixed 8
36 anticheat-movement Anti-cheat packet prepended to movement packets when moving large distances Fixed 4
39 Player action 5 Player action 5 performed Fixed 2
40 interface-continue Clicked continue in dialogue interface Fixed 2
41 item-option-2 Item option 2 selected Fixed 6
43 item-action-3 Item option 3 selected Fixed 6
45 player-flagged-data Player flagged, send additional mouse event data Variable Byte N/A
53 item-on-item Item used on another item Fixed 12
57 item-on-npc Item used on NPC Fixed 8
60 interface-name Typed name in "Enter name:" dialogue Fixed 8
70 object-action-3 Object action 3 performed Fixed 6
72 npc-action-2 NPC action 2 performed Fixed 2
73 player-action-3 Player action 3 performed Fixed 2
74 social-ignore-remove Removed player from ignore list Fixed 8
75 item-option-4 Item option 4 selected Fixed 6
77 unknown-2 TODO Variable Byte N/A
78 unknown-3 TODO Fixed 0
79 light-item Menu action 213 Fixed 6
85 anticheat-1 TODO Fixed 1
86 camera-movement Camera moved Fixed 4
87 item-option-5 Item option 5 selected Fixed 6
95 privacy-options Privacy options changed Fixed 3
98 world-action-movement Player performed action, move to target Variable Byte N/A
101 interface-design Player finished designing character Fixed 13
103 chat-command Player sent chat command Variable Byte N/A
117 item-action-2 Item action 2 performed Fixed 6
120 interface-flashing-tab-clicked Flashing tab clicked Fixed 1
121 region-loaded Sent after a region loads successfully Fixed 0
122 item-option-1 Item option 1 selected Fixed 6
126 chat-private Player sent private chat to another player Variable Byte N/A
128 player-action-1 Player action 1 performed Fixed 2
129 item-action-4 Menu action 431 Fixed 6
130 interface-closed Closed interface window Fixed 0
131 magic-on-npc Magic spell casted on NPC Fixed 4
132 object-action-1 Object action 1 performed Fixed 6
133 social-ignore-add Added player to ignore list Fixed 8
135 item-action-5 Item action 5 performed Fixed 6
136 anti-cheat-2 TODO Fixed 0
139 player-action-4 Player action 4 performed Fixed 2
145 item-action-1 Item action 1 performed Fixed 6
148 unknown-4 TODO Fixed 0
150 unknown-5 TODO Fixed 0
152 anti-cheat-3 TODO Fixed 1
153 player-action-2 Player action 2 performed Fixed 2
155 npc-action-1 NPC action 1 performed Fixed 2
156 unknown-6 TODO Fixed 6
164 world-movement Player clicked tile Variable Byte N/A
165 unknown-7 TODO Variable Byte N/A
181 magic-on-ground-item Magic spell casted on ground item Fixed 8
183 anti-cheat-4 TODO Fixed 3
185 interface-button Interface button clicked Fixed 2
188 social-friend-add Added player to friend list Fixed 8
189 anti-cheat-5 TODO Fixed 1
192 item-on-object Item used on object Fixed 12
200 anti-cheat-6 TODO Fixed 2
202 idle-timer Player idle for too long, notify server Fixed 0
208 interface-amount Typed value in "Enter amount:" dialogue Fixed 4
210 client-running-as-frame TODO Fixed 4
214 item-move Item moved to another slot Fixed 7
215 social-friend-remove Removed player from friend list Fixed 8
218 report-abuse Reported player Fixed 10
226 unknown-8 TODO Variable Byte N/A
228 object-action-4 Object action 4 performed Fixed 6
230 anti-cheat-7 TODO Fixed 1
234 object-action-5 Object action 5 performed Fixed 6
236 pickup-ground-item Picked up ground item Fixed 6
237 magic-on-item Magic spell casted on item Fixed 8
238 unknown-9 TODO Fixed 1
241 mouse-clicked Mouse clicked event Fixed 4
246 anti-cheat-8 TODO Variable Byte N/A
248 minimap-movement Player clicked minimap Variable Byte N/A
249 magic-on-player Magic spell casted on player Fixed 4
252 object-action-2 Object action 2 performed Fixed 6
253 ground-item-action Ground item action performed Fixed 6

Server Opcodes

There are 73 opcodes in this revision to support. Not all are necessary, some servers only use half at most, but if you are going for accuracy you should aim to implement as many as you can.

Opcode Name Purpose Type Bytes
1 reset-animations Stop all visible NPC/Player animations Fixed 0
4 interface-graphic Display a stationary graphic on a tile in the world Fixed 6
8 interface-model Display a model on an interface Fixed 4
24 interface-sidebar-flash Flash a sidebar icon Fixed 1
27 interface-amount Display "Enter amount:" dialogue interface Fixed 0
34 interface-item-slot Add items to specific slots on an interface Fixed N/A
35 camera-shake Shake the camera Fixed 4
36 interface-setting Configure an interface setting Fixed 3
44 ground-item-add Add a ground item Fixed 5
50 social-add-friend Add a friend and set their online status Fixed 9
53 interface-item-array Add items into sequential slots on an interface Variable Word N/A
60 process-group-packets Can process opcodes: 84, 105, 215, 156, 160, 147, 151, 4, 44, 101, and 117 Variable Word N/A
61 display-multi-icon Display the multi-combat zone icon Fixed 1
64 ground-item-remove-all Remove all ground items directly under the player Fixed N/A
65 update-npcs Update local NPCs Variable Word N/A
68 interface-setting-reset Reset interface settings Fixed 0
70 interface-xy Display an interface at X, Y on the screen Fixed 6
71 interface-sidebar Set a sidebar to load a specific interface Fixed 3
72 interface-items-clear Clear all items from an interface Fixed 2
73 player-region Load a region around the player Fixed 4
74 music Begin playing a MIDI song Fixed 2
75 interface-npchead Display a NPC head on an interface Fixed 4
78 clear-walking-queue Clear walking queue Fixed 0
79 interface-scrollbar-position Scroll on an interface to a specific position Fixed 4
81 update-players Update local Players Variable Byte N/A
84 ground-item-update Update a ground item Fixed 6
85 player-position Update the player's local position Fixed 2
87 interface-setting-int Longer form of opcode 36, used when value >255 Fixed 6
97 interface Display an interface Fixed 2
99 player-minimap Set the minimap state Fixed 1
101 object-remove Remove an object Fixed N/A
104 set-player-interaction Add a new player interaction; configure right-click menu entry Variable Byte N/A
105 sound-location Play a sound if the player is in a specific boundary area Fixed 4
106 interface-sidebar-focus Change sidebar focus Fixed N/A
107 camera-reset Reset camera after cutscene Fixed 0
109 logout Disconnect gracefully Fixed 0
110 player-energy Update run energy % Fixed 1
114 system-update System update notification with countdown timer Fixed 2
117 projectile Create a projectile Fixed 15
121 music-queue Queue a song to play next FIxed 4
122 interface-color Set an interface color Fixed 4
126 interface-text Change text on an interface Variable Word N/A
134 player-skill Update a skill's experience and level Fixed 6
142 interface-inventory Display an inventory overlay on an interface Fixed 2
147 player-to-object Transform player into an object Fixed N/A
151 object-add Add an object Fixed N/A
156 ground-item-remove Remove a ground item Fixed 3
160 object-add-animated Add an animated object Fixed N/A
164 interface-chatbox Display an interface over the chatbox Fixed 2
166 camera-rotate Rotate the camera Fixed 6
171 interface-hover Set an interface to hide until hovered over Fixed 3
174 sound Play a sound Fixed 5
176 interface-welcome Display the welcome interface Fixed 10
177 camera-cutscene Activate the cutscene camera Fixed 6
185 interface-playerhead Display the player head on an interface Fixed 2
187 interface-name Display "Enter name:" dialogue interface Fixed 0
196 private-message Receive a private message Variable Byte N/A
200 interface-animate Play an animation on an interface Fixed 4
206 interface-privacy Set chat privacy settings Fixed 3
208 interface-walkable Display a walkable interface (does not close when you move) Fixed 2
214 social-add-ignore Add a list of ignored players Variable Short N/A
215 ground-item-add-other Add a ground item if the player who dropped it is not the local player Fixed N/A
218 interface-dialogue Display a dialogue interface Fixed 2
219 interface-clear Clear all closable interfaces from the screen (ignores walkable) Fixed 0
221 social-status Set friend list / ignore list tab status Fixed 1
230 interface-model-zoom Display a zoomed and/or rotated model on an interface Fixed 8
240 player-weight Update weight Fixed 2
241 player-region-construct Load a constructed region (8x8) around the player Variable Short N/A
246 interface-item-model Display an item model on an interface Fixed 6
248 interface-child Display an interface on an interface Fixed 4
249 player-info Set membership status and player list ID. Membership status is only used to determine how many friends you can add. Fixed 3
253 send-message Send a server message, trade request, duel request, or challenge request Variable Byte N/A
254 mob-hint Set a hint icon over an NPC or player Variable Byte N/A

Player Updating

The player updating process consists of 4 parts:

  • a. Our player movement updates
  • b. Other player movement updates
  • c. Player list updating
    • c.a. Apperance updating
    • c.b. Location updating
  • d. Player update block flag-based updates

Our player movement updates

The client begins by reading 1 bit. This bit tells the client whether or not it is currently updating 'our player', or the player the client is controlling.

If it's not updating our player, it exits and goes onto step b. If it is, it then reads 2 bits. The value is called the movement update type.

There are 4 recognized movement update types:

  • Type 0 basically tells the client there is nothing to update for our player, just add its index to the local updating list.
  • Type 1 tells the client you moved in one direction. The client reads 3 bits, which represents the direction you moved in, and then 1 bit, which states whether further update is required. If so, it adds it to the updating list. This is used in walking.
  • Type 2 functions in much of the same way as its previous, only this time it reads two 3 bit values. The first represents the player's last direction, and the second it's current direction. Trailing behind it is also the 1 bit 'update required' flag as type 1. This is used in running.
  • Type 3 on the other hand is different. It reads in 2 bits which represents our player's plane, or its level of height, in the game world.

Only 0-3 inclusive are appropriate planes supported by the client. It then reads 1 bit, which describes whether or not to clear the awaiting-waypoint queue, basically to stop client from further queued stepping, such as used in teleporting. After this, it reads the 'update required' bit, and checks to see if further update is required. Directly after, it reads two 7 bit quantities, representing the new relative X and relative Y coordinates of our player to our current map region's origin. It then sets our players position to the plane, x, and y positions as told to.

Other player movement updates

The client begins by reading an 8 bit value telling the client how many players there are to update. It then enters a loop for each player there is to update.

Inside this loop, the client reads 1 bit. This is the movement update required flag. If the flag is 0, it sets the current updating player's last update cycle time to the current game logic loop cycle time, and adds the player to the local player list. If the flag is not 0, it then reads the movement update type, which is a 2 bit quantity.

The following known types are:

  • 0, the client updates the current player's last update cycle time, adds the current player to the local player list, and adds it to the updating list.
  • 1, the client updates the current player's last update cycle time and adds the current player to the local player list as well, but also reads in 3 bit quantity. This represents the current player's direction it walked to. It then reads the a 1 bit value that specifies whether or not to add the player to the updating list.
  • 2, the client does the exact same thing as the type 2 update, except it reads in two of the 3 bit quantities. The first represents the current player's last direction, and the second its current direction running.
  • 3, the client queues to remove the player from the list of players to be updated but it is possible such as in the instances for when players teleport to add them back to the list of players to be updated during the populate update.

Player list updating

The next step in the player updating procedure is the player list updating, or where the client recieves data on every player in its local list, such as appearance and location relative to ours. The client loops through a process for each player in the updating.

The client reads an 11 bit quantity from the buffer, which is the next player in the updated list to be informed about. The clietn then checks if it has a cached buffer for that player's updating, and if it does, it updates the player appearance.

Appearance updating

Appearance updating starts off by first reading an unsigned byte that represents the current player's gender. Then it reads another unsigned byte that represents the player's over-head icon id. This is used with prayer icons above heads. Next, a loop occurs 12 times to read equipment data.

In the loop, the client reads an unsigned byte that is the equipment slot's item id high byte. If it is 0, the player's equpment slot has no item. If it is not 0, another unsigned byte is read the merged with the previous to create the equipment's item id. If the id is 65535 (written as a -1 signed short), then the player's appearance is that of an NPC. The client reads in an unsigned short representing the NPC's id and sets the player's definition to that NPC's.

After the equipment loop, it loops 5 times, once for each type of coloured body part. In each loop, the client reads an unsigned short and assigns it as the color of the current loop idx (which represents the body part).

Finally, after the color loop, the client reads 7 unsigned shorts representing animation indices; the animations belong to:

  • Standing still
  • Turning while standing
  • Walking
  • Turning around (backwards)
  • Turning a quarter-way clockwise
  • Turning a quarter-way counter clockwise
  • Running

After these animation indices are read, a long representing the player's name is read, an unsigned byte representing the combat level, and an unsigned short representing the players skill level (for things where players arent ranked by levels, such as where it states <player name> (skill <skill>) as an action menu text).

Location updating

After the appearance updating, the client starts to update that player's location relative to our player. The player is added to the local player list and it's last update cycle time. It then reads a 1 bit quantity that defines whether or not the client has a chunk in the player update block list. If it does, it adds it to the updating list. The next bit states whether or not to discard the awaiting-waypoint queue, such as when teleporting. It then reads to 5 bit values that determine the players relative X and Y coordinates to our player. The local player area is 16x16, so if the delta of the two coordinates is > 15, 32 is subtracted from it to signify the player is on the other side of ours. The client then sets the player's position, ending the player list updating process.

Update block flag-based updating

The following is what most people think of when they say 'update mask' and 'update flag'. This process of the updating procedure is very important. It begins with looping through ALL players in the local player update list, reading an unsigned byte which from now on will be called the update flag. All further updates are seen to be 'included' by comparing a bitwise mask to this flag. If the flag has the bits for 0x40 all on, this signifies that the flag was too large for a simple unsigned byte and reads in another unsigned byte, which it uses as the upper unsigned byte, therefore the update flag is an unsigned little-endian short. The client then passes off the data to a helper method which processes all updates this flag signifies.

Inside this method, many different bitwise masks are compared to the player's flag, and if the mask is set, logic is performed. These masks are frequently called update masks. A list of player update masks are below:

  • 0x400: The 0x400 mask is used to update the player so they appear to be asynchronously animating and walking. This mask is often used for the Agility skill. The data associated goes in order of: byte (type C) which is the first location's X coordinate value, byte (type S) which is the first location's Y coordinate value, byte (type S) which is the second location's X coordinate value, byte (type C) the second location's Y coordinate value. After the locations are written, there is a required movement speed which is written as a short which marks how fast to move from position 1 to position 2. Another short (type A) is written as the movement speed going from position 2 to position 1. Finally one byte is written to end the mask block, which marks the direction.
  • 0x100: The 0x100 mask is responsible for player graphics updating. The data associated is a little-endian unsigned short which represents the graphics id, and an int which is the graphics delay.
  • 0x8: Animations are handled by the 0x8 mask. The payload for this update is a little-endian unsigned short that is the animation id, and an unsigned inversed byte (Special C) which states the animation's delay.
  • 0x4: The beloved 0x4 mask takes care of forced player text that is only displayed above the player's model. The only data associated with this is a jagex ASCII string with a terminator of 10.
  • 0x80: Unlike the previous, the 0x80 mask handles normal player chat text. The client will read a little-endian unsigned short which holds chat text attributes. It holds the text color and chat effects. Next, the client reads an unsigned byte which states the player's priveleges (normal player, player moderator, moderator, staff) to give the chatter's name a crown. Right behind it trails an unsigned inversed byte that gives chat text length in bytes. Trailing afterwards is dictionary-compressed chat text. All chat text characters become indexes into a valid character table and are written as nibbles (4 bit quantities).
  • 0x1: Updating the player's current interacting-entity is done via mask 0x1. The entity id is written as a little-endian unsigned short.
  • 0x10: The 0x10 mask updates appearance of the player in exact same way as in updating player list. Only difference is that appearance is updated from a set-sized buffer filled from the current buffer. An unsigned inversed byte is read first which describes appearance buffer size, and the buffer is filled.
  • 0x2: Facing coordinate updating is signified by the 0x2 mask. The player's facing-towards X and Y are set to read values; specifically, an unsigned lower-inverted short and little-endian unsigned short, respectively.
  • 0x20: Notifying client's of a player's health is done via the 0x20 mask. The hitpoint damage done to the player is sent as an unsigned byte, followed by the hit type as a positive inverted byte. The player's current and max health are read as an unsigned inverted byte and unsigned byte, respectively.
  • 0x200: The 0x200 mask acts in the same way as the 0x20 mask and is most likely associated with special attacks from weapons that have the ability to hit twice at the same time. Hitpoint damage is an unsigned byte, the hit type an unsigned inverted byte, and the current and maximum health being an unsigned byte and unsigned inverted byte, respectively.

After the client processes every single player in the update player list, it ends player updating.

Embedded Applet

The client was embedded in a cab archive that was called by a loader jar on the Play page. You can embed a client jar without the loader assuming you have the default parameters defined. Applets will call init() instead of main(args).

Music and sounds were played by some JavaScript code interacting with the signlink class. Both midi and wav files were played using a <bgsound> tag and setting the src attribute. bgsound was only supported in Internet Explorer.

Getting the client to load as an applet requires you to use Internet Explorer, or a 32-bit Firefox version up to 52.0esr. Firefox did not allow NPAPI plugins on 64-bit installs. You may encounter a lot of Java security warnings/policies that have to be disabled.