mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-25 13:21:36 +00:00
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:
parent
f8749a242a
commit
236fcb5fb4
1 changed files with 50 additions and 37 deletions
|
@ -40,22 +40,25 @@ Updated network primitives:
|
||||||
Entity numbers:
|
Entity numbers:
|
||||||
Entities are no longer coded as just a short.
|
Entities are no longer coded as just a short.
|
||||||
Instead, they are coded as:
|
Instead, they are coded as:
|
||||||
short. bit15=remove flag. bits14to0=entity number bits 14 - 0.
|
short. bit15=extend byte. bits14-0=entity number bits 14 - 0.
|
||||||
optional byte. bits0to7=entity number bits 22-15.
|
optional byte. bit7=unused. bits6-0=entity number bits 21-15.
|
||||||
bit 22 should never be set.
|
|
||||||
This coding gives compatibility with mods using writeshort up to ent 32767.
|
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.
|
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:
|
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.
|
Note that the entity coding below does not match regular entity numbers.
|
||||||
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 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
|
short. bit15=REMOVE flag. bit14=EEXTEND flag. bits13-0=entity number bits 13 - 0.
|
||||||
UF_EXTEND1(7): byte - bits&0xff00
|
EEXTEND: byte. bits7-0=entity number bits 21-14.
|
||||||
UF_EXTEND2(15): byte - bits&0xff0000
|
byte - UF flag bits&0xff
|
||||||
UF_EXTEND3(23): byte - bits&0xff000000
|
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_FRAME(0): updated frame index:
|
||||||
UF_16BIT: short
|
UF_16BIT: ushort
|
||||||
otherwise: byte
|
otherwise: byte
|
||||||
UF_ORIGINXY(1): coord - origin[0]
|
UF_ORIGINXY(1): coord - origin[0]
|
||||||
UF_ORIGINXY(1): coord - origin[1]
|
UF_ORIGINXY(1): coord - origin[1]
|
||||||
|
@ -67,8 +70,8 @@ Updated network primitives:
|
||||||
UF_PREDINFO: shortangle
|
UF_PREDINFO: shortangle
|
||||||
otherwise: stdangle
|
otherwise: stdangle
|
||||||
one of: entity effects
|
one of: entity effects
|
||||||
UF_EFFECTS(5)|UF_EFFECTS2(29): long
|
UF_EFFECTS(5)|UF_EFFECTS2(29): ulong
|
||||||
UF_EFFECTS2(29): short
|
UF_EFFECTS2(29): ushort
|
||||||
UF_EFFECTS(5): byte
|
UF_EFFECTS(5): byte
|
||||||
otherwise: nothing
|
otherwise: nothing
|
||||||
UF_PREDINFO(6):
|
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.
|
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.
|
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.
|
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_FORWARD(0): short, otherwise 0 - +forwards/+back speed
|
||||||
UFP_SIDE(1): short, otherwise 0 - +right/+left speed
|
UFP_SIDE(1): short, otherwise 0 - +right/+left speed
|
||||||
UFP_UP(2): short, otherwise 0 - +moveup/+movedown 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_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_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_MODEL(10): modelindex. bit 15 enables full ragdoll, and should otherwise be masked out.
|
||||||
UF_16BIT: short
|
UF_16BIT: ushort
|
||||||
otherwise: byte
|
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
|
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_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.
|
UF_FLAGS(14): byte - some misc flags, yay. Flags are consistant with the DP5+ protocol.
|
||||||
1 = stepping.
|
1 = stepping.
|
||||||
2 = glowtrail. leaves a trail the same colour as the glowmod stuff.
|
2 = glowtrail. leaves a trail the same colour as the glowmod stuff.
|
||||||
4 = viewmodelforclient was set
|
4 = viewmodelforclient was set
|
||||||
8 = exteriormodelforclient 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.
|
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.
|
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.
|
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.
|
optional byte - abslight. sent+used if (drawflags&7)==7.
|
||||||
UF_TAGINFO(20):
|
UF_TAGINFO(20):
|
||||||
entityidx - tagentity. 0 = disable.
|
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):
|
UF_LIGHT(21):
|
||||||
short - red light scale
|
short - red light scale
|
||||||
short - green light scale
|
short - green light scale
|
||||||
|
@ -140,7 +143,7 @@ Updated network primitives:
|
||||||
byte - blue
|
byte - blue
|
||||||
UF_FATNESS(26): byte - how many qu/16 to move expand models by (move them outwards along their normal)
|
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_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
|
otherwise: byte
|
||||||
UF_GRAVITYDIR(28): both bytes=0 correlates to normal gravity.
|
UF_GRAVITYDIR(28): both bytes=0 correlates to normal gravity.
|
||||||
byte - ((pitch/360) * 256) - 192
|
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.
|
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.
|
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 first 7 flags are the flags 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 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 bits after that are generally considered extensions (solid+flags), although the 'stepping' hint is useful.
|
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.
|
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 following 2 flags 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 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 bits are reserved for future expansion. yay.
|
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.
|
The information is sent in the unreliable channel.
|
||||||
This means that the server can directly detect packets which are not mentioned. Such unmentioned packets are assumed to be dropped.
|
The client must ack the frame using the unreliable packet sequence (via clcfte_ackframe or quakeworld netchan).
|
||||||
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.
|
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.
|
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:
|
Modified/Added SVCs:
|
||||||
|
svcnq_time:
|
||||||
|
nq fast update:
|
||||||
|
svcqw_packetentities:
|
||||||
|
svcqw_deltapacketentities:
|
||||||
|
svcqw_playerinfo:
|
||||||
|
No longer sent.
|
||||||
svcfte_spawnstatic2=21
|
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.
|
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
|
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.
|
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.
|
Otherwise identical to the regular svc_spawnbaseline in purpose.
|
||||||
svcfte_updateentities=86
|
svcfte_updateentities=86
|
||||||
NQ: Replaces fast updates, svc_time.
|
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
|
QW: Replaces svc_[delta]packetentities, svc_playerinfo.
|
||||||
The contents of this packet are:
|
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.
|
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.
|
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.
|
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).
|
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.
|
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.
|
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:
|
Information:
|
||||||
Player prediction is implemented by building a log of all the input frames clientside.
|
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.
|
Soundindex limits are not changed. That's an independant extension.
|
||||||
|
|
||||||
Hack Zone:
|
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.
|
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.
|
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.
|
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.
|
||||||
|
|
Loading…
Reference in a new issue