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.

Note: This documentation assumes you have basic knowledge of C++ programming and game development concepts.

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
Download Required Tools:

💡 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.

Audio System Overview

SSOEngine provides a comprehensive audio system for music and sound effects management.

Key Features

  • Music streaming and management
  • Sound effect playback
  • Volume control and fading
  • Memory-safe audio handling
#include "tools/sso_audio.h"

// Load and play music
SSO::Audio::Music bgm = SSO::Audio::LoadMusic("assets/music.mp3");
SSO::Audio::PlayMusic(bgm);

// Load and play sound
SSO::Audio::Sound jump = SSO::Audio::LoadSound("assets/jump.wav");
SSO::Audio::PlaySound(jump);

Music Management

Complete music system with streaming, volume control, and memory management.

Music Functions

// Music control
SSO::Audio::PlayMusic(music);
SSO::Audio::PauseMusic();
SSO::Audio::ResumeMusic();
SSO::Audio::StopMusic();

// Volume control
SSO::Audio::SetMusicVolume(0.8f);
SSO::Audio::FadeMusicIn(2.0f);
SSO::Audio::FadeMusicOut(1.5f);

Sound Effects

Sound effect system for game audio feedback and interactions.

Sound Functions

// Sound playback
SSO::Audio::PlaySound(sound);
SSO::Audio::PlaySoundMulti(sound); // Multiple instances
SSO::Audio::StopSound(sound);

// Sound control
SSO::Audio::SetSoundVolume(sound, 0.5f);
SSO::Audio::SetSoundPitch(sound, 1.2f);

Audio Examples

Complete audio implementation examples for common game scenarios.

class AudioManager {
public:
    void Init() {
        bgm = SSO::Audio::LoadMusic("assets/background.mp3");
        jumpSound = SSO::Audio::LoadSound("assets/jump.wav");
        coinSound = SSO::Audio::LoadSound("assets/coin.wav");
    }
    
    void PlayBackgroundMusic() {
        SSO::Audio::PlayMusic(bgm);
        SSO::Audio::SetMusicVolume(0.6f);
    }
    
    void PlayJumpSound() {
        SSO::Audio::PlaySound(jumpSound);
    }
    
private:
    SSO::Audio::Music bgm;
    SSO::Audio::Sound jumpSound;
    SSO::Audio::Sound coinSound;
};

Splash System Overview

Professional splash screen system for game startup and branding.

Key Features

  • Fade in/out effects
  • Customizable duration
  • Logo and text support
  • Professional transitions
#include "tools/sso_splash.h"

// Show splash screen
SSO::Splash::Show(3.0f); // 3 seconds

// Custom splash
SSO::Splash::Show("My Game", "Loading...", 2.0f);

Splash Effects

Advanced splash screen effects and customization options.

// Splash with custom effects
SSO::Splash::ShowWithFade("Game Title", 2.0f);
SSO::Splash::ShowWithLogo("logo.png", "Studio Name", 3.0f);
SSO::Splash::ShowAnimated("Loading...", 1.5f);

Splash Customization

Customize splash screen appearance and behavior.

// Custom splash configuration
SSO::Splash::SetBackgroundColor(BLACK);
SSO::Splash::SetTextColor(WHITE);
SSO::Splash::SetFadeSpeed(1.0f);
SSO::Splash::SetLogoSize(200);

File System Overview

Comprehensive file system for asset management and data storage.

Key Features

  • Cross-platform file operations
  • Asset bundle management
  • File reading and writing
  • Directory operations
#include "tools/sso_file.h"

// File operations
bool exists = SSO::File::Exists("data/save.txt");
std::string content = SSO::File::ReadText("config.json");
SSO::File::WriteText("output.txt", "Hello World");

Asset Bundles

Custom .sso bundle format for efficient asset packaging and loading.

Bundle Features

  • Compressed asset storage
  • Fast loading times
  • Cross-platform compatibility
  • Encryption support
#include "tools/sso_provider.h"

// Load from bundle
unsigned char* data = SSO::Provider::LoadRawDataFromBundle("assets.sso", "player.png", &size);
Texture2D texture = LoadTextureFromImage(LoadImageFromMemory(data, size));

File Operations

Advanced file operations for data management and persistence.

// File management
SSO::File::CreateDirectory("saves");
SSO::File::CopyFile("template.txt", "new_save.txt");
SSO::File::DeleteFile("old_save.txt");

// Directory listing
std::vector files = SSO::File::ListFiles("assets/");

Game Loops

Game loop patterns and best practices for SSOEngine development.

// Main game loop
while (!WindowShouldClose()) {
    float dt = timer.GetDeltaTime();
    
    UpdateGame(dt);
    RenderGame();
    
    SSO::Window::BeginDrawingVirtual();
    // Render game content
    SSO::Window::EndDrawingVirtual();
}

3D Rendering Overview

High-level 3D rendering API built on Raylib's 3D capabilities.

Key Features

  • Model loading and rendering
  • Basic 3D shapes
  • Camera system
  • Lighting support
#include "tools/sso_3d.h"

// Load and render 3D model
Model model = SSO::ThreeD::LoadModel("assets/player.obj");
SSO::ThreeD::DrawModel(model, position, 1.0f, WHITE);

// Draw 3D shapes
SSO::ThreeD::DrawCube({0, 0, 0}, 1.0f, RED);
SSO::ThreeD::DrawSphere({5, 0, 0}, 0.5f, BLUE);

Shader System

Advanced shader system for custom visual effects.

// Load and use shaders
Shader shader = SSO::ThreeD::LoadShader("vertex.vs", "fragment.fs");
SSO::ThreeD::BeginShaderMode(shader);
// Draw with shader
SSO::ThreeD::EndShaderMode();

Rendering Pipeline

Complete rendering pipeline for 2D and 3D graphics.

// Rendering pipeline
SSO::Window::BeginDrawingVirtual();
ClearBackground(BLACK);

// 2D rendering
DrawTexture2D(texture, {0, 0}, WHITE);

// 3D rendering
SSO::ThreeD::BeginMode3D(camera);
// 3D drawing
SSO::ThreeD::EndMode3D();

SSO::Window::EndDrawingVirtual();

Physics Engine Overview

Complete 2D physics engine for realistic game physics.

Key Features

  • Rigid body simulation
  • Collision detection
  • Force and impulse application
  • Material properties
#include "tools/sso_physics.h"

// Create physics world
SSO::Physics::World world({0, -9.81f});

// Create rigid body
SSO::Physics::Body body = world.CreateBody({100, 100}, 1.0f);
body.SetVelocity({5, 0});

// Physics simulation
world.Update(dt);

Collision Detection

Advanced collision detection system for physics interactions.

// Collision detection
bool collision = SSO::Physics::CheckCollision(rect1, rect2);
Vector2 collisionPoint = SSO::Physics::GetCollisionPoint(rect1, rect2);

// Collision response
SSO::Physics::ResolveCollision(body1, body2);

Rigid Bodies

Rigid body simulation for realistic physics behavior.

// Rigid body properties
body.SetMass(2.0f);
body.SetFriction(0.5f);
body.SetRestitution(0.8f);
body.SetGravityScale(1.0f);

// Apply forces
body.ApplyForce({100, 0});
body.ApplyImpulse({0, 50});

Save System (sso_memo.h)

NEW v1.6: Persistent data storage system for game saves and settings!

SSOEngine provides a simple key-value storage system for game save data and persistent settings. Uses std::map for efficient memory management and text files for cross-platform persistence.

Key Features

  • Key-Value Storage: Simple string-based data storage
  • File Persistence: Save and load data from text files
  • Cross-platform: Works on Windows and Android
  • Memory Management: Efficient std::map-based storage

Basic Usage

#include "tools/sso_memo.h"

SSO::Memo saveData;

// Store game data
saveData.write("player_score", "1500");
saveData.write("player_level", "5");
saveData.write("player_name", "Hero");

// Save to file
saveData.save("save.txt");

// Load from file
saveData.load("save.txt");

// Retrieve data
std::string score = saveData.read("player_score");
std::string level = saveData.read("player_level");

// Check if key exists
if (saveData.hasKey("player_health")) {
    std::string health = saveData.read("player_health");
}

File Format

The save system uses simple key=value format:

player_score=1500
player_level=5
player_name=Hero

Available Functions

  • write(key, value) - Store data with key-value pairs
  • read(key) - Read data by key (returns empty string if not found)
  • save(filename) - Save all data to file
  • load(filename) - Load data from file
  • hasKey(key) - Check if key exists
  • size() - Get number of stored items
  • clear() - Clear all data from memory

Best Practices

  • Use string conversion for numeric data with std::to_string() and std::stoi()
  • Check key existence before reading to avoid empty strings
  • Save frequently to prevent data loss
  • Use descriptive keys for easy debugging
  • Clear data when starting new game sessions

Audio System (sso_audio.h)

NEW v1.6: Automatic music management with cross-platform support!

SSOEngine provides a simplified audio system with automatic music management, eliminating the need to manually update each music stream every frame.

Key Features

  • Automatic Management: Register music once, update all with single call
  • Cross-platform: Works on both Windows and Android
  • Sound Effects: Support for multiple sound effects
  • Volume Control: Per-channel volume management

Basic Usage

#include "tools/sso_audio.h"

// Load and play background music
Music bgm = SSO::Audio::LoadMusicStream("assets/music.mp3");
SSO::Audio::RegisterMusic(bgm);
SSO::Audio::PlayMusic(bgm);

// Load sound effects
Sound shoot = SSO::Audio::LoadSound("assets/shoot.wav");
Sound explosion = SSO::Audio::LoadSound("assets/explosion.wav");

// In game loop
while (!WindowShouldClose()) {
    SSO::Audio::UpdateAudio(); // Updates ALL registered music
    
    if (IsKeyPressed(KEY_SPACE)) {
        SSO::Audio::PlaySound(shoot);
    }
    
    // Game code...
}

Advanced Features

// Volume control
SSO::Audio::SetMasterVolume(0.8f);    // 80% master volume
SSO::Audio::SetMusicVolume(0.6f);     // 60% music volume
SSO::Audio::SetSoundVolume(1.0f);     // 100% sound volume

// Music control
SSO::Audio::PauseMusic();
SSO::Audio::ResumeMusic();
SSO::Audio::StopMusic();

// Check if music is playing
bool isPlaying = SSO::Audio::IsMusicPlaying();

// Sound pitch control (if supported)
SSO::Audio::SetSoundPitch(shoot, 1.2f); // 20% higher pitch
Tip: Always call SSO::Audio::UpdateAudio() once per frame in your game loop to keep all registered music streams updated.

Splash System (sso_splash.h)

NEW v1.6: Flexible splash screen with customizable text and font integration!

SSOEngine provides a professional splash screen system with customizable text, font integration, and smooth animations.

Key Features

  • Customizable Text: Set your own title and subtitle or use defaults
  • Font Integration: Automatically loads JetBrainsMono font from assets bundle
  • Fallback Support: Graceful fallback to default font if bundle loading fails
  • Smooth Animations: Fade in/out effects with progress bar
  • Flexible API: Multiple usage patterns for different needs

Usage Examples

#include "tools/sso_splash.h"

// Option 1: Default SSOEngine splash
SSO::Splash::Show(2.0f);

// Option 2: Custom splash with your game title
SSO::Splash::Show(2.0f, "My Awesome Game", "Custom Subtitle");

// Option 3: Game-specific splash (adds "Powered by SSOEngine")
SSO::Splash::ShowGame(2.0f, "My Awesome Game");

Font Integration

Automatic Font Loading: The splash system automatically tries to load font/JetBrainsMono-Bold.ttf from your assets bundle for consistent UI design.
// Font loading priority:
// 1. Try: assets.sso -> font/JetBrainsMono-Bold.ttf
// 2. Fallback: Raylib default font

// This ensures your splash always looks professional
// even if the font bundle is missing.

API Reference

// Main splash function with defaults
void Show(float duration, const char* title = "SSOENGINE", const char* subtitle = "Lightweight C++ Power");

// Game-specific splash helper
void ShowGame(float duration, const char* gameTitle);

File System (sso_file.h)

NEW v1.6: Cross-platform file dialogs without Windows.h conflicts!

SSOEngine provides cross-platform file dialog functionality with clean header design that doesn't conflict with Raylib or other libraries.

Key Features

  • Cross-platform: Windows and Android support
  • No Windows.h Conflicts: Clean header, platform-specific implementations
  • File Operations: Open, save, browse folder dialogs
  • Easy Integration: Simple function calls with default parameters

Basic Usage

#include "tools/sso_file.h"

// Open file dialog
std::string filePath = SSO_OpenFile("Text Files (*.txt)\0*.txt\0", "Open Text File");
if (!filePath.empty()) {
    // Process selected file
    printf("Selected file: %s\n", filePath.c_str());
}

// Save file dialog
std::string savePath = SSO_SaveFile("All Files (*.*)\0*.*\0", "Save As");
if (!savePath.empty()) {
    // Save to selected path
    printf("Save to: %s\n", savePath.c_str());
}

// Browse folder dialog
std::string folderPath = SSO_BrowseFolder("Select Project Folder");
if (!folderPath.empty()) {
    // Use selected folder
    printf("Selected folder: %s\n", folderPath.c_str());
}

Advanced Usage

// Custom file filters
std::string imageFile = SSO_OpenFile(
    "Image Files\0*.png;*.jpg;*.bmp\0"
    "All Files\0*.*\0", 
    "Select Image"
);

// Multiple file types
std::string gameFile = SSO_OpenFile(
    "Game Files\0*.json;*.xml;*.cfg\0"
    "Save Files\0*.save\0"
    "All Files\0*.*\0",
    "Load Game"
);

// Default parameters
std::string quickOpen = SSO_OpenFile(); // Uses "All Files" filter
std::string quickSave = SSO_SaveFile(); // Uses "All Files" filter
std::string quickFolder = SSO_BrowseFolder(); // Uses "Select Folder" title

Platform-Specific Notes

Windows: Uses native Windows API dialogs (GetOpenFileNameA, GetSaveFileNameA, SHBrowseForFolderA)
Android: Returns empty strings (stub implementation) - Android file dialogs require platform-specific UI components
Best Practice: Always check if the returned string is empty before using it, as users may cancel the dialog.

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

Development Status: This feature is currently in development and may not be fully functional in the current release.

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 & Shader System

NEW v1.6: Professional shader system with 5 visual effects now available!

SSOEngine includes a high-level 3D API with advanced shader support for professional visual effects.

Shader Loading from Bundle

// Load shaders from asset bundle
Shader bloomShader = SSO::ThreeD::LoadShaderFromBundle("assets.sso", "shaders/bloom_glow.fs");
Shader crtShader = SSO::ThreeD::LoadShaderFromBundle("assets.sso", "shaders/retro_crt.fs");

// Available shader effects:
// - basic_light.fs    - Classic 3D lighting with shadows
// - bloom_glow.fs     - YouTube-ready glow effects  
// - retro_crt.fs      - TV tube scanlines and distortion
// - grayscale_sepia.fs - Flashback/death effects
// - blur_bokeh.fs     - Depth-of-field blur

Shader Application

// Apply shader effects
SSO::ThreeD::ApplyBasicLight(shader, lightPos, lightColor, viewPos);
SSO::ThreeD::ApplyBloomGlow(shader, gameTime, resolution, 0.8f, 2.0f);
SSO::ThreeD::ApplyRetroCRT(shader, gameTime, resolution, 0.1f, 0.15f);

// Render with shader
BeginShaderMode(currentShader);
SSO::ThreeD::SSO_DrawModel(model, position, scale, color);
EndShaderMode();

Model Loading

// Load 3D models (supports .obj, .gltf, .iqm)
Model playerModel = SSO::ThreeD::SSO_LoadModel("assets/player.obj");
Model terrainModel = SSO::ThreeD::SSO_LoadModel("assets/level.gltf");

// Clean up
SSO::ThreeD::SSO_UnloadModel(playerModel);

3D Rendering

// 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::ThreeD::SSO_BeginMode3D(camera);
// Draw 3D objects with shaders
SSO::ThreeD::SSO_EndMode3D();

Basic 3D Shapes

// Quick prototyping shapes
SSO::ThreeD::SSO_DrawCube({0, 0, 0}, 2.0f, RED);
SSO::ThreeD::SSO_DrawSphere({5, 0, 0}, 1.0f, BLUE);
SSO::ThreeD::SSO_DrawCylinder({-5, 0, 0}, 1.0f, 1.0f, 3.0f, 16, GREEN);

Physics Engines (2D & 3D)

NEW v1.6: Advanced 3D physics engine with realistic collision now available!

SSOEngine includes both 2D and 3D physics engines with realistic collision detection, forces, and rigid body dynamics.

3D Physics Engine (NEW)

// Initialize 3D physics world
SSO::Physics3D::Init();
SSO::Physics3D::SetGravity(-29.43f); // 3x Earth gravity

// Create rigid body
SSO::Physics3D::RigidBody* cube = SSO::Physics3D::CreateBody(position, size, mass);
cube->restitution = 0.2f; // Bounciness
cube->friction = 0.9f;    // Surface friction

// Apply forces and impulses
SSO::Physics3D::ApplyForce(body, forceVector);
SSO::Physics3D::ShootBullet(position, direction, force);
SSO::Physics3D::Explode(center, force, radius);

// Step physics simulation
SSO::Physics3D::Step(deltaTime);

// Draw all physics bodies
SSO::Physics3D::DrawAllBodies();

3D Physics Features

  • Realistic Gravity: Earth gravity simulation with customizable strength
  • Collision Detection: AABB collision with penetration depth calculation
  • Angular Velocity: Objects tumble and rotate realistically
  • Chain Reactions: Force propagation through connected objects
  • Raycast Shooting: Bullet collision with proper hit detection

2D Physics Engine

// 2D Physics constants
constexpr float GRAVITY = 980.0f;        // pixels/second^2
constexpr float AIR_RESISTANCE = 0.99f; // velocity dampening

// RigidBody structure
SSO::Physics::RigidBody body;
body.position = {x, y};
body.velocity = {vx, vy};
body.acceleration = {ax, ay};
body.mass = 1.0f;
body.isStatic = false;

// Apply forces
SSO::Physics::ApplyForce(body, {forceX, forceY});
SSO::Physics::ApplyImpulse(body, {impulseX, impulseY});

Collision Detection

// 2D Collision
bool collision = SSO::Physics::CheckCircleCollision(circle1, circle2);
bool collision = SSO::Physics::CheckRectCollision(rect1, rect2);

// 3D Collision
bool hit = SSO::Physics3D::SSO_CheckCollisionBoxSphere(boxBounds, sphereCenter, sphereRadius);
bool hit = SSO::Physics3D::SSO_CheckCollisionSpheres(center1, radius1, center2, radius2);

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);
Pro Tip: The build.bat script automatically runs the asset packer, so you don't need to run it manually unless you want to.

Examples

Simple Game Example (SSOEngine v1.6 - WORKING)

Here's a simple working game example that compiles successfully:

// File: 01_Core/game/main.cpp
#include "tools/sso_window.h"
#include "tools/sso_camera.h"
#include "tools/sso_timer.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;
}

Advanced Game Example (SSOEngine v1.6 - Modern UI)

Here's the complete modern game example with new theme colors and resolution-independent UI:

NEW v1.6: All UI coordinates are now automatically scaled for any resolution!
// File: 01_Core/game/main.cpp
#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"
#include "tools/sso_splash.h"

int main() {
    // Initialize systems FIRST (v1.6 fix)
    SSO::Window::Init(1280, 720, "Advanced Game Demo v1.6");
    SSO::Container::SSO_InitContainer();
    SSO::Container::SSO_SetTheme(SSO::Container::THEME_EMERALD); // Modern Emerald Theme
    
    // Show splash screen (v1.6 flexible API)
    SSO::Splash::Show(2.0f, "SSOEngine v1.6", "The New Era of Lightweight Power");
    
    // 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 (FIXED: proper template declaration)
    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) - Interactive Button Testing
        // Panel 1: Game Stats
        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();
        
        // Panel 2: Emerald Theme Buttons (Center Left)
        SSO::Container::SSO_SetTheme(SSO::Container::THEME_EMERALD);
        SSO::Container::SSO_BeginPanel({350, 250, 200, 180});
        SSO::Container::SSO_PushHeader("Emerald Controls");
        SSO::Container::SSO_PushWidget("Reset Timer");
        SSO::Container::SSO_PushWidget("Add Physics Ball");
        SSO::Container::SSO_PushWidget("Toggle Gravity");
        SSO::Container::SSO_RenderPanel();
        
        // Panel 3: Sky Blue Theme Buttons (Center)
        SSO::Container::SSO_SetTheme(SSO::Container::THEME_SKY_BLUE);
        SSO::Container::SSO_BeginPanel({570, 250, 200, 180});
        SSO::Container::SSO_PushHeader("Sky Blue Controls");
        SSO::Container::SSO_PushWidget("Change Theme");
        SSO::Container::SSO_PushWidget("Clear Objects");
        SSO::Container::SSO_PushWidget("Show Splash");
        SSO::Container::SSO_RenderPanel();
        
        // Panel 4: Crimson Theme Buttons (Center Right)
        SSO::Container::SSO_SetTheme(SSO::Container::THEME_CRIMSON);
        SSO::Container::SSO_BeginPanel({790, 250, 200, 180});
        SSO::Container::SSO_PushHeader("Crimson Controls");
        SSO::Container::SSO_PushWidget("Exit Game");
        SSO::Container::SSO_PushWidget("Fullscreen Toggle");
        SSO::Container::SSO_PushWidget("Debug Info");
        SSO::Container::SSO_RenderPanel();
        
        // Button Click Detection - Testing GetScaledMousePos()
        // Emerald Panel Actions
        if (SSO::Container::SSO_IsButtonClicked("Reset Timer")) {
            gameTimer.SetValue(120.0f);
            gameTimer.Start();
            TraceLog(LOG_INFO, "BUTTON CLICK: Timer Reset - GetScaledMousePos() working!");
            printf(">>> EMERALD: Timer reset successfully!\n");
        }
        
        if (SSO::Container::SSO_IsButtonClicked("Add Physics Ball")) {
            SSO::Physics::RigidBody newBall;
            newBall.position = {GetRandomValue(-200, 200), -100};
            newBall.velocity = {GetRandomValue(-50, 50), 0};
            newBall.radius = GetRandomValue(10, 30);
            newBall.mass = newBall.radius / 10.0f;
            physicsObjects.push_back(newBall);
            TraceLog(LOG_INFO, "BUTTON CLICK: Physics Ball Added - GetScaledMousePos() working!");
            printf(">>> EMERALD: Added physics ball at (%.1f, %.1f)\n", newBall.position.x, newBall.position.y);
        }
        
        if (SSO::Container::SSO_IsButtonClicked("Toggle Gravity")) {
            static bool gravityOn = true;
            gravityOn = !gravityOn;
            SSO::Physics::GRAVITY = gravityOn ? 500.0f : 0.0f;
            TraceLog(LOG_INFO, "BUTTON CLICK: Gravity Toggled - GetScaledMousePos() working!");
            printf(">>> EMERALD: Gravity %s\n", gravityOn ? "ENABLED" : "DISABLED");
        }
        
        // Sky Blue Panel Actions
        if (SSO::Container::SSO_IsButtonClicked("Change Theme")) {
            static int currentThemeIndex = 4;
            currentThemeIndex = (currentThemeIndex + 1) % 12;
            SSO::Container::SSO_SetTheme(currentThemeIndex);
            TraceLog(LOG_INFO, "BUTTON CLICK: Theme Changed - GetScaledMousePos() working!");
            printf(">>> SKY BLUE: Theme changed to index %d\n", currentThemeIndex);
        }
        
        if (SSO::Container::SSO_IsButtonClicked("Clear Objects")) {
            physicsObjects.clear();
            // Re-add player
            SSO::Physics::RigidBody player;
            player.position = {0, 0};
            player.velocity = {0, 0};
            player.radius = 20.0f;
            player.mass = 1.0f;
            physicsObjects.push_back(player);
            TraceLog(LOG_INFO, "BUTTON CLICK: Objects Cleared - GetScaledMousePos() working!");
            printf(">>> SKY BLUE: All physics objects cleared\n");
        }
        
        // Crimson Panel Actions
        if (SSO::Container::SSO_IsButtonClicked("Fullscreen Toggle")) {
            SSO::Window::ToggleFull();
            TraceLog(LOG_INFO, "BUTTON CLICK: Fullscreen Toggled - GetScaledMousePos() working!");
            printf(">>> CRIMSON: Fullscreen toggled - testing scaling!\n");
        }
        
        if (SSO::Container::SSO_IsButtonClicked("Debug Info")) {
            Vector2 mousePos = SSO::Window::GetVirtualMouse();
            Vector2 rawMouse = GetMousePosition();
            TraceLog(LOG_INFO, "BUTTON CLICK: Debug Info - GetScaledMousePos() working!");
            printf(">>> CRIMSON: Debug Info:\n");
            printf("    Virtual Mouse: (%.1f, %.1f)\n", mousePos.x, mousePos.y);
            printf("    Raw Mouse: (%.1f, %.1f)\n", rawMouse.x, rawMouse.y);
            printf("    Screen: %dx%d\n", GetScreenWidth(), GetScreenHeight());
            printf("    Physics Objects: %zu\n", physicsObjects.size());
        }
        
        // Reset to original theme for next frame
        SSO::Container::SSO_SetTheme(SSO::Container::THEME_SKY_BLUE);
        
        SSO::Window::EndDrawingVirtual();
    }
    
    SSO::Window::Close();
    return 0;
}

Build Instructions

IMPORTANT: Start with the Simple Example above, then use Debug Mode (Option 2) when building!
# 1. Use the Simple Example code in main.cpp
# 2. Run build.bat and select:
# [1] Windows Build
# [2] Debug (With console window for debugging) <- SELECT THIS!

# This ensures main() works correctly without WinMain errors

v1.6 Interactive Button System

NEW: Full button click detection with GetScaledMousePos() testing!
// Button Click Detection - Resolution Independent
if (SSO::Container::SSO_IsButtonClicked("Reset Timer")) {
    gameTimer.SetValue(120.0f);
    gameTimer.Start();
    TraceLog(LOG_INFO, "BUTTON CLICK: Timer Reset - GetScaledMousePos() working!");
    printf(">>> EMERALD: Timer reset successfully!\n");
}

if (SSO::Container::SSO_IsButtonClicked("Add Physics Ball")) {
    SSO::Physics::RigidBody newBall;
    newBall.position = {GetRandomValue(-200, 200), -100};
    newBall.velocity = {GetRandomValue(-50, 50), 0};
    newBall.radius = GetRandomValue(10, 30);
    newBall.mass = newBall.radius / 10.0f;
    physicsObjects.push_back(newBall);
    TraceLog(LOG_INFO, "BUTTON CLICK: Physics Ball Added - GetScaledMousePos() working!");
}

if (SSO::Container::SSO_IsButtonClicked("Fullscreen Toggle")) {
    SSO::Window::ToggleFull();
    TraceLog(LOG_INFO, "BUTTON CLICK: Fullscreen Toggled - GetScaledMousePos() working!");
    printf(">>> CRIMSON: Fullscreen toggled - testing scaling!\n");
}

v1.6 Multi-Theme Layout System

NEW: Multiple panels with different themes in same frame!
// Panel 1: Game Stats (Default Theme)
SSO::Container::SSO_BeginPanel({10, 10, 300, 200});
SSO::Container::SSO_PushLabel("Game Stats");
SSO::Container::SSO_RenderPanel();

// Panel 2: Emerald Theme (Center Left)
SSO::Container::SSO_SetTheme(SSO::Container::THEME_EMERALD);
SSO::Container::SSO_BeginPanel({350, 250, 200, 180});
SSO::Container::SSO_PushHeader("Emerald Controls");
SSO::Container::SSO_PushWidget("Reset Timer");
SSO::Container::SSO_PushWidget("Add Physics Ball");
SSO::Container::SSO_PushWidget("Toggle Gravity");
SSO::Container::SSO_RenderPanel();

// Panel 3: Sky Blue Theme (Center)
SSO::Container::SSO_SetTheme(SSO::Container::THEME_SKY_BLUE);
SSO::Container::SSO_BeginPanel({570, 250, 200, 180});
SSO::Container::SSO_PushHeader("Sky Blue Controls");
SSO::Container::SSO_PushWidget("Change Theme");
SSO::Container::SSO_PushWidget("Clear Objects");
SSO::Container::SSO_RenderPanel();

// Panel 4: Crimson Theme (Center Right)
SSO::Container::SSO_SetTheme(SSO::Container::THEME_CRIMSON);
SSO::Container::SSO_BeginPanel({790, 250, 200, 180});
SSO::Container::SSO_PushHeader("Crimson Controls");
SSO::Container::SSO_PushWidget("Exit Game");
SSO::Container::SSO_PushWidget("Fullscreen Toggle");
SSO::Container::SSO_PushWidget("Debug Info");
SSO::Container::SSO_RenderPanel();

v1.6 New Theme Colors

EXPANDED: 9 new professional theme colors available!
// Modern Theme Examples:
SSO::Container::THEME_EMERALD      // Success/Green UI
SSO::Container::THEME_SLATE       // Minimalist/Gray UI  
SSO::Container::THEME_AMBER        // Warning/Yellow UI
SSO::Container::THEME_SKY_BLUE     // Professional/Blue UI
SSO::Container::THEME_PURPLE       // Creative/Purple UI
SSO::Container::THEME_CRIMSON      // Alert/Red UI
SSO::Container::THEME_CYAN         // Tech/Cyan UI
SSO::Container::THEME_ORANGE       // Energy/Orange UI
SSO::Container::THEME_SSO_RED      // Classic Red Theme

v1.6 Fixes Applied

FIXED 1: Vector template declaration: std::vector<SSO::Physics::RigidBody>
FIXED 2: Build system now uses console subsystem to avoid WinMain requirement
FIXED 3: Added proper includes for splash screen functionality
FIXED 4: Resolution-independent UI scaling - works on all screen sizes!
FIXED 5: Input scaling and fullscreen compatibility

v1.6 Structure Notes

File Location: This code should be placed in 01_Core/game/main.cpp
Multi-file Support: You can add additional .cpp/.h files to the 01_Core/game/ folder and they'll be automatically included in the build
Assets: Keep all game assets in 01_Core/assets/ - this location hasn't changed in v1.6

Troubleshooting

Common Issues

Build Errors

Issue: "g++ not found" or compilation errors
Solution: Make sure MinGW-w64 is installed and in your PATH. Run the build script from the 01_Core directory.

WinMain Error

Issue: "undefined reference to `WinMain'" error
Solution: Use Debug Mode (Option 2) when building. Release mode was using Windows subsystem which requires WinMain instead of main(). This has been fixed in v1.6.

Vector Template Error

Issue: "class template argument deduction failed" for std::vector
Solution: Use proper template declaration: std::vector<SSO::Physics::RigidBody> physicsObjects; instead of std::vector physicsObjects;

Raylib Not Found

Issue: "raylib.h: No such file or directory"
Solution: The build script should automatically download Raylib. If it fails, manually download Raylib and extract to the include/ and lib/ folders.
Issue: Container System or 3D Rendering not working
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

Issue: Assets not loading from bundle
Solution: Make sure assets are in the 01_Core/assets/ folder and run build.bat to recreate the bundle.

Window Issues

Issue: Window not appearing or crashes
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