pkt: action-based entity stream throttling

isolation_bkp/dynres
Dominik Madarász 2022-08-01 11:19:52 +02:00
parent 28987c36d9
commit c7d251eb44
10 changed files with 150 additions and 71 deletions

View File

@ -12,6 +12,7 @@ uint64_t entity_spawn(uint16_t class_id) {
ecs_entity_t e = ecs_new(world_ecs(), 0); ecs_entity_t e = ecs_new(world_ecs(), 0);
ecs_set(world_ecs(), e, Classify, { .id = class_id }); ecs_set(world_ecs(), e, Classify, { .id = class_id });
entity_wake(e);
if (class_id != EKIND_SERVER) { if (class_id != EKIND_SERVER) {
ecs_set(world_ecs(), e, Velocity, {0}); ecs_set(world_ecs(), e, Velocity, {0});
@ -43,3 +44,39 @@ void entity_despawn(uint64_t ent_id) {
librg_entity_untrack(world_tracker(), ent_id); librg_entity_untrack(world_tracker(), ent_id);
ecs_delete(world_ecs(), ent_id); ecs_delete(world_ecs(), ent_id);
} }
void entity_wake(uint64_t ent_id) {
StreamInfo *si = ecs_get_mut(world_ecs(), ent_id, StreamInfo);
si->tick_delay = 0.0f;
si->last_update = 0.0f;
}
static ecs_query_t *ecs_streaminfo = NULL;
void entity_update_action_timers() {
static double last_update_time = 0.0f;
if (!ecs_streaminfo) {
ecs_streaminfo = ecs_query_new(world_ecs(), "components.StreamInfo");
last_update_time = zpl_time_rel();
}
ecs_iter_t it = ecs_query_iter(world_ecs(), ecs_streaminfo);
while (ecs_query_next(&it)) {
StreamInfo *si = ecs_field(&it, StreamInfo, 1);
for (size_t i = 0; i < it.count; i++) {
if (si[i].last_update < zpl_time_rel()) {
si[i].last_update = zpl_time_rel() + si[i].tick_delay;
si[i].tick_delay += (zpl_time_rel() - last_update_time) * 0.5f;
}
}
}
last_update_time = zpl_time_rel();
}
bool entity_can_stream(uint64_t ent_id) {
StreamInfo *si = ecs_get_mut(world_ecs(), ent_id, StreamInfo);
return (si->last_update < zpl_time_rel());
}

View File

@ -1,6 +1,13 @@
#pragma once #pragma once
#include "system.h" #include "system.h"
#define ENTITY_ACTION_VELOCITY_THRESHOLD 0.05f
uint64_t entity_spawn(uint16_t class_id /* 0 = no streaming */); uint64_t entity_spawn(uint16_t class_id /* 0 = no streaming */);
void entity_batch_despawn(uint64_t *ids, size_t num_ids); void entity_batch_despawn(uint64_t *ids, size_t num_ids);
void entity_despawn(uint64_t ent_id); void entity_despawn(uint64_t ent_id);
// NOTE(zaklaus): action-based entity stream throttling
void entity_wake(uint64_t ent_id);
void entity_update_action_timers();
bool entity_can_stream(uint64_t ent_id);

View File

@ -10,6 +10,7 @@
#include "platform.h" #include "platform.h"
#include "profiler.h" #include "profiler.h"
#include "game.h" #include "game.h"
#include "entity.h"
#include "packets/pkt_send_librg_update.h" #include "packets/pkt_send_librg_update.h"
@ -134,6 +135,13 @@ int32_t tracker_write_update(librg_world *w, librg_event *e) {
} }
} }
// NOTE(zaklaus): action-based updates
{
if (view.kind != EKIND_CHUNK && !entity_can_stream(entity_id)) {
return LIBRG_WRITE_REJECT;
}
}
return (int32_t)entity_view_pack_struct(buffer, actual_length, view); return (int32_t)entity_view_pack_struct(buffer, actual_length, view);
} }
@ -333,6 +341,7 @@ int32_t world_update() {
world_tracker_update(1, normal_ms, 2); world_tracker_update(1, normal_ms, 2);
world_tracker_update(2, slow_ms, 3); world_tracker_update(2, slow_ms, 3);
entity_update_action_timers();
debug_replay_update(); debug_replay_update();
return 0; return 0;
} }

View File

@ -14,6 +14,7 @@ ECS_COMPONENT_DECLARE(IsInVehicle);
ECS_COMPONENT_DECLARE(ItemDrop); ECS_COMPONENT_DECLARE(ItemDrop);
ECS_COMPONENT_DECLARE(Inventory); ECS_COMPONENT_DECLARE(Inventory);
ECS_COMPONENT_DECLARE(DemoNPC); ECS_COMPONENT_DECLARE(DemoNPC);
ECS_COMPONENT_DECLARE(StreamInfo);
void ComponentsImport(ecs_world_t *ecs) { void ComponentsImport(ecs_world_t *ecs) {
ECS_MODULE(ecs, Components); ECS_MODULE(ecs, Components);
@ -32,4 +33,5 @@ void ComponentsImport(ecs_world_t *ecs) {
ECS_COMPONENT_DEFINE(ecs, ItemDrop); ECS_COMPONENT_DEFINE(ecs, ItemDrop);
ECS_COMPONENT_DEFINE(ecs, Inventory); ECS_COMPONENT_DEFINE(ecs, Inventory);
ECS_COMPONENT_DEFINE(ecs, DemoNPC); ECS_COMPONENT_DEFINE(ecs, DemoNPC);
ECS_COMPONENT_DEFINE(ecs, StreamInfo);
} }

View File

@ -96,6 +96,11 @@ typedef struct {
float pickup_time; float pickup_time;
} Inventory; } Inventory;
typedef struct {
double last_update;
double tick_delay;
} StreamInfo;
typedef struct {char _unused;} DemoNPC; typedef struct {char _unused;} DemoNPC;
extern ECS_COMPONENT_DECLARE(Vector2D); extern ECS_COMPONENT_DECLARE(Vector2D);
@ -112,5 +117,6 @@ extern ECS_COMPONENT_DECLARE(IsInVehicle);
extern ECS_COMPONENT_DECLARE(ItemDrop); extern ECS_COMPONENT_DECLARE(ItemDrop);
extern ECS_COMPONENT_DECLARE(Inventory); extern ECS_COMPONENT_DECLARE(Inventory);
extern ECS_COMPONENT_DECLARE(DemoNPC); extern ECS_COMPONENT_DECLARE(DemoNPC);
extern ECS_COMPONENT_DECLARE(StreamInfo);
void ComponentsImport(ecs_world_t *ecs); void ComponentsImport(ecs_world_t *ecs);

View File

@ -114,6 +114,7 @@ void RegenerateHP(ecs_iter_t *it) {
h[i].heal_time = HP_REGEN_TIME; h[i].heal_time = HP_REGEN_TIME;
h[i].hp += HP_REGEN_RECOVERY; h[i].hp += HP_REGEN_RECOVERY;
h[i].hp = zpl_min(h[i].max_hp, h[i].hp); h[i].hp = zpl_min(h[i].max_hp, h[i].hp);
entity_wake(it->entities[i]);
} else { } else {
h[i].heal_time -= safe_dt(it); h[i].heal_time -= safe_dt(it);
} }

View File

@ -33,6 +33,7 @@ void PickItem(ecs_iter_t *it) {
item->quantity += picked_count; item->quantity += picked_count;
drop->quantity -= picked_count; drop->quantity -= picked_count;
item->kind = drop->kind; item->kind = drop->kind;
entity_wake(ents[j]);
if (drop->quantity == 0) if (drop->quantity == 0)
item_despawn(ents[j]); item_despawn(ents[j]);
@ -42,6 +43,7 @@ void PickItem(ecs_iter_t *it) {
} else if (range <= ITEM_ATTRACT_RADIUS) { } else if (range <= ITEM_ATTRACT_RADIUS) {
p2->x = zpl_lerp(p2->x, p[i].x, ITEM_ATTRACT_FORCE*it->delta_time); p2->x = zpl_lerp(p2->x, p[i].x, ITEM_ATTRACT_FORCE*it->delta_time);
p2->y = zpl_lerp(p2->y, p[i].y, ITEM_ATTRACT_FORCE*it->delta_time); p2->y = zpl_lerp(p2->y, p[i].y, ITEM_ATTRACT_FORCE*it->delta_time);
entity_wake(ents[j]);
} }
} }
} }
@ -222,5 +224,7 @@ void UseItem(ecs_iter_t *it) {
in[i].num_placements = 0; in[i].num_placements = 0;
} }
entity_wake(it->entities[i]);
} }
} }

View File

@ -1,3 +1,5 @@
#include "entity.h"
#define PLR_MOVE_SPEED 800.0f #define PLR_MOVE_SPEED 800.0f
#define PLR_MOVE_SPEED_MULT 1.5f #define PLR_MOVE_SPEED_MULT 1.5f
@ -12,5 +14,10 @@ void MovementImpulse(ecs_iter_t *it) {
float speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0f); float speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0f);
v[i].x += in[i].x*speed*drag*safe_dt(it); v[i].x += in[i].x*speed*drag*safe_dt(it);
v[i].y -= in[i].y*speed*drag*safe_dt(it); v[i].y -= in[i].y*speed*drag*safe_dt(it);
if ( zpl_abs(v[i].x) > ENTITY_ACTION_VELOCITY_THRESHOLD
|| zpl_abs(v[i].y) > ENTITY_ACTION_VELOCITY_THRESHOLD) {
entity_wake(it->entities[i]);
}
} }
} }

View File

@ -1,4 +1,5 @@
#include "debug_draw.h" #include "debug_draw.h"
#include "entity.h"
#define VEH_ENTER_RADIUS 45.0f #define VEH_ENTER_RADIUS 45.0f
@ -158,9 +159,14 @@ void VehicleHandling(ecs_iter_t *it) {
Velocity *v2 = ecs_get_mut(it->world, pe, Velocity); Velocity *v2 = ecs_get_mut(it->world, pe, Velocity);
*p2 = p[i]; *p2 = p[i];
*v2 = v[i]; *v2 = v[i];
entity_wake(pe);
} }
} }
if (zpl_abs(car->force) > ENTITY_ACTION_VELOCITY_THRESHOLD) {
entity_wake(it->entities[i]);
}
{ {
debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)}; debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)};
debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF); debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF);