Dibidab is a small game engine with some nice features that I'd like to reuse.
- ECS based (Entities are built out of Components, using EnTT)
- All components are serializable
- Saving and loading Levels (entities and their components)
- SaveGames (saving custom progress data, or custom data specific to an entity)
- Multiplayer (automagically sending entities and component updates over the network)
- Lua scripting (create and update entities and their components using the Lua API)
- Live reloading (reload assets and scripts while your game is running)
- Entity Inspector (inspect and change component values in a GUI)
- Profiler (get an overview of what is taking up the most time in your game-loop)
- Cross Platform (Linux, Windows, and Web browsers)
- Documentation
- Ease-of-use
- Unit-testing
- all the boring stuff
- seriously, don't use this game engine, it's a personal project
Usually you would define a component as a C-style struct like this:
struct MyComponent {
int a;
float x = -30;
std::list<std::string> myHobbies = {"writing shit code", "sleeping"};
};
But using C-structs there's no easy way to...
- send
MyComponent
over the network without breaking pointers - serialize
MyComponent
to json, used for saving and loading - read and change
MyComponent
's values from within a Lua script
So instead we define components in YAML files:
MyComponent:
- a: int
- x: [float, -30]
- myHobbies: std::list<std::string>
Before compilation these Yaml files automagically get converted into C++ structs (thanks to Niek). Alongside these structs, functions are generated to make the serializing and lua magic stuff listed above possible.
I hate it when I have to recompile my game every time I change a variable or a little bit of game logic. It slows down development a lot*.
So with this game engine you can create and update your entity's components inside a (live-reloadable) Lua script!
Example of an entity-template written in Lua:
-- On game restart: recreate this entity with the same template, at the original spawn position
persistenceMode(TEMPLATE | SPAWN_POS | REVIVE)
function create(enemy)
setComponents(enemy, {
Position {
x = 3, y = 50
},
Physics(),
Health {
maxHealth = 4
},
AsepriteView {
sprite = "sprites/enemy"
}
})
onEntityEvent(enemy, "Attacked", function(attack)
local health = component.Health.getFor(enemy)
print("OUCH!", attack.points, health.currHealth, "/", health.maxHealth)
end)
setUpdateFunction(enemy, .1, function(deltaTime)
-- do stuff every 0.1 second
end)
end
* You know what slows down development even more? Writing your own Game Engine in C++ with a scripting API that should speed up development.
Inspect your components as if it were a JSON tree:
void updateLevel()
{
gu::profiler::Zone zone("level update");
doStuff();
}
void loop()
{
{
gu::profiler::Zone zone("logic");
updateLevel();
}
{
gu::profiler::Zone zone("render");
// render stuff...
}
}