PKT: chunk block streaming + pkt enhancements

isolation_bkp/dynres
Dominik Madarász 2021-07-18 13:23:59 +02:00
parent e056395f8f
commit ee794495e9
11 changed files with 101 additions and 57 deletions

View File

@ -35,6 +35,10 @@ typedef struct entity_view {
float tx;
float ty;
// TODO(zaklaus): Find a way to stream dynamic arrays
uint8_t blocks_used;
uint8_t blocks[256];
// NOTE(zaklaus): internals
uint8_t layer_id;
uint64_t last_update;

View File

@ -97,6 +97,10 @@ static inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t i
#define PKT_ARRAY(t, a) .type = CWP_ITEM_BIN, .offset = PKT_OFFSETOF(t, a), .size = PKT_FIELD_SIZEOF(t,a), .it_size = PKT_FIELD_SIZEOF(t,a[0]), .name = #a
#endif
#ifndef PKT_SKIP_IF
#define PKT_SKIP_IF(t, a, e, n) .skip_count = n, .offset = PKT_OFFSETOF(t, a), .skip_eq = e, .name = #a
#endif
#ifndef PKT_END
#define PKT_END .type = CWP_NOT_AN_ITEM
#endif
@ -111,8 +115,10 @@ typedef struct pkt_desc {
size_t offset;
size_t size;
size_t it_size;
size_t skip_count;
uint8_t skip_eq;
} pkt_desc;
int32_t pkt_unpack_struct(cw_unpack_context *uc, pkt_desc *desc, void *raw_blob, uint32_t blob_size);
int32_t pkt_pack_struct(cw_pack_context *pc, pkt_desc *desc, void *raw_blob, uint32_t blob_size);

View File

@ -185,16 +185,16 @@ void debug_draw(void) {
color = RED;
is_handle_ctrl_held = 1;
}
if (is_handle_ctrl_held) {
debug_xpos = xpos = GetMouseX() - DBG_CTRL_HANDLE_DIM/2;
debug_ypos = ypos = GetMouseY() - DBG_CTRL_HANDLE_DIM/2;
if (area == DAREA_PRESS) {
is_handle_ctrl_held = 0;
}
}
DrawRectangle(xpos, ypos, DBG_CTRL_HANDLE_DIM, DBG_CTRL_HANDLE_DIM, color);
}

View File

@ -10,6 +10,8 @@ pkt_desc pkt_entity_view_desc[] = {
{ PKT_HALF(entity_view, y) },
{ PKT_HALF(entity_view, vx) },
{ PKT_HALF(entity_view, vy) },
{ PKT_SKIP_IF(entity_view, blocks_used, 0, 1) },
{ PKT_ARRAY(entity_view, blocks) },
{ PKT_END },
};

View File

@ -31,7 +31,7 @@ int main(int argc, char** argv) {
zpl_opts_add(&opts, "ed", "enable-dash", "enables flecs dash", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT);
zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT);
//zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT);
zpl_opts_add(&opts, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
zpl_opts_add(&opts, "n", "npc-count", "amount of demo npcs to spawn", ZPL_OPTS_INT);
@ -47,7 +47,7 @@ int main(int argc, char** argv) {
int8_t is_dash_enabled = zpl_opts_has_arg(&opts, "enable-dash");
int32_t seed = zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
uint16_t num_viewers = zpl_opts_integer(&opts, "viewer-count", 1);
uint16_t chunk_size = zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
uint16_t world_size = zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
uint32_t npc_count = zpl_opts_integer(&opts, "npc-count", 1000);

View File

@ -32,12 +32,12 @@ int32_t pkt_header_encode(pkt_messages id, uint16_t view_id, void *data, size_t
int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen) {
cw_unpack_context uc = {0};
pkt_unpack_msg_raw(&uc, data, datalen, PKT_HEADER_ELEMENTS);
cw_unpack_next(&uc);
if (uc.item.type != CWP_ITEM_POSITIVE_INTEGER || uc.item.as.u64 > UINT16_MAX) {
return -1; // invalid packet id
}
uint16_t pkt_id = (uint16_t)uc.item.as.u64;
cw_unpack_next(&uc);
@ -50,13 +50,13 @@ int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen) {
cw_unpack_next(&uc);
const void *packed_blob = uc.item.as.bin.start;
uint32_t packed_size = uc.item.as.bin.length;
table->id = pkt_id;
table->view_id = view_id;
table->data = packed_blob;
table->datalen = packed_size;
table->ok = 1;
return pkt_validate_eof_msg(&uc) != -1;
}
@ -64,6 +64,11 @@ int32_t pkt_unpack_struct(cw_unpack_context *uc, pkt_desc *desc, void *raw_blob,
uint8_t *blob = (uint8_t*)raw_blob;
for (pkt_desc *field = desc; field->type != CWP_NOT_AN_ITEM; ++field) {
cw_unpack_next(uc);
if (field->skip_count) {
if (uc->item.type != CWP_ITEM_POSITIVE_INTEGER) return -1; // unexpected field
field += uc->item.as.u64;
continue;
}
if (uc->item.type != field->type) return -1; // unexpected field
if (blob + field->offset + field->size > blob + blob_size) return -1; // field does not fit
switch (field->type) {
@ -99,6 +104,18 @@ int32_t pkt_unpack_struct(cw_unpack_context *uc, pkt_desc *desc, void *raw_blob,
int32_t pkt_pack_struct(cw_pack_context *pc, pkt_desc *desc, void *raw_blob, uint32_t blob_size) {
uint8_t *blob = (uint8_t*)raw_blob;
for (pkt_desc *field = desc; field->type != CWP_NOT_AN_ITEM; ++field) {
if (field->skip_count) {
uint8_t val = *(uint8_t*)(blob + field->offset);
if (val == field->skip_eq) {
field += field->skip_count;
cw_pack_unsigned(pc, field->skip_count);
} else {
cw_pack_unsigned(pc, 0);
}
continue;
}
switch (field->type) {
case CWP_ITEM_BIN: {
if (field->size >= PKT_BUFSIZ) return -1; // bin blob too big
@ -140,6 +157,14 @@ void pkt_dump_struct(pkt_desc *desc, void* raw_blob, uint32_t blob_size) {
uint8_t *blob = (uint8_t*)raw_blob;
zpl_printf("{\n");
for (pkt_desc *field = desc; field->type != CWP_NOT_AN_ITEM; ++field) {
if (field->skip_count) {
uint8_t val = *(uint8_t*)(blob + field->offset);
if (val == field->skip_eq) {
field += field->skip_count;
}
continue;
}
zpl_printf(" \"%s\": ", field->name);
switch (field->type) {
case CWP_ITEM_BIN: {

View File

@ -56,7 +56,7 @@ void platform_shutdown() {
assets_destroy();
CloseWindow();
}
uint8_t platform_is_running() {
return !WindowShouldClose();
}
@ -123,11 +123,11 @@ void platform_render() {
}
render_camera.zoom = zpl_lerp(render_camera.zoom, target_zoom, 0.18);
camera_update();
camera game_camera = camera_get();
render_camera.target = (Vector2){game_camera.x, game_camera.y};
zoom_overlay_tran = zpl_lerp(zoom_overlay_tran, (target_zoom <= CAM_OVERLAY_ZOOM_LEVEL) ? 1.0f : 0.0f, GetFrameTime()*2.0f);
BeginDrawing();
profile (PROF_RENDER) {
ClearBackground(GetColor(0x222034));
@ -167,7 +167,7 @@ void DEBUG_draw_ground(uint64_t key, entity_view * data) {
float x = data->x * size + offset;
float y = data->y * size + offset;
DrawRectangleEco(x, y, size-offset, size-offset, ColorAlpha(LIME, data->tran_time));
#if 0
@ -182,11 +182,11 @@ void DEBUG_draw_ground(uint64_t key, entity_view * data) {
DrawRectangleEco(bx, by, block_size, block_size, GREEN);
}
#endif
if (zoom_overlay_tran > 0.02f) {
DrawRectangleEco(x, y, size-offset, size-offset, ColorAlpha(ColorFromHSV(key*x, 0.13f, 0.89f), data->tran_time*zoom_overlay_tran));
DrawTextEco(TextFormat("%d %d", (int)data->x, (int)data->y), (int16_t)x+15, (int16_t)y+15, 65 , ColorAlpha(BLACK, data->tran_time*zoom_overlay_tran), 0.0);
DrawTextEco(TextFormat("%d %d", (int)data->x, (int)data->y), (int16_t)x+15, (int16_t)y+15, 200 , ColorAlpha(BLACK, data->tran_time*zoom_overlay_tran), 0.0);
}
}break;

View File

@ -39,6 +39,11 @@ entity_view world_build_entity_view(int64_t e) {
view.kind = EKIND_CHUNK;
view.x = chpos->x;
view.y = chpos->y;
view.blocks_used = 1;
for (int i = 0; i < world.chunk_size*world.chunk_size; i += 1) {
view.blocks[i] = *ecs_vector_get(chpos->blocks, uint8_t, i);
}
}
return view;
@ -134,10 +139,10 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
ECS_IMPORT(world.ecs, General);
ECS_IMPORT(world.ecs, Net);
world.ecs_update = ecs_query_new(world.ecs, "net.ClientInfo, general.Position");
int32_t world_build_status = worldgen_test(&world);
ZPL_ASSERT(world_build_status >= 0);
for (int i = 0; i < world.chunk_amount * world.chunk_amount; ++i) {
ecs_entity_t e = ecs_new(world.ecs, 0);
Chunk *chunk = ecs_get_mut(world.ecs, e, Chunk, NULL);
@ -146,13 +151,17 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
librg_chunk_to_chunkpos(world.tracker, i, &chunk->x, &chunk->y, NULL);
chunk->blocks = NULL;
// TODO(zaklaus): populate chunks from worldgen
for (int j = 0; j < world.chunk_size * world.chunk_size; j += 1) {
uint8_t *c = ecs_vector_add(&chunk->blocks, uint8_t);
*c = 0;
for (int y = 0; y < world.chunk_size; y += 1) {
for (int x = 0; x < world.chunk_size; x += 1) {
int chk = world.chunk_size * i;
int chk_x = chk % world.chunk_amount;
int chk_y = chk / world.chunk_amount;
uint8_t *c = ecs_vector_add(&chunk->blocks, uint8_t);
*c = world.data[(chk_y+y)*world.chunk_amount + (chk_x+x)];
}
}
}
zpl_printf("[INFO] Created a new server world\n");
return world_build_status;
@ -171,36 +180,36 @@ int32_t world_destroy(void) {
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;
world.tracker_update[ticker] = zpl_time_rel_ms() + freq;
profile(PROF_WORLD_WRITE) {
ECS_IMPORT(world.ecs, General);
ECS_IMPORT(world.ecs, Net);
ecs_iter_t it = ecs_query_iter(world.ecs_update);
static char buffer[WORLD_LIBRG_BUFSIZ] = {0};
world.active_layer_id = ticker;
while (ecs_query_next(&it)) {
ClientInfo *p = ecs_column(&it, ClientInfo, 1);
for (int i = 0; i < it.count; i++) {
size_t datalen = WORLD_LIBRG_BUFSIZ;
// TODO(zaklaus): SUPER TEMPORARY HOT !!! simulate variable radius queries
{
librg_entity_radius_set(world_tracker(), p[i].peer, radius);
}
// TODO(zaklaus): push radius once librg patch comes in
int32_t result = librg_world_write(world_tracker(), p[i].peer, buffer, &datalen, NULL);
if (result > 0) {
zpl_printf("[info] buffer size was not enough, please increase it by at least: %d\n", result);
} else if (result < 0) {
zpl_printf("[error] an error happened writing the world %d\n", result);
}
pkt_send_librg_update((uint64_t)p[i].peer, p[i].view_id, ticker, buffer, datalen);
}
}
@ -212,7 +221,7 @@ int32_t world_update() {
profile (PROF_UPDATE_SYSTEMS) {
ecs_progress(world.ecs, 0.0f);
}
world_tracker_update(0, WORLD_TRACKER_UPDATE_FAST_MS, 2);
world_tracker_update(1, WORLD_TRACKER_UPDATE_NORMAL_MS, 4);
world_tracker_update(2, WORLD_TRACKER_UPDATE_SLOW_MS, 6);

View File

@ -3,11 +3,11 @@
#include "flecs/flecs_meta.h"
ECS_STRUCT(Input, {
float x;
float y;
uint8_t use;
uint8_t sprint;
});
float x;
float y;
uint8_t use;
uint8_t sprint;
});
typedef struct {
ECS_DECLARE_COMPONENT(Input);
@ -22,14 +22,14 @@ typedef struct {
} Controllers;
#define ControllersImportHandles(handles)\
ECS_IMPORT_COMPONENT(handles, Input);\
ECS_IMPORT_TYPE(handles, Player);\
ECS_IMPORT_TYPE(handles, Builder);\
ECS_IMPORT_ENTITY(handles, EcsActor);\
ECS_IMPORT_ENTITY(handles, EcsPlayer);\
ECS_IMPORT_ENTITY(handles, EcsBuilder);\
ECS_IMPORT_ENTITY(handles, EcsDemoNPC);\
ECS_IMPORT_ENTITY(handles, MovementImpulse);\
ECS_IMPORT_ENTITY(handles, DemoNPCMoveAround);\
ECS_IMPORT_COMPONENT(handles, Input);\
ECS_IMPORT_TYPE(handles, Player);\
ECS_IMPORT_TYPE(handles, Builder);\
ECS_IMPORT_ENTITY(handles, EcsActor);\
ECS_IMPORT_ENTITY(handles, EcsPlayer);\
ECS_IMPORT_ENTITY(handles, EcsBuilder);\
ECS_IMPORT_ENTITY(handles, EcsDemoNPC);\
ECS_IMPORT_ENTITY(handles, MovementImpulse);\
ECS_IMPORT_ENTITY(handles, DemoNPCMoveAround);\
void ControllersImport(ecs_world_t *ecs);

View File

@ -35,13 +35,13 @@ void DemoNPCMoveAround(ecs_iter_t *it) {
void ControllersImport(ecs_world_t *ecs) {
ECS_MODULE(ecs, Controllers);
ecs_set_name_prefix(ecs, "Controllers");
ECS_IMPORT(ecs, General);
ECS_IMPORT(ecs, Physics);
ECS_IMPORT(ecs, FlecsMeta);
ECS_META(ecs, Input);
ECS_TAG(ecs, EcsActor);
ECS_TAG(ecs, EcsPlayer);
ECS_TAG(ecs, EcsBuilder);
@ -49,11 +49,11 @@ void ControllersImport(ecs_world_t *ecs) {
ECS_SYSTEM(ecs, MovementImpulse, EcsOnUpdate, Input, physics.Velocity);
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnUpdate, physics.Velocity, EcsDemoNPC);
ECS_PREFAB(ecs, Base, general.Position, physics.Velocity, Input, EcsActor);
ECS_TYPE(ecs, Player, INSTANCEOF | Base, SWITCH | physics.Movement, CASE | physics.Walking, EcsActor, EcsPlayer);
ECS_TYPE(ecs, Builder, INSTANCEOF | Base, SWITCH | physics.Movement, CASE | physics.Flying, EcsActor, EcsBuilder);
ECS_SET_COMPONENT(Input);
ECS_SET_ENTITY(EcsActor);
ECS_SET_ENTITY(EcsPlayer);
@ -61,5 +61,4 @@ void ControllersImport(ecs_world_t *ecs) {
ECS_SET_ENTITY(EcsDemoNPC);
ECS_SET_TYPE(Builder);
ECS_SET_TYPE(Player);
ECS_SET_ENTITY(MovementImpulse);
}

View File

@ -7,7 +7,7 @@
void MoveWalk(ecs_iter_t *it) {
Position *p = ecs_column(it, Position, 1);
Velocity *v = ecs_column(it, Velocity, 2);
for (int i = 0; i < it->count; i++) {
p[i].x += v[i].x * it->delta_time;
p[i].y += v[i].y * it->delta_time;
@ -18,7 +18,6 @@ void MoveWalk(ecs_iter_t *it) {
void HandleCollisions(ecs_iter_t *it) {
Position *p = ecs_column(it, Position, 1);
//Velocity *v = ecs_column(it, Velocity, 2);
for (int i = 0; i < it->count; i++) {
// NOTE(zaklaus): world bounds
@ -45,13 +44,13 @@ void PhysicsImport(ecs_world_t *ecs) {
ECS_TAG(ecs, Walking);
ECS_TAG(ecs, Flying);
ECS_TYPE(ecs, Movement, Walking, Flying);
ECS_META(ecs, Velocity);
ECS_SYSTEM(ecs, MoveWalk, EcsOnUpdate, general.Position, Velocity);
ECS_SYSTEM(ecs, HandleCollisions, EcsOnValidate, general.Position, Velocity);
ECS_SYSTEM(ecs, UpdateTrackerPos, EcsPostUpdate, general.Position);
ECS_SET_TYPE(Movement);
ECS_SET_ENTITY(Walking);
ECS_SET_ENTITY(Flying);