meta: foundation draft
parent
e302d1c865
commit
1a5ef9e8fc
|
@ -1,5 +1,5 @@
|
||||||
add_executable(minimal
|
add_executable(minimal
|
||||||
src/main.c
|
src/oldmain.c
|
||||||
src/platform.c
|
src/platform.c
|
||||||
src/worldgen.c
|
src/worldgen.c
|
||||||
src/texgen.c
|
src/texgen.c
|
||||||
|
|
|
@ -1,82 +1,5 @@
|
||||||
#define ZPL_IMPL
|
typedef int efd_main;
|
||||||
#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"
|
efd_main start() {
|
||||||
#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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
add_executable(survival
|
add_executable(survival
|
||||||
src/main.c
|
src/oldmain.c
|
||||||
src/platform.c
|
src/platform.c
|
||||||
src/worldgen.c
|
src/worldgen.c
|
||||||
src/texgen.c
|
src/texgen.c
|
||||||
|
|
|
@ -1,101 +1,321 @@
|
||||||
#define ZPL_IMPL
|
#include <stddef.h>
|
||||||
#include "zpl.h"
|
#include <stdint.h>
|
||||||
#include "platform/system.h"
|
#include <stdbool.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"
|
/// lib.c
|
||||||
#include "flecs/flecs_os_api_stdcpp.h"
|
|
||||||
|
|
||||||
#include "models/components.h"
|
// core
|
||||||
#include "systems/systems.h"
|
|
||||||
|
|
||||||
#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)
|
typedef enum efd_asset_type {
|
||||||
#include "tinyc2.h"
|
// EFD_ASSET_NONE = 0,
|
||||||
ZPL_DIAGNOSTIC_POP
|
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
|
typedef struct efd_app_desc {
|
||||||
#define DEFAULT_CHUNK_SIZE 16 /* amount of blocks within a chunk (single axis) */
|
const char *name;
|
||||||
#define DEFAULT_WORLD_SIZE 5 /* amount of chunks within a world (single axis) */
|
int debug_ui;
|
||||||
|
|
||||||
/*
|
int width;
|
||||||
TODO
|
int height;
|
||||||
- monster spawner
|
int fullscreen;
|
||||||
- the longer we survive, the more and stronger enemies we spawn
|
int vsync;
|
||||||
- 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 server_only;
|
||||||
|
int viewer_only;
|
||||||
|
int viewer_amount;
|
||||||
|
int world_seed;
|
||||||
|
int world_seed_random;
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
efd_result (*init_cb)();
|
||||||
zpl_opts opts={0};
|
efd_result (*update_cb)();
|
||||||
zpl_opts_init(&opts, zpl_heap(), argv[0]);
|
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);
|
struct {
|
||||||
zpl_opts_add(&opts, "v", "viewer-only", "run viewer-only client", ZPL_OPTS_FLAG);
|
float item_pickup_radius;
|
||||||
zpl_opts_add(&opts, "d", "server-only", "run dedicated server", ZPL_OPTS_FLAG);
|
float item_merge_radius;
|
||||||
zpl_opts_add(&opts, "p", "preview-map", "draw world preview", ZPL_OPTS_FLAG);
|
float item_drop_radius;
|
||||||
zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT);
|
float item_attract_radius;
|
||||||
zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG);
|
float item_attract_force;
|
||||||
//zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT);
|
} rules;
|
||||||
zpl_opts_add(&opts, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT);
|
} efd_app_desc;
|
||||||
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);
|
// assets
|
||||||
|
|
||||||
if (!ok) {
|
// #define EFD_ASSET_TEXTURE_LAST 15
|
||||||
zpl_opts_print_errors(&opts);
|
// #define EFD_ASSET_ANIMATION_LAST 2222222
|
||||||
zpl_opts_print_help(&opts);
|
// #define EFD_ASSET_ANIMATION_LAST 2222222
|
||||||
return -1;
|
|
||||||
|
// #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");
|
// define world generation rules, load existing world
|
||||||
int8_t is_server_only = zpl_opts_has_arg(&opts, "server-only");
|
// or set up a custom pipeline to generate a new one
|
||||||
int32_t seed = (int32_t)zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
|
// efd_world_load("worlds/default.json");
|
||||||
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;
|
// 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;
|
// 1. define itself
|
||||||
if (is_server_only) play_mode = GAMEKIND_HEADLESS;
|
// 2. render itself
|
||||||
|
// 3. register types for sedning data
|
||||||
|
// 4. define systems and components
|
||||||
|
|
||||||
if (zpl_opts_has_arg(&opts, "random-seed")) {
|
ECS_SYSTEM(efd_world(), Move, EcsOnUpdate, Position, [in] Velocity);
|
||||||
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")) {
|
// register game specific input bindings
|
||||||
generate_minimap(seed, WORLD_BLOCK_SIZE, chunk_size, world_size);
|
// pre-defined bindings and controlsets
|
||||||
return 0;
|
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();
|
// custom bindings and controlsets
|
||||||
game_init(host, port, play_mode, 1, seed, chunk_size, world_size, 0);
|
efd_controlset_keyboard(CONTROLSET_ACCELERATE, EFD_KEY_DOWN, EFD_KEY_SHIFT_LEFT | EFD_KEY_SHIFT_RIGHT);
|
||||||
game_setup_ecs();
|
efd_controlset_gamepad(CONTROLSET_ACCELERATE, EFD_GAMEPAD_LEFT_TRIGGER, 0.5f);
|
||||||
game_run();
|
efd_controlset_apply(EFD_ACTION_SPRINT, CONTROLSET_ACCERLATE);
|
||||||
|
|
||||||
game_shutdown();
|
// custom input bindings for custom actions
|
||||||
sighandler_unregister();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
Loading…
Reference in New Issue