Skip to main content

Client application

The client application is defined by you. You can create a game or other 3D applications through this client application. Your game code is going to be compiled into a shared library instead of an executable. The game code is then loaded by the FakeRuntime application, which itself is compiled into an executable. This has the advantage, to hot-reload the game code and modify and test it without having to restart the entire game/engine.

Client properties

The client application is basically just a struct, that is meant to be filled out by the client and read and understoof by the core engine. This struct contians options for startup and descriptions of how to execute the engine during runtime.

The struct looks like this:

typedef struct fake_application_config
{
/// @brief If enabled, the engine will start without any ui and it can be used as a command line tool.
b8 headless;

/// @brief Window starting position x axis, if applicable.
i16 start_pos_x;

/// @brief Window starting position y axis, if applicable.
i16 start_pos_y;

/// @brief Window starting width, if applicable.
i16 start_width;

/// @brief Window starting height, if applicable.
i16 start_height;

/// @brief The application name used in windowing, if applicable.
char *name;

/// @brief The size of the frame allocator.
u64 frame_allocator_size;

/// @brief The size of the application-specific frame data. Set to 0 if not used.
u64 app_frame_data_size;

/// @brief The renderer backend the client wishes to use.
fake_backend_renderer renderer;

/// @brief The renderer plugin. The engine needs to know about this,
// as it contains the rendering-api specific function pointers.
fake_plugin *renderer_plugin;

/// @brief The shader loader plugin. The engine needs to know about this,
// as it contains the shader compilation interface.
fake_plugin *shader_loader_plugin;

/// @brief Determines the path to the plugin directory and can be chosen by the client.
// It defaults to "../FakePlugins", if no directory was chosen by the client.
char *plugins_directory;
} fake_application_config;

typedef struct fake_application
{
/// @brief The application stage of execution.
fake_application_stage stage;

/// @brief The application configuration.
fake_application_config app_config;

/// @brief application-specific state. Created and managed by the client.
void *client_state;

/// @brief A block of memory to hold the engine state. Created and managed by the engine.
void *engine_state;

/// @brief A darray of all command line arguments.
char **command_line_arguments;

// Function pointers, to be filled by client application.

/// @brief Function pointer to the application's boot sequence. This should fill out the application config with the application's specific requirements.
/// @param app_inst A pointer to the application instance.
/// @returns True on success; otherwise false.
b8 (*boot)(struct fake_application *app_inst);

/// @brief Function pointer to application's initialize function.
/// @param app_inst A pointer to the application instance.
/// @returns True on success; otherwise false.
b8 (*initialize)(struct fake_application *app_inst);

/// @brief Function pointer to application's update function.
/// @param app_inst A pointer to the application instance.
/// @param p_frame_data A pointer to the current frame's data.
/// @returns True on success; otherwise false.
b8 (*update)(struct fake_application *app_inst, struct fake_frame_data *p_frame_data);

/// @brief Function pointer to application's prepare_frame function.
/// @param app_inst A pointer to the application instance.
/// @param p_frame_data A pointer to the current frame's data.
/// @returns True on success; otherwise false.
b8 (*prepare_frame)(struct fake_application *app_inst, struct fake_frame_data *p_frame_data);

/// @brief Function pointer to application's render_frame function.
/// @param app_inst A pointer to the application instance.
/// @param p_frame_data A pointer to the current frame's data.
b8 (*render_frame)(struct fake_application *app_inst, struct fake_frame_data *p_frame_data);

/// @brief Function pointer to handle resizes, if applicable.
/// @param app_inst A pointer to the application instance.
/// @param width The width of the window in pixels.
/// @param height The height of the window in pixels.
void (*on_resize)(struct fake_application *app_inst, u32 width, u32 height);

/// @brief Shuts down the application, prompting release of resources.
/// @param app_inst A pointer to the application instance.
void (*shutdown)(struct fake_application *app_inst);

/// @brief Called after a library file has been unloaded.
/// @note Called whenever the engine decides to reload a library file - the client needs to know about these events, to un/re-register event callbacks or any function pointer in general.
/// @param app_inst A pointer to the application instance.
void (*lib_on_unload)(struct fake_application *app_inst);

/// @brief Called after a library file has been successfully loaded.
/// @note Called whenever the engine decides to reload a library file - the client needs to know about these events, to un/re-register event callbacks or any function pointer in general.
/// @param app_inst A pointer to the application instance.
void (*lib_on_load)(struct fake_application *app_inst);

} fake_application;

Client interface

You need to define specific funtions in your application, that also need to be marked for export into the shared library. Those specific functions are known by the engine as well, in this way the engine can hook your provided functions into the life cycle of the runtime and execute your custom code.

These functions have to be defined as part of your application.


/// @brief Function pointer to the application's boot sequence. This should fill out the application config with the application's specific requirements.
/// @param app_inst A pointer to the application instance.
/// @returns True on success; otherwise false.
b8 boot(struct fake_application *app_inst);

/// @brief Function pointer to application's initialize function.
/// @param app_inst A pointer to the application instance.
/// @returns True on success; otherwise false.
b8 initialize(struct fake_application *app_inst);

/// @brief Function pointer to application's update function.
/// @param app_inst A pointer to the application instance.
/// @param p_frame_data A pointer to the current frame's data.
/// @returns True on success; otherwise false.
b8 update(struct fake_application *app_inst, struct fake_frame_data *p_frame_data);

/// @brief Function pointer to application's prepare_frame function.
/// @param app_inst A pointer to the application instance.
/// @param p_frame_data A pointer to the current frame's data.
/// @returns True on success; otherwise false.
b8 prepare_frame(struct fake_application *app_inst, struct fake_frame_data *p_frame_data);

/// @brief Function pointer to application's render_frame function.
/// @param app_inst A pointer to the application instance.
/// @param p_frame_data A pointer to the current frame's data.
b8 render_frame(struct fake_application *app_inst, struct fake_frame_data *p_frame_data);

/// @brief Function pointer to handle resizes, if applicable.
/// @param app_inst A pointer to the application instance.
/// @param width The width of the window in pixels.
/// @param height The height of the window in pixels.
void on_resize(struct fake_application *app_inst, u32 width, u32 height);

/// @brief Shuts down the application, prompting release of resources.
/// @param app_inst A pointer to the application instance.
void shutdown(struct fake_application *app_inst);

/// @brief Called after a library file has been unloaded.
/// @note Called whenever the engine decides to reload a library file - the client needs to know about these events, to un/re-register event callbacks or any function pointer in general.
/// @param app_inst A pointer to the application instance.
void lib_on_unload(struct fake_application *app_inst);

/// @brief Called after a library file has been successfully loaded.
/// @note Called whenever the engine decides to reload a library file - the client needs to know about these events, to un/re-register event callbacks or any function pointer in general.
/// @param app_inst A pointer to the application instance.
void lib_on_load(struct fake_application *app_inst);