Introduction
SSOEngine is a simplified C++ game development framework built on top of Raylib. It provides a complete toolkit for 2D game development with additional 3D capabilities, making it perfect for indie developers and hobbyists.
What Makes SSOEngine Special?
- Dual Development Paths: Choose between Classic Game (manual positioning) or App (container-based) development
- 15+ Tools: Complete toolkit including camera, UI, physics, and asset management
- Build Automation: One-click build with automatic Raylib installation
- Asset Bundling: Custom .sso format for efficient asset packaging
- 3D Support: High-level 3D API for prototyping and advanced features
Getting Started
Prerequisites
- Windows 10 or later (currently Windows-only)
- MinGW-w64 for compilation
- C++17 or later knowledge
- 4GB RAM minimum
💡 Important: Add MinGW-w64 to your PATH during installation for command-line access.
Installation
# Clone the repository
git clone https://github.com/Rozaq125/SSOEngine
cd SSOEngine/01_Core
# Build your game (automatically downloads Raylib)
build.bat
Project Structure
SSOEngine/
├── 00_BuildTools/ # Asset packer source
├── 01_Core/ # Your game code
│ ├── tools/ # Engine tools (C++ headers)
│ ├── assets/ # Game assets
│ ├── build.bat # Build script
│ └── main.cpp # Game entry point
├── 02_Docs/ # Documentation
├── include/ # Raylib headers
└── lib/ # Raylib libraries
Your First Game
#include "tools/sso_window.h"
#include "tools/sso_camera.h"
int main() {
// Initialize window
SSO::Window::Init(1280, 720, "My Game");
SSO::Timer timer;
while (!WindowShouldClose()) {
float dt = timer.GetDeltaTime();
SSO::Window::BeginDrawingVirtual();
ClearBackground(BLACK);
// Your game code here
DrawText("Hello SSOEngine!", 10, 10, 20, WHITE);
SSO::Window::EndDrawingVirtual();
}
SSO::Window::Close();
return 0;
}
Tools Overview
SSOEngine includes 15+ specialized tools for game development. Here's a quick overview:
📦 Container System
Auto-stacking widgets with theme system for applications and tools.
🎮 3D Rendering
High-level 3D API with model loading and basic shapes.
⚛️ Physics Engine
Complete 2D physics with collision detection and rigid bodies.
📷 Camera System
Advanced camera with smoothing, zoom, and screen shake.
⏱️ Timer System
High-precision timer with countdown and stopwatch functionality.
🖼️ Window Manager
Virtual resolution system with letterboxing and scaling.
🎨 UI Framework
Complete UI system with panels, modals, and buttons.
📊 Asset System
Custom .sso bundle format with fast loading.
Classic Game Path
The Classic Game path gives you full control over positioning and rendering. Perfect for traditional games where you need precise control over object placement.
Key Functions
// Manual positioning - free coordinate system
Vector2 playerPos = {100, 200};
SSO::Container::SSO_DrawSprite(playerTexture, playerPos);
SSO::Container::SSO_DrawRectangle({50, 50, 100, 100}, RED);
SSO::Container::SSO_DrawCircle({400, 300}, 50, BLUE);
SSO::Container::SSO_DrawText("Score: 100", {10, 10}, 20, WHITE);
Example: Platformer Character
struct Player {
Vector2 position;
Vector2 velocity;
float speed;
Rectangle bounds;
};
void UpdatePlayer(Player& player, float dt) {
// Input handling
if (IsKeyDown(KEY_RIGHT)) player.velocity.x = player.speed;
else if (IsKeyDown(KEY_LEFT)) player.velocity.x = -player.speed;
else player.velocity.x = 0;
// Update position
player.position.x += player.velocity.x * dt;
player.position.y += player.velocity.y * dt;
// Update bounds
player.bounds.x = player.position.x;
player.bounds.y = player.position.y;
}
App Container Path
The App Container path provides automatic widget stacking and theming. Perfect for applications, tools, and games with complex UI.
Key Functions
// Auto-stacking widgets - no manual positioning
SSO::Container::SSO_BeginPanel({10, 10, 300, 400});
SSO::Container::SSO_PushWidget("Click Me");
SSO::Container::SSO_PushLabel("Information");
SSO::Container::SSO_PushCheckbox("Enable", true);
SSO::Container::SSO_PushSlider("Volume", 50.0f);
SSO::Container::SSO_RenderPanel();
Theme System
// Set global theme
SSO::Container::SSO_SetTheme(SSO::Container::THEME_DARK); // Dark theme
SSO::Container::SSO_SetTheme(SSO::Container::THEME_LIGHT); // Light theme
SSO::Container::SSO_SetTheme(SSO::Container::THEME_SSO_BLUE); // SSO Blue theme
Widget Interaction
// Check button click
if (SSO::Container::SSO_IsButtonClicked("Click Me")) {
// Button was clicked
}
// Get checkbox state
bool enabled = SSO::Container::SSO_IsCheckboxChecked("Enable");
// Get slider value
float volume = SSO::Container::SSO_GetSliderValue("Volume");
3D Rendering
SSOEngine includes a high-level 3D API for prototyping and advanced features. Built on top of Raylib's 3D capabilities.
Model Loading
// Load 3D models (supports .obj, .gltf, .iqm)
Model playerModel = SSO::3D::SSO_LoadModel("assets/player.obj");
Model terrainModel = SSO::3D::SSO_LoadModel("assets/level.gltf");
// Clean up
SSO::3D::SSO_UnloadModel(playerModel);
3D Rendering
// Simple model rendering
SSO::3D::SSO_DrawModel(playerModel, {0, 0, 0}, 1.0f, WHITE);
// Camera system
Camera3D camera = { 0 };
camera.position = {10.0f, 10.0f, 10.0f};
camera.target = {0.0f, 0.0f, 0.0f};
camera.up = {0.0f, 1.0f, 0.0f};
camera.fovy = 45.0f;
camera.projection = CAMERA_PERSPECTIVE;
// 3D Mode switching
SSO::3D::SSO_BeginMode3D(camera);
// Draw 3D objects here
SSO::3D::SSO_EndMode3D();
// Draw 2D UI after 3D
DrawText("Score: 100", 10, 10, 20, WHITE);
Basic 3D Shapes
// Quick prototyping shapes
SSO::3D::SSO_DrawCube({0, 0, 0}, 2.0f, RED);
SSO::3D::SSO_DrawSphere({5, 0, 0}, 1.0f, BLUE);
SSO::3D::SSO_DrawCylinder({-5, 0, 0}, 1.0f, 1.0f, 3.0f, 16, GREEN);
// Wireframe versions
SSO::3D::SSO_DrawCubeWires({0, 2, 0}, 2.0f, WHITE);
SSO::3D::SSO_DrawSphereWires({5, 2, 0}, 1.0f, WHITE);
Grid & Gizmos
// Draw floor grid
SSO::3D::SSO_DrawGrid(20, 1.0f);
// Draw transform gizmo
SSO::3D::SSO_DrawGizmo({0, 0, 0});
Physics Engine
SSOEngine includes a complete 2D physics engine with collision detection, forces, and rigid body dynamics.
Physics Constants
constexpr float GRAVITY = 980.0f; // pixels/second^2
constexpr float AIR_RESISTANCE = 0.99f; // velocity dampening
constexpr float BOUNCE_DAMPING = 0.7f; // energy loss on bounce
RigidBody Structure
SSO::Physics::RigidBody body;
body.position = {x, y};
body.velocity = {vx, vy};
body.acceleration = {ax, ay};
body.radius = radius;
body.mass = mass;
body.isGrounded = false;
body.isStatic = false;
Forces & Impulses
// Apply continuous force
SSO::Physics::ApplyForce(body, {forceX, forceY});
// Apply instant impulse
SSO::Physics::ApplyImpulse(body, {impulseX, impulseY});
// Apply gravity
body.acceleration = {0, SSO::Physics::GRAVITY};
Collision Detection
// Circle vs Circle
bool collision = SSO::Physics::CheckCircleCollision(circle1, circle2);
// Circle vs Rectangle
bool collision = SSO::Physics::CheckCircleRectCollision(circle, rect);
// Rectangle vs Rectangle
bool collision = SSO::Physics::CheckRectCollision(rect1, rect2);
Physics Update Loop
void UpdatePhysics(std::vector& bodies, float dt) {
for (auto& body : bodies) {
if (body.isStatic) continue;
// Apply gravity
body.acceleration = {0, SSO::Physics::GRAVITY};
// Update velocity and position
body.velocity.x += body.acceleration.x * dt;
body.velocity.y += body.acceleration.y * dt;
body.position.x += body.velocity.x * dt;
body.position.y += body.velocity.y * dt;
// Apply air resistance
body.velocity.x *= SSO::Physics::AIR_RESISTANCE;
body.velocity.y *= SSO::Physics::AIR_RESISTANCE;
}
}
Asset Management
SSOEngine uses a custom .sso bundle format for efficient asset packaging and loading. This allows you to package all game assets into a single file for easy distribution.
Asset Packer
The asset packer automatically converts files in the assets/ folder to .sso format:
# Run the asset packer
sso_packer.exe
# Input: assets/ folder
# Output: build/assets.sso
Loading Assets from Bundle
// Load textures
Texture2D playerTex = SSO::Provider::LoadTextureFromBundle("assets.sso", "player.png");
// Load sounds
Sound jumpSound = SSO::Provider::LoadWaveFromBundle("assets.sso", "jump.wav");
// Load music
Music bgMusic = SSO::Provider::LoadMusicFromBundle("assets.sso", "background.ogg");
// Load 3D models (NEW!)
Model playerModel = SSO::Provider::LoadModelFromBundle("assets.sso", "player.obj");
// Load fonts
Font gameFont = SSO::Provider::LoadFontFromBundle("assets.sso", "font.ttf", 20);
Examples
Complete Game Example
Here's how to use multiple tools together in a complete game:
#include "tools/sso_window.h"
#include "tools/sso_camera.h"
#include "tools/sso_timer.h"
#include "tools/sso_ui.h"
#include "tools/sso_physics.h"
#include "tools/sso_container.h"
#include "tools/sso_3d.h"
int main() {
// Show splash screen
SSO::Splash::Show(2.0f);
// Initialize systems
SSO::Window::Init(1280, 720, "Advanced Game Demo");
SSO::Container::SSO_InitContainer();
SSO::Container::SSO_SetTheme(SSO::Container::THEME_SSO_BLUE);
// Setup camera
SSO::Camera camera(Vector2{0, 0}, 1280, 720);
camera.SetZoom(1.0f);
// Setup timer
SSO::Timer engineTimer;
SSO::Timer gameTimer;
gameTimer.SetValue(120.0f);
gameTimer.Start();
// Create physics world
std::vector physicsObjects;
// Player physics body
SSO::Physics::RigidBody player;
player.position = {0, 0};
player.velocity = {0, 0};
player.radius = 20.0f;
player.mass = 1.0f;
physicsObjects.push_back(player);
while (!WindowShouldClose()) {
float dt = engineTimer.GetDeltaTime();
gameTimer.UpdateCountdown(dt);
// Update physics
for (auto& body : physicsObjects) {
if (body.isStatic) continue;
body.acceleration = {0, SSO::Physics::GRAVITY};
body.velocity.x += body.acceleration.x * dt;
body.velocity.y += body.acceleration.y * dt;
body.position.x += body.velocity.x * dt;
body.position.y += body.velocity.y * dt;
body.velocity.x *= 0.98f;
body.velocity.y *= 0.98f;
}
// Camera follow
camera.Follow(physicsObjects[0].position, dt);
// Rendering
SSO::Window::BeginDrawingVirtual();
ClearBackground(BLACK);
// Game world (with camera)
camera.Begin();
DrawGrid(40, 100);
for (const auto& body : physicsObjects) {
DrawCircleV(body.position, body.radius, BLUE);
}
camera.End();
// UI (no camera)
SSO::Container::SSO_BeginPanel({10, 10, 300, 200});
SSO::Container::SSO_PushLabel("Game Stats");
SSO::Container::SSO_PushLabel(TextFormat("Time: %.1f", gameTimer.GetValue()));
SSO::Container::SSO_PushLabel(TextFormat("FPS: %d", GetFPS()));
SSO::Container::SSO_RenderPanel();
SSO::Window::EndDrawingVirtual();
}
SSO::Window::Close();
return 0;
}
Troubleshooting
Common Issues
Build Errors
Solution: Make sure MinGW-w64 is installed and in your PATH. Run the build script from the 01_Core directory.
Raylib Not Found
Solution: The build script should automatically download Raylib. If it fails, manually download Raylib and extract to the include/ and lib/ folders.
Solution: These features are currently in development. Please use the stable Classic Game path for production projects. Check GitHub for the latest development updates.
Asset Loading Issues
Solution: Make sure assets are in the 01_Core/assets/ folder and run build.bat to recreate the bundle.
Window Issues
Solution: Always use SSO::Window::BeginDrawingVirtual() and EndDrawingVirtual(), not the raw Raylib functions.
Best Practices
- Always call SSO::Window::Close() before exiting
- Use SSO::Window::BeginDrawingVirtual() for rendering
- Check timer IsFinished() before using values
- Free loaded assets when done
- Use namespace prefixes (SSO::) to avoid conflicts
Getting Help
If you're still having issues:
- Check the GitHub Issues
- Join our community on GitHub
- Email: spctacularstudio@gmail.com