-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Damage api] Custom damage types #284
[Damage api] Custom damage types #284
Conversation
Actually, having an array of 36 ints is more memory efficient than Dictionary of Dictionaries with one element. So, I will change how flags stored in the memory. |
Switched to use byte[] to store flags. Seems like it also simplified logic somewhat. |
Since there are quite a few vanilla classes that store damage type in a field and then pass it to the new
There also are a few more cases that I've not covered and they are questionable to do. Somewhat useful:
Things too specific to implement:
|
So, I think I've covered everything I've wanted. The only leftover thing is testing, a lot of it. And maybe add commentaries for private methods. |
I've finished with everything I've wanted to do. I think I've tested everything. There are some places where DamageTypes can be used that I've not covered because I think they are too specific and this API is already a monstrosity of IL hooks, though they can be added later if someone needs them. |
First draft of custom damage types.
TL; DR;
Allows to use up to 1152 damage types for modding purposes while sending only 3 extra bytes in most cases.
Still need to add extensions for vanilla EntityStates that store DamageType to later use in DamageInfo.
There are 3 public methods:
ReserveDamageType
- returnsModdedDamageType
enum value that mod can use to add/check with extension methods.AddModdedDamageType
- adds reserved damage type to DamageInfo. Can add more than one ModdedDamageType to single DamageInfo. (need to do overloads for some vanilla EntityStates)HasModdedDamageType
- checks reserved damage type on DamageInfo (need to do overloads for some vanilla EntityStates)Implementation details
Vanilla DamageInfos
Obviously, vanilla attacks won't use this system and for them, only 1 extra byte will be sent over the network that will indicate that there are no modded damage types.
Modded DamageInfos
The first thing necessary to understand is that while you can have a lot of unique damage types most of the time only 1-2 will be used per attack. This means you need to send 144 bytes with each attack (for 1152 unique flag values) even if it doesn't have any damage types enabled, or you can invent stupidly complicated compression that will allow you to send a lot less information in most cases, which I did.
There are 3 key pieces in this system:
Section
Section contains up to 8 blocks. When written to NetworkWriter it's converted to a byte with each bit indicating if a corresponding block has a value, that allows to not write blocks that don't have any value. Each block stores info about ModdedDamageTypes within range: from
block index * 144
to(block index + 1) * 144 - 1
.Block
Block contains up to 18 values. When written to NetworkWriter it's converted to 1-4 bytes depending on enabled values.

Block is the most complicated thing in this implementation, so it requires an image with a description:
Value
Byte value storing 8 flags that indicate that corresponding DamageTypes are enabled or not.
What is sent over the network
Examples
If I were to send DamageInfo with ModdedDamageType with index 12 enabled only 3 extra bytes would be used:
If I were to send 12, 13, and 14 I would still use only 3 bytes:
If I were to send 463, still only 3 bytes:
If I were to send 12 and 463, that would require 5 bytes:
It's pretty complicated, so, if you have any questions I will of course answer them.