Disclaimer: This project, or portions of its code and assets, were created with the assistance of Artificial Intelligence (AI).
RayneEngine is a modular 2D game engine built with modern C++20 and SFML. Designed as an in-depth portfolio project during game engineering training, it focuses on exploring clean software design patterns, high performance, and core engine subsystems from first principles:
- Custom, cache-conscious Entity Component System (ECS) supporting up to 5 000 entities
- 2D Rigidbody Physics System with impulse-based collision response, friction, triggers, and raycasting
- Template (Prefab) System for saving reusable entity blueprints and instantiating them dynamically
- Parent-Child Entity Hierarchy with local and world transform propagation and drag-and-drop tree editing
- Project Hub first-run setup modal for easily configuring project settings and standalone target specs
- Native Visual Level Editor with live property inspection, Inspector Lock, smooth scrolling, grid snapping, and undo/redo
- Script Export Variables supporting
Image,Vec2,Color,Entity, andTemplatewith live thumbnail previews and color picker - Dedicated UI Editor for designing game HUDs visually on a fixed 1920×1080 canvas
- In-Editor Console Panel with live stdout/stderr capture, scrollable log, and command input
- Embedded Lua 5.4 scripting environment via
sol2with lifecycle events and hot-reload - Multi-channel Audio Engine and hardware input polling
- Complete JSON Scene & UI Serialization and project auto-saving
- UI Manager for runtime Text, Panel, and Button elements controlled from Lua
- Standalone Game Export creating an optimized
RayneGameexecutable using your project settings
-
Add Object Spotlight Palette & Interactive Placement System (
Ctrl + Space):- Replaced the simple Add dropdown with an intelligent, keyboard-navigable Spotlight Palette modal:
- Global Shortcut: Press
Ctrl + Spaceor click+ Addin the top toolbar to open the palette instantly. - Live Real-time Search: Filter across object names, descriptions, and categories dynamically with instant keystroke matching.
- Category Filters: Quick category chips (
All,Primitives,Gameplay,Physics,Media & FX) with keyboard navigation (Left,Right,Tab,Up,Down,Enter,Esc). - Interactive Placement Mode: Selecting any preset puts the editor into placement mode with a cursor-following ghost preview showing exact dimensions, shape, colors, and contextual labels (
[TRIGGER],World Text,SPAWN, camera frustum). Left-click to place anywhere on the canvas with grid snapping.
- Global Shortcut: Press
- 15 Built-in Object Presets Across 4 Categories:
- Primitives:
Rectangle,Circle,Triangle,Pentagon,Hexagon. - Gameplay:
Empty Entity(transform node for parenting & hierarchy pivots),Spawn Point(actor spawn point with animated beacon gizmo),Trigger Zone(sensor collider withisTrigger=true),Camera(in-game camera with live viewfinder frustum). - Physics:
Physics Box(dynamic Box2D entity with collider and Rigidbody2D),Physics Ball(dynamic bouncy ball with Rigidbody2D),Static Platform(solid static ground/barrier). - Media & FX:
Sprite(entity ready for texture drag-and-drop),World Text(formatted 2D world text with custom font/size/color),Audio Source(spatial/ambient sound emitter),Particle Emitter(live real-time 2D particle simulation).
- Primitives:
- New Core ECS Components:
TextComponent: Render formatted text in 2D world space with customizable string, character size, color, alignment, and outlines.AudioSourceComponent: Play sound clips with volume (0-100), pitch, looping, play-on-start, and spatial attenuation settings. Drag-and-drop.wav/.oggfiles directly from the Content Browser onto objects or the canvas.ParticleEmitterComponent: Full real-time 2D particle simulation engine running both in play mode and live in the editor. Configurable emission rate, particle lifetime, speed, variance, cone spread angle, start/end size interpolation, start/end RGBA color interpolation, and gravity vectors.
- Inspector UI & Serialization:
- Dedicated Inspector controls for
TextComponent,AudioSourceComponent, andParticleEmitterComponentincluding interactive color pickers via native dialog, numeric steppers, toggles, and test playback button. - Full JSON serialization and deserialization in scene files and template prefabs.
- Dedicated Inspector controls for
- Lua Scripting Bindings:
AddText,SetText,GetText,SetTextSize,SetTextColor,HasText.AddAudioSource,PlayAudio,SetAudioClip,SetAudioVolume,SetAudioPitch,SetAudioLoop,HasAudioSource.AddParticleEmitter,SetParticleEmitting,IsParticleEmitting,SetParticleRate,SetParticleSpeed,HasParticleEmitter.
- Replaced the simple Add dropdown with an intelligent, keyboard-navigable Spotlight Palette modal:
-
In-Game Camera System & Scripting Library (
Camera):- Added full-featured
CameraManagerhandling dynamic viewport transforms, zoom, rotation, screen shake, multi-entity following, dynamic bounding framing, and boundary constraints during play mode. - Added
Cameraentity to the editor Add dropdown menu (ObjectType::Camera):- Placed as a dedicated camera entity with a custom camera gizmo icon and recording LED.
- Freely movable, resizable, and rotatable in the editor and scriptable at runtime.
- Full serialization to/from JSON scene files and undo/redo history.
- Live Camera Viewport Frustum / Viewfinder Visualizer:
- Live viewport representation in
EditorSceneshowing the exact screen frame (1920×1080base resolution scaled by zoom, rotated by camera angle, and offset). - Center crosshair and informative overlay badge displaying current zoom and dimensions.
- Live viewport representation in
- Multi-Camera & Multi-Target Follow Resolution System:
- Devised and implemented conflict-free multi-target tracking when two or more objects have camera follow active (
CameraMultiFollowMode):CameraMultiFollowMode.Priority(0): The camera target with the highest priority value takes control; lower-priority cameras are ignored.CameraMultiFollowMode.Average(1): Midpoint follow that smoothly averages the world positions of all active follow targets.CameraMultiFollowMode.AutoFrame(2): Intelligent bounding-box framing that automatically tracks the centroid of all targets and dynamically zooms the camera in/out to keep all targets comfortably on-screen with configurable world padding (autoFramePadding) and zoom clamps (minZoom,maxZoom).
- Multi-camera visualizer in
EditorScene: draws connecting dashed link lines between all active camera targets and renders the shared focus / auto-frame centroid indicator in real time. - Upgraded
CameraComponentwithpriority,multiFollowMode,minZoom,maxZoom, andautoFramePadding. - Added Inspector UI controls for
CameraComponent: active toggle, multi-target mode selector cycle button, priority, smooth speed, offsets, zoom, padding, and zoom limits.
- Devised and implemented conflict-free multi-target tracking when two or more objects have camera follow active (
- Added global
CameraLua library table for complete runtime control:- Position & Free Movement:
Camera.SetPosition(x, y),Camera.GetPosition(),Camera.GetX(),Camera.GetY(),Camera.Move(dx, dy). - Zoom:
Camera.SetZoom(zoom),Camera.GetZoom(),Camera.Zoom(factor). - Rotation:
Camera.SetRotation(deg),Camera.GetRotation(),Camera.Rotate(deltaDeg). - View Size & Reset:
Camera.SetSize(w, h),Camera.GetSize(),Camera.Reset(). - Target Following:
Camera.Follow(entity, [smoothSpeed], [offsetX], [offsetY]),Camera.StopFollow(),Camera.ResumeFollow(),Camera.IsFollowing(),Camera.GetFollowTarget(),Camera.SetFollowSpeed(speed),Camera.GetFollowSpeed(),Camera.SetFollowOffset(ox, oy),Camera.GetFollowOffset(). - Multi-Target Tracking:
Camera.AddFollowTarget(entity),Camera.RemoveFollowTarget(entity),Camera.ClearFollowTargets(),Camera.FollowGroup(targets, [mode], [padding]),Camera.GetFollowTargets(),Camera.GetFollowTargetCount(),Camera.SetMultiFollowMode(mode),Camera.GetMultiFollowMode(),Camera.SetAutoFramePadding(padding),Camera.GetAutoFramePadding(),Camera.SetAutoFrameZoomLimits(minZoom, maxZoom),Camera.GetAutoFrameZoomLimits(),Camera.SetPrimary(entity),Camera.GetPrimary(). - Boundary Constraints:
Camera.SetBounds(minX, minY, maxX, maxY, [clampEdges=true]),Camera.ClearBounds(),Camera.HasBounds(),Camera.GetBounds(). - Screen Shake:
Camera.Shake(intensity, duration, [decay=true]),Camera.StopShake(),Camera.IsShaking(). - Coordinate Mapping:
Camera.ScreenToWorld(screenX, screenY),Camera.WorldToScreen(worldX, worldY)converting seamlessly with view transformations.
- Position & Free Movement:
- Upgraded
AddCamera(e, [smoothSpeed], [offsetX], [offsetY], [zoom], [priority])and addedGetCamera(e) -> CameraComponent. - Added comprehensive test script:
assets/scripting/CameraTestScript.lua.
- Added full-featured
-
Event-Driven Input System (
OnInputReceived/OnInputReceiced):- Added dedicated script callback
OnInputReceived(self, event)(withOnInputReceicedalias) that triggers exclusively when hardware input arrives (keyboard, mouse, joystick, text) rather than polling every frame. - Added typed enum table
InputEvent(with aliasesInputEventType,EventType) supporting enum comparisons likeif event.type == InputEvent.KeyDownorif event.type == InputEvent.Keydown. - Added
InputEventDatatable fields:type,typeName,typeStr,key,keyCode,keyName,button,buttonCode,buttonName,x,y,worldX(camera-mapped),worldY(camera-mapped),delta,wheel,text,unicode,alt,control,shift,system,joystickId,axis,position,isInput, andisPaused. - Added input helper functions:
Input.HasInput(),Input.GetLastEvent(),Input.KeyToString(key), andInput.MouseButtonToString(button). - Added Inspector SCRIPT section visual indicator for
OnInputReceivedcallback hook. - Added test scripts:
assets/scripting/InputTestScript.luaandassets/scripting/InteractiveInputDemo.lua.
- Added dedicated script callback
-
2D Rigidbody Physics System & Impulse Solver:
- Added
Rigidbody2DComponentwith configurablebodyType(Dynamic,Kinematic,Static),mass,gravityScale,restitution(bounciness),drag(linear damping), andfreezeRotation. - Added fixed-timestep physics simulation loop with sub-stepping (
PhysicsSystem). - Added impulse-based physical collision resolution with coefficient of restitution and tangential surface friction.
- Added trigger / sensor collider support (
isTrigger) with zero-impulse passthrough and event dispatch. - Added physics lifecycle callbacks in Lua:
OnCollisionEnter(self, other, normalX, normalY)andOnTriggerEnter(self, other). - Added full Lua
Physicslibrary:Physics.Raycast,Physics.ApplyForce,Physics.ApplyImpulse,Physics.SetVelocity,Physics.GetVelocity,Physics.SetGravity,Physics.GetGravity,Physics.SetFixedTimestep, andPhysics.GetFixedTimestep. - Added global entity Rigidbody Lua helpers:
AddRigidbody(entity, bodyType, mass, gravityScale),GetRigidbody(entity), andHasRigidbody(entity).
- Added
-
Velocity Component Overhaul & Editor Inspector Integration:
- Added full interactive Inspector UI for
VelocityComponentwith editableVelocity XandVelocity Ynumeric fields. - Added convenient property aliases on Lua
Velocityusertype:.dx,.dy,.vx,.vy,.x, and.y. - Added
RemoveVelocity(entity)Lua binding. - Improved
SetVelocity(e, dx, dy)in Lua to automatically attachVelocityComponentif not yet present. - Improved
AddVelocity(e, dx, dy)to return a reference to the component. - Fixed component pool update semantics so adding or setting components on entities that already possess them updates their values in place instead of discarding changes.
- Ensured automatic attachment of
VelocityComponentwhenever aRigidbody2Dis created (via Inspector, templates, scenes, or LuaAddRigidbody) to guarantee physics simulation reliability. - Added post-collision world transform synchronization so physics position corrections are immediately reflected in rendered positions.
- Added full interactive Inspector UI for
-
Inspector Lock Feature:
- Added Unity-style lock toggle button in the top-right corner of the Inspector panel.
- Freezes the active inspector view on the selected object so clicking other entities in the viewport or hierarchy does not deselect or alter the inspector view.
-
Script Export Variables Expansion & Visual Previews:
- Added first-class export variable constructors in Lua:
Image(path),Vec2(x, y),Color(r, g, b),Entity(name), andTemplate(path). - Added live thumbnail rendering directly inside the Inspector for
Imagetexture assets andTemplateprefabs. - Added native Windows color picker integration (
ChooseColor) forColorexport properties. - Added drag-and-drop targeting: drag images and templates from the Content Browser, or entities from the Hierarchy tree, directly into matching export property slots.
- Added complete JSON serialization and deserialization for all script export property types.
- Added first-class export variable constructors in Lua:
-
Inspector Scrolling & Content Clipping:
- Added smooth mouse-wheel scrolling for the Inspector panel when content exceeds viewport height.
- Added viewport scissor clipping below the fixed title header to keep content cleanly contained within the panel.
-
Template (Prefab) System:
- Added support for saving entity hierarchies as reusable
.templateasset files. - Added template instantiation from Lua via
Instantiate(template, x, y, [parent])andTemplate(path):Instantiate(...). - Added circular reference detection and nested prefab dependency warnings.
- Added support for saving entity hierarchies as reusable
-
Parent-Child Hierarchy System:
- Added complete transform parenting system (
HierarchySystem) supporting local and world coordinate spaces. - Added Lua hierarchy APIs:
SetParent(child, parent, [keepWorldTransform]),GetParent(child),GetChildren(parent),GetWorldPosition(e),GetWorldRotation(e), andGetWorldScale(e). - Added drag-and-drop reparenting inside the Hierarchy tree with visual feedback.
- Added unsaved changes dirty indicator (
*) across scenes, UI layouts, and scripts.
- Added complete transform parenting system (
-
UI Editor Enhancements & Layout Containers:
- Added
VerticalBoxandHorizontalBoxlayout elements with automatic element spacing and alignment. - Added progress bar elements with
SetProgressValue/GetProgressValue. - Added slider min/max boundary configuration (
SetSliderMin,SetSliderMax,GetSliderMin,GetSliderMax). - Added vertical text alignment (
SetTextVAlign) and auto-wrapping labels in the UI inspector. - Added UI element focus management (
SetFocused,GetFocused,OnUIFocus). - Added script method stub insertion, asset synchronization, and IDE workflow directly from the UI Editor.
- Added
-
Editor Tooling & Visual Feedback:
- Added viewport world coordinate axes and origin marker (0, 0).
- Added automatic scene saving on Play Mode launch (
F5). - Added hot-reloading and inspector property refreshing for exported script variables.
- Added on-screen notification toasts via
Engine.LogToScreenandLogToScreenduring play mode. - Added color-coded console badges for
Engine.Log(teal),Engine.LogWarning(amber), andEngine.LogError(red). - Added
.jfifimage format loading support. - Added read-only file attributes for engine content and template files in standalone builds.
- Fixed input event dispatch ordering in
Application::SetEventssoInputManagerprocesses events before scene event handling, ensuringInput.HasInput()and queries are immediately up-to-date during script callbacks. - Fixed editor crash when opening the UI Editor for the first time in standalone builds.
- Fixed scene save issue where objects could occasionally reset to (0, 0) by committing active input fields and ensuring local transforms are preserved.
- Fixed
VelocityComponentbeing non-editable in the Inspector and failing to update or simulate when attached to entities. - Fixed text underline disappearing when bold style is active in UIManager text rendering.
- Fixed object rotation handle positioning and smooth angular dragging in the level editor viewport.
- Fixed hit detection and selection on scaled entities to prevent miss-clicks and inaccurate marquee selection.
- Fixed non-uniform edge scaling and ellipse stretching for circle primitives across both editor and runtime.
- Fixed IDE launch command to run detached without spawning extraneous console windows.
- Fixed UI button click handling in standalone builds and ensured all audio channels stop when exiting play mode.
- Fixed startup freeze/hang in
EditorSceneand revealed hidden scripting directories in build mode. - Fixed template asset path resolution to reliably locate project root using
FindProjectRoot().
- Removed requirement for magic string comparisons for input event types in Lua scripts in favor of
InputEventenum constants. - Removed legacy non-Lua comment cruft from
EditorScene,ContentBrowser,PhysicsSystem,SplashScreen, and scripting manager classes. - Removed redundant
SetPathReadOnlycalls fromEditorSceneconstructor.
The engine architecture is structured into decoupled modules under src/Core/:
RayneEngine
|-- Core/
| |-- Application/ Main loop, DPI awareness, window management, engine versioning
| |-- Audio/ AudioManager sound effect pool (32 channels) and music streaming
| |-- ECS/ Registry, component pools, view iterators, entity handles,
| | PhysicsSystem (Rigidbody2D solver), HierarchySystem (parenting)
| |-- Input/ InputManager keyboard & mouse tracking with frame edge detection
| |-- Math/ MathR custom math routines, interpolation, trigonometric tables; Vector3
| |-- Primitives/ Geometric primitive factories (Rectangles, Circles, Polygons)
| |-- Resources/ ResourceManager centralized caching (textures, fonts, sounds)
| |-- Scenes/ SceneManager, EditorScene, UIEditorScene, GameScene,
| | ContentBrowser, ConsolePanel, SceneSerializer
| |-- Scripting/ LuaState bindings, ScriptComponent lifecycle, EventManager,
| | TimerManager, TweenManager, api_stub.lua
| `-- UI/ UIManager (Text, Panel, Button elements, JSON persistence)
`-- assets/ Scenes, scripts, audio files, fonts, textures, and UI layouts
When launching the engine for the first time (i.e. no project_settings.json is found), the Project Hub will appear as a sleek modal dialog over a dimmed editor background. Similar to modern engine hubs, it allows you to configure your new project before jumping into development:
-
Project Details: Define the project name and author.
-
Resolution: Set the target window width and height for your standalone game export.
-
Engine Settings: Toggle VSync and specify a target framerate (FPS).
-
These settings are serialized to project_settings.json which governs the standalone game's runtime behavior without interfering with the editor's fixed resolution.
The built-in level editor provides a real-time environment for constructing and previewing 2D game scenes:
- Entity Hierarchy & Parenting:
- Scrollable hierarchy tree displaying all active scene entities.
- Transform Parenting: Drag-and-drop entities onto other objects to establish parent-child relationships with automatic local/world coordinate propagation.
- Context menu actions: Rename, duplicate, delete, and save entity subtrees as
.templateassets. - Multi-selection and group hierarchy operations.
- Property Inspector:
- Inspector Lock: Unity-style lock button in the header freezes inspection on the current entity, preventing accidental selection changes when clicking in the viewport or hierarchy.
- Smooth Scrolling & Viewport Scissor: Mouse-wheel scrolling with view clipping ensures large component lists and extensive export variables remain completely accessible.
- Rigidbody 2D Section: Real-time configuration of
BodyType(Dynamic / Kinematic / Static),Mass,Gravity Scale,Restitution(bounciness),Drag, andFreeze Rotation. - Script Export Variables: Auto-generates UI fields for all exported script properties (
Int,Float,Bool,String,Image,Vec2,Color,Entity,Template). - Visual Asset Previews: Real-time thumbnail rendering for
Imagetexture assets andTemplateprefab files. - Windows Color Picker: Interactive color swatches that launch the native Windows
ChooseColordialog. - Drag-and-Drop Slots: Drop textures and templates from the Content Browser, or entities from the Hierarchy tree, directly into matching property slots.
- Live numerical manipulation of position (
x,y), size (width,height), rotation (degrees), and scale (scaleX,scaleY). - Entity Tag and Name assignment for easy query from Lua scripts.
- Color palette tinting (
R,G,B) for primitives and sprites. - Script path assignment with automatic Lua binding and hot-reload reflection.
- Sprite asset assignment with aspect-correct scaling.
- Collision channel, collision type (
Static/Solid), collider shape (Box/Circle), and sensor trigger (isTrigger) configuration. - UI element text editing directly from the inspector (
UITextfield).
- Content Browser:
- Integrated file browser with breadcrumb navigation and path history.
- Asset category filters: All, Images, Scripts, Audio, Scenes.
- Live search bar with instant filtering across all entries.
- File management: Create scripts, scenes, or folders; rename, duplicate, or delete assets; copy asset path to clipboard; reveal file in OS file explorer.
- Drag-and-drop: Drag textures or scripts from the browser directly onto viewport entities.
- Scene loading: Double-click or trigger scene loading requests directly from the browser.
- In-Editor Console Panel:
- Switchable bottom panel (Content Browser ↔ Console via tab bar).
- Captures all
std::coutandstd::cerroutput in real time via stream redirectors installed at engine boot. - Color-coded log lines: normal output in light grey, errors in red.
- Scrollable log area with draggable scrollbar and mouse-wheel support; auto-scrolls to the newest message.
- Command input field with blinking cursor, Ctrl+V paste support, and Enter-to-submit.
- Built-in
clearcommand to reset the log. Buffer capped at 2 000 messages.
- Interactive Viewport & Selection:
- Free camera panning using Middle Mouse Button (invertible and sensitivity-configurable).
- Smooth camera zooming with user-defined min/max limits.
- Multi-Selection & Box-Select: Drag in empty space to create a selection box (marquee select); hold
ShiftorCtrlto toggle entities in the selection group. - Group Manipulation: Move or delete multiple selected entities simultaneously.
- Undo / Redo (Command Pattern): Full history stack supporting
Ctrl + ZandCtrl + Yfor entity creation, deletion, dragging, and resizing — including atomicMacroCommandgrouping for multi-object operations. - 8-point interactive resize handles for live scaling of selected objects.
- Grid rendering with configurable cell dimensions, color, and opacity.
- Toggleable snap-to-grid alignment.
- Scene Serialization:
- Completely relative asset paths: Sprite textures and script files are saved relative to
assets/for cross-platform and team portability.
- Completely relative asset paths: Sprite textures and script files are saved relative to
- Auto-Save & Configuration:
- Configurable auto-save intervals with on-screen notification popups.
- Persistent JSON-based editor settings dialog covering general, editor, camera, and debug parameters (including pan inversion, scroll sensitivity, log level, and title bar auto-save indicator).
- Debug Overlays:
- Real-time FPS monitoring with configurable framerate limits.
- Collider outline rendering for rapid physics debugging.
- Entity ID labels drawn in world space.
A dedicated scene for visually designing the game's HUD and UI layouts:
- Fixed 1920×1080 canvas — matches the runtime UI view for pixel-perfect WYSIWYG design.
- Element Palette — create Text, Panel, and Button UI elements with a single click.
- Canvas Interaction — select, drag, and resize elements using 8-point handles; middle-mouse pan across the canvas.
- Element Hierarchy — scrollable panel listing all UI elements by auto-generated ID (
text_1,panel_1,btn_1, …). - Property Inspector — live editing of 40+ fields including position, size, z-index, opacity, color (RGBA), text content, font size, letter/line spacing, text alignment (
Left/Center/Right), text style bitmask (Bold, Italic, Underline, StrikeThrough), text outline, text offset, button normal/hover/pressed/disabled colors, and panel border/outline. - Persistence — UI layouts are saved to and loaded from
assets/ui.jsonvia theUIManager. The engine reloads this file on startup automatically. - Menu Bar — Save, Load, New UI, and Back to Editor actions.
The runtime UI system renders interactive elements on top of the game world in a fixed 1920×1080 screen-space view:
- Element types:
Text,Panel,Button - Z-ordering: Elements are sorted by
zIndexfor correct layering (ascending for render, descending for hit testing). - Button interactivity: Tracks hover, pressed, and released states per frame; supports disabled state with a distinct color.
- JSON persistence:
UIManager::Save()/UIManager::Load()serialise and restore all element properties. - Lua integration: All properties are controllable from Lua scripts at runtime (see UI Library below).
The custom ECS emphasizes data locality, cache friendliness, and clean decoupling. The registry supports up to 5 000 entities (MAX_ENTITIES = 5000):
Registry: Manages entity lifecycles (CreateEntity,DestroyEntity,Clear) and hosts type-safe component pools. Entity IDs start at1;NULL_ENTITY = 0.Pool<T>: Contiguous memory pools storing component instances with sparse-to-dense mappings for fast iteration (swap-and-pop removal).View<Components...>: Multi-component query views enablingRegistry::ForEach<T1, T2>(...)iteration patterns via range-based for loop support.- Available Components:
TagComponent: Name and classification tag for entities (std::string tag).TransformComponent: 2D spatial position (float x,float y), rotation angle in degrees (float rotation), and scaling (float scaleX,float scaleY). Supports parent-child hierarchies with world coordinates.VelocityComponent: Movement velocity delta (float dx,float dy).Rigidbody2DComponent: Physics body attributes (BodyTypedynamic/kinematic/static,mass,gravityScale,restitution,drag,freezeRotation).RenderComponent: Visual representation (sf::Color,sf::Vector2f size, andShapeType: Rectangle, Circle, Triangle, Pentagon, Hexagon).SpriteComponent: Renderable SFML sprite with texture handle and dimensions; auto-loads viaResourceManagerand computes scale on construction.CameraComponent: Marks an entity as a camera focus (bool active,float smoothSpeed,float offsetX,float offsetY,float zoom,int priority,CameraMultiFollowMode multiFollowMode,float minZoom,float maxZoom,float autoFramePadding).CollisionComponent: Configures collision filtering via integerchannel, collision type (Static,Solid), collider shape (Box,Circle), and trigger flag (isTrigger).ScriptComponent: Encapsulates a sol2 Lua environment, filesystem modification timestamp tracking for live hot-reloading, exported variables, and lifecycle hooks.
RayneEngine features a unified 2D Rigidbody Physics System alongside legacy simple AABB checks:
- Physics Simulation (
PhysicsSystem):- Fixed Timestep Loop: Accumulator-based fixed-timestep integration with sub-stepping for deterministic physical behavior (
Physics.SetFixedTimestep(dt)). - Gravity Acceleration: Configurable global gravity vector (
Physics.SetGravity(gx, gy)). Default:(0, 980). - Linear Velocity Damping: Applies aerodynamic/frictional drag per body (
drag). - Body Types:
BodyType::Dynamic— Full physics simulation responding to gravity, forces, impulses, and contact collisions.BodyType::Kinematic— Controlled programmatically via velocity; pushes dynamic objects without being displaced by them.BodyType::Static— Immovable obstacles (walls, terrain, floors); infinite mass in collision responses.
- Rotation Lock: Entities can toggle
freezeRotationto prevent angular tumble on impact.
- Fixed Timestep Loop: Accumulator-based fixed-timestep integration with sub-stepping for deterministic physical behavior (
- Impulse Solver & Friction:
- Physical collision resolution computes instantaneous contact normals and applies restitution-weighted impulses
j = -(1 + e) * v_rel / (invMassA + invMassB). - Realistic tangential friction damping (
frictionMu = 0.2) stops sliding objects naturally.
- Physical collision resolution computes instantaneous contact normals and applies restitution-weighted impulses
- Sensor / Trigger Colliders:
- Any collider flagged with
isTrigger = truebypasses impulse resolution entirely and acts as a sensor zone, firingOnTriggerEnter(self, other).
- Any collider flagged with
- Collision Callbacks:
OnCollisionEnter(self, other, normalX, normalY)dispatches once upon solid contact, supplying the collision normal.OnTriggerEnter(self, other)dispatches when entering a sensor zone.OnCollision(self, other)legacy fallback event dispatched on contact.
- Raycasting:
Physics.Raycast(startX, startY, dirX, dirY, distance, [channel])performs ray intersection against active scene colliders, returning hit status, hit entity, contact point, normal, and distance.
- Channel Pooling: Dynamically managed pool supporting up to 32 simultaneous sound effect instances with automated cleanup upon completion.
- Music Streaming: Continuous background music playback with support for looping, pause, resume, individual volume control, and global master volume (rescales all active sounds proportionally).
- Asset Integration: Communicates directly with the
ResourceManagerto ensure sound buffers are loaded once and reused across instances.
- State Buffering: Tracks continuous press states (
IsKeyDown,IsMouseDown), single-frame press transitions (IsKeyPressed,IsMousePressed), and release events (IsKeyReleased,IsMouseReleased). - Cursor Tracking: Real-time mouse coordinate queries (
MouseX,MouseY) and scroll delta tracking. - Frame Lifecycle: Automatic edge-state resets at the conclusion of each frame.
- Resource Cache: Singleton repository caching
sf::Texture,sf::Font, andsf::SoundBufferinstances viastd::shared_ptr. Textures are loaded withsetSmooth(false)by default. - Memory Optimization: Manual cache flushing capabilities (
ClearTextures,ClearFonts,ClearSounds,ClearAll). - Telemetry: In-engine telemetry tracking loaded resource counts and memory utilization.
SceneManager: Finite state machine managing transitions between scene states:"editor"(EditorScene),"ui_editor"(UIEditorScene), and"game"(GameScene). CallsOnExit()/OnEnter()on transitions; throwsstd::runtime_errorfor unknown scene names.SceneSerializer: JSON serialization format preserving entity hierarchies, geometric types, colors, transforms, velocities, sprite textures, collision channels, collision types, and attached Lua scripts.
The Rayne namespace in EngineVersion.h provides compile-time constants and helpers:
Rayne::VERSION_MAJOR / MINOR / PATCH— current version (0.1.0)Rayne::VersionString()— returns"0.1.0"Rayne::PlatformString()— returns"Windows"/"macOS"/"Linux"/"Unknown"based on compile-time macrosRayne::DEFAULT_PROJECT_NAME— default window title prefix used in Play Mode
| Shortcut / Input | Context | Action |
|---|---|---|
F5 |
Editor | Run simulation in Play Mode (GameScene) |
F6 |
Game Mode | Hot-reload all modified Lua scripts dynamically |
Escape |
Game Mode | Return to Editor Mode |
Escape |
Editor | Cancel text input, close menus, or deselect active entity |
Ctrl + Z |
Editor | Undo last action (create, delete, move, resize) |
Ctrl + Y |
Editor | Redo last undone action |
Ctrl + S |
Editor | Save current scene to JSON (using relative asset paths) |
Ctrl + L |
Editor | Reload current scene from JSON |
Ctrl + D |
Editor | Duplicate selected entity with offset |
Ctrl + , |
Editor | Open / Close Editor Settings modal |
G |
Editor | Toggle grid snapping on / off |
Delete |
Editor | Delete all currently selected entities |
Middle Mouse Drag |
Editor | Pan camera viewport |
Mouse Scroll Wheel |
Editor | Zoom camera in / out |
Left Click (Entity) |
Editor | Select entity and drag to reposition |
Shift / Ctrl + Click |
Editor | Add or toggle entity in multi-selection group |
Left Click + Drag (Empty) |
Editor | Box-select (marquee) multiple entities in viewport |
Left Click (Handles) |
Editor | Resize entity along 8 anchor handles |
Left Click (Empty) |
Editor | Place new primitive shape of selected type (on click) |
RayneEngine embeds Lua 5.4 using sol2. Every script attached to an entity receives its own isolated environment with the entity handle available through the global self variable. Scripts are automatically monitored and hot-reloaded at runtime upon file modification.
An api_stub.lua file (---@meta) ships with the engine, providing full LSP type annotations for IDE autocomplete in editors like VS Code with the Lua Language Server extension.
function OnCreate(self)
-- Invoked once when the entity is instantiated in the scene
end
function OnUpdate(self, dt)
-- Invoked every simulation frame; dt represents delta time in seconds
end
function OnInputReceived(self, event)
-- Invoked strictly when hardware input arrives (keyboard, mouse, joystick, text)
-- (OnInputReceiced is also accepted as an alias)
if event.type == InputEvent.KeyDown and event.key == Key.Space then
print("Space key pressed!")
end
end
function OnCollisionEnter(self, other, normalX, normalY)
-- Invoked upon physical contact with another entity, providing the collision normal
end
function OnTriggerEnter(self, other)
-- Invoked when entering a trigger/sensor collider zone
end
function OnCollision(self, other)
-- Legacy fallback invoked upon collision contact
end
function OnDestroy(self)
-- Invoked when the entity or scene is destroyed
endRayneEngine allows scripts to expose typed variables to the Editor Inspector using an Export table and built-in type constructors:
-- ExportDemoScript.lua
characterTexture = Image("assets/sprites/character.png") -- Texture asset path (thumbnail preview)
spawnOffset = Vec2(50.0, -20.0) -- 2D Vector (X, Y fields)
tintColor = Color(255, 128, 64) -- RGB Color (Windows color picker)
targetObject = Entity("Player") -- Entity reference (drag from hierarchy)
spawnPrefab = Template("assets/bullet.template") -- Prefab path (thumbnail preview)
moveSpeed = 120.0 -- Float
maxHealth = 100 -- Integer
enableGlow = true -- Boolean checkbox
greetingMessage = "Hello RayneEngine!" -- String
Export = {
"characterTexture",
"spawnOffset",
"tintColor",
"targetObject",
"spawnPrefab",
"moveSpeed",
"maxHealth",
"enableGlow",
"greetingMessage"
}- Visual Previews: The Inspector displays real-time thumbnail previews for
Imageassets andTemplateprefabs. - Color Picker: Clicking the color swatch opens the native Windows color selection dialog (
ChooseColor). - Drag & Drop: Drag files directly from the Content Browser onto Image/Template slots, or drag objects from the Hierarchy tree onto Entity slots.
| Function | Signature | Description |
|---|---|---|
CreateEntity |
() -> Entity |
Instantiates a new entity and returns its integer ID |
DestroyEntity |
(e: Entity) |
Removes an entity and all its attached components |
AddTag |
(e: Entity, tag: string) |
Attaches a new TagComponent |
SetTag |
(e: Entity, tag: string) |
Attaches or updates an existing TagComponent |
GetTag |
(e: Entity) -> string |
Retrieves entity tag / name string |
HasTag |
(e: Entity) -> boolean |
Checks if entity has a TagComponent |
FindEntityWithTag |
(tag: string) -> Entity |
Searches and returns first entity with matching tag, or 0 |
AddTransform |
(e: Entity, x: number, y: number) |
Attaches a TransformComponent |
GetTransform |
(e: Entity) -> Transform |
Returns a mutable reference to { x, y, rotation, scaleX, scaleY } |
SetPosition |
(e: Entity, x: number, y: number) |
Sets spatial position directly |
SetRotation |
(e: Entity, angle: number) |
Sets spatial rotation angle in degrees |
SetScale |
(e: Entity, sx: number, sy: number) |
Sets spatial scale factors |
HasTransform |
(e: Entity) -> boolean |
Checks if entity has a transform |
AddVelocity |
(e: Entity, dx: number, dy: number) -> Velocity |
Attaches or updates a VelocityComponent |
GetVelocity |
(e: Entity) -> Velocity |
Returns a mutable reference to { dx, dy, vx, vy, x, y } |
SetVelocity |
(e: Entity, dx: number, dy: number) |
Sets velocity vector directly (attaches if not present) |
HasVelocity |
(e: Entity) -> boolean |
Checks if entity has velocity |
RemoveVelocity |
(e: Entity) |
Removes VelocityComponent from entity |
AddSprite |
(e: Entity, path: string, w: number, h: number) |
Attaches a SpriteComponent |
SetSprite |
(e: Entity, path: string) |
Updates or swaps the sprite texture |
SetSpriteSize |
(e: Entity, w: number, h: number) |
Updates rendered dimensions of sprite |
HasSprite |
(e: Entity) -> boolean |
Checks if entity has a sprite |
SetColor |
(e: Entity, r: number, g: number, b: number, [a]: number) |
Sets color of RenderComponent (0–255) |
AddCamera |
(e: Entity, [smoothSpeed=0.0], [ox=0.0], [oy=0.0], [zoom=1.0], [priority=0]) -> CameraComponent |
Attaches or updates camera tracking component |
GetCamera |
`(e: Entity) -> CameraComponent | nil` |
RemoveCamera |
(e: Entity) |
Removes camera component |
HasCamera |
(e: Entity) -> boolean |
Checks if entity has camera tracking |
AddCollision |
(e: Entity, [channel]: integer) |
Attaches a CollisionComponent (default channel 0, type Static) |
RemoveCollision |
(e: Entity) |
Removes collision component |
HasCollision |
(e: Entity) -> boolean |
Checks if entity has collision enabled |
SetCollisionChannel |
(e: Entity, channel: integer) |
Sets collision filter channel |
GetCollisionChannel |
(e: Entity) -> integer |
Reads collision filter channel |
SetCollisionType |
(e: Entity, type: string) |
Sets collision type: "static" or "solid" |
GetCollisionType |
(e: Entity) -> string |
Returns current collision type as string |
SetParent |
(child: Entity, parent: Entity, [keepWorldTransform=true]: boolean) |
Sets entity parent; 0 unparents |
GetParent |
(child: Entity) -> Entity |
Returns parent entity ID, or 0 |
GetChildren |
(parent: Entity) -> Entity[] |
Returns array of child entity IDs |
GetWorldPosition |
(e: Entity) -> number, number |
Computes global world coordinates x, y |
GetWorldRotation |
(e: Entity) -> number |
Computes global world rotation in degrees |
GetWorldScale |
(e: Entity) -> number, number |
Computes global world scale factors sx, sy |
Template |
(path: string) -> Template |
Creates template reference object |
Instantiate |
`(template: Template | string, x: number, y: number, [parent]: Entity) -> Entity` |
LoadScene |
(sceneName: string) |
Switches active scene to assets/scenes/<sceneName>.json |
Tip:
GetTransform(e)returns a mutable table — you can read and writet.x,t.y,t.rotation,t.scaleX,t.scaleYdirectly on the returned reference.
| Function | Signature | Description |
|---|---|---|
Camera.SetPosition |
(x: number, y: number) |
Sets absolute world center of the camera |
Camera.GetPosition |
() -> number, number |
Returns world center x, y of the camera |
Camera.GetX |
() -> number |
Returns camera center world X |
Camera.GetY |
() -> number |
Returns camera center world Y |
Camera.Move |
(dx: number, dy: number) |
Translates camera position by relative world offsets |
Camera.SetZoom |
(zoom: number) |
Sets camera zoom factor (1.0 = normal, >1 = in, <1 = out) |
Camera.GetZoom |
() -> number |
Returns current camera zoom factor |
Camera.Zoom |
(factor: number) |
Multiplies camera zoom by a multiplier |
Camera.SetRotation |
(deg: number) |
Sets camera rotation angle in degrees |
Camera.GetRotation |
() -> number |
Returns camera rotation angle in degrees |
Camera.Rotate |
(deltaDeg: number) |
Rotates camera by delta angle in degrees |
Camera.SetSize |
(w: number, h: number) |
Sets base viewport dimensions |
Camera.GetSize |
() -> number, number |
Returns base viewport dimensions w, h |
Camera.Reset |
() |
Resets camera to default position, zoom (1.0), rotation (0.0), shake, and clears follow targets |
Camera.Follow |
(e: Entity, [smoothSpeed=0.0], [ox=0.0], [oy=0.0]) |
Follows entity target with optional smooth damping and offset |
Camera.StopFollow |
() |
Disables following any entity target |
Camera.ResumeFollow |
() |
Resumes following the active entity target |
Camera.IsFollowing |
() -> boolean |
Returns true if the camera is actively tracking an entity |
Camera.GetFollowTarget |
() -> Entity |
Returns tracked entity ID (or 0 if none) |
Camera.SetFollowSpeed |
(speed: number) |
Sets follow smooth damping speed (0 for instant snapping) |
Camera.GetFollowSpeed |
() -> number |
Returns current follow damping speed |
Camera.SetFollowOffset |
(ox: number, oy: number) |
Sets camera tracking offset in world units |
Camera.GetFollowOffset |
() -> number, number |
Returns camera tracking offset ox, oy |
Camera.AddFollowTarget |
(e: Entity) |
Adds an entity to the multi-target tracking group |
Camera.RemoveFollowTarget |
(e: Entity) |
Removes an entity from multi-target tracking |
Camera.ClearFollowTargets |
() |
Clears all tracked entities in the follow group |
Camera.FollowGroup |
(targets: Entity[], [mode], [padding]) |
Replaces follow targets with a list and sets optional follow mode & padding |
Camera.GetFollowTargets |
() -> Entity[] |
Returns an array of all currently tracked entity IDs |
Camera.GetFollowTargetCount |
() -> integer |
Returns the number of currently tracked follow targets |
Camera.SetMultiFollowMode |
(mode: CameraMultiFollowMode | integer | string) |
Sets multi-follow mode: Priority (0), Average (1), AutoFrame (2) |
Camera.GetMultiFollowMode |
() -> integer |
Returns the active CameraMultiFollowMode integer value |
Camera.SetAutoFramePadding |
(padding: number) |
Sets world margin/padding added around tracked targets in AutoFrame mode |
Camera.GetAutoFramePadding |
() -> number |
Returns the active AutoFrame world margin padding |
Camera.SetAutoFrameZoomLimits |
(minZoom: number, maxZoom: number) |
Sets min and max zoom clamp boundaries for AutoFrame mode |
Camera.GetAutoFrameZoomLimits |
() -> minZoom, maxZoom |
Returns the min and max zoom boundaries |
Camera.SetPrimary |
(e: Entity) |
Sets the primary active camera entity |
Camera.GetPrimary |
() -> Entity |
Returns the primary active camera entity ID |
Camera.SetBounds |
(minX, minY, maxX, maxY, [clampEdges=true]) |
Restricts camera movement within specified world bounding box |
Camera.ClearBounds |
() |
Clears world boundary constraints |
Camera.HasBounds |
() -> boolean |
Checks if world boundary constraints are active |
Camera.GetBounds |
() -> minX, minY, maxX, maxY |
Returns active camera boundary box coordinates |
Camera.Shake |
(intensity: number, duration: number, [decay=true]) |
Triggers screenshake with optional decay over duration |
Camera.StopShake |
() |
Immediately stops active screenshake |
Camera.IsShaking |
() -> boolean |
Returns true if screenshake is currently active |
Camera.ScreenToWorld |
(sx: number, sy: number) -> number, number |
Maps screen pixel coordinates to world coordinates |
Camera.WorldToScreen |
(wx: number, wy: number) -> number, number |
Maps world coordinates to screen pixel coordinates |
| Constant | Value | Description |
|---|---|---|
CameraMultiFollowMode.Priority |
0 |
Tracks solely the highest-priority entity (priority field in CameraComponent) |
CameraMultiFollowMode.Average |
1 |
Midpoint tracking: computes the average centroid position of all active entities |
CameraMultiFollowMode.AutoFrame |
2 |
Intelligent dynamic framing: centers on target centroid and adjusts zoom to frame all targets with padding |
| Function | Signature | Description |
|---|---|---|
AddRigidbody |
(e: Entity, [bodyType], [mass=1.0], [gravityScale=1.0]) -> Rigidbody2D |
Attaches a Rigidbody2D component |
GetRigidbody |
(e: Entity) -> Rigidbody2D | nil |
Returns the Rigidbody2D component or nil |
HasRigidbody |
(e: Entity) -> boolean |
Checks if entity has a Rigidbody |
Physics.Raycast |
(startX, startY, dirX, dirY, distance, [channel=-1]) -> RaycastResult |
Casts a ray and returns closest hit (hit, entity, pointX, pointY, normalX, normalY, distance) |
Physics.ApplyForce |
(e: Entity, fx: number, fy: number) |
Applies a continuous force (accumulated for the next physics step) |
Physics.ApplyImpulse |
(e: Entity, ix: number, iy: number) |
Applies an instantaneous impulse directly modifying velocity |
Physics.SetVelocity |
(e: Entity, vx: number, vy: number) |
Sets linear velocity directly |
Physics.GetVelocity |
(e: Entity) -> number, number |
Gets current linear velocity vx, vy |
Physics.SetGravity |
(gx: number, gy: number) |
Sets global physics gravity vector (default: 0, 980) |
Physics.GetGravity |
() -> number, number |
Returns current global gravity vector |
Physics.SetFixedTimestep |
(dt: number) |
Sets fixed simulation timestep in seconds (default: 1/60 ~ 0.01667) |
Physics.GetFixedTimestep |
() -> number |
Returns current fixed simulation timestep |
Enums:
BodyType:BodyType.Dynamic(0),BodyType.Kinematic(1),BodyType.Static(2)ColliderShape:ColliderShape.Box(0),ColliderShape.Circle(1)
| Function | Signature | Description |
|---|---|---|
Engine.Log / print |
(...) |
Prints highlighted message to in-editor console with teal [LOG] badge |
Engine.LogWarning |
(msg: string) |
Prints warning message with amber [WARN] badge |
Engine.LogError |
(msg: string) |
Prints error message with red [ERROR] badge |
Engine.LogToScreen / LogToScreen |
(msg: string, [duration=3.5], [r], [g], [b]) |
Displays on-screen notification toast during play mode |
Engine.SetPaused / PauseGame |
(paused: boolean) |
Pauses or unpauses game simulation |
Engine.IsPaused / Engine.GetPaused |
() -> boolean |
Returns true if simulation is currently paused |
Engine.TogglePause |
() |
Toggles simulation pause state |
Engine.SetTimeScale / SetTimeScale |
(scale: number) |
Sets simulation time scale factor |
Engine.GetTimeScale |
() -> number |
Gets current simulation time scale factor |
Engine.SetFullscreen |
(fullscreen: boolean) |
Sets window fullscreen mode |
Engine.ToggleFullscreen |
() |
Toggles window fullscreen mode |
Engine.IsFullscreen |
() -> boolean |
Returns true if window is currently fullscreen |
Engine.SetCursorVisible |
(visible: boolean) |
Shows or hides the mouse cursor |
Engine.TakeScreenshot |
([filename]: string) -> string |
Captures screenshot and saves to screenshots/ |
Engine.OpenURL |
(url: string) |
Opens URL or file path in default OS handler |
Engine.GetFPS / GetFPS |
() -> number |
Returns current frames per second |
Engine.GetDeltaTime |
() -> number |
Returns unscaled delta time of current frame |
Engine.ShowFPS |
(show: boolean) |
Shows or hides on-screen FPS counter overlay |
Engine.IsFPSShown |
() -> boolean |
Returns true if FPS counter is visible |
Engine.RestartScene / RestartScene |
() |
Resets and reloads the active scene |
Engine.RestartCurrentScene |
() |
Alias for Engine.RestartScene() |
Engine.LoadScene / LoadScene |
(sceneName: string) |
Loads scene from assets/scenes/<name>.json |
Engine.Quit / QuitGame |
() |
Exits standalone build or returns to editor |
| Function | Signature | Description |
|---|---|---|
MathR.ClampI |
(value: number, min: number, max: number) -> number |
Clamps an integer between bounds |
MathR.ClampF |
(value: number, min: number, max: number) -> number |
Clamps a float between bounds |
MathR.ClampF01 |
(value: number) -> number |
Clamps a float into [0.0, 1.0] |
MathR.AbsI |
(value: number) -> number |
Returns integer absolute value |
MathR.AbsF |
(value: number) -> number |
Returns floating-point absolute value |
MathR.Ceil |
(value: number) -> number |
Smallest integer greater than or equal to argument |
MathR.Floor |
(value: number) -> number |
Largest integer less than or equal to argument |
MathR.Lerp |
(start: number, endVal: number, factor: number) -> number |
Linearly interpolates between two values (factor clamped to [0, 1]) |
MathR.InverseLerp |
(start: number, endVal: number, value: number) -> number |
Computes interpolation factor for value |
MathR.Sin |
(x: number) -> number |
Sine via 10-term Taylor series approximation |
MathR.Cos |
(x: number) -> number |
Cosine computation |
| Function | Signature | Description |
|---|---|---|
Input.IsKeyDown |
(key: number | string) -> boolean |
True while key is held down |
Input.IsKeyPressed |
(key: number | string) -> boolean |
True during the frame key was pressed |
Input.IsKeyJustPressed |
(key: number | string) -> boolean |
True during the frame key was pressed (alias for IsKeyPressed) |
Input.IsKeyReleased |
(key: number | string) -> boolean |
True during the frame key was released |
Input.IsMouseDown |
(button: number | string) -> boolean |
True while mouse button is held down |
Input.IsMousePressed |
(button: number | string) -> boolean |
True during the frame mouse button was pressed |
Input.IsMouseReleased |
(button: number | string) -> boolean |
True during the frame mouse button was released |
Input.MouseX |
() -> number |
Mouse horizontal position in screen space |
Input.MouseY |
() -> number |
Mouse vertical position in screen space |
Input.MouseScroll |
() -> number |
Mouse wheel scroll delta for current frame |
Input.HasInput |
() -> boolean |
True if any hardware input event occurred this frame |
Input.GetLastEvent |
() -> InputEventData | nil |
Returns the most recently processed input event data |
Input.KeyToString |
(key: integer) -> string |
Converts a numeric key code to its human-readable name |
Input.MouseButtonToString |
(button: integer) -> string |
Converts a numeric mouse button code to its name |
Key Enums (Key / KeyCode): A through Z, Space, Enter, Escape, LShift, RShift, LCtrl, RCtrl, Left, Right, Up, Down, Tab, Delete. (Both Key.Space and KeyCode.Space are supported).
Key strings (case-insensitive): single letters "a"–"z", digits "0"–"9", "space", "enter" / "return", "escape" / "esc", "shift" / "lshift", "rshift", "ctrl" / "lctrl", "rctrl", "alt" / "lalt", "ralt", "left", "right", "up", "down", "tab", "delete" / "del", "backspace".
Mouse Enums (Mouse): Left, Right, Middle.
Strings "left" / "0", "right" / "1", "middle" / "2" are also accepted.
Input Event Enums (InputEvent / InputEventType / EventType):
KeyDown, KeyUp, MouseDown, MouseUp, MouseMove, MouseWheel, TextEntered, JoystickPressed, JoystickReleased, JoystickMoved, Unknown (with lowercase and legacy aliases like Keydown, Mousedown, KeyPressed, MouseScroll, etc.).
InputEventData Fields:
type(integer): Enum code fromInputEvent(e.g.InputEvent.KeyDown)typeName(string): Event name (e.g."KeyDown","MouseDown","MouseMove","TextEntered")key/keyCode(integer) &keyName(string): Key informationbutton/buttonCode(integer) &buttonName(string): Mouse button informationx,y(number): Screen mouse coordinatesworldX,worldY(number): Camera-mapped world coordinatesdelta(number),wheel(string): Mouse wheel delta and orientation ("vertical"or"horizontal")text(string),unicode(integer): Typed character and codepoint forTextEnteredalt,control,shift,system(boolean): Modifier key statesjoystickId,axis,position: Gamepad / joystick valuesisInput(boolean): Always trueisPaused(boolean): Current engine pause status
| Function | Signature | Description |
|---|---|---|
Audio.PlaySound |
(path: string, [volume=100]: number, [pitch=1.0]: number) |
Plays sound effect via channel pool |
Audio.StopAllSounds |
() |
Stops all active sound channels |
Audio.PlayMusic |
(path: string, [loop=true]: boolean, [volume=100]: number) |
Plays streaming background music |
Audio.StopMusic |
() |
Stops background music stream |
Audio.PauseMusic |
() |
Pauses background music stream |
Audio.ResumeMusic |
() |
Resumes paused music stream |
Audio.SetMusicVolume |
(volume: number) |
Adjusts music volume (0–100) |
Audio.SetMasterVolume |
(volume: number) |
Adjusts global engine volume (0–100), rescales all active sounds |
| Function | Signature | Description |
|---|---|---|
Resource.PreloadTexture |
(path: string) -> boolean |
Caches a texture in memory |
Resource.PreloadFont |
(path: string) -> boolean |
Caches a font in memory |
Resource.PreloadSound |
(path: string) -> boolean |
Caches a sound buffer in memory |
Resource.ClearTextures |
() |
Flushes texture cache |
Resource.ClearFonts |
() |
Flushes font cache |
Resource.ClearSounds |
() |
Flushes sound cache |
Resource.ClearAll |
() |
Flushes entire resource cache |
Resource.TextureCount |
() -> number |
Number of cached textures |
Resource.FontCount |
() -> number |
Number of cached fonts |
Resource.SoundCount |
() -> number |
Number of cached sounds |
Resource.PrintStats |
() |
Prints memory statistics to console |
The Timer utility allows scheduling one-shot Lua callbacks without manual delta-time accumulators:
| Function | Signature | Description |
|---|---|---|
Timer.After |
(delay: number, callback: function) |
Executes the callback function once after delay seconds |
-- Example: Spawn an effect after 1.5 seconds
Timer.After(1.5, function()
print("One-shot timer fired!")
end)The Tween utility provides smooth position interpolation for entities with easing curves:
| Function | Signature | Description |
|---|---|---|
Tween.Position |
(entity: Entity, targetX: number, targetY: number, duration: number, [easing]: string) |
Interpolates entity position over duration seconds |
Supported Easing Modes:
"linear"(default) — constant velocity interpolation"EaseInQuad"— quadratic acceleration (starts slowly)"EaseOutQuad"— quadratic deceleration (ends gently)"EaseInOutQuad"— smooth ease-in followed by ease-out
-- Example: Move an entity smoothly to (500, 300) over 1.2 seconds
Tween.Position(self, 500, 300, 1.2, "EaseOutQuad")All UI elements designed in the UI Editor can be queried and manipulated from Lua scripts at runtime.
| Function | Signature | Description |
|---|---|---|
UI_SetText |
(id: string, text: string) |
Sets the display text of a Text or Button element |
UI_GetText |
(id: string) -> string |
Gets the current text content |
UI_SetPosition |
(id: string, x: number, y: number) |
Moves the element on the screen |
UI_SetSize |
(id: string, w: number, h: number) |
Resizes the element |
UI_SetColor |
(id: string, r, g, b, a: number) |
Sets the background fill color (0–255) |
UI_SetZIndex |
(id: string, z: integer) |
Controls render/hit-test order |
UI_GetZIndex |
(id: string) -> integer |
Reads current z-index |
UI_IsButtonClicked |
(id: string) -> boolean |
True during the frame the button was clicked |
UI_IsButtonHovered |
(id: string) -> boolean |
True while cursor is over the button |
UI_SetVisible |
(id: string, visible: boolean) |
Shows or hides the element |
UI_GetVisible |
(id: string) -> boolean |
Returns current visibility |
UI_SetOpacity |
(id: string, opacity: number) |
Sets opacity (0–255) |
UI_SetTextStyle |
(id: string, style: integer) |
SFML style bitmask: 0=Regular, 1=Bold, 2=Italic, 4=Underline, 8=StrikeThrough |
UI_SetTextAlign |
(id: string, align: integer) |
Text alignment: 0=Left, 1=Center, 2=Right |
UI_SetUpperCase |
(id: string, upper: boolean) |
Converts text to uppercase |
UI_SetFontSize |
(id: string, size: integer) |
Sets character size in pixels |
UI_SetLetterSpacing |
(id: string, spacing: number) |
Sets letter spacing factor |
UI_SetLineSpacing |
(id: string, spacing: number) |
Sets line spacing factor |
UI_SetTextOutline |
(id: string, r, g, b, a, thickness: number) |
Sets text outline color and thickness |
UI_SetTextOffset |
(id: string, ox: number, oy: number) |
Offsets text within the element |
UI_SetTextColor |
(id: string, r, g, b, a: number) |
Sets the text color independently |
UI_SetOutline |
(id: string, r, g, b, a, thickness: number) |
Sets panel/button border color and thickness |
UI_SetDisabled |
(id: string, disabled: boolean) |
Disables button interaction and applies disabled color |
-- Example: Show score label and react to button click
function OnUpdate(self, dt)
UI_SetText("score_label", "Score: " .. tostring(score))
if UI_IsButtonClicked("btn_start") then
LoadScene("level1")
end
end-- Player controller demonstrating Input, Transform, Audio, Collision, and UI
local speed = 250
local bounceAmplitude = 20
local timer = 0
function OnCreate(self)
if not HasCollision(self) then
AddCollision(self, 0)
SetCollisionType(self, "solid")
end
print("Entity " .. tostring(self) .. " spawned successfully.")
end
function OnUpdate(self, dt)
local t = GetTransform(self)
if not t then return end
local moveX = 0
local moveY = 0
-- Input polling via string names or Key enums
if Input.IsKeyDown("w") or Input.IsKeyDown(Key.Up) then
moveY = moveY - 1
end
if Input.IsKeyDown("s") or Input.IsKeyDown(Key.Down) then
moveY = moveY + 1
end
if Input.IsKeyDown("a") or Input.IsKeyDown(Key.Left) then
moveX = moveX - 1
end
if Input.IsKeyDown("d") or Input.IsKeyDown(Key.Right) then
moveX = moveX + 1
end
-- Smooth movement
t.x = t.x + moveX * speed * dt
t.y = t.y + moveY * speed * dt
-- Trigonometric animation via MathR
timer = timer + dt
local bounceOffset = MathR.Sin(timer * 4.0) * bounceAmplitude
-- Update HUD
UI_SetText("pos_label", string.format("X: %.0f Y: %.0f", t.x, t.y))
-- Sound effect on key press edge
if Input.IsKeyPressed(Key.Space) then
Audio.PlaySound("assets/sounds/jump.wav", 80, 1.0)
Tween.Position(self, t.x, t.y - 100, 0.3, "EaseOutQuad")
end
end
function OnCollision(self, other)
local tag = HasTag(other) and GetTag(other) or "unknown"
print("Collided with: " .. tag)
end- Language: C++20
- Graphics, Windowing & Audio: SFML 2.6+
- Scripting Engine: Lua 5.4 & sol2
- JSON Parser & Serializer: nlohmann_json 3.11.3
- Build System: CMake 3.16+ (automated dependency management via
FetchContent) - Platform: Windows (primary), Linux
- C++20 compliant compiler:
- MSVC (Visual Studio 2022 v17.0 or newer)
- GCC 11+
- Clang 13+
- CMake 3.16 or higher
- Git
All engine dependencies (SFML, Lua 5.4, sol2, nlohmann_json) are automatically downloaded, built, and linked by CMake during compilation.
# Clone the repository
git clone https://github.com/prayyOnIntelliJ/RayneEngine.git
cd RayneEngine
# Generate build configuration
cmake -B build -DCMAKE_BUILD_TYPE=Release
# Compile binary
cmake --build build --config ReleaseThe project includes a standalone target called RayneGame that compiles without the editor tools and overhead. It uses the project_settings.json configured via the Project Hub to boot directly into your game, making it ready for distribution.
Run the binary from the root project directory so that the relative assets/ path resolves correctly:
# Windows
.\build\Release\RayneEngine.exe
.\build\Release\RayneGame.exe # To test the standalone game
# Linux
./build/RayneEngine
./build/RayneGame
