aosprotocol
aosprotocol copied to clipboard
PPA: Entity packets
I propose these packets to perform actions on entities:
(packet ids begin with 0xE as a reference to the word entity
)
Packet Entity Create (0xE0)
Field name | Type | Example | Notes |
---|---|---|---|
entity id | uint | 1 | |
x pos | float | 256.0F | |
y pos | float | 256.0F | |
z pos | float | 32.0F | |
scale | float | 0.1F | unit: kv6_voxels/world_block |
team | char | 0 | |
kv6 id | uint | 256 |
Packet Entity Destroy (0xE1)
Field name | Type | Example |
---|---|---|
entity id | uint | 1 |
Packet Entity Move (0xE2)
Field name | Type | Example |
---|---|---|
entity id | uint | 1 |
x pos | float | 128.0F |
y pos | float | 128.0F |
z pos | float | 32.0F |
Packet Entity Velocity (0xE3)
Field name | Type | Example |
---|---|---|
entity id | uint | 1 |
x speed | float | 1.0F |
y speed | float | 1.0F |
z speed | float | 0.0F |
Packet Entity Rotate (0xE4)
If the absolute flag is not set, rotation fields are used as 'velocities' in unit degree/s
.
This is useful for constantly rotating ammo boxes, or the rotor of a plane etc.
Field name | Type | Example | Notes |
---|---|---|---|
entity id | uint | 1 | |
absolute? | uchar | 1 | |
x rot | char | 127 | map [0°,360°] to [-128,127] |
y rot | char | 127 | same |
Packet Entity Team (0xE5)
Field name | Type | Example |
---|---|---|
entity id | uint | 1 |
team | char | 1 |
Packet KV6 Load (0xEF)
Field name | Type | Example |
---|---|---|
kv6 id | uint | 256 |
kv6_data size | uint | 1315 |
kv6_data | uchar[] | Kvxl... |
It would be nice if these could be identical to the 1.x packets... Is this the case?
I don't think they are
I think it might be a better idea to do the resource packs thing instead of reinventing the wheel for every model... although I can't think of a way to make anything but KV6 models and sounds work in a cross-platform way.
do they need to be bound to player? 🤔 not sure, just thinking out loud.
You mean for intel and such? Could be useful
The 1.x entities have a "carrier" field which can specify which user is currently carrying the object. I think genereally it would be useful to make this as close to the 1.x packets so the implementation only has to be done once.
https://piqueserver.github.io/aosprotocol/protocol100a1.html#entity
Packet Entity Carrier (0xE6)
If an entity is carried, position is relative to the carrier point defined by carrier_type
and rotation is relative to the player's orientation.
Field name | Type | Example | Notes |
---|---|---|---|
entity id | uint | 1 | |
has_carrier | char | 1 | 0: false 1: true if true, data follows |
carrier | uchar | 31 | a valid player id |
carrier_type | char | 5 | 0: at head pos 1: torso 2: arms 3: left leg 4: right leg 5: on back These points are at the kv6's pivot positions, except for type 5. |
a few more concerns:
- how should the physics used for the object be decided? Some objects like tents have different types of physics and those should ideally be brought under the umbrella of the new entity system
- if we allow transmitting kv6 over the wire, does it not make more sense to give the kv6 id as e.g. crc32 or truncated sha256 so that the server can cache it? Do we even want to transmit KV6s over the wire? If so, how does the client request KV6s it does not have? How does this system deal with custom models the client may have installed? Should it instead be left as is for now and a packet sending a table mapping IDs to hashes/checksums added later?
- can the packets be processed out of order?
- Physics:
- all physics code should run on the server
- tents are easy. We would just set their velocity to 0 and change their pos like we have it now when an update is required.
- positions will be interpolated using the velocity for e.g. planes, grenades...
(you would set the velocity to 0 to avoid glitching when, e.g. an entity is teleported from one side of the map to another) - we could have another packet that contains a bitfield to enable special properties, like zeroing/inverting velocity on a map collision
- Caching: I don't think we need this, most kv6s are not larger than a few kilobytes.
- This is not a multi-path pipeline, so all packets are processed how they were received from the server.
- Just to make things clear, all packets are server to client only.
Sound good, except for this part:
all packets are processed how they were received from the server
Well, due to the internet being the internet, care needs to be given in implementation that e.g. a carrier packet can arrive before a create packet and everything is fine. Sure, everything can be sent as Sequenced and Reliable, but that might make things like e.g. an outdated velocity packet arriving out of sync with a newer position packet weird.
Also note that the current update frequency on the server is only 10Hz, so I'm very cautious of the server-side only physics idea.
What is the purpose of the Entity team packet?
Giving certain KV6s constant IDs would allow not only for caching, but also for modding the models client-side.
I'll summarize some thoughts:
- [ ] How should sending a position behave when a carrier is set? I think it should dismount the entity.
- [ ] How can existing entity types fit into this model, while still allowing client side mods? Should certain model IDs (<128) be reserved? I think that would be a good idea.
- [ ] How can clients predict future locations? You point to sever-side only physics, but if we want to replace e.g. Grenades with that, it just won't work. Tents will work fine though. This can probably just be solved later.
- Carrier should override position imo
- one byte is not really enough for that imo, go for like 4, then can set more ranges
- why won't? lag? true that.
- [x] This is described in the
Entity Carrier
packet. If a carrier is set, all positions and rotations are applied relative to the carrier point, which is located on the specified part of the player's body. Rotation would be applied after the translation, so that its centered around the entity's pivot. This allows for e.g.- having a backpack [carrier type: 0x05, position of (0,0,0)]
- a nade to the side of the player [carrier type: 0x05, position: (1,0,0)]
- [ ] I think reserving ids is a good idea. Client could cache those kv6 ids under 216 and save them to disk, to allow for easy modding. They should be named
[decimalnmbr].kv6
. Assets the server doesn't want to be changed would be outside this range, and not cached. However, a special newcache
field in theKv6 load
packet could also allow this, without special circumvention. - [ ] Actually, I see the use of this extension not in the replacement of already existing entities like tents and grenades, but in adding new types, like the famous LMG. All legacy entity types would still use their respective old packet types.
What about adding an option to be able to set these as tools?
Maybe in a later revision.
Would it be better to have a simpler cut down version of this which can cover CTF and TC and anything else that can be done using mostly-static entities?
I'd also be tempted to do it as a "Set Entity" packet which would set all relevant fields, and a "Destroy Entity" packet which would delete an entity concisely. Later protocol versions could have a "Set Entity V2" packet.
As far as fields go though I'd do away with velocities (linear and angular), and instead opt for a float field which would indicate a number of seconds to linearly interpolate towards the position.
Carrier stuff is definitely worth having. Providing an offset and rotation will most likely be useful but that's kinda leaning in the large direction... but should decently genericise the rotated intel on one's back. Whether that should be part of the initial version of this or not is another matter.
For rotation, 8 bits is probably not enough. 16 bits, on the other hand, would for example give someone about 80 steps at the fogline (127.5 blocks away) to move from one side of a block to the other. I'm very much eyeing up 16-bit angles for that "new protocol!!!!1" idea that's been swimming around in my head (which is partially why I'm considering all that RISC-V stuff that I've been blabbering on about in the Dicsord).
As for sending KV6 models... those are too good an opportunity to miss out on. I'd definitely reserve some of the model IDs for the stock AoS models and that could allow one to swap out models for... other models I guess?
So basically, here's what I'm suggesting:
- Packet Entity Set (0xE0): A combination of the fields of the following:
- Packet Entity Create
- Packet Entity Move
- Packet Entity Team
- Packet Entity Carrier
- Packet Entity Rotate (angles bumped up to 16 bits, absolute case only unless we want to achieve peak Ken Silverman)
- A float to denote "interpolation time" in seconds, or 0.0 for an instant update
- Packet Entity Destroy (0xE1): As-is.
- Packet KV6 Load (0xEF): As-is.
And then get rid of these packets from the initial version:
- Packet Entity Velocity
- Packet Entity Rotate
And there you have it, that's the physics can solved by kicking it down Next Proposal Road.
Ideally, the "interpolation time" would be the absolute time that it should arrive at the desination, in number of ticks. But that would require exact time synchronization and lockstep between client and server, which we unfortunately don't have. So we will continue to have issues with high pings and especially spikes there.