PDA

View Full Version : The Player Updating Procedure



Method
August 20th, 2010, 20:27
The Player Updating Procedure [570+]

Player updating in clients after revision 570 consists of two major parts:

General updating (movement, local player list)
Local player updating
External player updating
Flag-based appearance updating


This update system is fairly different from the older updating procedure and still isn't fully understood, but this document should provide some clarification and guidance for implementing player updating on your server.

General updating

The client processes most of the updating in this part of the procedure. It is split up into two parts, local player updating and external player updating, each of which loop twice through their respective players. Of note in this process is the ability to "skip" players when updating. To see whether or not a player will be updated, the client reads a one bit flag. If it is not set, the client reads a two bit quantity indicating the size of the number of players to be skipped, which is then read as a five, eight, or eleven bit number. If the skip number is read during one of the loops, the client flags the current player as being skipped and continues to do so for the amount sent by the server. If the update flag is set, the player will be updated. This process then repeats until the end of the loop.

Local player updating processes players who were not skipped during the last update first and players who were skipped second, while external player updating does this the other way around.

Local player updating

When a local player is updated, a one bit flag is read to indicate whether or not the player requires flag-based updating after it is done being updated. After that, a two bit "type" value is read to signify what sort of update needs to be done to the current player. The available types are:

0
1
2
3

When moving, if the update flag is not set, the client simply changes the player's position. However, when this flag is set, more data needs to be sent in the flag-based updating part. This will be discussed later.

Type 0 is used to remove a player from the local list and add it to the external player list. If the "update" flag was set, however, the player is not removed from the local list and is just added to the list of players needing flag-based updating. In this case the player receives no movement update. If the update flag was not set, the player is transfered from the local list to the external list and a one bit flag is read to determine if the player is to be updated by the external player update method. If so, it is updated immediately.

Type 1 is used in walking. A three bit value containing the direction of movement is read and used to determine the player's next step.

Type 2 contains similar data to type 1, except four bits are read instead of three. This is used for running.

Type 3 has two different cases, both of which are used for teleporting or other forms of instantaneous movement. A one bit flag is read to determine whether or not the player is changing regions, so the client knows what data to expect.

If the player is not switching regions a 12 bit packed integer is read. The highest two bits represent the offset in the player's plane. The next five bits represent the delta x coordinate while the other five bits represent the delta y coordinate. It is important to note that an x or y value less than zero needs to have 32 added to it before sending the data to the client. This type is used for teleporting within the region.

If the player is switching regions, a 30 bit packed integer is read instead. As with the other type, the high two bits contain the plane offset. However, the x and y offsets are fourteen bits each, allowing for a much wider range of coordinate values. This is believed to be used for teleporting the local player to another region, but has the capability to be used for other players as well. Perhaps there are features planned to use this functionality for other players in the future.

External player updating

Once local player updating is done, external player updating can begin. The server keeps the client informed of regional changes in player movement outside of the local area. Like in local player updating, a two bit "type" value is read to see what update needs to be done. The available types are:

0
1
2
3

Type 0 is the counterpart of local player updating's type 0 and is used to add a player to the local list from the external list. First, a bit is read to see if the external player needs its regional location updated before it is added to the list. If it does, the method is called again and one of the other types are used to update the player's regional location before adding it to the local player list. After this, two six bit values representing the player's delta x and delta y values from the start of the region the player is in are read. Next, a one bit "update" flag is read to see if the player requires any further flag-based updates. If a player is updated using this update type, it will be counted as having been skipped in the current update.

Type 1 is used to inform the client of a change to an external player's plane. Two bits are used to represent the offset from the stored plane value.

Type 2 is similar to the movement change types in local player updating. It contains a 5 bit packed integer containing a plane offset in the high two bits and the direction of movement in the low three bits. This type is used for informing a client about an external player moving to a region adjacent to its current one.

Type 3 is similar to type 2, except it is used for clients that do not move to an adjacent region. An 18 bit packed integer is read containing the plane offset as the high two bits and the regional x and y offsets as the next 8 bits each.

Flag-based appearance updating

As is the case with the older updating system, appearance updating is done through a flag-based updating system. A flag is read from the server, containing the update flag data. The data is then compared with a number of bitwise masks to see if an update is required. If more data than can be stored in an unsigned byte is required, another byte is read, making the flag a little endian short. If even more data is required, another byte is read, making the flag a little endian medium integer. These changes to the data are indicated through specific bit masks that change from revision to revision.

There are over 15 available updates, including:

Two different graphic types
Animation
Primary and secondary damage
"Force movement"
Movement type change
Temporary movement type change
Chat message
General appearance update (resend player information including gender, equipment, body colors, name, etc.)
Character target (for npc/player interaction)
Orientation change

The graphic updates both read a short, an int, and a byte. Respectively, they contain the id, settings (delay and height), and possibly orientation.

The animation update reads a short and a byte for the id and delay.

Primary and secondary hit updates read a smart for damage and a byte for the type of hit. The primary hit update also reads a byte containing the player's hitpoint ratio, used for drawing the health bar above the player's head.

The force movement update, used in agility and a few other instances, reads four bytes representing the starting and ending coordinates of the movement, two shorts representing delays from the current game loop cycle that are used to calculate the speed of movement, and a byte for the player's orientation when moving.

The movement type updates are used to signify how the player is moving currently. Both types read a byte as the movement type. The first type stores the value in the client so it remembers the player's last movement type. The second type is used if the player needs to temporarily move in a different way (for example to walk the last step in running movement). This temporary value, if set, overrides the cached value in the client. A value of 1 is used for walking while 2 is used for running. If the value 127 is sent for the temporary movement type, the player is teleported to the position sent in the movement update. The actual position updating occurs at the end of the flag-based updating for a particular player.

The chat message update reads a null-terminated string that represents a message to be displayed over the player's head. Unlike the old player updating procedure, the message attributes are not sent along with this update.

The general appearance update reads a byte to determine the length of the data and then reads that amount of bytes. It is used to update gender, head icons, equipment, body colors, name, combat level, and other player-specific values.

Both the character target and orientation change updates change the direction the player faces. The first type reads a short containing the local index of the npc or player to interact with. If a player is to be interacted with, the player's index needs to have 32768 added to it before being sent to the client. The second type reads a short representing the new orientation for the player.

There are a few update types I have not figured out yet, including one that displays a different minimap dot for the player. If you have any information on the ones I missed, feel free to let me know. Thanks to super_ for his documentation on the previous protocol and Graham for his documentation on this one.

Arista
August 30th, 2010, 22:05
Nice, but you should really make a easier to read list than a bunch of paragraphs.

P r 0 tank
August 30th, 2010, 22:22
Thats alot of reading to do :)

Trey
August 31st, 2010, 00:12
Nice, but you should really make a easier to read list than a bunch of paragraphs.

I lol'd.

Arista
August 31st, 2010, 00:46
I lol'd.

oRly, he made it too long, if you look at the documentation found by Graham & blake you would see that there is a short and easy-to-read description which states the main product of the item.

except for the STATES of the player update procedure 0-4, which he done well....

so next time think before saying "I lol'd" .... newfags these dayz

Trey
August 31st, 2010, 00:49
oRly, he made it too long, if you look at the documentation found by Graham & blake you would see that there is a short and easy-to-read description which states the main product of the item.

except for the STATES of the player update procedure 0-4, which he done well....

so next time think before saying "I lol'd" .... newfags these dayz

I lol'd harder.

Cart
August 31st, 2010, 00:51
oRly, he made it too long, if you look at the documentation found by Graham & blake you would see that there is a short and easy-to-read description which states the main product of the item.

except for the STATES of the player update procedure 0-4, which he done well....

so next time think before saying "I lol'd" .... newfags these dayz

TL;Dr version: teaching.

Aaron
August 31st, 2010, 00:52
Eh, Nice tutorial, Involves alot of brain work but eh, Not everyone is like me

Arista
August 31st, 2010, 00:55
I lol'd harder.

Dumbass.


TL;Dr version: teaching.

Making a small but accurate list, is teaching to the mind.


Eh, Nice tutorial, Involves alot of brain work but eh, Not everyone is like me

All you need to do is observe the packets Client -> Server and send them back to you as a description

system.out.println("PACKET triggered: "+pkttype);

when triggered. then you can just figure it out on the way.

Trey
August 31st, 2010, 00:57
All you need to do is observe the packets Client -> Server and send them back to you as a description

system.out.println("PACKET triggered: "+pkttype);

when triggered. then you can just figure it out on the way.
Once you figure out what's being sent when, the easiest way to figure out what is actually being sent is just to use the client source code. Usually if you can narrow it down to knowing what should happen, understanding and refactoring the code in the client is easy.

nd ur cewl, mr.rebel.

Trey
August 31st, 2010, 01:38
why so hostile mayne?

I'm not hostile. I just thought it was funny that you criticized a well structured teaching tutorial (more like documentation) for having too many paragraphs, then you proceeded to insult me and make me cry.

Method
August 31st, 2010, 01:44
Unfortunately, Arista, the player update packet isn't quite as simple as the rest of the packets. Describing it in a "list" would be fairly silly.

Faab234
August 31st, 2010, 07:13
Nice job Method.

[I'm]_[Not]_[Caelum]
September 1st, 2010, 07:57
so basically put(i already knew this BTW from when i wrote my gpi ages ago), gpi contains 5 loops, loop 1, is for steps 2-end, loop 2, step 1, loop 3, adding players etc, loop 4, basically the same as loop 3, though im not 100% sure really, and loop 5 contains the sending of masks.

Graham_
September 1st, 2010, 13:11
_[Not]_[Caelum];100879"]so basically put(i already knew this BTW from when i wrote my gpi ages ago), gpi contains 5 loops, loop 1, is for steps 2-end, loop 2, step 1, loop 3, adding players etc, loop 4, basically the same as loop 3, though im not 100% sure really, and loop 5 contains the sending of masks.

I guess you could put it like that, however, most people group the first four together as they are similar and treat sending the masks as an entirely different thing, as Method has done here.

Also, for people who hear them being called 'nsn's, nsn0-3 are the exceptions through when the skip number is not zero. Therefore nsn might stand for 'non-zero skip number'.