refactor the world system

isolation_bkp/dynres
Dominik Madarász 2021-05-06 17:30:38 +02:00
parent 8c122607a8
commit 97b4cc6864
23 changed files with 274 additions and 121 deletions

View File

@ -19,5 +19,5 @@ add_subdirectory(code/common)
add_subdirectory(code/vendors) add_subdirectory(code/vendors)
add_subdirectory(code/apps/client) add_subdirectory(code/apps/client)
add_subdirectory(code/apps/server) #add_subdirectory(code/apps/server)
add_subdirectory(code/apps/playground) #add_subdirectory(code/apps/playground)

View File

@ -7,6 +7,7 @@ add_library(client-common STATIC
source/main.c source/main.c
source/camera.c source/camera.c
source/entity_view.c source/entity_view.c
source/world_view.c
source/utils/options.c source/utils/options.c

View File

@ -11,11 +11,11 @@ typedef struct entity_view {
ZPL_TABLE_DECLARE(, entity_view_tbl, entity_view_tbl_, entity_view); ZPL_TABLE_DECLARE(, entity_view_tbl, entity_view_tbl_, entity_view);
void entity_view_init(void); void entity_view_init(entity_view_tbl *map);
void entity_view_free(void); void entity_view_free(entity_view_tbl *map);
void entity_view_update_or_create(uint64_t ent_id, entity_view data); void entity_view_update_or_create(entity_view_tbl *map, uint64_t ent_id, entity_view data);
void entity_view_destroy(uint64_t ent_id); void entity_view_destroy(entity_view_tbl *map, uint64_t ent_id);
entity_view *entity_view_get(uint64_t ent_id); entity_view *entity_view_get(entity_view_tbl *map, uint64_t ent_id);
void entity_view_map(void (*map_proc)(uint64_t key, entity_view value)); void entity_view_map(entity_view_tbl *map, void (*map_proc)(uint64_t key, entity_view value));

View File

@ -0,0 +1,14 @@
#pragma once
#include "system.h"
#include "entity_view.h"
#include "world/world.h"
typedef struct {
uint64_t owner_id;
entity_view_tbl entities;
librg_world *tracker;
} world_view;
world_view world_view_create(void);
void world_view_init(world_view *view, uint64_t ent_id, uint16_t block_size, uint16_t chunk_size, uint16_t world_size);
void world_view_destroy(world_view *view);

View File

@ -1,6 +1,7 @@
#include "zpl.h" #include "zpl.h"
#include "camera.h" #include "camera.h"
#include "entity_view.h" #include "entity_view.h"
#include "game.h"
static camera main_camera; static camera main_camera;
@ -12,7 +13,7 @@ void camera_reset(void) {
void camera_update(void) { void camera_update(void) {
switch (main_camera.mode) { switch (main_camera.mode) {
case CAMERA_MODE_FOLLOW: { case CAMERA_MODE_FOLLOW: {
entity_view *view = entity_view_get(main_camera.ent_id); entity_view *view = entity_view_get(game_world_view_get_active(), main_camera.ent_id);
if (!view) break; if (!view) break;
main_camera.x = view->x; main_camera.x = view->x;

View File

@ -2,29 +2,26 @@
ZPL_TABLE_DEFINE(entity_view_tbl, entity_view_tbl_, entity_view); ZPL_TABLE_DEFINE(entity_view_tbl, entity_view_tbl_, entity_view);
static entity_view_tbl cli_entities = {0}; void entity_view_init(entity_view_tbl *map) {
entity_view_tbl_init(map, zpl_heap());
void entity_view_init(void) {
entity_view_tbl_init(&cli_entities, zpl_heap());
} }
void entity_view_free(void) { void entity_view_free(entity_view_tbl *map) {
entity_view_tbl_destroy(&cli_entities); entity_view_tbl_destroy(map);
} }
void entity_view_update_or_create(uint64_t ent_id, entity_view data) { void entity_view_update_or_create(entity_view_tbl *map, uint64_t ent_id, entity_view data) {
entity_view_tbl_set(&cli_entities, ent_id, data); entity_view_tbl_set(map, ent_id, data);
} }
void entity_view_destroy(uint64_t ent_id) { void entity_view_destroy(entity_view_tbl *map, uint64_t ent_id) {
entity_view_tbl_remove(&cli_entities, ent_id); entity_view_tbl_remove(map, ent_id);
} }
entity_view *entity_view_get(uint64_t ent_id) { entity_view *entity_view_get(entity_view_tbl *map, uint64_t ent_id) {
return entity_view_tbl_get(&cli_entities, ent_id); return entity_view_tbl_get(map, ent_id);
} }
void entity_view_map(void (*map_proc)(uint64_t key, entity_view value)) { void entity_view_map(entity_view_tbl *map, void (*map_proc)(uint64_t key, entity_view value)) {
entity_view_tbl_map(&cli_entities, map_proc); entity_view_tbl_map(map, map_proc);
} }

View File

@ -1,9 +1,11 @@
#include "game.h" #include "game.h"
#include "zpl.h"
#include "platform.h" #include "platform.h"
#include "world/world.h" #include "world/world.h"
#include "packet.h" #include "packet.h"
#include "signal_handling.h" #include "signal_handling.h"
#include "network.h" #include "network.h"
#include "world_view.h"
#include "entity_view.h" #include "entity_view.h"
#include "camera.h" #include "camera.h"
@ -12,14 +14,18 @@
#include "flecs/flecs_systems_civetweb.h" #include "flecs/flecs_systems_civetweb.h"
#include "flecs/flecs_os_api_stdcpp.h" #include "flecs/flecs_os_api_stdcpp.h"
#include "packets/pkt_00_init.h"
#include "packets/pkt_01_welcome.h" #include "packets/pkt_01_welcome.h"
static int8_t is_networked_play; static int8_t is_networked_play;
static uint64_t sp_player;
static world_view *world_viewers;
static world_view *active_viewer;
static WORLD_PKT_READER(pkt_reader) { static WORLD_PKT_READER(pkt_reader) {
pkt_header header = {0}; pkt_header header = {0};
uint32_t ok = pkt_header_decode(&header, data, datalen); uint32_t ok = pkt_header_decode(&header, data, datalen);
header.udata = udata;
if (ok && header.ok) { if (ok && header.ok) {
return pkt_handlers[header.id].handler(&header) >= 0; return pkt_handlers[header.id].handler(&header) >= 0;
@ -30,7 +36,7 @@ static WORLD_PKT_READER(pkt_reader) {
} }
static WORLD_PKT_WRITER(sp_pkt_writer) { static WORLD_PKT_WRITER(sp_pkt_writer) {
return world_read(pkt->data, pkt->datalen, NULL); return world_read(pkt->data, pkt->datalen, 0);
} }
static WORLD_PKT_WRITER(mp_pkt_writer) { static WORLD_PKT_WRITER(mp_pkt_writer) {
@ -42,22 +48,30 @@ static WORLD_PKT_WRITER(mp_pkt_writer) {
} }
} }
void game_init(int8_t play_mode, int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) { void world_viewers_init(uint32_t num_viewers) {
is_networked_play = play_mode; zpl_buffer_init(world_viewers, zpl_heap(), num_viewers);
platform_init();
entity_view_init();
camera_reset();
if (is_networked_play) { for (uint32_t i = 0; i < num_viewers; i++) {
world_init_minimal(0, 0, 0, pkt_reader, mp_pkt_writer); world_viewers[i] = world_view_create();
network_init(); }
network_client_connect("127.0.0.1", 27000); }
} else {
stdcpp_set_os_api();
world_init(seed, block_size, chunk_size, world_size, pkt_reader, sp_pkt_writer);
/* server dashboard */ void world_viewers_destroy() {
{ for (uint32_t i = 0; i < zpl_buffer_count(world_viewers); i++) {
world_view_destroy(&world_viewers[i]);
}
zpl_buffer_free(world_viewers);
}
world_view *game_world_view_get(uint16_t idx) {
return &world_viewers[idx];
}
world_view *game_world_view_get_active(void) {
return active_viewer;
}
void flecs_dash_init() {
ECS_IMPORT(world_ecs(), FlecsDash); ECS_IMPORT(world_ecs(), FlecsDash);
ECS_IMPORT(world_ecs(), FlecsSystemsCivetweb); ECS_IMPORT(world_ecs(), FlecsSystemsCivetweb);
@ -65,10 +79,26 @@ void game_init(int8_t play_mode, int32_t seed, uint16_t block_size, uint16_t chu
ecs_set_target_fps(world_ecs(), 60); ecs_set_target_fps(world_ecs(), 60);
} }
sp_player = player_spawn("unnamed"); void game_init(int8_t play_mode, uint32_t num_viewers, int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
is_networked_play = play_mode;
platform_init();
world_viewers_init(num_viewers);
active_viewer = &world_viewers[0];
camera_reset();
pkt_01_welcome table = {.ent_id = 0, .block_size = block_size, .chunk_size = chunk_size, .world_size = world_size}; if (is_networked_play) {
pkt_world_write(MSG_ID_01_WELCOME, pkt_01_welcome_encode(&table), 1, NULL); world_setup_pkt_handlers(pkt_reader, mp_pkt_writer);
network_init();
network_client_connect("127.0.0.1", 27000);
} else {
stdcpp_set_os_api();
world_setup_pkt_handlers(pkt_reader, sp_pkt_writer);
world_init(seed, block_size, chunk_size, world_size);
flecs_dash_init();
}
for (uint32_t i = 0; i < num_viewers; i++) {
pkt_00_init_send(i);
} }
} }
@ -77,13 +107,12 @@ int8_t game_is_networked() {
} }
void game_shutdown() { void game_shutdown() {
entity_view_free(); world_viewers_destroy();
if (is_networked_play) { if (is_networked_play) {
network_client_disconnect(); network_client_disconnect();
network_destroy(); network_destroy();
} else { } else {
player_despawn(sp_player);
world_destroy(); world_destroy();
} }
} }

View File

@ -16,6 +16,7 @@ int main(int argc, char** argv)
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG); zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "s", "single-player", "play single-player game.", ZPL_OPTS_FLAG); zpl_opts_add(&opts, "s", "single-player", "play single-player game.", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "c", "viewer-count", "number of viewers (detachable clients)", ZPL_OPTS_INT);
zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG); zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT); 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, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
@ -33,6 +34,7 @@ int main(int argc, char** argv)
int8_t is_networked_play = !zpl_opts_has_arg(&opts, "single-player"); int8_t is_networked_play = !zpl_opts_has_arg(&opts, "single-player");
int32_t seed = zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED); int32_t seed = zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
uint16_t num_viewers = zpl_opts_integer(&opts, "viewer-count", 1);
uint16_t block_size = zpl_opts_integer(&opts, "block-size", DEFAULT_BLOCK_SIZE); uint16_t block_size = zpl_opts_integer(&opts, "block-size", DEFAULT_BLOCK_SIZE);
uint16_t chunk_size = zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE); uint16_t chunk_size = zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
uint16_t world_size = zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE); uint16_t world_size = zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
@ -50,7 +52,7 @@ int main(int argc, char** argv)
} }
sighandler_register(); sighandler_register();
game_init(is_networked_play, seed, block_size, chunk_size, world_size); game_init(is_networked_play, num_viewers, seed, block_size, chunk_size, world_size);
while (game_is_running()) { while (game_is_running()) {
game_input(); game_input();

View File

@ -26,6 +26,7 @@ int32_t network_destroy() {
} }
int32_t network_client_connect(const char *hostname, uint16_t port) { int32_t network_client_connect(const char *hostname, uint16_t port) {
ENetAddress address = {0}; address.port = port; ENetAddress address = {0}; address.port = port;
enet_address_set_host(&address, hostname); enet_address_set_host(&address, hostname);

View File

@ -40,7 +40,7 @@ void platform_render() {
ClearBackground(BLACK); ClearBackground(BLACK);
BeginMode2D(render_camera); BeginMode2D(render_camera);
DrawRectangleV((Vector2){0,0}, (Vector2){40,40}, RED); DrawRectangleV((Vector2){0,0}, (Vector2){40,40}, RED);
entity_view_map(DEBUG_draw_entities); entity_view_map(&game_world_view_get_active()->entities, DEBUG_draw_entities);
EndMode2D(); EndMode2D();
display_conn_status(); display_conn_status();
EndDrawing(); EndDrawing();

View File

@ -0,0 +1,56 @@
#include "world_view.h"
#include "librg.h"
int32_t tracker_read_create(librg_world *w, librg_event *e) {
int64_t owner_id = librg_event_owner_get(w, e);
int64_t entity_id = librg_event_entity_get(w, e);
zpl_printf("[INFO] An entity %d was created for owner: %d\n", (int)entity_id, (int)owner_id);
world_view *view = (world_view*)librg_world_userdata_get(w);
// TODO(zaklaus): receive real data
entity_view_update_or_create(&view->entities, entity_id, (entity_view){0});
return 0;
}
int32_t tracker_read_remove(librg_world *w, librg_event *e) {
int64_t owner_id = librg_event_owner_get(w, 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_destroy(&view->entities, entity_id);
return 0;
}
int32_t tracker_read_update(librg_world *w, librg_event *e) {
// int64_t entity_id = librg_event_entity_get(w, e);
size_t actual_length = librg_event_size_get(w, e);
char *buffer = librg_event_buffer_get(w, e);
// TODO(zaklaus): update real data
return 0;
}
world_view world_view_create(void) {
world_view view = {0};
view.tracker = librg_world_create();
entity_view_init(&view.entities);
return view;
}
void world_view_init(world_view *view, uint64_t ent_id, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
view->owner_id = ent_id;
librg_config_chunksize_set(view->tracker, block_size * chunk_size, block_size * chunk_size, 1);
librg_config_chunkamount_set(view->tracker, world_size, world_size, 1);
librg_config_chunkoffset_set(view->tracker, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, 0);
librg_event_set(view->tracker, LIBRG_READ_CREATE, tracker_read_create);
librg_event_set(view->tracker, LIBRG_READ_REMOVE, tracker_read_remove);
librg_event_set(view->tracker, LIBRG_READ_UPDATE, tracker_read_update);
librg_world_userdata_set(view->tracker, view);
}
void world_view_destroy(world_view *view) {
librg_world_destroy(view->tracker);
entity_view_free(&view->entities);
}

View File

@ -1,7 +1,8 @@
#pragma once #pragma once
#include "system.h" #include "system.h"
#include "world_view.h"
void game_init(int8_t play_mode, int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size); void game_init(int8_t play_mode, uint32_t num_viewers, int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size);
void game_shutdown(); void game_shutdown();
uint8_t game_is_running(); uint8_t game_is_running();
int8_t game_is_networked(); int8_t game_is_networked();
@ -9,3 +10,6 @@ int8_t game_is_networked();
void game_input(); void game_input();
void game_update(); void game_update();
void game_render(); void game_render();
world_view *game_world_view_get_active(void);
world_view *game_world_view_get(uint16_t idx);

View File

@ -4,23 +4,26 @@
// NOTE(zaklaus): packets // NOTE(zaklaus): packets
#include "packets/pkt_00_init.h"
#include "packets/pkt_01_welcome.h" #include "packets/pkt_01_welcome.h"
#include "packets/pkt_send_keystate.h" #include "packets/pkt_send_keystate.h"
#include "packets/pkt_send_librg_update.h" #include "packets/pkt_send_librg_update.h"
#define PKT_HEADER_ELEMENTS 2 #define PKT_HEADER_ELEMENTS 3
pkt_handler pkt_handlers[] = { pkt_handler pkt_handlers[] = {
{.id = MSG_ID_00_INIT, .handler = pkt_00_init_handler},
{.id = MSG_ID_01_WELCOME, .handler = pkt_01_welcome_handler}, {.id = MSG_ID_01_WELCOME, .handler = pkt_01_welcome_handler},
{.id = MSG_ID_LIBRG_UPDATE, .handler = pkt_send_librg_update_handler}, {.id = MSG_ID_LIBRG_UPDATE, .handler = pkt_send_librg_update_handler},
}; };
uint8_t pkt_buffer[PKT_BUFSIZ]; uint8_t pkt_buffer[PKT_BUFSIZ];
int32_t pkt_header_encode(pkt_messages id, void *data, size_t datalen) { int32_t pkt_header_encode(pkt_messages id, uint16_t view_id, void *data, size_t datalen) {
cw_pack_context pc = {0}; cw_pack_context pc = {0};
pkt_pack_msg(&pc, PKT_HEADER_ELEMENTS); pkt_pack_msg(&pc, PKT_HEADER_ELEMENTS);
cw_pack_unsigned(&pc, id); cw_pack_unsigned(&pc, id);
cw_pack_unsigned(&pc, view_id);
cw_pack_bin(&pc, data, datalen); cw_pack_bin(&pc, data, datalen);
return pkt_pack_msg_size(&pc); return pkt_pack_msg_size(&pc);
} }
@ -36,11 +39,19 @@ int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen) {
uint16_t pkt_id = (uint16_t)uc.item.as.u64; uint16_t pkt_id = (uint16_t)uc.item.as.u64;
cw_unpack_next(&uc);
if (uc.item.type != CWP_ITEM_POSITIVE_INTEGER || uc.item.as.u64 > UINT16_MAX) {
return -1; // invalid view id
}
uint16_t view_id = (uint16_t)uc.item.as.u64;
cw_unpack_next(&uc); cw_unpack_next(&uc);
const void *packed_blob = uc.item.as.bin.start; const void *packed_blob = uc.item.as.bin.start;
uint32_t packed_size = uc.item.as.bin.length; uint32_t packed_size = uc.item.as.bin.length;
table->id = pkt_id; table->id = pkt_id;
table->view_id = view_id;
table->data = packed_blob; table->data = packed_blob;
table->datalen = packed_size; table->datalen = packed_size;
table->ok = 1; table->ok = 1;

View File

@ -4,6 +4,7 @@
#define PKT_BUFSIZ 4096 #define PKT_BUFSIZ 4096
typedef enum { typedef enum {
MSG_ID_00_INIT,
MSG_ID_01_WELCOME, MSG_ID_01_WELCOME,
MSG_ID_LIBRG_UPDATE, MSG_ID_LIBRG_UPDATE,
MSG_ID_SEND_KEYSTATE, MSG_ID_SEND_KEYSTATE,
@ -13,10 +14,12 @@ typedef enum {
typedef struct pkt_header { typedef struct pkt_header {
uint16_t id; uint16_t id;
uint16_t sender; uint16_t sender;
uint16_t view_id;
uint8_t *data; uint8_t *data;
uint32_t datalen; uint32_t datalen;
int8_t is_reliable; int8_t is_reliable;
int8_t ok; int8_t ok;
void* udata;
} pkt_header; } pkt_header;
#define PKT_HANDLER_PROC(name) int32_t name(pkt_header *header) #define PKT_HANDLER_PROC(name) int32_t name(pkt_header *header)
@ -27,7 +30,7 @@ typedef struct {
pkt_handler_proc *handler; pkt_handler_proc *handler;
} pkt_handler; } pkt_handler;
int32_t pkt_header_encode(pkt_messages id, void *data, size_t datalen); int32_t pkt_header_encode(pkt_messages id, uint16_t view_id, void *data, size_t datalen);
int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen); int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen);
extern pkt_handler pkt_handlers[]; extern pkt_handler pkt_handlers[];

View File

@ -39,13 +39,14 @@ inline size_t pkt_pack_msg_size(cw_pack_context *pc) {
return pc->current - pc->start; // NOTE(zaklaus): length return pc->current - pc->start; // NOTE(zaklaus): length
} }
inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, size_t pkt_size, int8_t is_reliable) { inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, uint16_t view_id, size_t pkt_size, int8_t is_reliable) {
zpl_zero_item(pkt); zpl_zero_item(pkt);
static uint8_t pkt_data[PKT_BUFSIZ] = {0}; static uint8_t pkt_data[PKT_BUFSIZ] = {0};
zpl_memcopy(pkt_data, pkt_buffer, pkt_size); zpl_memcopy(pkt_data, pkt_buffer, pkt_size);
pkt->data = pkt_buffer; pkt->data = pkt_buffer;
pkt->datalen = pkt_header_encode(id, pkt_data, pkt_size); pkt->view_id = view_id;
pkt->datalen = pkt_header_encode(id, view_id, pkt_data, pkt_size);
pkt->is_reliable = is_reliable; pkt->is_reliable = is_reliable;
pkt->id = id; pkt->id = id;
return 0; return 0;
@ -53,9 +54,9 @@ inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, size_t pkt_size, i
extern int32_t world_write(pkt_header *pkt, void *udata); extern int32_t world_write(pkt_header *pkt, void *udata);
inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_reliable, void *udata) { inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_reliable, uint16_t view_id, void *udata) {
pkt_header pkt; pkt_header pkt;
PKT_IF(pkt_prep_msg(&pkt, id, pkt_size, is_reliable)); PKT_IF(pkt_prep_msg(&pkt, id, view_id, pkt_size, is_reliable));
return world_write(&pkt, udata); return world_write(&pkt, udata);
} }

View File

@ -0,0 +1,38 @@
#include "packets/pkt_00_init.h"
#include "packets/pkt_01_welcome.h"
#include "packet.h"
#include "world/world.h"
#include "game.h"
#include "entity_view.h"
#include "camera.h"
#include "modules/net.h"
pkt_desc pkt_00_init_desc[] = {
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_00_init, view_id) },
{ PKT_END },
};
size_t pkt_00_init_encode(pkt_00_init *table) {
cw_pack_context pc = {0};
pkt_pack_msg(&pc, pkt_pack_desc_args(pkt_00_init_desc));
pkt_pack_struct(&pc, pkt_00_init_desc, PKT_STRUCT_PTR(table));
return pkt_pack_msg_size(&pc);
}
size_t pkt_00_init_send(uint16_t view_id) {
pkt_00_init table = {.view_id = view_id };
return pkt_world_write(MSG_ID_00_INIT, pkt_00_init_encode(&table), 1, view_id, NULL);
}
int32_t pkt_00_init_handler(pkt_header *header) {
ECS_IMPORT(world_ecs(), Net);
pkt_00_init table;
PKT_IF(pkt_msg_decode(header, pkt_00_init_desc, pkt_pack_desc_args(pkt_00_init_desc), PKT_STRUCT_PTR(&table)));
uint64_t peer_id = (uint64_t)header->udata;
uint64_t ent_id = player_spawn(zpl_bprintf("client_%d", peer_id));
ecs_set(world_ecs(), ent_id, ClientInfo, {.peer = ent_id, .view_id = header->view_id });
pkt_01_welcome_send(peer_id, header->view_id, ent_id, world_block_size(), world_chunk_size(), world_world_size());
return 0;
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "system.h"
#include "packet_utils.h"
typedef struct {
uint16_t view_id;
} pkt_00_init;
size_t pkt_00_init_encode(pkt_00_init *table);
size_t pkt_00_init_send(uint16_t view_id);
pkt_desc pkt_00_init_desc[];
PKT_HANDLER_PROC(pkt_00_init_handler);

View File

@ -2,11 +2,8 @@
#include "packet.h" #include "packet.h"
#include "world/world.h" #include "world/world.h"
#include "game.h" #include "game.h"
#ifdef CLIENT
#include "entity_view.h" #include "entity_view.h"
#include "camera.h" #include "camera.h"
#endif
pkt_desc pkt_01_welcome_desc[] = { pkt_desc pkt_01_welcome_desc[] = {
{ PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, ent_id) }, { PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, ent_id) },
@ -22,19 +19,23 @@ size_t pkt_01_welcome_encode(pkt_01_welcome *table) {
pkt_pack_struct(&pc, pkt_01_welcome_desc, PKT_STRUCT_PTR(table)); pkt_pack_struct(&pc, pkt_01_welcome_desc, PKT_STRUCT_PTR(table));
return pkt_pack_msg_size(&pc); return pkt_pack_msg_size(&pc);
} }
size_t pkt_01_welcome_send(uint64_t peer_id,
uint16_t view_id,
uint64_t ent_id,
uint16_t block_size,
uint16_t chunk_size,
uint16_t world_size) {
pkt_01_welcome table = {.ent_id = ent_id, .block_size = block_size, .chunk_size = chunk_size, .world_size = world_size};
return pkt_world_write(MSG_ID_01_WELCOME, pkt_01_welcome_encode(&table), 1, view_id, (void*)peer_id);
}
int32_t pkt_01_welcome_handler(pkt_header *header) { int32_t pkt_01_welcome_handler(pkt_header *header) {
pkt_01_welcome table; pkt_01_welcome table;
PKT_IF(pkt_msg_decode(header, pkt_01_welcome_desc, pkt_pack_desc_args(pkt_01_welcome_desc), PKT_STRUCT_PTR(&table))); PKT_IF(pkt_msg_decode(header, pkt_01_welcome_desc, pkt_pack_desc_args(pkt_01_welcome_desc), PKT_STRUCT_PTR(&table)));
#ifdef CLIENT world_view *view = game_world_view_get(header->view_id);
if (game_is_networked()) {
zpl_printf("[INFO] initializing read-only world view ...\n");
world_init_minimal(table.block_size, table.chunk_size, table.world_size, NULL, NULL);
}
entity_view_update_or_create(table.ent_id, (entity_view){0}); zpl_printf("[INFO] initializing read-only world view ...\n");
camera_set_follow(table.ent_id); world_view_init(view, table.ent_id, table.block_size, table.chunk_size, table.world_size);
#endif
return 0; return 0;
} }

View File

@ -9,6 +9,12 @@ typedef struct {
uint16_t world_size; uint16_t world_size;
} pkt_01_welcome; } pkt_01_welcome;
size_t pkt_01_welcome_send(uint64_t peer_id,
uint16_t view_id,
uint64_t ent_id,
uint16_t block_size,
uint16_t chunk_size,
uint16_t world_size);
size_t pkt_01_welcome_encode(pkt_01_welcome *table); size_t pkt_01_welcome_encode(pkt_01_welcome *table);
pkt_desc pkt_01_welcome_desc[]; pkt_desc pkt_01_welcome_desc[];

View File

@ -1,6 +1,7 @@
#include "packet_utils.h" #include "packet_utils.h"
#include "packets/pkt_send_librg_update.h" #include "packets/pkt_send_librg_update.h"
#include "world/world.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) {
cw_pack_context pc = {0}; cw_pack_context pc = {0};
@ -17,7 +18,9 @@ int32_t pkt_send_librg_update_handler(pkt_header *header) {
if (uc.item.type != CWP_ITEM_BIN) if (uc.item.type != CWP_ITEM_BIN)
return -1; return -1;
int32_t state = librg_world_read(world_tracker(), 1, uc.item.as.bin.start, uc.item.as.bin.length, NULL); world_view *view = game_world_view_get(header->view_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); if (state < 0) zpl_printf("[ERROR] world read error: %d\n", state);
return state; return state;

View File

@ -29,32 +29,9 @@ static world_data world = {0};
int32_t world_gen(); int32_t world_gen();
int32_t tracker_read_create(librg_world *w, librg_event *e) {
int64_t owner_id = librg_event_owner_get(w, e);
int64_t entity_id = librg_event_entity_get(w, e);
zpl_printf("[INFO] An entity %d was created for owner: %d\n", (int)entity_id, (int)owner_id);
return 0;
}
int32_t tracker_read_remove(librg_world *w, librg_event *e) {
int64_t owner_id = librg_event_owner_get(w, 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);
return 0;
}
int32_t tracker_read_update(librg_world *w, librg_event *e) {
// int64_t entity_id = librg_event_entity_get(w, e);
size_t actual_length = librg_event_size_get(w, e);
char *buffer = librg_event_buffer_get(w, e);
return 0;
}
int32_t tracker_write_create(librg_world *w, librg_event *e) { int32_t tracker_write_create(librg_world *w, librg_event *e) {
int64_t owner_id = librg_event_owner_get(w, e); int64_t owner_id = librg_event_owner_get(w, e);
int64_t entity_id = librg_event_entity_get(w, e); int64_t entity_id = librg_event_entity_get(w, e);
zpl_printf("let's add prtint here\n");
return 0; return 0;
} }
@ -74,11 +51,19 @@ int32_t tracker_write_update(librg_world *w, librg_event *e) {
return 0; return 0;
} }
int32_t world_init_minimal(uint16_t block_size, uint16_t chunk_size, uint16_t world_size, world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc) { void world_setup_pkt_handlers(world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc) {
world.reader_proc = reader_proc;
world.writer_proc = writer_proc;
}
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
if (world.data) {
return 0;
}
world.seed = seed;
world.chunk_size = chunk_size; world.chunk_size = chunk_size;
world.world_size = world_size; world.world_size = world_size;
if (reader_proc) world.reader_proc = reader_proc;
if (writer_proc) world.writer_proc = writer_proc;
world.width = chunk_size * world_size; world.width = chunk_size * world_size;
world.height = chunk_size * world_size; world.height = chunk_size * world_size;
@ -99,24 +84,10 @@ int32_t world_init_minimal(uint16_t block_size, uint16_t chunk_size, uint16_t wo
librg_config_chunkamount_set(world.tracker, world_size, world_size, 1); librg_config_chunkamount_set(world.tracker, world_size, world_size, 1);
librg_config_chunkoffset_set(world.tracker, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, 0); librg_config_chunkoffset_set(world.tracker, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, 0);
librg_event_set(world.tracker, LIBRG_READ_CREATE, tracker_read_create);
librg_event_set(world.tracker, LIBRG_READ_REMOVE, tracker_read_remove);
librg_event_set(world.tracker, LIBRG_READ_UPDATE, tracker_read_update);
librg_event_set(world.tracker, LIBRG_WRITE_CREATE, tracker_write_create); librg_event_set(world.tracker, LIBRG_WRITE_CREATE, tracker_write_create);
librg_event_set(world.tracker, LIBRG_WRITE_REMOVE, tracker_write_remove); librg_event_set(world.tracker, LIBRG_WRITE_REMOVE, tracker_write_remove);
librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, tracker_write_update); librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, tracker_write_update);
return 0;
}
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size, world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc) {
if (world.data) {
return 0;
}
world.seed = seed;
world_init_minimal(block_size, chunk_size, world_size, reader_proc, writer_proc);
world.data = zpl_malloc(sizeof(uint8_t)*world.size); world.data = zpl_malloc(sizeof(uint8_t)*world.size);
world.tracker_update = 0; world.tracker_update = 0;
@ -129,11 +100,11 @@ int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint1
ECS_IMPORT(world.ecs, General); ECS_IMPORT(world.ecs, General);
for (int i = 0; i < chunk_size * chunk_size; ++i) { for (int i = 0; i < world_size * world_size; ++i) {
ecs_entity_t e = ecs_new(world.ecs, 0); ecs_entity_t e = ecs_new(world.ecs, 0);
ecs_set(world.ecs, e, Chunk, { ecs_set(world.ecs, e, Chunk, {
.x = i % chunk_size, .x = i % world_size,
.y = i / chunk_size, .y = i / world_size,
}); });
librg_entity_track(world.tracker, e); librg_entity_track(world.tracker, e);
@ -162,15 +133,14 @@ static void world_tracker_update(void) {
ecs_query_t *query = ecs_query_new(world.ecs, "Net.ClientInfo"); ecs_query_t *query = ecs_query_new(world.ecs, "Net.ClientInfo");
ecs_iter_t it = ecs_query_iter(query); ecs_iter_t it = ecs_query_iter(query);
static char buffer[16000] = {0}; char buffer[8096] = {0};
static int32_t datalen = 16000;
while (ecs_query_next(&it)) { while (ecs_query_next(&it)) {
ClientInfo *p = ecs_column(&it, ClientInfo, 1); ClientInfo *p = ecs_column(&it, ClientInfo, 1);
for (int i = 0; i < it.count; i++) { for (int i = 0; i < it.count; i++) {
datalen = 16000; size_t datalen = 8096;
int32_t result = librg_world_write(world_tracker(), it.entities[i], buffer, &datalen, NULL); int32_t result = librg_world_write(world_tracker(), p[i].peer, buffer, &datalen, NULL);
if (result > 0) { if (result > 0) {
zpl_printf("[info] buffer size was not enough, please increase it by at least: %d\n", result); zpl_printf("[info] buffer size was not enough, please increase it by at least: %d\n", result);
@ -178,7 +148,7 @@ static void world_tracker_update(void) {
zpl_printf("[error] an error happened writing the world %d\n", result); 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].peer); pkt_world_write(MSG_ID_LIBRG_UPDATE, pkt_send_librg_update_encode(buffer, datalen), 1, p[i].view_id, p[i].peer);
} }
} }
} }

View File

@ -17,8 +17,8 @@ typedef WORLD_PKT_READER(world_pkt_reader_proc);
#define WORLD_PKT_WRITER(name) int32_t name(pkt_header *pkt, void *udata) #define WORLD_PKT_WRITER(name) int32_t name(pkt_header *pkt, void *udata)
typedef WORLD_PKT_WRITER(world_pkt_writer_proc); typedef WORLD_PKT_WRITER(world_pkt_writer_proc);
int32_t world_init_minimal(uint16_t block_size, uint16_t chunk_size, uint16_t world_size, world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc); void world_setup_pkt_handlers(world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc);
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size, world_pkt_reader_proc *reader_proc, world_pkt_writer_proc *writer_proc); int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size);
int32_t world_destroy(void); int32_t world_destroy(void);
int32_t world_update(void); int32_t world_update(void);
int32_t world_read(void* data, uint32_t datalen, void *udata); int32_t world_read(void* data, uint32_t datalen, void *udata);

View File

@ -4,6 +4,7 @@
ECS_STRUCT(ClientInfo, { ECS_STRUCT(ClientInfo, {
uintptr_t peer; uintptr_t peer;
uint16_t view_id;
}); });
typedef struct { typedef struct {