02.09.2016, 14:27
(
Последний раз редактировалось Spmn; 03.09.2016 в 12:28.
)
Retexturing RPCs format seems to be VERY, VERY unefficient and bandwidth consuming.
Bug 1:
Let's consider the following snippet:
At a first view, this code should send to client the following info:
- 1x CreateObject + parameters
- 8x SetObjectMaterial + parameters
- 8x SetObjectMaterialText + parameters
This is what a player receives from server:
1) RPC: CreateObject() parameters
2) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0)
3) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0) + all SetObjectMaterialText() parameters (for material index 'idx = 0')
4) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0) + all SetObjectMaterialText() parameters (for material index 'idx = 0') + all SetObjectMaterial() parameters (for material index 'idx' = 1)
5) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0) + all SetObjectMaterialText() parameters (for material index 'idx = 0') + all SetObjectMaterial() parameters (for material index 'idx' = 1) + all SetObjectMaterialText() parameters (for material index 'idx = 1')
6) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0) + all SetObjectMaterialText() parameters (for material index 'idx = 0') + all SetObjectMaterial() parameters (for material index 'idx' = 1) + all SetObjectMaterialText() parameters (for material index 'idx = 1') + all SetObjectMaterial() parameters (for material index 'idx' = 2) + all SetObjectMaterialText() parameters (for material index 'idx = 2')
...
17) ...
So, for each subsequent SetObjectMaterial(Text) call, server sends all previous material(text) data + current call data (+ initial CreateObject parameters + some extra bytes)
In case of our code snippet:
- object data is being sent 17 times
- material data is being sent 72 times
- text data is being sent 64 times
Size of data:
- for object: ~32 bytes each time
- for material: ~75 bytes each time
- for material text: ~2000 bytes each time (calculated for worst case = 2048 length text string)
Total size of data:
- for object: 17 * 32 = 544 Bytes
- for material: 72 * 75 = 5400 Bytes = ~= 5KB
- for material text: 64 * 2000 = 128,000 Bytes = ~128 KB (which is a lot for only 1 object per player)
- TOTAL: ~134 KB/object/player
Things get a lot worse when there are a lot of players to send data to and/or a streamer is used since objects are created, textured and destroyed very often, especially if there are lots of objects with small stream distances in very 'popular' areas.
------------------
Bug 2:
It states on wiki page that there are 16 (0-15) material indexes that can be used.
Let's consider the following snippet:
Server will stop sending new data when idx >= 8. I guess there is a hardcoded limit of 16 material changes and the counter is increased by both material and material text function calls.
// I am aware that no-one would ever has a reason neither to send 2048 length strings for material retexturing, nor to call retexturing functions so often as I presented.
// But, heavily mapped servers that use streamer and lots of retextured objects would certainly benefit from optimizing these RPCs.
// Later edit: I forgot to mention that all my tests were made on global objects only (CreateObject) and everything I said about streamer plugin is based on assumptions. I did not test how player objects (or streamer objects, since streamer plugin is based on them) are sent to clients. I will post data usage for player objects in the following days.
Bug 1:
Let's consider the following snippet:
Код:
main() { new handle = CreateObject(19371, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0); for(new idx; idx < 8; ++idx) { SetObjectMaterial(handle, idx, 19341, "egg_texts", "easter_egg01", -1); SetObjectMaterialText(handle, "2048 characters string", idx, OBJECT_MATERIAL_SIZE_256x128, "Arial", 28, 1, 0xFFFF8200, 0xFF000000, 2); } }
- 1x CreateObject + parameters
- 8x SetObjectMaterial + parameters
- 8x SetObjectMaterialText + parameters
This is what a player receives from server:
1) RPC: CreateObject() parameters
2) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0)
3) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0) + all SetObjectMaterialText() parameters (for material index 'idx = 0')
4) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0) + all SetObjectMaterialText() parameters (for material index 'idx = 0') + all SetObjectMaterial() parameters (for material index 'idx' = 1)
5) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0) + all SetObjectMaterialText() parameters (for material index 'idx = 0') + all SetObjectMaterial() parameters (for material index 'idx' = 1) + all SetObjectMaterialText() parameters (for material index 'idx = 1')
6) RPC: CreateObject() parameters + all SetObjectMaterial() parameters (for material index 'idx' = 0) + all SetObjectMaterialText() parameters (for material index 'idx = 0') + all SetObjectMaterial() parameters (for material index 'idx' = 1) + all SetObjectMaterialText() parameters (for material index 'idx = 1') + all SetObjectMaterial() parameters (for material index 'idx' = 2) + all SetObjectMaterialText() parameters (for material index 'idx = 2')
...
17) ...
So, for each subsequent SetObjectMaterial(Text) call, server sends all previous material(text) data + current call data (+ initial CreateObject parameters + some extra bytes)
In case of our code snippet:
- object data is being sent 17 times
- material data is being sent 72 times
- text data is being sent 64 times
Size of data:
- for object: ~32 bytes each time
- for material: ~75 bytes each time
- for material text: ~2000 bytes each time (calculated for worst case = 2048 length text string)
Total size of data:
- for object: 17 * 32 = 544 Bytes
- for material: 72 * 75 = 5400 Bytes = ~= 5KB
- for material text: 64 * 2000 = 128,000 Bytes = ~128 KB (which is a lot for only 1 object per player)
- TOTAL: ~134 KB/object/player
Things get a lot worse when there are a lot of players to send data to and/or a streamer is used since objects are created, textured and destroyed very often, especially if there are lots of objects with small stream distances in very 'popular' areas.
------------------
Bug 2:
It states on wiki page that there are 16 (0-15) material indexes that can be used.
Let's consider the following snippet:
Код:
main() { new handle = CreateObject(19371, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0); for(new idx; idx < 16; ++idx) // 8 -> 16 { SetObjectMaterial(handle, idx, 19341, "egg_texts", "easter_egg01", -1); SetObjectMaterialText(handle, "Hello there", idx, OBJECT_MATERIAL_SIZE_256x128, "Arial", 28, 1, 0xFFFF8200, 0xFF000000, 2); } }
// I am aware that no-one would ever has a reason neither to send 2048 length strings for material retexturing, nor to call retexturing functions so often as I presented.
// But, heavily mapped servers that use streamer and lots of retextured objects would certainly benefit from optimizing these RPCs.
// Later edit: I forgot to mention that all my tests were made on global objects only (CreateObject) and everything I said about streamer plugin is based on assumptions. I did not test how player objects (or streamer objects, since streamer plugin is based on them) are sent to clients. I will post data usage for player objects in the following days.