Overview
SCM is a compact engine built for fast iteration and predictable runtime behavior.
The core is native and performance oriented. Gameplay logic and UI are in Lua.
Goals
Keep the workflow simple, reduce boilerplate, and make small to mid sized projects
easy to ship without an editor dependency.
Workflow
Scenes are stored as JSON, assets live in folders, and scripts are plain Lua files.
You edit text, run the game, and iterate quickly.
Quick Start
Minimal Layout
Project/
Scenes/
main.scene.json
Scripts/
main.lua
Assets/
First Scene
The engine looks for Scenes/main.scene.json. If it is missing, it can create a default scene.
First Script
local M = {}
function M.oninit()
Print("init")
end
function M.onupdate()
-- logic
end
return M
Run
Build with the batch script and launch the executable. The scene will load and the Lua entry
script will run automatically.
Project Structure
Scenes
JSON files that describe entities, components, render settings, fog, and skybox settings.
Scripts
Lua files that provide behavior. Scripts can be attached to entities or used as global logic.
Assets
Models, textures, and audio. Paths are stored in scenes and scripts as relative strings.
Config
A simple config file controls window size, title, FPS, and vsync.
Engine Core
The core owns the window, the render loop, and the active scene. It initializes subsystems and
shuts them down cleanly.
Startup
The engine reads config, creates a window, initializes audio, scene manager, scripting, and particles,
then loads the entry scene and scripts.
Main Loop
Each frame runs script updates, processes scene requests, updates particles and audio,
then renders 3D and UI.
Scene Requests
Scene load, unload, and activate requests are deferred and applied at the end of the frame.
Shutdown
All resources are released, render targets are cleaned up, and the window is closed.
Scene System
Scenes are containers for entities and settings. Multiple scenes can be loaded, but only one is active.
Scene JSON
A scene defines a list of entities. Each entity stores a name, GUID, and component data.
Render Settings
Ambient light and fog are stored per scene and passed to the renderer each frame.
Skybox
Scenes can specify a skybox texture and panorama flag. The renderer will build a cubemap when needed.
ECS Model
The engine uses a lightweight entity component system. Entities are IDs. Components store all data.
Entities
Entities can be created, destroyed, named, tagged, and queried. Scripts usually interact by name or tag.
Components
Core components include Transform, Camera, MeshRenderer, Material, Light, Collider, AudioSource,
AudioListener, SpriteRenderer, ParticleEmitter, Script, Animator, Properties, and CustomComponents.
Parenting
Parent relationships are stored via GUID. Child transforms are combined with parent transforms at runtime.
Properties
Properties and CustomComponents provide flexible JSON storage for game-specific data.
Rendering
The renderer supports models, primitives, sprites, and skyboxes. The default shading model is PBR.
Materials and PBR
Materials define albedo and optional textures for metallic, roughness, AO, and normal.
Numeric factors and UV scaling are also supported.
Lighting
Directional and point lights are supported. Light data is passed to the shader each frame.
Shadows
The primary directional light can cast shadows via a depth map. Shadow bias is adjustable in the shader.
Fog and Ambient
Fog color and density are per scene. Ambient light is applied before direct lighting.
Environment
Skyboxes can be panorama textures or cubemaps. If cubemap generation fails, a 2D shader fallback is used.
Sprites
SpriteRenderer draws textured billboards in 3D. Sprites can face the camera or use a fixed orientation.
Animation
Model animations are supported through the Animator component.
Animator Component
Animator tracks clip index, playback speed, looping, and current time.
Clips
Clips are loaded from the model. Scripts can play, pause, stop, and switch clips at runtime.
Physics
Physics provides simple collision, triggers, and spatial queries.
Colliders
Collider shapes include box, sphere, and capsule. Triggers are supported via a flag.
Queries
Raycast and overlap queries return entities and hit data for gameplay logic.
Events
Scripts receive oncollision and ontrigger events for enter, stay, and exit.
Audio
Audio sources are attached to entities. A listener defines the point of hearing.
Sources and Listener
Sources play clips, can be spatial or non spatial, and may loop. The listener usually follows the camera.
Groups
Volume can be controlled per audio group for global balancing.
Particles
The particle system is component driven and updated every frame.
Emitters
Emitters control rate, lifetime, speed, size, spread, gravity, drag, and color over time.
Textures
Particles can use sprite sheets with frame columns, rows, and animation FPS.
Scripting
Lua scripts drive gameplay and UI. Each script returns a table of callbacks.
Lifecycle
Common callbacks are oninit, onupdate, onfixedupdate, onlateupdate, and collision or trigger events.
Messaging
Scripts can send messages to other scripts or broadcast to all scripts in the active scene.
Global Scripts
Global Lua files can expose functions such as OnInit that the engine calls once.
Lua files must be saved as UTF-8 without BOM.
UI and Debug
UI and debug drawing are immediate mode and executed after 3D rendering.
UI Commands
Draw rectangles, outlines, text, and textures directly from Lua each frame.
Debug Draw
Debug helpers draw 3D lines, rays, points, and screen text overlays.
Input
Time and Update Order
Delta
Delta returns the last frame time after timeScale is applied. GetFPS returns the current FPS.
Fixed Step
FixedDelta controls the fixed update step for physics and timers.
Resource Management
Caching
Models, textures, fonts, and audio are cached by path to avoid redundant loading.
Build and Run
Default Build
The batch script configures CMake, builds, and launches the editor executable.
Release
For release builds, disable editor targets and embed project data if needed.
Embedded Project Data
Embedding Flow
A Python tool converts Scenes and Scripts into a generated C++ file compiled into the engine.
Runtime Fallback
At runtime the engine tries disk files first, then falls back to embedded data.
Lua API
The Lua API is grouped by domain. The sections below summarize all available functions
and the behavior you can expect in scripts.
Base Types
Type Description
entity64 bit handle represented as a number.
vec3Table {x,y,z} or indexed {[1]=x,[2]=y,[3]=z}.
quatTable {x,y,z,w} or indexed {[1]=x,[2]=y,[3]=z,[4]=w}.
Core and Time
Function Description
Quit()Close the application.
SetTimeScale(scale)Set time scale multiplier.
GetTimeScale()Get current time scale.
SetFixedDelta(dt)Set fixed update delta.
GetFixedDelta()Get fixed update delta.
SetTargetFPS(fps)Set FPS target.
GetTargetFPS()Get FPS target.
Time()Time since startup.
Delta()Scaled frame delta.
GetFPS()Current FPS.
Scenes
Function Description
SceneCreate(name)Create a new scene.
LoadScene(path)Request scene load, deferred to end of frame.
SaveScene(path, id?)Save a scene to disk.
SceneSetActive(id)Request active scene change.
SceneGetActive()Get active scene id.
SceneUnload(id)Request scene unload.
SceneList()List loaded scenes.
Entities
Function Description
CreateEntity(name?)Create entity.
DestroyEntity(entity)Destroy entity.
IsAlive(entity)Check if entity is valid.
FindEntityByName(name)Find first entity by name.
GetName(entity)Get name.
SetName(entity, name)Set name.
GetGuid(entity)Get GUID.
SetTag(entity, tag)Set tag.
GetTag(entity)Get tag.
FindByTag(tag)Find entities by tag.
SetActive(entity, enabled)Enable or disable entity.
IsActive(entity)Check active state.
Components
Function Description
AddComponent(entity, name)Add component by name.
RemoveComponent(entity, name)Remove component.
HasComponent(entity, name)Check component.
SetComponent(entity, name, table)Update component fields.
GetComponent(entity, name)Get component data.
Properties
Function Description
SetProperty(entity, key, value)Set property value.
GetProperty(entity, key)Get property value.
HasProperty(entity, key)Check property existence.
RemoveProperty(entity, key)Remove property.
Scripts and Messages
Function Description
AddScript(entity, file)Attach script to entity.
RemoveScript(entity)Remove script from entity.
SetScriptEnabled(entity, enabled)Enable or disable script.
SendMessage(entity, fn, ...)Call method on entity script.
Broadcast(fn, ...)Call method on all scripts.
CallGlobal(fn, ...)Call a global Lua function.
File System
Function Description
FSReadText(path)Read text file.
FSWriteText(path, text?)Write text file.
FSAppendText(path, text?)Append text file.
FSExists(path)Check path exists.
FSDelete(path)Delete file.
FSListDir(path)List directory.
Audio
Function Description
SetAudioGroupVolume(group, volume)Set group volume.
GetAudioGroupVolume(group)Get group volume.
AudioPlay(entity)Play source.
AudioPause(entity)Pause source.
AudioResume(entity)Resume source.
AudioStop(entity)Stop source.
Physics
Function Description
Raycast(ox,oy,oz, dx,dy,dz, maxDist)Raycast, returns hit info.
RaycastIgnore(ox,oy,oz, dx,dy,dz, maxDist, ignore)Raycast with ignore entity.
OverlapSphere(cx,cy,cz, r)Sphere overlap query.
OverlapBox(cx,cy,cz, sx,sy,sz)Box overlap query.
OverlapCapsule(cx,cy,cz, h, r)Capsule overlap query.
Fog and Ambient
Function Description
SetFog(enabled, r,g,b,a, density)Set fog parameters.
GetFog()Get fog parameters.
SetAmbient(r,g,b,a)Set ambient color.
GetAmbient()Get ambient color.
UI
Function Description
UIRect(x,y,w,h, r?,g?,b?,a?)Draw filled rect.
UIRectOutline(x,y,w,h, thickness?, r?,g?,b?,a?)Draw rect outline.
UIText(text,x,y, size?, r?,g?,b?,a?)Draw text.
UIFont(path?, size?)Set UI font.
UIImage(path, x,y,w,h, r?,g?,b?,a?)Draw image.
UIInput(id, x,y,w,h, text?, size?, r?,g?,b?,a?)Text input widget.
Animation
Function Description
AnimPlay(entity, clip?)Play clip.
AnimPause(entity)Pause animation.
AnimResume(entity)Resume animation.
AnimStop(entity)Stop animation.
AnimSetLoop(entity, loop)Set looping.
AnimSetSpeed(entity, speed)Set speed.
AnimSetClip(entity, clip)Set clip index.
Debug
Function Description
DebugLine(x1,y1,z1, x2,y2,z2, r?,g?,b?,a?)Draw 3D line.
DebugRay(ox,oy,oz, dx,dy,dz, len, r?,g?,b?,a?)Draw ray.
DebugPoint(x,y,z, size?, r?,g?,b?,a?)Draw point.
DebugText(text,x,y, size?, r?,g?,b?,a?)Draw screen text.
Timers and Coroutines
Function Description
SetTimeout(sec, fn)Run once after delay.
SetInterval(sec, fn)Repeat at interval.
ClearTimer(id)Cancel timer.
StartCoroutine(fn)Start coroutine.
StopCoroutine(id)Stop coroutine.
Wait(sec)Yield for seconds.
Math
Function Description
Math.Vec3(x,y,z)Create vec3.
Math.Vec3Add(a,b)Add vectors.
Math.Vec3Sub(a,b)Subtract vectors.
Math.Vec3Mul(a, s|b)Multiply by scalar or vector.
Math.Vec3Dot(a,b)Dot product.
Math.Vec3Cross(a,b)Cross product.
Math.Vec3Length(v)Vector length.
Math.Vec3Normalize(v)Normalize vector.
Math.Vec3Lerp(a,b,t)Vector lerp.
Math.Lerp(a,b,t)Scalar lerp.
Math.Clamp(v, min, max)Clamp value.
Math.Random(min, max)Random float.
Math.RandomInt(min, max)Random int.
Math.Deg2Rad(deg)Degrees to radians.
Math.Rad2Deg(rad)Radians to degrees.
Math.QuatFromEuler(x,y,z)Create quaternion.
Math.QuatMul(a,b)Quaternion multiply.
Key and Mouse Constants
Constants include KEY_A to KEY_Z, KEY_0 to KEY_9,
function keys, arrows, modifiers, numpad, and mouse buttons such as MOUSE_LEFT.
Troubleshooting
Lua BOM
If you see unexpected symbol near '<\\239>', the Lua file has a BOM header.
Re-save the file as UTF-8 without BOM.
Limits and Notes
Scope
SCM focuses on clarity and fast iteration. It does not aim to replace full editor pipelines.
Use it when you want simple structure and direct control.
Previous
Next