meta: foundation draft

efd/v1
Vladyslav Hrytsenko 2023-02-13 10:12:32 +02:00
parent e302d1c865
commit 1a5ef9e8fc
7 changed files with 550 additions and 160 deletions

View File

@ -1,5 +1,5 @@
add_executable(minimal
src/main.c
src/oldmain.c
src/platform.c
src/worldgen.c
src/texgen.c

View File

@ -1,82 +1,5 @@
#define ZPL_IMPL
#include "zpl.h"
#include "platform/system.h"
#include "core/game.h"
#include "models/entity.h"
#include "world/entity_view.h"
#include "utils/options.h"
#include "platform/signal_handling.h"
#include "platform/profiler.h"
typedef int efd_main;
#include "flecs.h"
#include "flecs/flecs_os_api_stdcpp.h"
#include "models/components.h"
#include "systems/systems.h"
#include "platform/arch.h"
#define DEFAULT_WORLD_SEED 302097
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
int main(int argc, char** argv) {
zpl_opts opts={0};
zpl_opts_init(&opts, zpl_heap(), argv[0]);
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", 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, "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, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING);
zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT);
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
if (!ok) {
zpl_opts_print_errors(&opts);
zpl_opts_print_help(&opts);
return -1;
}
int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only");
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
zpl_string host = zpl_opts_string(&opts, "host", NULL);
uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0);
game_kind play_mode = GAMEKIND_SINGLE;
if (is_viewer_only) play_mode = GAMEKIND_CLIENT;
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
if (zpl_opts_has_arg(&opts, "random-seed")) {
zpl_random rnd={0};
zpl_random_init(&rnd);
seed = zpl_random_gen_u32(&rnd);
zpl_printf("Seed: %u\n", seed);
}
if (zpl_opts_has_arg(&opts, "preview-map")) {
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
return 0;
}
sighandler_register();
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
game_run();
game_shutdown();
sighandler_unregister();
zpl_string_free(host);
zpl_opts_free(&opts);
efd_main start() {
return 0;
}

View File

@ -0,0 +1,82 @@
#define ZPL_IMPL
#include "zpl.h"
#include "platform/system.h"
#include "core/game.h"
#include "models/entity.h"
#include "world/entity_view.h"
#include "utils/options.h"
#include "platform/signal_handling.h"
#include "platform/profiler.h"
#include "flecs.h"
#include "flecs/flecs_os_api_stdcpp.h"
#include "models/components.h"
#include "systems/systems.h"
#include "platform/arch.h"
#define DEFAULT_WORLD_SEED 302097
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
int main(int argc, char** argv) {
zpl_opts opts={0};
zpl_opts_init(&opts, zpl_heap(), argv[0]);
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", 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, "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, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING);
zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT);
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
if (!ok) {
zpl_opts_print_errors(&opts);
zpl_opts_print_help(&opts);
return -1;
}
int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only");
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
zpl_string host = zpl_opts_string(&opts, "host", NULL);
uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0);
game_kind play_mode = GAMEKIND_SINGLE;
if (is_viewer_only) play_mode = GAMEKIND_CLIENT;
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
if (zpl_opts_has_arg(&opts, "random-seed")) {
zpl_random rnd={0};
zpl_random_init(&rnd);
seed = zpl_random_gen_u32(&rnd);
zpl_printf("Seed: %u\n", seed);
}
if (zpl_opts_has_arg(&opts, "preview-map")) {
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
return 0;
}
sighandler_register();
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
game_run();
game_shutdown();
sighandler_unregister();
zpl_string_free(host);
zpl_opts_free(&opts);
return 0;
}

View File

@ -1,5 +1,5 @@
add_executable(survival
src/main.c
src/oldmain.c
src/platform.c
src/worldgen.c
src/texgen.c

View File

@ -1,101 +1,321 @@
#define ZPL_IMPL
#include "zpl.h"
#include "platform/system.h"
#include "core/game.h"
#include "game.h"
#include "models/entity.h"
#include "world/entity_view.h"
#include "utils/options.h"
#include "platform/signal_handling.h"
#include "platform/profiler.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "flecs.h"
#include "flecs/flecs_os_api_stdcpp.h"
/// lib.c
#include "models/components.h"
#include "systems/systems.h"
// core
#include "platform/arch.h"
typedef int efd_app;
typedef uint16_t efd_entity_type;
typedef int32_t efd_result;
typedef uint64_t efd_entity;
ZPL_DIAGNOSTIC_PUSH_WARNLEVEL(0)
#include "tinyc2.h"
ZPL_DIAGNOSTIC_POP
typedef enum efd_asset_type {
// EFD_ASSET_NONE = 0,
EFD_ASSET_TEXTURE,
EFD_ASSET_ANIMATION,
EFD_ASSET_SOUND,
EFD_ASSET_FONT,
EFD_ASSET_SHADER,
EFD_ASSET_COUNT_TYPES,
} efd_asset_type;
#define DEFAULT_WORLD_SEED 302097
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
typedef struct efd_app_desc {
const char *name;
int debug_ui;
/*
TODO
- monster spawner
- the longer we survive, the more and stronger enemies we spawn
- player grows HP by leveling up
- XP increases by killing mobs
- player can pick an "ability" upon reaching level milestones
- abilities: armor/shield, TODO ...
- enemies damage player when close to him in ticks (damage effects, ...)
- basic projectile pooling (flecs)
- somewhat believable world gen, small hamlets with cols, etc
*/
int width;
int height;
int fullscreen;
int vsync;
int server_only;
int viewer_only;
int viewer_amount;
int world_seed;
int world_seed_random;
int main(int argc, char** argv) {
zpl_opts opts={0};
zpl_opts_init(&opts, zpl_heap(), argv[0]);
efd_result (*init_cb)();
efd_result (*update_cb)();
efd_result (*render_cb)(efd_entity_type type);
efd_result (*player_join_cb)(efd_entity player_id);
efd_result (*player_leave_cb)(efd_entity player_id);
efd_result (*cleanup_cb)();
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", 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, "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, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING);
zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT);
struct {
float item_pickup_radius;
float item_merge_radius;
float item_drop_radius;
float item_attract_radius;
float item_attract_force;
} rules;
} efd_app_desc;
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
// assets
if (!ok) {
zpl_opts_print_errors(&opts);
zpl_opts_print_help(&opts);
return -1;
// #define EFD_ASSET_TEXTURE_LAST 15
// #define EFD_ASSET_ANIMATION_LAST 2222222
// #define EFD_ASSET_ANIMATION_LAST 2222222
// #define CONC(a, b) a##b
/* + CONC(type, _LAST) */
#define EFD_ASSET_SHIFT 16
#define EFD_ASSET(type) ((type) << EFD_ASSET_SHIFT)
#define EFD_ASSET_TYPE(id) ((id) >> EFD_ASSET_SHIFT)
typedef struct efd_asset {
int id;
const char *path;
void *data; /* TODO: make a union */
} efd_asset;
efd_result efd_asset_add(int id, const char *path);
efd_result efd_asset_remove(int id);
efd_asset *efd_asset_get(int id);
// notifications
efd_result efd_notify_push(efd_entity actor, const char *title, const char *text, float duration);
efd_result efd_notify_clear(efd_entity actor);
// tooltips
efd_result efd_tooltip_add(const char *name, const char *text);
efd_result efd_tooltip_remove(const char *name);
// entities
enum efd_entity_type_builtins {
EFD_ENTITY_NONE = 0,
EFD_ENTITY_PLAYER = 1,
EFD_ENTITY_CHUNK,
EFD_ENTITY_OBJECT,
EFD_ENTITY_ITEM,
EFD_ENTITY_NPC,
EFD_ENTITY_VEHICLE,
EFD_ENTITY_TYPE_LAST,
EFD_ENTITY_TYPE_MAX = 0xFFFF,
};
/// app.c
enum {
/* textures */
ASSET_TILE_DIRT = EFD_ASSET(EFD_ASSET_TEXTURE),
ASSET_TILE_GRASS,
ASSET_TILE_STONE,
ASSET_BLOCK_STONE,
ASSET_BLOCK_BRICK,
ASSET_PLAYER,
ASSET_TREE,
ASSET_CHEST,
ASSET_MONSTER,
/* animations */
ASSET_PLAYER_ANIM = EFD_ASSET(EFD_ASSET_ANIMATION),
/* sounds */
ASSET_PLAYER_SOUND = EFD_ASSET(EFD_ASSET_SOUND),
ASSET_TREE_SOUND,
ASSET_CHEST_SOUND,
/* fonts */
ASSET_FONT_DEFAULT = EFD_ASSET(EFD_ASSET_FONT),
};
enum {
ENTITY_MONSTER = EFD_ENTITY_TYPE_LAST,
ENTITY_WEAPON,
};
void Move(ecs_iter_t *it) {
// Get fields from system query
Position *p = ecs_field(it, Position, 1);
Velocity *v = ecs_field(it, Velocity, 2);
// Iterate matched entities
for (int i = 0; i < it->count, i++) {
p[i].x += v[i].x;
p[i].y += v[i].y;
}
}
efd_result init() {
// register assets
{
// register textures (tiles)
efd_asset_add(ASSET_TILE_DIRT, "assets/tile_dirt.png");
efd_asset_add(ASSET_TILE_GRASS, "assets/tilegrass.png");
efd_asset_add(ASSET_TILE_STONE, "assets/tilestone.png");
// register textures (blocks)
efd_asset_add(ASSET_BLOCK_STONE, "assets/block_stone.png");
efd_asset_add(ASSET_BLOCK_BRICK, "assets/block_brick.png");
// register textures (entities)
efd_asset_add(ASSET_PLAYER, "assets/player.png");
efd_asset_add(ASSET_TREE, "assets/tree.png");
efd_asset_add(ASSET_CHEST, "assets/chest.png");
efd_asset_add(ASSET_MONSTER, "assets/monster.png");
// register animations
efd_asset_add(ASSET_PLAYER_ANIM, "assets/player.anim");
// register sounds
efd_asset_add(ASSET_PLAYER_SOUND, "assets/player.ogg");
efd_asset_add(ASSET_TREE_SOUND, "assets/tree.ogg");
// register fonts
efd_asset_add(ASSET_FONT_DEFAULT, "assets/font.ttf");
}
int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only");
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
zpl_string host = zpl_opts_string(&opts, "host", NULL);
uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0);
// define world generation rules, load existing world
// or set up a custom pipeline to generate a new one
// efd_world_load("worlds/default.json");
game_kind play_mode = GAMEKIND_SINGLE;
// register tooltips
efd_tooltip_add("ASSET_TREE", "A tree, it's a tree, what do you expect?");
efd_tooltip_add("ASSET_CHEST", "A chest, it's a chest, what do you expect?");
if (is_viewer_only) play_mode = GAMEKIND_CLIENT;
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
// 1. define itself
// 2. render itself
// 3. register types for sedning data
// 4. define systems and components
if (zpl_opts_has_arg(&opts, "random-seed")) {
zpl_random rnd={0};
zpl_random_init(&rnd);
seed = zpl_random_gen_u32(&rnd);
zpl_printf("Seed: %u\n", seed);
}
ECS_SYSTEM(efd_world(), Move, EcsOnUpdate, Position, [in] Velocity);
if (zpl_opts_has_arg(&opts, "preview-map")) {
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
return 0;
}
// register game specific input bindings
// pre-defined bindings and controlsets
efd_controlset_apply(EFD_ACTION_MOVE, EFD_CONTROLSET_WASD | EFD_CONTROLSET_ARROWS | EFD_CONTROLSET_GAMEPAD_LEFT);
efd_controlset_apply(EFD_ACTION_POINT, EFD_CONTROLSET_MOUSE | EFD_CONTROLSET_GAMEPAD_RIGHT);
sighandler_register();
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
game_setup_ecs();
game_run();
// custom bindings and controlsets
efd_controlset_keyboard(CONTROLSET_ACCELERATE, EFD_KEY_DOWN, EFD_KEY_SHIFT_LEFT | EFD_KEY_SHIFT_RIGHT);
efd_controlset_gamepad(CONTROLSET_ACCELERATE, EFD_GAMEPAD_LEFT_TRIGGER, 0.5f);
efd_controlset_apply(EFD_ACTION_SPRINT, CONTROLSET_ACCERLATE);
game_shutdown();
sighandler_unregister();
// custom input bindings for custom actions
efd_controlset_register(ACTION_USE);
efd_controlset_keyboard(CONTROLSET_USE, EFD_KEY_DOWN, EFD_KEY_E);
efd_controlset_gamepad(CONTROLSET_USE, EFD_GAMEPAD_BUTTON_A, 0.5f);
efd_controlset_apply(ACTION_USE, CONTROLSET_USE);
return 0;
}
efd_result update() {
return 0;
}
efd_result render(efd_entity_type type) {
switch (type) {
case EFD_ENTITY_PLAYER:
/* additional/replacable rendering code on top of what EFD provides for built-in types */
efd_render_texture(ASSET_PLAYER, 0, 0, 0, 0, 0, 0, 0, 0);
return 1; /* we handled the rendering, don't render with the default renderer */
break;
case ENTITY_MONSTER:
/* our custom rendering code for monster */
efd_render_texture(ASSET_MONSTER, 0, 0, 0, 0, 0, 0, 0, 0);
break;
case ENTITY_WEAPON:
/* our custom rendering code for weapon */
break;
}
return 0;
}
efd_result player_join(efd_entity player) {
efd_notify_push(player, "Test", "Welcome to the game!", 5.0f);
return 0;
}
efd_result player_leave(efd_entity player) {
return 0;
}
efd_result cleanup() {
return 0;
}
efd_app_desc efd_main() {
return (efd_app_desc){
.name = "Survival",
.debug_ui = true,
/* these are defaults, with zpl_option/config files overrides */
.width = 1280,
.height = 720,
.fullscreen = 0,
.vsync = 1,
/* these are code overrides for zpl_option flags (not defaults) */
.server_only = false,
.viewer_only = false,
.viewer_amount = 1,
.world_seed = 0,
.world_seed_random = true,
/* primary callbacks */
.init_cb = init,
.update_cb = update,
.render_cb = render,
.player_join_cb = player_join,
.player_leave_cb = player_leave,
.cleanup_cb = cleanup,
.rules = {
.item_pickup_radius = 25.0f,
.item_merge_radius = 75.0f,
.item_drop_radius = 15.0f,
.item_attract_radius = 75.0f,
.item_attract_force = 0.1f,
},
};
}
/// test.c
#include <stdio.h>
efd_result efd_asset_add(int id, const char *path) {
printf("asset_add: %d, %s\n", id, path);
return 0;
}
efd_result efd_tooltip_add(const char *id, const char *text) {
printf("tooltip_add: %s, %s\n", id, text);
return 0;
}
efd_result efd_notify_push(efd_entity player, const char *title, const char *text, float duration) {
printf("notify_push: %llu, %s, %s, %f\n", player, title, text, duration);
return 0;
}
void test(efd_entity_type type) { printf("type: %d\n", type); }
int main(int argc, char **argv) {
efd_app_desc desc = efd_main();
printf("value: %f\n", desc.rules.item_pickup_radius);
printf("ASSET_TILE_DIRT: %d\n", ASSET_TILE_DIRT);
printf("ASSET_TILE_GRASS: %d\n", ASSET_TILE_GRASS);
printf("ASSET_PLAYER: %d\n", ASSET_PLAYER);
printf("ASSET_CHEST: %d\n", ASSET_CHEST);
printf("ASSET_PLAYER_ANIM: %d\n", ASSET_PLAYER_ANIM);
printf("ASSET_PLAYER_SOUND: %d\n", ASSET_PLAYER_SOUND);
printf("ASSET_TREE_SOUND: %d\n", ASSET_TREE_SOUND);
desc.init_cb();
zpl_string_free(host);
zpl_opts_free(&opts);
return 0;
}

View File

@ -0,0 +1,101 @@
#define ZPL_IMPL
#include "zpl.h"
#include "platform/system.h"
#include "core/game.h"
#include "game.h"
#include "models/entity.h"
#include "world/entity_view.h"
#include "utils/options.h"
#include "platform/signal_handling.h"
#include "platform/profiler.h"
#include "flecs.h"
#include "flecs/flecs_os_api_stdcpp.h"
#include "models/components.h"
#include "systems/systems.h"
#include "platform/arch.h"
ZPL_DIAGNOSTIC_PUSH_WARNLEVEL(0)
#include "tinyc2.h"
ZPL_DIAGNOSTIC_POP
#define DEFAULT_WORLD_SEED 302097
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
/*
TODO
- monster spawner
- the longer we survive, the more and stronger enemies we spawn
- player grows HP by leveling up
- XP increases by killing mobs
- player can pick an "ability" upon reaching level milestones
- abilities: armor/shield, TODO ...
- enemies damage player when close to him in ticks (damage effects, ...)
- basic projectile pooling (flecs)
- somewhat believable world gen, small hamlets with cols, etc
*/
int main(int argc, char** argv) {
zpl_opts opts={0};
zpl_opts_init(&opts, zpl_heap(), argv[0]);
zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", 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, "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, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
zpl_opts_add(&opts, "ip", "host", "host IP address", ZPL_OPTS_STRING);
zpl_opts_add(&opts, "port", "port", "port number", ZPL_OPTS_INT);
uint32_t ok = zpl_opts_compile(&opts, argc, argv);
if (!ok) {
zpl_opts_print_errors(&opts);
zpl_opts_print_help(&opts);
return -1;
}
int8_t is_viewer_only = zpl_opts_has_arg(&opts, "viewer-only");
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
uint16_t world_size = (uint16_t)zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
zpl_string host = zpl_opts_string(&opts, "host", NULL);
uint16_t port = (uint16_t)zpl_opts_integer(&opts, "port", 0);
game_kind play_mode = GAMEKIND_SINGLE;
if (is_viewer_only) play_mode = GAMEKIND_CLIENT;
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
if (zpl_opts_has_arg(&opts, "random-seed")) {
zpl_random rnd={0};
zpl_random_init(&rnd);
seed = zpl_random_gen_u32(&rnd);
zpl_printf("Seed: %u\n", seed);
}
if (zpl_opts_has_arg(&opts, "preview-map")) {
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
return 0;
}
sighandler_register();
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
game_setup_ecs();
game_run();
game_shutdown();
sighandler_unregister();
zpl_string_free(host);
zpl_opts_free(&opts);
return 0;
}

64
foundation.md 100644
View File

@ -0,0 +1,64 @@
foundation:
* platform
* viewer system ??
* camera
* game
* debug ui
* packet utils
* arch
* input
* profiler
* renderer
* signal handling
* zpl options
* gen/textgen -> assets
* items
* inventory
* crafting
* notifications
* tooltips
* chunk
* blocks
* tiles (and chunk baker)
* systems (core systems)
* components
* net
* packets (but add custom messaging, and security)
* compression
* world
* wrold_view
* entity_view
-------
app - thing that runs game
game - the game stuff, includes client and server
packet - structure that has data written/read by client/server
asset - structure that describes tile/block/object/entity, something that can be visualized
module - a thing that uses a set of ecs components and systems to create a self-contained ecs module
------------
world - a map of chunks within the game world
world-view - a representation of the world recreated by the client
----------
tile - basic thing that makes up the chunks
block - 2nd level of things that make up the chunk
chunk - entity that contains set of tiles and blocks
object - an grid-independant static entity that can exist in the world
entity - a dynamic object that can change position within the world
item - an entity in the world, that can have a different state when its picked up
zpl.eco
foundation
sandbox
survival
prefix: efd_
entity
* objects
* players
* nps
* vehicles
* items