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.
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)
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 pairsread(key)- Read data by key (returns empty string if not found)save(filename)- Save all data to fileload(filename)- Load data from filehasKey(key)- Check if key existssize()- Get number of stored itemsclear()- Clear all data from memory
Best Practices
- Use string conversion for numeric data with
std::to_string()andstd::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)
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
Splash System (sso_splash.h)
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
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)
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
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 & Shader System
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)
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);
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:
// 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
# 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
// 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
// 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
// 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
std::vector<SSO::Physics::RigidBody>
v1.6 Structure Notes
01_Core/game/main.cpp
01_Core/game/ folder and they'll be automatically included in the build
01_Core/assets/ - this location hasn't changed in v1.6
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.
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
Solution: Use proper template declaration:
std::vector<SSO::Physics::RigidBody> physicsObjects; instead of std::vector physicsObjects;
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