Getting Started - hadron13/Skeewb GitHub Wiki
This is a quick guide on modding Skeewb
Installing
Prerequisites
- C compiler: gcc/clang/mingw-w64
- Cmake
- SDL3 required libraries (Linux)
Downloading and compiling Skeewb (Windows/Linux)
git clone https://github.com/hadron13/Skeewb.git --recurse-submodules
cd Skeewb
gcc crane.c -o crane # clang works too!
./crane
Creating a module
After installing
./crane example
cd examplemod
gcc crane.c -o crane
./crane
Doing these commands will create and compile a simple example Module containing the following code:
#define MODULE "Example"
#include<skeewb/skeewb.h>
module_desc_t load(core_interface_t *core){
core->console_log(INFO, "hello Skeewb!");
return (module_desc_t){
.modid = str("example"),
.version = {0, 0, 1},
};
}
Breaking this code down:
#define MODULE "Example"
Changes the displayed module using console_log()
#include<skeewb/skeewb.h>
Includes the base module library
module_desc_t load(core_interface_t *core)
Is the standard entry point for the module
core->console_log(INFO, "hello Skeewb!");
Logs a message into the console, more info in Core
return (module_desc_t){
.modid = str("example"),
.version = {0, 0, 1},
};
Returns the module description to the Core.
Beyond Hello Skeewb
Using events
void start(core_interface_t *core){
// all modules loaded by now
}
void loop(core_interface_t *core){
// executed in a loop
}
void quit(core_interface_t *core){
// quit() called
}
module_desc_t load(core_interface_t *core){
core->event_listen(str("start"), start);
core->event_listen(str("loop"), start);
core->event_listen(str("quit"), start);
return (module_desc_t){
.modid = str("example"),
.version = {0, 0, 1},
};
}
This example code uses all the standard events in the Core
Using configs
Configs can be used for user customization and configuring other modules
//set configuration
core->config_set((config_t){
.name = str("maximum burgers"),
.type = TYPE_INTEGER,
.value = 10000
});
//get configuration
config_t burger = core->config_get(str("maximum burgers"));
printf("%i burgers", burger.value.integer);
Using resources
Resources are files that can be loaded and overridden by modules
resource_t *funny_text = core->resource_load(str("text"), str("test/fun.txt")));
funny_text = core->resource_overload(str("text"), str("test/Joe.txt"));
string_t joe_string = core->resource_string(funny_text); // contents of Joe.txt
Refer to the Core documentation for more information
Using other module interfaces
#include<skeewb/renderer.h>
void start(core_interface_t *core){
renderer_interface_t *renderer = core->module_get_interface(str("renderer"));
renderer->window_resize(300, 300);
}
All the base game modules should be available under skeewb/
in the examplemod directory
Exporting your own interface
I recommend you create 2 headers: example.h and example_internal.h, with the first containing the types and the interface, and the latter internal module functions and data.
example.h
typedef enum {CHEESE_BURGER, BACON_BURGER, FISH_BURGER} burger_type_t;
typedef struct{
burger_type_t type;
int size;
}burger_t;
typedef struct{
burger_t (*burger_generate)(int budget);
}example_interface_t;
example_internal.h
#include "example.h"
example_interface_t example_interface = {
.burger_generate = example_burger_generate
};
example.c
#include "example_internal.h"
module_desc_t load(core_interface_t *core){
return (module_desc_t){
.modid = str("example"),
.version = {0, 0, 1},
.interface = &example_interface
};
}
Code Convention
I encourage you to follow the Code Convention for better consistency among all modules.
Exploring other modules
The base game module's will contain useful code in modding, ranging from a simple popup to whole rendering pipelines. These are (or will be) the base modules: