Small tweaks to clarify a few things.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4321 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-05-01 02:11:39 +00:00
parent f8749a242a
commit 236fcb5fb4

View file

@ -40,22 +40,25 @@ Updated network primitives:
Entity numbers:
Entities are no longer coded as just a short.
Instead, they are coded as:
short. bit15=remove flag. bits14to0=entity number bits 14 - 0.
optional byte. bits0to7=entity number bits 22-15.
bit 22 should never be set.
short. bit15=extend byte. bits14-0=entity number bits 14 - 0.
optional byte. bit7=unused. bits6-0=entity number bits 21-15.
This coding gives compatibility with mods using writeshort up to ent 32767.
Certain QuakeWorld mods already use writeshort hacks to pass entities less than 0. This practise should be discouraged. If you want a railgun effect, use TE=17 or a call to trailparticles.
Entity deltas:
The entity index is not considered part of the delta. It generally does not use the entity coding above, but reserves an extra bit as a remove flag, which is why bit 22 of the entity number should always be 0.
In the information below, the number in brackets denotes the bit value of the named flag. predinfo has its own 8bit set of bits, otherwise its the main set of 32bit bits.
Note that the entity coding below does not match regular entity numbers.
Note that if the entity number is read as 0, then either it is the end of the message (remove=0) (do not read any flags), or ALL known entities must be discarded(remove=1).
If the remove flag is set, there are no flags, just the 2-3 bytes of entity number with the embedded remove flag.
In the description below, the flag name is followed by its bit (0-based) value. If the flag is set, the data is read.
byte - bits&0xff
UF_EXTEND1(7): byte - bits&0xff00
UF_EXTEND2(15): byte - bits&0xff0000
UF_EXTEND3(23): byte - bits&0xff000000
short. bit15=REMOVE flag. bit14=EEXTEND flag. bits13-0=entity number bits 13 - 0.
EEXTEND: byte. bits7-0=entity number bits 21-14.
byte - UF flag bits&0xff
UF_EXTEND1(7): byte - UF flag bits&0xff00
UF_EXTEND2(15): byte - UF flag bits&0xff0000
UF_EXTEND3(23): byte - UF flag bits&0xff000000
UF_FRAME(0): updated frame index:
UF_16BIT: short
UF_16BIT: ushort
otherwise: byte
UF_ORIGINXY(1): coord - origin[0]
UF_ORIGINXY(1): coord - origin[1]
@ -67,8 +70,8 @@ Updated network primitives:
UF_PREDINFO: shortangle
otherwise: stdangle
one of: entity effects
UF_EFFECTS(5)|UF_EFFECTS2(29): long
UF_EFFECTS2(29): short
UF_EFFECTS(5)|UF_EFFECTS2(29): ulong
UF_EFFECTS2(29): ushort
UF_EFFECTS(5): byte
otherwise: nothing
UF_PREDINFO(6):
@ -76,7 +79,7 @@ Updated network primitives:
movetype and weaponframe are the only parts that are deltaed. the other fields all reset to 0 if their bit is not set.
WARNING: at this time, only players will have this set. a future version will enable this for rockets/nails also.
this means that nq engines will need to support MOVETYPE_FLY as a simple VectorMA projection, but should otherwise be able to use interpolation for all other movetypes.
byte - predbits
byte - UFP pred flags
UFP_FORWARD(0): short, otherwise 0 - +forwards/+back speed
UFP_SIDE(1): short, otherwise 0 - +right/+left speed
UFP_UP(2): short, otherwise 0 - +moveup/+movedown speed
@ -90,22 +93,22 @@ Updated network primitives:
UF_RESET(8): nothing - if bit is set, reset from baseline before parsing data. First two updates containing this entity will always contain this bit set.
UF_16BIT(9): nothing itself - merely extends the size of other bits of info (model, skin, frame)
UF_MODEL(10): modelindex. bit 15 enables full ragdoll, and should otherwise be ignored.
UF_16BIT: short
UF_MODEL(10): modelindex. bit 15 enables full ragdoll, and should otherwise be masked out.
UF_16BIT: ushort
otherwise: byte
UF_SKIN(11): modelindex
UF_SKIN(11): the skin number to use. note that it is signed. negative values instead state q1 contents. This is consistant with fte's ssqc and with halflife. for compatibility with hexen2, values 100-109 inclusive are 'global skins' and will use the image "gfx/skin%d.lmp" instead, but only if the model does not have that many skins.
UF_16BIT: short
otherwise: byte
otherwise: char
UF_COLORMAP(12): byte - normally the 1-basedentity player slot of owning player, or 0 for world. treat-as-0 if invalid.
UF_SOLID(13): short - encoding of bbox size.
UF_SOLID(13): ushort - encoding of bbox size. 0 means non-solid, 31 means 'use model size', otherwise the low 5 bits are the -mins_x,-mins_y,maxs_x,maxs_y, the next 5 bits are -maxs_z, the final 6 bits state the maxs_z+32 (thereby allowing maxs_z to range between -32 and 31). This encoding is consistant with Q2. Without client-side prediction, you can ignore this setting.
UF_FLAGS(14): byte - some misc flags, yay. Flags are consistant with the DP5+ protocol.
1 = stepping.
2 = glowtrail. leaves a trail the same colour as the glowmod stuff.
4 = viewmodelforclient was set
8 = exteriormodelforclient was set
16 = low precision.
16 = reserved: low precision.
32 = specific colourmap. UF_COLORMAP byte's low 4 bits are pants. high 4 bits are shirt.
64 = act as if part of world.
64 = reserved: act as if part of world.
128 = complex animation. If set, there are more bytes following. This is not implemented by FTE at this time.
UF_EXTEND2(15): nothing here - already sent. listed for completeness.
@ -117,7 +120,7 @@ Updated network primitives:
optional byte - abslight. sent+used if (drawflags&7)==7.
UF_TAGINFO(20):
entityidx - tagentity. 0 = disable.
byte - tagindex. 0 = use tagentity's origin
byte - tagindex. 0 = use tagentity's origin, otherwise 1-based bone index.
UF_LIGHT(21):
short - red light scale
short - green light scale
@ -140,7 +143,7 @@ Updated network primitives:
byte - blue
UF_FATNESS(26): byte - how many qu/16 to move expand models by (move them outwards along their normal)
UF_MODELINDEX2(27): second modelindex to use for the entity. for visible weapon models or some such. Note: uses the same frame as the normal entity. For compatibility, if qw vweaps were sent then this uses those instead (and changes the normal modelindex to a weapon-less player as appropriate too).
UF_16BIT: short
UF_16BIT: ushort
otherwise: byte
UF_GRAVITYDIR(28): both bytes=0 correlates to normal gravity.
byte - ((pitch/360) * 256) - 192
@ -155,32 +158,41 @@ Updated network primitives:
there is no information regarding the nextthink of entities. It *should* be possible to guess well enough without it.
Either way it is rare enough that engines already need to interpolate well enough without this info, making it somewhat redundant, imho.
the first 7 bits are the bits that are normally going to be encountered every update.
the 6 bits following those are often used only when an entity first becomes visible. the 16bit flag allows for more modelindicies etc and is used as a general 'whoa dude' flag.
the 2 bits after that are generally considered extensions (solid+flags), although the 'stepping' hint is useful.
the first 7 flags are the flags that are normally going to be encountered every update.
the 6 flags following those are often used only when an entity first becomes visible. the 16bit flag allows for more modelindicies etc and is used as a general 'whoa dude' flag.
the 2 flags after that are generally considered extensions (solid+flags), although the 'stepping' hint is useful.
either way, these bits are likely to be present in a vanilla progs, and common during entity setup.
the following 2 bits are required for many fairly generic custom maps now, that target fitzquake (alpha).
the 13 bits after those are much more rarely used. You can justifyably get away with not implementing them (assuming you error if you do receive any), though its prefered to parse and ignore the results.
the final 2 bits are reserved for future expansion. yay.
the following 2 flags are required for many fairly generic custom maps now, that target fitzquake (alpha).
the 13 flags after those are much more rarely used. You can justifyably get away with not implementing them (assuming you error if you do receive any), though its prefered to parse and ignore the results.
the final 2 flags are reserved for future expansion. yay.
The information is sent in the unreliable channel. QuakeWorld clients have always acknowledged the server's unreliable sequence with every single packet.
This means that the server can directly detect packets which are not mentioned. Such unmentioned packets are assumed to be dropped.
The server keeps a log of the entities and updated bits that were sent with each outgoing packet. Once a packet has been detected as dropped, the ents+bits in that packet are folded back into the current outgoing state (taking care of added/removed entities). If too many packets are dropped, the server cannot track the entities which were sent and will drop ALL entities, starting from scratch.
The information is sent in the unreliable channel.
The client must ack the frame using the unreliable packet sequence (via clcfte_ackframe or quakeworld netchan).
This means that the server can detect packets/frames which are not mentioned. Such unmentioned packets are assumed to be dropped.
The server keeps a log of the entities and updated bits that were sent with each outgoing packet. When the server thinks a frame has been dropped, the ents+UFlags in that frame are folded back into the current outgoing state (taking care of added/removed entities). If too many frames are dropped, the server cannot track the entities which were sent and will drop ALL entities, starting from scratch.
When a bit is resent, current information is used, rather than the stale information that was previously sent, thus its possible to not see an update.
This all means that the server needs to track one set of previous state (maximum visible at once), and 64 or so sets of ent+bits (maximum updatable in a single packet). This can be used to keep memory use down when there are 4 million potential ents on the server.
This all means that the server needs to track one set of previous-frame state (maximum visible at once) to detect when a new flag must be sent, one set of pending UFlags (maximum on map, set when the previous state was no longer valid or if a dropped packet contained that flag, cleared when sent), and 64 or so sets of entnum+UFlags (maximum updatable in a single packet). This can be used to keep memory use down when there are 4 million potential ents on the server.
The server needs to be smart enough to handle dropped frames with remove flags, as well as double-sending(or tripple-sending) reset flags to cover packet loss.
The client can be pretty stupid and just update whichever fields are said, so long as it correctly ack the datagrams containing received frames.
The server is assumed to build an entity state list containing each visible entity. It is assumed to cross-reference this list with the previous frame in order to compare values and set the pending UFlags. The previous frame is then discarded, and the new list is retained for the following frame. This is why the server only needs to track max-visible instead of max-on-map states. Entity transmission uses only the state for the current frame and the pending UFlags (entities newly no longer visible should must have the remove flag set (due to the cross-reference). non-current entities with other UFlags set due to dropped packets can be ignored as there's already a remove flag pending). If the server runs out of space in the outgoing packet, it can simply leave the pending bits set for the extra ents (and should start mid-way through the list for the next frame).
Modified/Added SVCs:
svcnq_time:
nq fast update:
svcqw_packetentities:
svcqw_deltapacketentities:
svcqw_playerinfo:
No longer sent.
svcfte_spawnstatic2=21
Instead of the standard baseline info, the packet will contain only a delta from the null entity state. This allows transparent entities etc.
svcfte_spawnbaseline2=66
Instead of the standard baseline info, the packet will contain an entity number followed by a delta from the null entity state. Yay for transparent ents.
Otherwise identical to the regular svc_spawnbaseline in purpose.
svcfte_updateentities=86
NQ: Replaces fast updates, svc_time.
QW: Replaces svc_[delta]packetentities, svc_playerinfo
NQ: Replaces fast updates, svc_time. Note: Do not invalidate all entities simply because its a new netframe!
QW: Replaces svc_[delta]packetentities, svc_playerinfo.
The contents of this packet are:
NQ: inputack (this is an ack of the client's input sequence. for QW, use the netchan's ack sequence instead).
servertime of update, as a float32.
optional short=0x8000. (ie: when the entity index reads as 0 with the remove flag set) If present, remove ALL entities.
[
@ -204,9 +216,9 @@ Modified/Added CLCs:
Message data consists of a single 32bit integer, which is the entity frame that is being acked.
Frames not mentioned are assumed to be dropped. Acks MUST arrive at the server in ascending order, and should be sent unreliably to reduce latency (even though this is more likely to result in resending the frame).
You may ack multiple entity frames within a single packet.
QuakeWorld packets contain an ack sequence in the packet header itself. This sequence will be acked automatically after any acks within contents of the packet, and does not need an explicit ackframe inside.
QuakeWorld: as QW packets contain an ack sequence in the packet header itself, you should omit that ack. If multiple packets are received without an outgoing client packet, you should send explicit acks for all but the last (as that will automatically be acked by the netchan).
Because of this fact and typical packet sequences, QuakeWorld clients can omit sending these entirely.
If frame ~0u is 'acked', the server will reset and resend all ents
If frame ~0u is 'acked', the server will reset and resend all ents.
Information:
Player prediction is implemented by building a log of all the input frames clientside.
@ -231,6 +243,7 @@ Things not updated:
Soundindex limits are not changed. That's an independant extension.
Hack Zone:
prediction support with NQ has been defered for a later extension (which should hopefully replace svc_clientdata also). There is no information about input frames or physics cvars. However, this info should be added for csqc support... PEXT2_PREDINFO marks the preliminary code in fte.
FTE servers will not wait for modellist/soundlist/prespawn commands to be acked before sending the next part of data, other than to correctly parse the map checksum. FTE servers will only burst all this information if ReplacementDeltas is supported. It was found that certain clients (namely FTE) was triggering some code to detect messed up ordering - messed up ordering that is fixed having the server track progress instead of relying on echos.
This extension is simply a handy check to see if the client can cope and without spamming the console.
Vanilla QuakeWorld clients appeared to be able to cope with this, but there are indeed certain ways it can fail, like if the client tries to pause for downloads.