Arquitetura
Estrutura de Módulos
O repositório é organizado como um projeto CMake multi-target:
guebly-engine/
├── core/ # guebly_core (biblioteca estática)
│ ├── include/guebly/
│ │ ├── core/ # Engine, EventBus, Time, VFS, Log, JobSystem
│ │ ├── ecs/ # World, Entity, Components
│ │ ├── renderer/ # Renderer2D (OpenGL 3.3 batched)
│ │ ├── renderer3d/ # Renderer3D (deferred PBR)
│ │ ├── audio/ # AudioSystem (miniaudio)
│ │ ├── physics/ # PhysicsWorld (Jolt stub)
│ │ ├── input/ # Input (SDL2)
│ │ ├── scene/ # SceneManager
│ │ └── ui/ # UISystem
│ └── src/
├── scripting/ # guebly_scripting (biblioteca estática)
│ ├── include/guebly/scripting/lua_engine.hpp
│ └── src/
│ ├── lua_engine.cpp # Registro de todas as APIs Lua
│ └── bindings/ # Bindings por módulo
├── editor/ # guebly_editor (executável)
│ └── src/
│ ├── editor_app.cpp # Loop principal do editor
│ └── panels/ # Painéis ImGui
├── runtime/ # guebly_runtime (executável)
│ └── src/main.cpp # Loop de execução de jogos Lua
├── tests/ # guebly_tests (Catch2)
├── templates/ # Templates de projeto
├── tools/ # Ferramentas Python (export, publish)
├── installer/ # Scripts de instalação Windows
├── engine-landing/ # Landing page HTML estática
└── docs/ # Esta documentação (Docusaurus)
Dependências
Gerenciadas pelo sistema (devem estar instaladas)
| Biblioteca | Uso |
|---|---|
| GLEW | Extensões OpenGL |
| Lua 5.x | VM para scripting |
Baixadas pelo FetchContent (automático no configure)
| Biblioteca | Versão | Uso |
|---|---|---|
| SDL2 | 2.32.8 | Janela, contexto GL, input, audio device |
| GLM | 1.0.1 | Matemática vetorial/matricial |
| spdlog | 1.15.3 | Logging estruturado |
| nlohmann_json | 3.12.0 | Serialização JSON (SaveSystem, projeto) |
| Dear ImGui | latest | UI do editor |
| Catch2 | 3.8.1 | Framework de testes |
| stb | latest | stb_image, stb_truetype |
| miniaudio | 0.11 | Engine de áudio cross-platform |
Loop Principal (Runtime)
runtime/src/main.cpp
│
├── SDL_Init (video + audio + gamepad)
├── SDL_CreateWindow + SDL_GL_CreateContext
├── glewInit
├── Renderer2D::init(width, height)
├── AudioSystem::init()
├── Input::init()
├── LuaEngine::init()
│ └── register_api() <- registra todas as APIs Lua
├── LuaEngine::load(script_path)
├── LuaEngine::call("on_start", entity_index)
│
└── loop {
│ SDL_PollEvent → Input::update(events)
│ LuaEngine::call("on_update", entity, dt)
│ Renderer2D::begin_frame()
│ LuaEngine::call("on_render", entity)
│ Renderer2D::end_frame() <- flush + SDL_GL_SwapWindow
│ hot-reload check (F5 key)
│ frame time cap (target_fps)
}
│
└── LuaEngine::call("on_destroy", entity)
Renderer2D — Pipeline de Batching
O Renderer2D usa um único VAO/VBO/IBO com capacidade para 10.000 quads e 32 texturas por batch:
begin_frame()— reseta contadores, limpa cor- Calls de draw — empurram vértices + índices no buffer de CPU
end_frame()— se lotes cheios OU nova textura, flush parcial; no fim, flush final + swap
Formato de vértice: position(3f) + color(4f) + uv(2f) + texIndex(1f)
Shader: shaders/renderer2d.vert / shaders/renderer2d.frag
Projeção: glm::ortho(0, w, h, 0, -1, 1) — y-down, origem canto superior esquerdo
ECS (Entity Component System)
O World usa arrays de componentes indexed por (index, generation):
- Entidades são pares
(uint32_t index, uint32_t generation)empacotados em 64 bits - Componentes disponíveis: Transform, Name, MeshRenderer, Camera, Light, Rigidbody, Script, Tag, Children
- Queries via
World::query<T>()retornam view sobre todos os componentes do tipo T
Do Lua, entidades são representadas como inteiros: (index << 16) | generation.
Sistema de Áudio
Usa miniaudio (header-only, incluído em miniaudio/miniaudio.h):
- Device: auto-detect (WASAPI no Windows, CoreAudio no macOS, ALSA no Linux)
- Formatos suportados: WAV, OGG, FLAC, MP3
- Múltiplas instâncias simultâneas via sound pool interno
- Áudio 3D via atributos de listener + emitter
- Categorias: Master, Music, SFX (volumes independentes)
- Fade in/out implementado via interpolação por frame
Inicialização do LuaEngine
LuaEngine::init()
├── luaL_newstate()
├── luaL_openlibs()
├── sandbox: remove "os", "debug", "io"
└── register_api()
├── lua_register_debug_api
├── lua_register_time_api
├── lua_register_entity_api
├── lua_register_transform_api
├── lua_register_input_api
├── lua_register_audio_api
├── lua_register_physics_api
├── lua_register_renderer_api
├── lua_register_scene_api
├── lua_register_save_system_api
├── register_event_bindings (sobrescreve Event)
├── register_world_bindings (sobrescreve Entity, Transform)
├── register_input_bindings (estende Input)
├── register_audio_bindings (estende Audio)
├── register_physics_bindings (estende Physics)
├── register_math_bindings (estende Vec3, math)
└── register_ui_bindings (UI direto no Renderer2D)