improve prediction code + layer updates

isolation_bkp/dynres
Dominik Madarász 2021-05-09 15:52:46 +02:00
parent 074a3c601f
commit 7c39e51a07
9 changed files with 67 additions and 15 deletions

View File

@ -1,5 +1,5 @@
#pragma once
#include "entity_view.h"
float smooth_val(float cur, float tgt, float dt);
float smooth_val(float cur, float tgt, uint64_t dt);
void predict_receive_update(entity_view *d, entity_view *data);

View File

@ -14,6 +14,11 @@ typedef struct {
uint16_t block_size;
uint16_t chunk_size;
uint16_t chunk_amount;
// NOTE(zaklaus): metrics
uint64_t last_update[WORLD_TRACKER_LAYERS];
uint64_t delta_time[WORLD_TRACKER_LAYERS];
uint8_t active_layer_id;
} world_view;
world_view world_view_create(uint16_t view_id);

View File

@ -114,7 +114,6 @@ void platform_input() {
y = mouse_pos.y;
}
game_action_send_keystate(x, y, use, sprint);
}
@ -236,7 +235,12 @@ void lerp_entity_positions(uint64_t key, entity_view data) {
if (data.flag == EFLAG_INTERP) {
entity_view *e = entity_view_get(&view->entities, key);
e->x = smooth_val(e->x, e->tx, 0);
e->y = smooth_val(e->y, e->ty, 0);
#if 1
e->x = smooth_val(e->x, e->tx, view->delta_time[e->layer_id]);
e->y = smooth_val(e->y, e->ty, view->delta_time[e->layer_id]);
#else
e->x = e->tx;
e->y = e->ty;
#endif
}
}

View File

@ -1,12 +1,27 @@
#include "zpl.h"
#include "prediction.h"
#include "world/world.h"
#include "game.h"
#define PREDICT_SMOOTH_FACTOR_LO 0.8
#define PREDICT_SMOOTH_FACTOR_HI 0.12
#define PREDICT_SMOOTH_FACTOR_LO 0.80
#define PREDICT_SMOOTH_FACTOR_HI 0.007
float smooth_val(float cur, float tgt, float dt) {
return zpl_lerp(cur, tgt, zpl_lerp(PREDICT_SMOOTH_FACTOR_HI, PREDICT_SMOOTH_FACTOR_LO, zpl_unlerp(dt, WORLD_TRACKER_UPDATE_FAST_MS, WORLD_TRACKER_UPDATE_SLOW_MS)));
static inline float map_factor(float x) {
x = 1.0f - zpl_clamp01(x);
return 1.0f - x*x*x*x*x*x*x*x;
}
float smooth_val(float cur, float tgt, uint64_t dt) {
float factor = zpl_clamp01(map_factor(zpl_unlerp(dt, WORLD_TRACKER_UPDATE_FAST_MS, WORLD_TRACKER_UPDATE_SLOW_MS)));
#if 0
dt = 200;
factor = map_factor(zpl_unlerp(dt, WORLD_TRACKER_UPDATE_FAST_MS, WORLD_TRACKER_UPDATE_SLOW_MS));
zpl_printf("lerp factor: %f\n", factor);
zpl_exit(0);
#endif
return zpl_lerp(cur, tgt, zpl_lerp(PREDICT_SMOOTH_FACTOR_LO, PREDICT_SMOOTH_FACTOR_HI, factor));
}
void predict_receive_update(entity_view *d, entity_view *data) {

View File

@ -9,6 +9,11 @@ int32_t tracker_read_remove(librg_world *w, librg_event *e) {
int64_t entity_id = librg_event_entity_get(w, e);
zpl_printf("[INFO] An entity %d was removed for owner: %d\n", (int)entity_id, (int)owner_id);
world_view *view = (world_view*)librg_world_userdata_get(w);
entity_view *d = entity_view_get(&view->entities, entity_id);
if (d && d->layer_id < view->active_layer_id) {
// NOTE(zaklaus): reject updates from slower layers
return 0;
}
entity_view_destroy(&view->entities, entity_id);
return 0;
@ -22,6 +27,11 @@ int32_t tracker_read_update(librg_world *w, librg_event *e) {
entity_view data = entity_view_unpack_struct(buffer, actual_length);
entity_view *d = entity_view_get(&view->entities, entity_id);
data.layer_id = view->active_layer_id;
if (d && d->layer_id < data.layer_id) {
// NOTE(zaklaus): reject updates from slower layers
return 0;
}
predict_receive_update(d, &data);
entity_view_update_or_create(&view->entities, entity_id, data);
return 0;
@ -36,6 +46,7 @@ int32_t tracker_read_create(librg_world *w, librg_event *e) {
world_view *view = (world_view*)librg_world_userdata_get(w);
entity_view data = entity_view_unpack_struct(buffer, actual_length);
data.layer_id = view->active_layer_id;
if (data.flag & EFLAG_INTERP) {
data.tx = data.x;
data.ty = data.y;
@ -57,7 +68,6 @@ void world_view_init(world_view *view, uint64_t ent_id, uint16_t block_size, uin
view->block_size = block_size;
view->chunk_size = chunk_size;
view->chunk_amount = chunk_amount;
view->dim = block_size * chunk_size * chunk_amount;
view->size = view->dim * view->dim;

View File

@ -27,6 +27,9 @@ typedef struct entity_view {
float vy;
float tx;
float ty;
// NOTE(zaklaus): internals
uint8_t layer_id;
} entity_view;
ZPL_TABLE_DECLARE(, entity_view_tbl, entity_view_tbl_, entity_view);

View File

@ -1,27 +1,41 @@
#include "zpl.h"
#include "packet_utils.h"
#include "packets/pkt_send_librg_update.h"
#include "world/world.h"
#include "game.h"
size_t pkt_send_librg_update_encode(void *data, int32_t data_length) {
size_t pkt_send_librg_update_encode(void *data, int32_t data_length, uint8_t layer_id) {
cw_pack_context pc = {0};
pkt_pack_msg(&pc, 1);
pkt_pack_msg(&pc, 2);
cw_pack_unsigned(&pc, layer_id);
cw_pack_bin(&pc, data, data_length);
return pkt_pack_msg_size(&pc);
}
int32_t pkt_send_librg_update_handler(pkt_header *header) {
cw_unpack_context uc = {0};
pkt_unpack_msg(&uc, header, 1);
pkt_unpack_msg(&uc, header, 2);
cw_unpack_next(&uc);
if (uc.item.type != CWP_ITEM_POSITIVE_INTEGER)
return -1;
uint8_t layer_id = (uint8_t)uc.item.as.u64;
cw_unpack_next(&uc);
if (uc.item.type != CWP_ITEM_BIN)
return -1;
world_view *view = game_world_view_get(header->view_id);
view->active_layer_id = layer_id;
int32_t state = librg_world_read(view->tracker, header->view_id, uc.item.as.bin.start, uc.item.as.bin.length, NULL);
if (state < 0) zpl_printf("[ERROR] world read error: %d\n", state);
uint64_t now = zpl_time_rel_ms();
view->delta_time[layer_id] = now - view->last_update[layer_id];
view->last_update[layer_id] = now;
return state;
}

View File

@ -152,7 +152,7 @@ int32_t world_destroy(void) {
#define WORLD_LIBRG_BUFSIZ 2000000
static void world_tracker_update(uint8_t ticker, uint8_t freq, uint8_t radius) {
static void world_tracker_update(uint8_t ticker, uint32_t freq, uint8_t radius) {
if (world.tracker_update[ticker] > zpl_time_rel_ms()) return;
world.tracker_update[ticker] = zpl_time_rel_ms() + freq;
@ -178,7 +178,7 @@ static void world_tracker_update(uint8_t ticker, uint8_t freq, uint8_t radius) {
zpl_printf("[error] an error happened writing the world %d\n", result);
}
pkt_world_write(MSG_ID_LIBRG_UPDATE, pkt_send_librg_update_encode(buffer, datalen), 1, p[i].view_id, p[i].peer);
pkt_world_write(MSG_ID_LIBRG_UPDATE, pkt_send_librg_update_encode(buffer, datalen, ticker), 1, p[i].view_id, p[i].peer);
}
}
}

View File

@ -11,9 +11,10 @@
#define WORLD_ERROR_INVALID_BUFFER -0x0004
#define WORLD_ERROR_TRACKER_FAILED -0x0005
#define WORLD_TRACKER_LAYERS 3
#define WORLD_TRACKER_UPDATE_FAST_MS 10
#define WORLD_TRACKER_UPDATE_NORMAL_MS 100
#define WORLD_TRACKER_UPDATE_SLOW_MS 800
#define WORLD_TRACKER_UPDATE_SLOW_MS 400
#define WORLD_PKT_READER(name) int32_t name(void* data, uint32_t datalen, void *udata)
typedef WORLD_PKT_READER(world_pkt_reader_proc);