code: added flecs, integrated with librg
parent
3dabfc965e
commit
2ed30603c1
|
@ -15,6 +15,9 @@ add_executable(eco2d-server
|
|||
|
||||
../../vendors/cwpack/cwpack.c
|
||||
../../vendors/cwpack/cwpack.h
|
||||
|
||||
../../vendors/flecs/flecs.c
|
||||
../../vendors/flecs/flecs.h
|
||||
)
|
||||
|
||||
include_directories(eco2d-server header)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
#include "flecs/flecs.h"
|
||||
|
||||
typedef struct {
|
||||
int16_t x, y;
|
||||
} chunk;
|
||||
|
||||
typedef struct {
|
||||
float x, y;
|
||||
} position;
|
||||
|
||||
typedef struct {
|
||||
uint16_t peer_id;
|
||||
} netclient;
|
||||
|
||||
ECS_COMPONENT_DECLARE(chunk);
|
||||
ECS_COMPONENT_DECLARE(position);
|
||||
ECS_COMPONENT_DECLARE(netclient);
|
||||
|
||||
static inline void components_register(ecs_world_t *ecs) {
|
||||
ECS_COMPONENT_DEFINE(ecs, chunk);
|
||||
ECS_COMPONENT_DEFINE(ecs, position);
|
||||
ECS_COMPONENT_DEFINE(ecs, netclient);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#include "system.h"
|
||||
|
||||
void generate_minimap(int32_t seed, uint16_t, uint16_t);
|
||||
void generate_minimap(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size);
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
#pragma once
|
||||
#include "system.h"
|
||||
#include "librg.h"
|
||||
#include "flecs/flecs.h"
|
||||
|
||||
#define WORLD_ERROR_NONE +0x0000
|
||||
#define WORLD_ERROR_OUTOFMEM -0x0001
|
||||
#define WORLD_ERROR_INVALID_BLOCKS -0x0002
|
||||
#define WORLD_ERROR_INVALID_DIMENSIONS -0x0003
|
||||
#define WORLD_ERROR_INVALID_BUFFER -0x0004
|
||||
#define WORLD_ERROR_TRACKER_FAILED -0x0005
|
||||
|
||||
int32_t world_init(int32_t seed, uint16_t chunk_width, uint16_t chunk_height, uint16_t chunk_amountx, uint16_t chunk_amounty);
|
||||
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_update(void);
|
||||
|
||||
uint32_t world_buf(uint8_t const **ptr, uint32_t *width);
|
||||
ecs_world_t * world_ecs(void);
|
||||
librg_world * world_tracker(void);
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include "utils/options.h"
|
||||
|
||||
#define DEFAULT_WORLD_SEED 302097
|
||||
#define DEFAULT_CHUNK_SIZE 16
|
||||
#define DEFAULT_CHUNK_AMOUNT 8
|
||||
#define DEFAULT_BLOCK_SIZE 64 /* amount of units within a block (single axis) */
|
||||
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
|
||||
#define DEFAULT_WORLD_SIZE 8 /* amount of chunks within a world (single axis) */
|
||||
|
||||
#define IF(call) do { \
|
||||
if (call != 0) { \
|
||||
|
@ -25,8 +26,10 @@ int main(int argc, char** argv) {
|
|||
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, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
|
||||
zpl_opts_add(&opts, "cs", "chunk-size", "size of a single chunk", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "ca", "chunk-amount", "amount of chunks", ZPL_OPTS_INT);
|
||||
zpl_opts_add(&opts, "bs", "block-size", "amount of units within a block (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);
|
||||
|
||||
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
|
||||
|
||||
if (!ok) {
|
||||
|
@ -36,9 +39,9 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
int32_t seed = zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
|
||||
int32_t chunk_size = zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
|
||||
int32_t chunk_amount = zpl_opts_integer(&opts, "chunk-amount", DEFAULT_CHUNK_AMOUNT);
|
||||
int32_t world_size = chunk_size * chunk_amount;
|
||||
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 world_size = zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "random-seed")) {
|
||||
zpl_random rnd={0};
|
||||
|
@ -48,12 +51,12 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "preview-map")) {
|
||||
generate_minimap(seed, chunk_size, chunk_amount);
|
||||
generate_minimap(seed, block_size, chunk_size, world_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
zpl_printf("[INFO] Generating world of size: %d x %d\n", world_size, world_size);
|
||||
IF(world_init(seed, chunk_size, chunk_size, chunk_amount, chunk_amount));
|
||||
IF(world_init(seed, block_size, chunk_size, world_size));
|
||||
|
||||
zpl_printf("[INFO] Initializing network...\n");
|
||||
IF(network_init());
|
||||
|
@ -61,6 +64,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
while (true) {
|
||||
network_server_tick();
|
||||
world_update();
|
||||
}
|
||||
|
||||
IF(network_server_stop());
|
||||
|
|
|
@ -9,12 +9,13 @@
|
|||
|
||||
#include "system.h"
|
||||
#include "network.h"
|
||||
#include "components.h"
|
||||
#include "world/world.h"
|
||||
|
||||
#define NETWORK_UPDATE_DELAY 0.100
|
||||
#define NETWORK_MAX_CLIENTS 32
|
||||
|
||||
static ENetHost *server = NULL;
|
||||
static librg_world *server_world = NULL;
|
||||
static zpl_timer nettimer = {0};
|
||||
|
||||
int32_t network_init(void) {
|
||||
|
@ -28,34 +29,6 @@ int32_t network_destroy(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t server_write_update(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);
|
||||
|
||||
return 0;
|
||||
|
||||
// /* prevent sending updates to users who own that entity */
|
||||
// /* since they will be responsible on telling where that entity is supposed to be */
|
||||
// if (librg_entity_owner_get(w, entity_id) == owner_id) {
|
||||
// return LIBRG_WRITE_REJECT;
|
||||
// }
|
||||
|
||||
// /* read our current position */
|
||||
// ENetPeer *peer = (ENetPeer *)librg_entity_userdata_get(w, entity_id);
|
||||
|
||||
// char *buffer = librg_event_buffer_get(w, e);
|
||||
// size_t max_length = librg_event_size_get(w, e);
|
||||
|
||||
// /* check if we have enough space to write and valid position */
|
||||
// if (sizeof(vec3) > max_length || !peer->data) {
|
||||
// return LIBRG_WRITE_REJECT;
|
||||
// }
|
||||
|
||||
// /* write data and return how much we've written */
|
||||
// memcpy(buffer, peer->data, sizeof(vec3));
|
||||
// return sizeof(vec3);
|
||||
}
|
||||
|
||||
int32_t network_server_start(const char *host, uint16_t port) {
|
||||
zpl_unused(host);
|
||||
|
||||
|
@ -73,26 +46,6 @@ int32_t network_server_start(const char *host, uint16_t port) {
|
|||
}
|
||||
|
||||
zpl_printf("[INFO] Started an ENet server...\n");
|
||||
server_world = librg_world_create();
|
||||
|
||||
if (server_world == NULL) {
|
||||
zpl_printf("[ERROR] An error occurred while trying to create a server world.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
zpl_printf("[INFO] Created a new server world\n");
|
||||
|
||||
/* store our host to the userdata */
|
||||
librg_world_userdata_set(server_world, server);
|
||||
|
||||
/* config our world grid */
|
||||
librg_config_chunksize_set(server_world, 16, 16, 16);
|
||||
librg_config_chunkamount_set(server_world, 9, 9, 9);
|
||||
librg_config_chunkoffset_set(server_world, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID);
|
||||
|
||||
librg_event_set(server_world, LIBRG_WRITE_UPDATE, server_write_update);
|
||||
// librg_event_set(server_world, LIBRG_READ_UPDATE, server_read_update);
|
||||
|
||||
zpl_timer_start(&nettimer, NETWORK_UPDATE_DELAY);
|
||||
|
||||
return 0;
|
||||
|
@ -101,11 +54,7 @@ int32_t network_server_start(const char *host, uint16_t port) {
|
|||
int32_t network_server_stop(void) {
|
||||
zpl_timer_stop(&nettimer);
|
||||
enet_host_destroy(server);
|
||||
librg_world_destroy(server_world);
|
||||
|
||||
server_world = NULL;
|
||||
server = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -115,29 +64,32 @@ int32_t network_server_tick(void) {
|
|||
switch (event.type) {
|
||||
case ENET_EVENT_TYPE_CONNECT: {
|
||||
zpl_printf("[INFO] A new user %d connected.\n", event.peer->incomingPeerID);
|
||||
int64_t entity_id = event.peer->incomingPeerID;
|
||||
uint16_t peer_id = event.peer->incomingPeerID;
|
||||
|
||||
// /* we create an entity for our client */
|
||||
// /* in our case it is going to have same id as owner id */
|
||||
// /* since we do not really plan on adding more entities per client for now */
|
||||
// /* and place his entity right in the centerl of the world */
|
||||
// librg_entity_track(server_world, entity_id);
|
||||
// librg_entity_owner_set(server_world, entity_id, event.peer->incomingPeerID);
|
||||
// librg_entity_chunk_set(server_world, entity_id, 1);
|
||||
// librg_entity_radius_set(server_world, entity_id, 2); /* 2 chunk radius visibility */
|
||||
// librg_entity_userdata_set(server_world, entity_id, event.peer); /* save ptr to peer */
|
||||
ecs_entity_t e = ecs_new(world_ecs(), 0);
|
||||
ecs_set(world_ecs(), e, position, {0, 0});
|
||||
ecs_set(world_ecs(), e, netclient, {peer_id});
|
||||
|
||||
event.peer->data = (void*)e;
|
||||
|
||||
librg_entity_track(world_tracker(), e);
|
||||
librg_entity_owner_set(world_tracker(), e, peer_id);
|
||||
librg_entity_chunk_set(world_tracker(), e, 1);
|
||||
librg_entity_radius_set(world_tracker(), e, 2); /* 2 chunk radius visibility */
|
||||
librg_entity_userdata_set(world_tracker(), e, event.peer); /* save ptr to peer */
|
||||
} break;
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT: {
|
||||
zpl_printf("[INFO] A user %d disconnected.\n", event.peer->incomingPeerID);
|
||||
int64_t entity_id = event.peer->incomingPeerID;
|
||||
// librg_entity_untrack(server_world, entity_id);
|
||||
ecs_entity_t e = (ecs_entity_t)event.peer->data;
|
||||
librg_entity_untrack(world_tracker(), e);
|
||||
ecs_delete(world_ecs(), e);
|
||||
} break;
|
||||
|
||||
case ENET_EVENT_TYPE_RECEIVE: {
|
||||
// /* handle a newly received event */
|
||||
// librg_world_read(
|
||||
// server_world,
|
||||
// world_tracker(),
|
||||
// event.peer->incomingPeerID,
|
||||
// (char *)event.packet->data,
|
||||
// event.packet->dataLength,
|
||||
|
@ -170,7 +122,7 @@ void network_server_update(void *data) {
|
|||
|
||||
// /* serialize peer's the world view to a buffer */
|
||||
// librg_world_write(
|
||||
// server_world,
|
||||
// world_tracker(),
|
||||
// currentPeer->incomingPeerID,
|
||||
// buffer,
|
||||
// &buffer_length,
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
#include "world/blocks.h"
|
||||
#include "utils/options.h"
|
||||
|
||||
void generate_minimap(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
|
||||
world_init(seed, chunk_size, chunk_size, chunk_amount, chunk_amount);
|
||||
void generate_minimap(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
|
||||
world_init(seed, block_size, chunk_size, world_size);
|
||||
|
||||
uint8_t const *world;
|
||||
uint32_t world_size = chunk_size * chunk_amount;
|
||||
uint32_t world_length = chunk_size * world_size;
|
||||
uint32_t len = world_buf(&world, NULL);
|
||||
|
||||
for (int i=0; i<len; i++) {
|
||||
if (i > 0 && i % world_size == 0) {
|
||||
if (i > 0 && i % world_length == 0) {
|
||||
putc('\n', stdout);
|
||||
}
|
||||
putc(blocks_get_symbol(world[i]), stdout);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "zpl.h"
|
||||
#include "librg.h"
|
||||
#include "components.h"
|
||||
#include "world/world.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -7,39 +9,114 @@ typedef struct {
|
|||
uint32_t size;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint16_t chunk_width;
|
||||
uint16_t chunk_height;
|
||||
uint16_t chunk_amountx;
|
||||
uint16_t chunk_amounty;
|
||||
uint16_t block_size;
|
||||
uint16_t chunk_size;
|
||||
uint16_t world_size;
|
||||
ecs_world_t *ecs;
|
||||
librg_world *tracker;
|
||||
} world_data;
|
||||
|
||||
|
||||
static world_data world = {0};
|
||||
|
||||
int32_t world_gen();
|
||||
|
||||
int32_t world_init(int32_t seed, uint16_t chunk_width, uint16_t chunk_height, uint16_t chunk_amountx, uint16_t chunk_amounty) {
|
||||
int32_t world_write_update(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);
|
||||
|
||||
return 0;
|
||||
|
||||
// /* prevent sending updates to users who own that entity */
|
||||
// /* since they will be responsible on telling where that entity is supposed to be */
|
||||
// if (librg_entity_owner_get(w, entity_id) == owner_id) {
|
||||
// return LIBRG_WRITE_REJECT;
|
||||
// }
|
||||
|
||||
// /* read our current position */
|
||||
// ENetPeer *peer = (ENetPeer *)librg_entity_userdata_get(w, entity_id);
|
||||
|
||||
// char *buffer = librg_event_buffer_get(w, e);
|
||||
// size_t max_length = librg_event_size_get(w, e);
|
||||
|
||||
// /* check if we have enough space to write and valid position */
|
||||
// if (sizeof(vec3) > max_length || !peer->data) {
|
||||
// return LIBRG_WRITE_REJECT;
|
||||
// }
|
||||
|
||||
// /* write data and return how much we've written */
|
||||
// memcpy(buffer, peer->data, sizeof(vec3));
|
||||
// return sizeof(vec3);
|
||||
}
|
||||
|
||||
int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) {
|
||||
if (world.data) {
|
||||
world_destroy();
|
||||
}
|
||||
|
||||
world.seed = seed;
|
||||
world.width = chunk_width * chunk_amountx;
|
||||
world.height = chunk_height * chunk_amounty;
|
||||
world.size = world.width*world.height;
|
||||
world.block_size = block_size;
|
||||
world.chunk_size = chunk_size;
|
||||
world.world_size = world_size;
|
||||
|
||||
world.width = chunk_size * world_size;
|
||||
world.height = chunk_size * world_size;
|
||||
world.size = world.width * world.height;
|
||||
world.data = zpl_malloc(sizeof(uint8_t)*world.size);
|
||||
|
||||
if (!world.data) {
|
||||
return WORLD_ERROR_OUTOFMEM;
|
||||
}
|
||||
|
||||
world.ecs = ecs_init();
|
||||
components_register(world.ecs);
|
||||
|
||||
world.tracker = librg_world_create();
|
||||
|
||||
if (world.tracker == NULL) {
|
||||
zpl_printf("[ERROR] An error occurred while trying to create a server world.\n");
|
||||
return WORLD_ERROR_TRACKER_FAILED;
|
||||
}
|
||||
|
||||
zpl_printf("[INFO] Created a new server world\n");
|
||||
|
||||
/* config our world grid */
|
||||
librg_config_chunksize_set(world.tracker, block_size * chunk_size, block_size * chunk_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, LIBRG_OFFSET_MID);
|
||||
|
||||
for (int i = 0; i < chunk_size * chunk_size; ++i) {
|
||||
ecs_entity_t e = ecs_new(world.ecs, 0);
|
||||
ecs_set(world.ecs, e, chunk, {
|
||||
.x = i % chunk_size,
|
||||
.y = i / chunk_size,
|
||||
});
|
||||
|
||||
librg_entity_track(world.tracker, e);
|
||||
librg_entity_chunk_set(world.tracker, e, i);
|
||||
|
||||
zpl_printf("creating chunk: #%lld %d %d\n", e, i % chunk_size, i / chunk_size);
|
||||
}
|
||||
|
||||
// librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, world_write_update);
|
||||
// librg_event_set(world.tracker, LIBRG_READ_UPDATE, server_read_update);
|
||||
|
||||
return world_gen();
|
||||
}
|
||||
|
||||
int32_t world_destroy(void) {
|
||||
librg_world_destroy(world.tracker);
|
||||
ecs_fini(world.ecs);
|
||||
zpl_mfree(world.data);
|
||||
zpl_memset(&world, 0, sizeof(world));
|
||||
return WORLD_ERROR_NONE;
|
||||
}
|
||||
|
||||
int32_t world_update() {
|
||||
ecs_progress(world.ecs, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t world_buf(uint8_t const **ptr, uint32_t *width) {
|
||||
ZPL_ASSERT_NOT_NULL(world.data);
|
||||
ZPL_ASSERT_NOT_NULL(ptr);
|
||||
|
@ -48,23 +125,12 @@ uint32_t world_buf(uint8_t const **ptr, uint32_t *width) {
|
|||
return world.size;
|
||||
}
|
||||
|
||||
ecs_world_t * world_ecs() {
|
||||
return world.ecs;
|
||||
}
|
||||
|
||||
librg_world * world_tracker() {
|
||||
return world.tracker;
|
||||
}
|
||||
|
||||
#include "world_gen.c"
|
||||
|
||||
|
||||
|
||||
// 11111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222333333333333333333333333333333333333333
|
||||
|
||||
// world 3x3
|
||||
// chunk 3x3
|
||||
|
||||
// 111 111 111
|
||||
// 222 222 222
|
||||
// 333 333 333
|
||||
|
||||
// 111 111 111
|
||||
// 222 222 222
|
||||
// 333 333 333
|
||||
|
||||
// 111 111 111
|
||||
// 222 222 222
|
||||
// 333 333 333
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
// nothing
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue