Getting Started
Installation, first launch, and editor overview.
Welcome to TEGE
TEGE (The Enjin Game Engine) is an open-source (BSL 1.1) game engine built entirely from scratch using C++20 and the Vulkan graphics API. It ships with a complete editor powered by Dear ImGui, an Entity-Component-System architecture with over 70 component types, physically-based rendering, skeletal animation, and AngelScript scripting — everything you need to create 2D, 2.5D, and 3D games from a single, unified toolset.
Feature Highlights
- 70+ ECS components — Transform, Mesh, Material, Light, Camera, Rigidbody, Sprite, Tilemap, Audio, UI Canvas, Dialogue, and many more.
- Vulkan PBR rendering — Physically-based materials with metallic/roughness workflow, normal maps, height maps, emissive, transmission, subsurface scattering, and cel shading.
- Ray tracing — Full RT pipeline for shadows, reflections, ambient occlusion, global illumination, translucency, and caustics with SVGF, OIDN, and OptiX denoisers.
- 6 character controllers — First-person, third-person, top-down, platformer, vehicle, and planet-gravity controllers.
- Jolt 3D + Box2D 2D physics — Dual physics backends via a unified interface, with collision filtering, sensors, joints, gravity zones, and conveyors.
- AngelScript + visual scripting — Sandboxed text scripting with a complete API, plus a 76-node blueprint-style visual script editor with debugger.
- Tiered save system — Three persistence tiers (RunState, SceneState, MetaProgression) covering collectibles, checkpoints, and cross-session progression.
- LAN multiplayer — Built-in networking layer for local-area multiplayer and splitscreen support.
- 23+ templates — Ready-made starting points across 5 categories: Foundations, Genre Showcases, Systems Deep-Dives, Retro & Flash, and Advanced.
- Procedural generation — Terrain, dungeon, and world generation utilities built on Perlin/simplex noise.
- Accessibility — 11 editor themes, colorblind simulation modes, reduced-motion settings, subtitle sizing, and focus-navigable UI.
- Build pipeline — One-click export to a standalone player with asset packing (
.enjpak), CRC integrity checks, and configurable window settings.
Philosophy
TEGE is built from the ground up with zero middleware dependencies. Every subsystem — rendering, physics abstraction, audio, scripting, animation, networking, UI, AI, and the editor itself — is implemented in-house. This gives you a single, cohesive codebase where every layer is designed to work together, with no hidden third-party licenses, no black-box libraries, and full source access under the BSL 1.1 license.
Installation and Build
Prerequisites
Before building TEGE, ensure the following tools are installed on your system:
| Requirement | Minimum Version | Notes |
|---|---|---|
| CMake | 3.20+ | Build system generator. Download |
| C++20 Compiler | MSVC 2019+ / GCC 10+ / Clang 12+ | Must support C++20 language features and standard library |
| Vulkan SDK | 1.3+ | Includes validation layers, vulkaninfo, and shader compilers. LunarG |
| GLFW3 | 3.3+ | Cross-platform windowing and input. Available via package managers or glfw.org |
Installing Dependencies
Ubuntu / Debian
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
libvulkan-dev \
vulkan-tools \
vulkan-validationlayers \
libglfw3-dev \
glslang-tools
Fedora / RHEL
sudo dnf install -y \
gcc-c++ \
cmake \
vulkan-devel \
vulkan-tools \
glfw-devel \
glslang
Arch Linux
sudo pacman -S \
base-devel \
cmake \
vulkan-devel \
vulkan-tools \
glfw \
glslang
macOS (Homebrew)
brew install cmake vulkan-headers vulkan-loader glfw glslang
brew install molten-vk # MoltenVK required for Vulkan on macOS
Windows (vcpkg)
- Install Visual Studio 2019 or 2022 with the "Desktop development with C++" workload.
- Install CMake 3.20+ — download from cmake.org or run
winget install Kitware.CMake. - Install the Vulkan SDK from LunarG. The installer sets
VULKAN_SDKand PATH automatically. -
Install GLFW3 via vcpkg (recommended):
git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.bat ./vcpkg install glfw3:x64-windows ./vcpkg integrate install
Platform Build Instructions
Windows (Visual Studio)
Open an x64 Native Tools Command Prompt and run:
mkdir build && cd build
cmake .. -G "Visual Studio 17 2022" -A x64
cmake --build . --config Release
If using vcpkg for GLFW, add the toolchain file:
cmake .. -G "Visual Studio 17 2022" -A x64 \
-DCMAKE_TOOLCHAIN_FILE=C:/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
The editor executable will be located at build/bin/Release/EnjinEditor.exe.
Linux
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc)
The editor executable will be located at build/bin/EnjinEditor.
macOS
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(sysctl -n hw.ncpu)
The editor executable will be located at build/bin/EnjinEditor.
CMake Build Options
| Option | Default | Description |
|---|---|---|
ENJIN_BUILD_EDITOR |
ON | Build the editor application (ImGui-based workspace with all panels and tools) |
ENJIN_BUILD_PLAYER |
ON | Build the standalone game player (no editor UI, loads .enjpak archives) |
ENJIN_BUILD_TESTS |
OFF | Build the unit test suite (~700+ test cases across 50 CTest targets) |
ENJIN_PHYSICS_JOLT |
OFF | Enable the Jolt Physics 3D backend (FetchContent, v5.2.0) |
ENJIN_PHYSICS_BOX2D |
OFF | Enable the Box2D 2D physics backend (FetchContent, v3.0.0) |
ENJIN_STEAM |
OFF | Enable Steam integration (requires the Steamworks SDK) |
Pass options on the CMake configure line:
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DENJIN_BUILD_EDITOR=ON \
-DENJIN_BUILD_PLAYER=ON \
-DENJIN_BUILD_TESTS=OFF \
-DENJIN_PHYSICS_JOLT=ON \
-DENJIN_PHYSICS_BOX2D=ON
Verifying Your Installation
After installing dependencies, verify each tool is available:
# Check CMake version
cmake --version
# Check Vulkan runtime and driver
vulkaninfo --summary
# Check shader compiler
glslc --version
# Check GLFW (Linux/macOS)
pkg-config --modversion glfw3
After adding new source files to the project, re-run cmake .. from the build directory to pick them up. CMake does not automatically detect new .cpp or .h files unless you reconfigure.
First Launch
Launch Sequence
When you run the editor for the first time, the following sequence occurs:
- Splash screen — A brief engine splash screen appears while subsystems initialize (Vulkan context, audio device, asset caches).
- Template Selector — A dialog opens presenting 23+ built-in templates organized into 5 categories. Pick one to create a pre-populated starting scene, or choose Blank for an empty canvas.
- Editor opens — The editor workspace loads with the selected template's scene, entities, and components already in place. A default 5-panel layout is applied: Hierarchy, Inspector, Viewport, Console, and Asset Browser.
Template Selector
The template selector provides 23+ ready-made starting points across five categories, each designed to showcase different engine subsystems and game genres:
| Category | Templates |
|---|---|
| Foundations | Blank, 2D Platformer, 2D Top-Down Action, 3D Third Person, 3D First Person |
| Genre Showcases | Sokoban Puzzle, Survival, RPG Village, Horror, Vehicle Racing, PS1 RPG, Arena Fighter |
| Systems Deep-Dives | Physics Playground, Dialogue & Narrative, Save System Demo, Visual Scripting, UI Canvas Demo |
| Retro & Flash | Point & Click, Bullet Hell, Idle/Clicker |
| Advanced | Planet Gravity, Dungeon Crawler, Accessibility Menu |
Each template creates the appropriate entities (ground, lights, player with
controller, camera) and pre-configures component values for its genre. Every
template includes NotesComponent hints explaining the featured
systems.
You can also save your own templates: set up a scene the way you want it, go to File > Save as Template, give it a name, and it will appear alongside the built-in templates in the selector.
Setting a Custom Window Icon
To brand your project with a custom window icon, you have two options:
- File-based: Place an
icon.pngfile next to the editor executable. The engine loads it automatically on startup. - Settings-based: Go to View > Settings > Project > Window Icon, browse for any PNG file, and click Apply. The icon updates immediately and the path is saved in the
.enjinprojectfile so it auto-applies on future launches. Use Clear to revert to the OS default icon.
The default 5-panel layout (Hierarchy, Inspector, Viewport, Console, Asset Browser) is designed for a clean first impression. All panels are dockable and can be rearranged freely — drag any panel tab to reposition it, or use the View menu to toggle panels on and off.
Editor Tour
The TEGE editor is a panel-based workspace. All panels can be toggled from the View menu in the top menu bar, and every panel is dockable — drag tabs to rearrange, split, or stack them however you prefer.
Panels
| Panel | Description |
|---|---|
| Hierarchy | Entity tree view. Right-click to add, delete, or duplicate entities. Supports drag-and-drop reparenting to build parent-child hierarchies. |
| Inspector | Component editor for the selected entity. Displays and edits all attached components (70+ component types). Includes an Add Component button with a searchable dropdown. |
| Console | Log output for engine messages, warnings, and errors. Categorized by subsystem (Renderer, Script, Physics, Audio, etc.) with severity filtering. |
| Asset Browser | Browse and manage project files with grid/list view, thumbnail previews, full-text search, and drag-and-drop import. |
| Settings | Unified settings window with 3 tabs: System (camera, performance, IDE, accessibility, fonts), Project (project mode, window icon, physics, frame rate, audio, collision groups, build config), and Scene (skybox, shadows, lighting, cel shading, display, ray tracing, light probes, post processing, retro effects, environment). |
| Game View | Rendered game camera output with Play/Pause/Stop transport controls. Shows exactly what the player will see at runtime. |
| Scene List | Multi-scene project management. Add, reorder, load scenes, and designate the start scene for builds. |
| Stats Overlay | Real-time performance metrics: FPS, frame time, draw calls, and triangle count. |
| Visual Script | Blueprint-style visual scripting editor with 76+ node types across categories (math, logic, flow, ECS, physics, input, audio) and an integrated debugger. |
| Behavior Tree | AI behavior tree editor with 20 node types (composites, decorators, leaves), a blackboard variable editor, and play-mode visualization showing live node execution. |
| Quest Flow | Visual quest designer for authoring objectives, branches, conditions, and rewards with a node-graph interface. |
| Pixel Editor | Pixel art creation tool with layers, 8 drawing tools (pencil, eraser, fill, line, rectangle, circle, eyedropper, selection), undo/redo history, and retro resolution presets. |
| Sprite Sheet Importer | Import and slice sprite sheets using grid-based or auto-detect slicing modes. Generates animation frames for use with AnimatedSpriteComponent. |
Entity and Component Icons
Entities in the Hierarchy panel display bracket-tag icons based on their primary component type, making it easy to identify entity roles at a glance. The same icon convention is used in component headers within the Inspector panel.
| Icon | Component Type |
|---|---|
[C] | Camera |
[L] | Light |
[M] | Mesh |
[S] | Sprite |
[T] | Tilemap |
[P] | Particle |
[A] | Audio |
[R] | Rigidbody |
[D] | Dialogue |
[V] | Visual Script |
[U] | UI Canvas |
[AI] | AI Agent |
[BT] | Behavior Tree |
Empty States
Panels display helpful empty-state messages when there is nothing to show, guiding you toward the next action:
- Hierarchy — "No World Loaded" or "No Entities" (with a Create Entity button).
- Inspector — "No Entity Selected".
- Asset Browser — "Directory Not Found".
- Dialogue — "No DialogueComponent".
- Plugin Browser — "No Plugins Found".
Keyboard Shortcuts
| Key | Action |
|---|---|
| 1 | Translate gizmo |
| 2 | Rotate gizmo |
| 3 | Scale gizmo |
| 4 | Toggle local / world space |
| W A S D | Fly camera movement |
| Space / E | Camera up |
| Q / Ctrl | Camera down |
| Shift | Sprint (faster fly camera) |
| Hold RMB + Mouse | Look around (orbit) |
| Left-click | Select entity |
| Double-click | Focus on entity |
| Ctrl + click | Toggle entity in/out of multi-selection |
| Shift + click | Range select in hierarchy |
| Drag in viewport | Marquee / rubber-band selection |
| Delete | Delete all selected entities |
| Ctrl + D | Duplicate all selected entities |
| F | Focus camera on selection centroid |
| Scroll wheel | Adjust fly camera speed |
| Ctrl + S | Save scene |
| Ctrl + O | Open scene |
| Ctrl + I | Import model |
| Ctrl + X | Cut entity |
| Ctrl + C | Copy entity |
| Ctrl + V | Paste entity |
| Ctrl + Z | Undo |
| Ctrl + Y | Redo |
Multi-Select
TEGE supports selecting multiple entities at once for batch operations. Selection works in both the Hierarchy panel and the 3D/2D viewport:
- Ctrl + click — Toggles an individual entity in or out of the current selection, in both the hierarchy and the viewport.
- Shift + click — Performs a range select in the hierarchy from the current primary selected entity to the clicked entity, selecting everything in between.
- Drag in viewport — Draws a marquee (rubber-band) rectangle; all entities enclosed by the rectangle are added to the selection on mouse release.
- Primary entity — The last entity clicked becomes the primary selection. The Inspector and gizmo use the primary entity as their reference point.
When multiple entities are selected, the following batch operations become available:
-
The Inspector displays a list of all selected entities and provides batch transform editing:
- Position offset — Apply a positional offset to all selected entities.
- Rotation offset — Apply a rotational offset to all selected entities.
- Scale multiplier — Multiply the scale of all selected entities.
- The Gizmo appears at the centroid of all selected entities. Dragging the gizmo applies the delta transform to every selected entity simultaneously, preserving their relative positions and orientations.
Core Concepts
Projects, ECS architecture, transforms, and play mode.
Projects and Scenes
Every game in TEGE is organized around two file types: the project manifest
(.enjinproject) and one or more scene files (.enjin).
Understanding how these relate is essential before you start building.
Project vs. Scene Files
| File | Extension | Purpose |
|---|---|---|
| Project Manifest | .enjinproject |
Top-level JSON file that names the project, lists every scene, assigns build indices, and designates the start scene. One per project. |
| Scene File | .enjin |
JSON file containing all entity and component data for a single scene. A project can have any number of scenes. |
The project manifest acts as a table of contents. It does not store entity data itself; that
lives entirely in the individual .enjin scene files.
Project Manifest Format
A .enjinproject file is a small JSON document with the following structure:
{
"name": "My Game",
"scenes": [
{ "name": "Main Menu", "path": "scenes/main.enjin", "buildIndex": 0, "isStart": true },
{ "name": "Level 1", "path": "scenes/level1.enjin", "buildIndex": 1 },
{ "name": "Level 2", "path": "scenes/level2.enjin", "buildIndex": 2 }
]
}
| Field | Type | Description |
|---|---|---|
name |
string | Human-readable project name shown in the editor title bar and build pipeline. |
scenes |
array | Ordered list of scene entries. Each entry contains the fields below. |
scenes[].name |
string | Display name for the scene in the Scene List panel. |
scenes[].path |
string | Relative path from the project root to the .enjin file. |
scenes[].buildIndex |
integer | Load order index used in exported builds. Lower indices load first. |
scenes[].isStart |
boolean | If true, this scene is loaded automatically when the built game starts. Exactly one scene should be marked as start. |
Scene List Panel
Open the Scene List panel via View > Scene List. It provides a central place to manage all scenes within your project:
- Add — create a new scene or add an existing
.enjinfile to the project. - Reorder — drag scenes up or down to change their build index order.
- Load — click any scene entry to load it into the editor viewport.
- Set Start Scene — right-click a scene and choose "Set as Start" to designate the scene that loads first in exported builds.
You can also save the current scene with Ctrl+S and open a scene with Ctrl+O.
Scene Transitions
When switching between scenes at runtime (e.g., from a main menu to gameplay), TEGE provides four transition types:
| Transition | Description | Configurable Duration |
|---|---|---|
| Instant | Immediate cut to the new scene with no visual effect. | No |
| Fade Black | The screen fades to black, the new scene loads, then fades back in. | Yes |
| Fade White | Same as Fade Black but fades through white instead. | Yes |
| Cross Fade | The old scene blends smoothly into the new scene over the transition duration. | Yes |
All transitions except Instant have a configurable duration (in seconds). Scene transitions can be triggered from AngelScript or visual scripts at runtime.
Additive Scene Loading
Scenes can be loaded additively, meaning the new scene's entities are merged on top of the currently loaded scene rather than replacing it. This is useful for layering concerns—for example, loading a UI overlay scene on top of a gameplay scene, or streaming in a new section of a level without unloading the current one.
Additive loading pairs well with the Level Streaming system for open-world designs where adjacent areas load and unload based on the player's position.
Project File Structure
A typical TEGE project on disk follows this directory layout:
my_game/
my_game.enjinproject # Project manifest (JSON)
scenes/
main.enjin # Scene files
level1.enjin
level2.enjin
assets/
textures/ # Texture files (PNG, JPG)
models/ # 3D models (GLTF, GLB)
audio/ # Audio files (WAV, OGG, MP3)
fonts/ # TTF fonts
scripts/ # AngelScript files (.as)
templates/ # Custom scene templates
All paths inside the .enjinproject manifest and scene files are relative to the
project root directory. This makes projects fully portable—move or rename the root
folder and everything continues to work.
Entity-Component-System
TEGE uses an Entity-Component-System (ECS) architecture as the foundation for all game objects. Instead of deep inheritance hierarchies, ECS separates identity, data, and logic into three orthogonal concepts:
| Concept | What It Is | Example |
|---|---|---|
| Entity | A lightweight identifier—just a u64 ID. Entities have no data or behavior by themselves. |
Entity 42 |
| Component | A plain data struct attached to an entity. Components hold state but contain no logic. | TransformComponent, MeshComponent, MaterialComponent |
| System | A function or class that iterates over entities matching a specific set of components and applies logic each frame. | RenderSystem reads Transform + Mesh + Material to draw geometry. |
ECS::World
The central manager is ECS::World. It owns all entities and their component
storage, and provides the API for creating, querying, and destroying entities. Structural
operations (creating or destroying entities, adding or removing components) are
thread-safe.
TEGE ships with over 70 component types spanning core rendering, physics, gameplay, AI, networking, animation, and more. You can compose any game object by mixing and matching the components it needs.
Creating Entities
There are two ways to create entities in the editor:
-
Entity menu — use the top menu bar's Entity menu to
create common objects:
Category Options General Create Empty 3D Objects Cube, Sphere, Plane, Cylinder, Cone 2D Objects Sprite, Animated Sprite, Tilemap Lights Directional Light, Point Light, Spot Light Camera Camera Environment Ground Plane - Hierarchy panel — right-click in the Hierarchy panel to access the same creation options via a context menu. You can also right-click an existing entity to create a child entity parented to it.
Adding Components
Select an entity in the Hierarchy or viewport, then click the Add Component
button at the bottom of the Inspector panel. A searchable dropdown lists all available
component types. Type a few characters to filter—for example, typing "light" will show
LightComponent, SpotLightComponent, and similar matches.
ECS Data Flow
The following diagram illustrates how entities, components, and systems relate at runtime. Entities are composed of components, and systems read (and sometimes write) those components each frame:
This design makes it easy to add new behavior to existing entities. Need an entity to play
footstep sounds? Attach a FootstepComponent—the FootstepSystem
will pick it up automatically on the next frame. No base class changes required.
DestroyEntity() is deferred—entities marked for destruction are not
actually removed until the start of the next Update() call. If you need to
check whether an entity is still alive (and not pending destruction), use
IsValid().
Coordinate System and Transform
TEGE uses a left-handed coordinate system:
- +X points to the right.
- +Y points up.
- +Z points forward (into the screen).
This is the same convention used by DirectX and many popular game engines. If you import models from tools that use a right-handed system (e.g., Blender defaults), the GLTF importer handles the coordinate conversion automatically.
TransformComponent
Every entity has a TransformComponent. It defines the entity's position,
orientation, and size in the scene:
| Field | Type | Default | Description |
|---|---|---|---|
position |
Vector3 | (0, 0, 0) | World-space position of the entity. |
rotation |
Vector3 | (0, 0, 0) | Euler rotation in degrees (pitch, yaw, roll). |
scale |
Vector3 | (1, 1, 1) | Scale factor on each axis. Uniform scale uses (N, N, N). |
The Inspector panel displays editable fields for each transform property. You can type exact values or use the drag handles on the numeric fields for quick adjustments.
Hierarchy and Parenting
Entities can be parented to other entities by dragging them in the Hierarchy panel. When entity B is parented to entity A:
- B's transform becomes relative to A's transform.
- Moving, rotating, or scaling A will carry B along with it.
- B's local position (0, 0, 0) means "at the same position as A."
This is essential for building compound objects—for example, a car entity with child entities for each wheel, or a character entity with an attached weapon.
Transform Gizmos
The viewport provides visual gizmos for manipulating transforms interactively. Switch between gizmo modes using the number keys:
| Key | Gizmo Mode | Description |
|---|---|---|
| 1 | Translate | Drag the arrows or planes to move the entity along an axis or plane. |
| 2 | Rotate | Drag the rings to rotate the entity around an axis. |
| 3 | Scale | Drag the handles to scale the entity on one or all axes. |
| 4 | Toggle Space | Switch between local (entity-relative) and world (global) coordinate space for the gizmo. |
When multiple entities are selected, the gizmo appears at the centroid of the selection. Dragging the gizmo applies the delta transform to every selected entity simultaneously.
Play Mode
Play Mode lets you test your game directly inside the editor. The Game View panel provides three buttons for controlling playback:
| Button | Action |
|---|---|
| Play | Enter play mode. Saves the current editor state, then activates all runtime systems (controllers, physics, scripts, gameplay). |
| Pause | Freeze the game simulation. The scene stays in play mode but time stops advancing. Press Play again to resume. |
| Stop | Exit play mode. The engine computes a diff of all changes, restores the original editor state, and shows the PlayModeDiff dialog if anything changed. |
What Happens on Play
When you press Play, the engine takes a snapshot of the entire scene state (every entity and all their components). This snapshot is held in memory so the editor can restore it when you stop. Then, all runtime systems begin updating each frame.
Behavior During Play
-
Editor input is locked. Panels receive
NoInputsflags to prevent accidental edits. Keyboard shortcuts are suppressed so they don't conflict with game controls. -
The game camera renders in the Game View panel using the highest-priority
active
CameraComponentin the scene. - The editor camera continues to be visible in the main viewport, allowing you to observe the scene from any angle while the game runs.
Active Systems During Play
The following systems are updated each frame while play mode is active:
| System | Responsibility |
|---|---|
| ControllerSystem | Processes all character controllers—movement, jumping, camera orbit, vehicle input. |
| Physics | Rigidbody simulation, collision detection, gravity, joint constraints (Jolt 3D / Box2D 2D). |
| ScriptSystem | AngelScript lifecycle callbacks: OnUpdate, OnFixedUpdate, OnLateUpdate. |
| CoroutineScheduler | Resumes suspended script coroutines each frame. |
| FootstepSystem | Surface-aware footstep audio based on character movement. |
| QuestSystem | Quest state tracking and objective progression updates. |
| HUDSystem | Runtime HUD widget rendering—health bars, resource bars, labels, crosshair. |
| CinematicSystem | Waypoint-based cinematic camera sequence playback with easing. |
| ObjectPool | Entity lifetime management, recycling, and auto-release. |
| EventBus | Deferred entity and script event dispatch for decoupled communication. |
| SaveSystem | Auto-save timer, play time tracking, checkpoint management (tiered persistence). |
| VisualScriptSystem | Visual script graph execution, including save/load/checkpoint nodes. |
| BehaviorTreeSystem | AI behavior tree tick execution for all entities with a BehaviorTreeComponent. |
| NetworkSystem | LAN multiplayer state synchronization (if a network session is active). |
What Happens on Stop
When you press Stop, the engine performs the following steps:
- All runtime systems are deactivated.
- The engine computes a JSON diff between the pre-play snapshot and the current scene state.
- The original editor state is restored from the snapshot.
- If the diff contains any changes, the PlayModeDiff dialog appears.
PlayModeDiff Dialog
The PlayModeDiff dialog lets you selectively keep changes that occurred during play. This is invaluable for level design—for example, you might play-test to find the perfect position for an object, then apply just that transform change back to the editor scene.
- Tree view — all changed entities are listed in an expandable tree. Expand an entity to see its changed components, and expand a component to see individual property changes.
-
Color-coded actions:
- Green — entity or component was created during play.
- Red — entity or component was deleted during play.
- Yellow — entity or component was modified during play.
- Checkboxes — every node in the tree (entity, component, and individual property) has a checkbox. Check only the changes you want to keep.
- Apply Selected — re-applies the checked changes to the restored editor scene.
- Discard All — closes the dialog without applying any changes. The scene returns to its exact pre-play state.
Play Mode Flow
The complete state machine for play mode is shown below:
Note that stopping from either Playing or Paused state always goes through the diff dialog (when changes exist). If nothing changed during play, the editor returns directly to the Editing state without showing the dialog.
Play mode changes are computed at the entity, component, and property level. Even if you move dozens of objects during play-testing, you can cherry-pick exactly which positional changes to keep and discard the rest.
Component Reference
Complete documentation for every component type in TEGE.
9. Core Components
Core components provide the foundational data every entity may need: spatial
placement, naming, tagging, and developer annotations. Most entities will
carry at least a TransformComponent and a
NameComponent.
TransformComponent
Every entity has a transform. It controls the entity's position, rotation, and scale in the scene. The transform is the single most commonly used component and is automatically present on all entities created through the editor.
| Field | Type | Default | Description |
|---|---|---|---|
position |
Vector3 | (0, 0, 0) | World position. |
rotation |
Vector3 | (0, 0, 0) | Euler rotation in degrees. |
scale |
Vector3 | (1, 1, 1) | Scale on each axis. |
NameComponent
Gives the entity a human-readable display name shown in the hierarchy panel.
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | "" | Entity display name. |
MeshComponent
Stores the vertex and index data used by the renderer to draw geometry. Each vertex contains position, normal, UV coordinates, vertex color, tangent, bone weights, and bone indices. The mesh is typically populated by importing a 3D model (GLTF/GLB) or by using a built-in primitive such as Cube, Sphere, Plane, or Cylinder.
| Field | Type | Default | Description |
|---|---|---|---|
vertices |
vector<Vertex> | [] | Vertex buffer (position, normal, UV, color, tangent, bone weights, bone indices). |
indices |
vector<u32> | [] | Index buffer for indexed drawing. |
NotesComponent
Attaches text annotations to entities for documentation or design notes. Notes are visible only in the editor and are stripped from exported builds.
| Field | Type | Default | Description |
|---|---|---|---|
notes |
string | "" | Free-form text annotation. |
The field name is .notes, not .text. This is a common source of confusion in scripts and serialization code.
TagComponent
String-based tags for filtering and identification. An entity can have
multiple tags, enabling flexible querying (e.g., find all entities tagged
"enemy" or "destructible").
| Field | Type | Default | Description |
|---|---|---|---|
tags |
list<string> | [] | List of tag strings. |
Methods:
| Method | Returns | Description |
|---|---|---|
HasTag(tag) |
bool | Returns true if the entity has the specified tag. |
AddTag(tag) |
void | Adds a tag string. Duplicates are ignored. |
RemoveTag(tag) |
void | Removes a tag by value. No-op if not present. |
LayerComponent
Numeric layer assignment used for collision filtering and selective
rendering. Layers work with CameraComponent::cullingMask and
the collision bitmask system.
| Field | Type | Default | Description |
|---|---|---|---|
layer |
u32 | 0 | Layer number (0-31). |
layerName |
string | "" | Human-readable layer name. |
10. Rendering Components
Rendering components control how entities appear in the viewport: surface materials, lighting, cameras, billboards, text, and post-processing volumes.
MaterialComponent
Controls the visual surface properties of a mesh. Supports physically-based rendering (PBR), texture maps, alpha modes, and a full suite of retro rendering flags for stylized visuals.
PBR & Surface Fields
| Field | Type | Default | Description |
|---|---|---|---|
baseColor |
Vector3 | (1, 1, 1) | Albedo color (RGB, 0-1 range). |
opacity |
f32 | 1.0 | Transparency (0 = invisible, 1 = opaque). |
metallic |
f32 | 0.0 | Metallic factor (0 = dielectric, 1 = metal). |
roughness |
f32 | 0.5 | Surface roughness (0 = mirror, 1 = diffuse). |
emissiveColor |
Vector3 | (0, 0, 0) | Emission color (RGB). |
emissiveStrength |
f32 | 0.0 | Emission intensity multiplier. |
baseColorTexturePath |
string | "" | Path to base color / albedo texture. |
normalTexturePath |
string | "" | Path to tangent-space normal map. |
heightTexturePath |
string | "" | Path to height map for parallax mapping. |
parallaxScale |
f32 | 0.05 | Parallax occlusion mapping depth. |
doubleSided |
bool | false | Render both front and back faces. |
castShadows |
bool | true | Whether this mesh casts shadows. |
receiveShadows |
bool | true | Whether this mesh receives shadows. |
alphaMode |
enum | Opaque | Alpha mode: Opaque, Mask, or Blend. |
alphaCutoff |
f32 | 0.5 | Cutoff threshold for Mask alpha mode. |
Retro Rendering Flags
Per-material flags that enable retro visual styles (PS1-era aesthetics, dithered transparency, Gouraud shading, etc.).
| Flag | Type | Default | Description |
|---|---|---|---|
flatShading |
bool | false | Disables smooth shading for a faceted look. |
affineTexturing |
bool | false | PS1-style texture warping (no perspective correction). |
vertexSnapping |
bool | false | PS1-style vertex jittering. |
vertexSnapResolution |
i32 | 160 | Grid resolution for vertex snapping (80-320). |
stippleTransparency |
bool | false | Dithered transparency pattern instead of alpha blending. |
uvQuantize |
bool | false | Quantize UV coordinates for a retro look. |
gouraudOnly |
bool | false | Force Gouraud shading (no per-pixel lighting). |
LightComponent
Adds a light source to the entity. The engine supports multiple
simultaneous lights with shadow mapping. For directional and spot lights
the direction field controls the light direction; you can also
extract the forward vector from the entity's
TransformComponent rotation.
| Field | Type | Default | Description |
|---|---|---|---|
type |
enum | Directional | Light type: Directional, Point, or Spot. |
color |
Vector3 | (1, 1, 1) | Light color (RGB). |
intensity |
f32 | 1.0 | Brightness multiplier. |
direction |
Vector3 | (0, -1, 0) | Light direction (for directional and spot lights). |
CameraComponent
Attaches a game camera to an entity. The editor has its own camera; this component is for in-game cameras used during play mode. The highest-priority active camera is used for rendering. Camera frustum visualization is shown in the editor viewport for game cameras.
| Field | Type | Default | Description |
|---|---|---|---|
projectionType |
enum | Perspective | Perspective or Orthographic. |
fieldOfView |
f32 | 60.0 | Vertical FOV in degrees (perspective only). |
nearPlane |
f32 | 0.1 | Near clipping plane distance. |
farPlane |
f32 | 1000.0 | Far clipping plane distance. |
orthoSize |
f32 | 10.0 | Half-height of orthographic view. |
priority |
i32 | 0 | Higher priority cameras take precedence. |
isActive |
bool | true | Whether this camera is eligible for activation. |
backgroundColor |
Vector3 | (0.1, 0.1, 0.15) | Clear color when this camera renders. |
viewportX |
f32 | 0.0 | Viewport X position (normalized 0-1). |
viewportY |
f32 | 0.0 | Viewport Y position (normalized 0-1). |
viewportWidth |
f32 | 1.0 | Viewport width (normalized 0-1). |
viewportHeight |
f32 | 1.0 | Viewport height (normalized 0-1). |
cullingMask |
u32 | 0xFFFFFFFF | Layer bitmask controlling which layers this camera renders. |
Camera Presets
The editor provides 9 built-in camera presets that configure the camera component and entity transform in one click:
| Preset | Description |
|---|---|
Isometric 45 |
Classic isometric view at 45-degree angle. |
Isometric 30 |
Shallow isometric view at 30-degree angle. |
Top-Down |
Straight-down orthographic camera. |
Side Scroller |
Orthographic camera facing the XY plane. |
First Person |
Perspective camera at eye level, narrow FOV. |
Third Person |
Perspective camera offset behind and above the entity. |
Cinematic Wide |
Wide-angle perspective for cinematic shots. |
Security Cam |
High-angle fixed camera with wide FOV. |
Bird's Eye |
High-altitude overhead perspective view. |
BillboardComponent
Makes the entity always face the camera. Useful for sprites, health bars, labels, and particle-like effects in 3D scenes.
| Field | Type | Default | Description |
|---|---|---|---|
faceCamera |
bool | true | Enable billboard behavior. |
lockY |
bool | true | Only rotate on Y axis (vertical lock, like trees). |
rotationOffset |
f32 | 0.0 | Additional rotation in degrees. |
TextComponent
Renders 3D text in the world using stb_truetype font
rasterization to a texture. Supports any TrueType (.ttf) font
file.
| Field | Type | Default | Description |
|---|---|---|---|
text |
string | "" | The text string to render. |
fontPath |
string | "" | Path to a .ttf font file. |
fontSize |
f32 | 32.0 | Font size in pixels. |
color |
Vector3 | (1, 1, 1) | Text color (RGB). |
PostProcessVolumeComponent
Defines a spatial region with custom post-processing settings. When the active camera enters a volume, the volume's settings blend with the global/default settings based on priority and distance-based weight falloff. Multiple volumes can overlap; blending is priority-sorted. A global volume applies everywhere and serves as a scene-wide base layer.
| Field | Type | Default | Description |
|---|---|---|---|
shape |
enum | Box | Volume shape: Box or Sphere. |
halfExtents |
Vector3 | (10, 10, 10) | Bounding box half-extents (for Sphere, radius = halfExtents.x). |
priority |
i32 | 0 | Higher priority volumes override lower ones when overlapping. |
isActive |
bool | true | Whether this volume is active. |
isGlobal |
bool | false | Global volume: applies everywhere, ignores shape and position. |
blendRadius |
f32 | 2.0 | Distance over which the volume fades in at its edges (0 = hard boundary). |
weight |
f32 | 1.0 | Maximum influence of this volume (0 = none, 1 = full override). |
overrideMask |
u32 | 0xFFFFFFFF | Bitmask of which effect groups this volume overrides (see override flags below). |
settings |
PostProcessSettings | — | The post-process settings this volume applies (bloom, tone mapping, vignette, etc.). |
The overrideMask bitmask allows partial overrides. For
example, a volume can modify only bloom without touching tone mapping.
Override flag bits include: ToneMapping (bit 0), Bloom (1), Vignette (2),
ChromaticAberration (3), ColorGrading (4), FilmGrain (5), FXAA (6),
Dither (7), ColorQuantize (8), ResolutionDownscale (9), CRT (10), LUT (11),
VHS (12), Palette (13), DepthOfField (14), TiltShift (15), CelOutline (16),
Stipple (17), CRTPhosphor (18), GodRays (19), SSAO (20),
ContactShadows (21), Caustics (22), and FogShafts (23).
11. Physics 3D Components
3D physics components enable physical simulation for entities: rigid body dynamics, collision shapes, trigger zones, and collision filtering. The engine uses Jolt Physics v5.2.0 as the 3D physics backend.
RigidbodyComponent
Adds physics simulation to an entity. Controls mass, velocity, gravity, and per-axis constraints. Pair with one or more collider components to define the collision shape.
| Field | Type | Default | Description |
|---|---|---|---|
mass |
f32 | 1.0 | Object mass. |
drag |
f32 | 0.0 | Linear drag (air resistance). |
angularDrag |
f32 | 0.05 | Angular drag. |
useGravity |
bool | true | Apply gravity to this body. |
gravityScale |
f32 | 1.0 | Gravity strength multiplier. |
velocity |
Vector3 | (0, 0, 0) | Current linear velocity. |
angularVelocity |
Vector3 | (0, 0, 0) | Current angular velocity. |
freezePositionX |
bool | false | Lock position on the X axis. |
freezePositionY |
bool | false | Lock position on the Y axis. |
freezePositionZ |
bool | false | Lock position on the Z axis. |
freezeRotationX |
bool | false | Lock rotation on the X axis. |
freezeRotationY |
bool | false | Lock rotation on the Y axis. |
freezeRotationZ |
bool | false | Lock rotation on the Z axis. |
bodyType |
enum | Dynamic | Dynamic (fully simulated), Kinematic (moved by code), or Static (never moves). |
collisionMode |
enum | Discrete | Discrete, Continuous, or ContinuousSpeculative. Continuous modes prevent fast objects from tunneling through geometry. |
BoxColliderComponent
Axis-aligned box collision shape.
| Field | Type | Default | Description |
|---|---|---|---|
center |
Vector3 | (0, 0, 0) | Collider center offset from entity origin. |
size |
Vector3 | (1, 1, 1) | Box dimensions. |
isTrigger |
bool | false | If true, fires events only (does not block movement). |
friction |
f32 | 0.5 | Surface friction. |
bounciness |
f32 | 0.0 | Restitution (0 = no bounce, 1 = full bounce). |
categoryBits |
u32 | 1 | Bitmask of collision groups this object belongs to. |
collisionMask |
u32 | 0xFFFFFFFF | Bitmask of groups this object collides with. |
SphereColliderComponent
Spherical collision shape.
| Field | Type | Default | Description |
|---|---|---|---|
center |
Vector3 | (0, 0, 0) | Collider center offset. |
radius |
f32 | 0.5 | Sphere radius. |
isTrigger |
bool | false | Trigger mode. |
friction |
f32 | 0.5 | Surface friction. |
bounciness |
f32 | 0.0 | Restitution. |
categoryBits |
u32 | 1 | Collision group bitmask. |
collisionMask |
u32 | 0xFFFFFFFF | Collision mask. |
CapsuleColliderComponent
Capsule collision shape, commonly used for characters.
| Field | Type | Default | Description |
|---|---|---|---|
center |
Vector3 | (0, 0, 0) | Collider center offset. |
radius |
f32 | 0.5 | Capsule radius. |
height |
f32 | 2.0 | Capsule total height. |
direction |
enum | Y | Capsule orientation axis: X, Y, or Z. |
isTrigger |
bool | false | Trigger mode. |
friction |
f32 | 0.5 | Surface friction. |
bounciness |
f32 | 0.0 | Restitution. |
categoryBits |
u32 | 1 | Collision group bitmask. |
collisionMask |
u32 | 0xFFFFFFFF | Collision mask. |
TriggerZoneComponent
Fires events when entities enter, exit, or stay inside the zone. Useful for area-based game logic (cutscene triggers, damage zones, checkpoints).
| Field | Type | Default | Description |
|---|---|---|---|
shape |
enum | Box | Box or Sphere. |
boxSize |
Vector3 | (2, 2, 2) | Box dimensions (when shape is Box). |
sphereRadius |
f32 | 1.0 | Sphere radius (when shape is Sphere). |
triggerMask |
u32 | 0xFFFFFFFF | Which collision layers can trigger this zone. |
triggerOnce |
bool | false | Only fire the first time (one-shot). |
onEnterNotify |
Entity | 0 | Entity to notify when something enters. |
onExitNotify |
Entity | 0 | Entity to notify when something exits. |
onStayNotify |
Entity | 0 | Entity to notify while something stays inside. |
Collision Filtering
Collision filtering uses a bilateral bitmask system. Two objects A and B only collide when both sides agree:
(A.categoryBits & B.collisionMask) && (B.categoryBits & A.collisionMask)
Defaults: categoryBits = 1,
collisionMask = 0xFFFFFFFF. This means every object belongs
to group 1 and collides with all groups by default. The engine supports up
to 32 named collision groups, configurable per-scene via
SceneManager::m_CollisionGroupNames.
Example: to make object A (player, group 1) ignore object B (ghost, group 4),
set A's collisionMask to exclude bit 4, or set B's
categoryBits to 4 and A's collisionMask to
0xFFFFFFF7.
Physics backends: Jolt v5.2.0 for 3D, Box2D v3.0.0 for 2D. The backend is auto-selected based on the project mode, but can be overridden via PhysicsBackendFactory using the type enum (Auto, Jolt, Box2D, Simple).
12. Physics 2D Components
2D physics components provide collision detection and rigid body dynamics for side-scrollers, top-down games, and other 2D projects. The engine uses Box2D v3.0.0 as the 2D physics backend. The 2D physics system shares the same bilateral bitmask collision filtering as the 3D system.
Body2DComponent
The primary 2D physics body. Defines shape, material properties, and body
behavior. Add alongside TransformComponent to enable 2D
physics simulation. The shapeType field selects which
sub-shape (circle, box, polygon, or capsule) is used for collision.
| Field | Type | Default | Description |
|---|---|---|---|
shapeType |
enum | Box | Shape type: Circle, Box, Polygon, or Capsule. |
isStatic |
bool | false | Static body (never moves, infinite mass). |
isSensor |
bool | false | Sensor body: triggers callbacks but has no physical response (see below). |
fixedRotation |
bool | false | Prevent the body from rotating. |
gravityScale |
f32 | 1.0 | Gravity strength multiplier. |
linearDamping |
f32 | 0.1 | Linear velocity damping. |
angularDamping |
f32 | 0.1 | Angular velocity damping. |
mass |
f32 | 1.0 | Body mass. |
velocity |
Vector2 | (0, 0) | Current linear velocity. |
angularVelocity |
f32 | 0.0 | Current angular velocity. |
categoryBits |
u32 | 1 | Collision group bitmask. |
collisionMask |
u32 | 0xFFFFFFFF | Collision mask. |
Physics Material
Each Body2DComponent contains a PhysicsMaterial2D
controlling surface behavior:
| Field | Type | Default | Description |
|---|---|---|---|
material.friction |
f32 | 0.3 | Surface friction. |
material.restitution |
f32 | 0.2 | Bounciness (0 = no bounce, 1 = full bounce). |
material.density |
f32 | 1.0 | Shape density (affects mass calculation). |
2D Collider Shapes
The shape used by Body2DComponent is selected via
shapeType. Each shape type has its own configuration:
CircleShape2D
| Field | Type | Default | Description |
|---|---|---|---|
circle.radius |
f32 | 0.5 | Circle radius. |
circle.offset |
Vector2 | (0, 0) | Local offset from entity center. |
BoxShape2D
| Field | Type | Default | Description |
|---|---|---|---|
box.halfExtents |
Vector2 | (0.5, 0.5) | Half-width and half-height of the box. |
box.offset |
Vector2 | (0, 0) | Local offset from entity center. |
box.rotation |
f32 | 0.0 | Local rotation in radians. |
PolygonShape2D
| Field | Type | Default | Description |
|---|---|---|---|
polygon.vertices |
vector<Vector2> | [] | Vertices in counter-clockwise winding (max 8 vertices). |
polygon.offset |
Vector2 | (0, 0) | Local offset from entity center. |
CapsuleShape2D
| Field | Type | Default | Description |
|---|---|---|---|
capsule.radius |
f32 | 0.3 | Capsule radius. |
capsule.height |
f32 | 1.0 | Total height (including semicircle caps). |
capsule.offset |
Vector2 | (0, 0) | Local offset from entity center. |
PolygonCollider2DComponent
A standalone polygon collider for 2D sprite silhouettes. Unlike the
polygon shape embedded in Body2DComponent, this is a
separate component that can be added alongside other physics components.
| Field | Type | Default | Description |
|---|---|---|---|
vertices |
vector<Vector2> | [] | Polygon vertices in counter-clockwise winding (local space). |
isTrigger |
bool | false | Trigger mode (callbacks only, no physical response). |
friction |
f32 | 0.5 | Surface friction. |
bounciness |
f32 | 0.0 | Restitution. |
categoryBits |
u32 | 1 | Collision group bitmask. |
collisionMask |
u32 | 0xFFFFFFFF | Collision mask. |
Joint2DComponent
Connects two 2D bodies with a physical constraint. Five joint types are available, each with type-specific parameters:
| Joint Type | Description |
|---|---|
Revolute |
Hinge/pin joint. Bodies rotate around a shared anchor point. Supports angle limits and motor. |
Prismatic |
Slider joint. Bodies translate along a fixed axis. Supports translation limits. |
Distance |
Fixed distance spring. Maintains a set distance between anchors with optional stiffness and damping. |
Rope |
Maximum distance constraint. Bodies cannot exceed a set distance but can be closer. |
Weld |
Rigid attachment. Locks two bodies together at a fixed relative position and angle. |
Common Joint Fields
| Field | Type | Default | Description |
|---|---|---|---|
type |
enum | Revolute | Joint type (see table above). |
connectedEntity |
Entity | 0 | The other entity this joint connects to. |
anchorA |
Vector2 | (0, 0) | Local anchor point on this entity. |
anchorB |
Vector2 | (0, 0) | Local anchor point on the connected entity. |
collideConnected |
bool | false | Allow collision between the two connected bodies. |
Revolute Joint Fields
| Field | Type | Default | Description |
|---|---|---|---|
enableLimit |
bool | false | Enable angular limits. |
lowerAngle |
f32 | 0.0 | Lower angle limit (radians). |
upperAngle |
f32 | 0.0 | Upper angle limit (radians). |
enableMotor |
bool | false | Enable joint motor. |
motorSpeed |
f32 | 0.0 | Motor target speed. |
maxMotorTorque |
f32 | 0.0 | Maximum motor torque. |
Prismatic Joint Fields
| Field | Type | Default | Description |
|---|---|---|---|
axis |
Vector2 | (1, 0) | Sliding axis direction. |
lowerTranslation |
f32 | 0.0 | Lower translation limit. |
upperTranslation |
f32 | 0.0 | Upper translation limit. |
Distance & Rope Joint Fields
| Field | Type | Default | Description |
|---|---|---|---|
length |
f32 | 1.0 | Target distance between anchors. |
minLength |
f32 | 0.0 | Minimum allowed distance. |
maxLength |
f32 | 0.0 | Maximum allowed distance. |
stiffness |
f32 | 0.0 | Spring stiffness (0 = rigid constraint). |
damping |
f32 | 0.0 | Spring damping. |
Sensor Bodies
When Body2DComponent::isSensor is set to true,
the body becomes a sensor. Sensor bodies have a critical
difference in how position synchronization works:
- Normal bodies: Box2D simulates physics and writes positions to the ECS (Box2D → ECS).
- Sensor bodies: Box2D syncs positions from the ECS (ECS → Box2D). The ECS transform is the source of truth.
This design enables entities driven by character controllers, AI systems, or tweens to still receive collision callbacks (enter, exit, stay) without Box2D overwriting their positions. Common use cases include:
- Player characters controlled by
Platformer2DControllerorTopDown2DControllerthat need overlap detection. - AI-driven enemies that patrol via waypoints but need to detect the player.
- Tween-animated platforms or moving hazards that should trigger events on contact.
Sensor bodies participate in collision callbacks but never generate physical contact forces. If you need both physical response and controller-driven movement, use a Kinematic body type in the 3D system or manage velocity directly via SetVelocity2D in the 2D system.
Gameplay Components
Character controllers, 2D rendering, audio, AI and navigation, and gameplay systems.
Character Controllers
Character controllers provide pre-built movement behaviors that handle input processing, camera management, and physics integration out of the box. Adding any controller component to an entity auto-creates a configured camera entity appropriate for that controller type. TEGE ships with six controller types covering first-person, third-person, top-down, side-scrolling, and vehicle gameplay.
Common Base Fields
All six controllers inherit a shared set of input and movement properties. These fields appear in the inspector for every controller type:
| Field | Type | Default | Description |
|---|---|---|---|
moveSpeed |
f32 | 5.0 | Base movement speed. |
sprintMultiplier |
f32 | 2.0 | Speed multiplier when sprinting. |
isEnabled |
bool | true | Whether the controller processes input. |
useWASD |
bool | true | Use WASD keys for movement. |
useArrowKeys |
bool | false | Use arrow keys for movement. |
useGamepad |
bool | false | Use gamepad input. |
gamepadIndex |
i32 | 0 | Gamepad index (0–3) for splitscreen. |
gamepadLookSensitivity |
f32 | 2.0 | Right stick camera sensitivity. |
disableMouseLook |
bool | false | Disable mouse/stick camera control. |
gridMovement |
bool | false | Snap movement to grid cells. |
gridCellSize |
f32 | 1.0 | Grid cell size in world units. |
gridMoveSpeed |
f32 | 8.0 | Speed of lerp between grid cells. |
First-person and third-person controllers integrate with
ResourceComponent. When a ResourceComponent is
present on the same entity, sprinting consumes stamina at the rate defined by
sprintCostPerSec, and jumping consumes jumpCost.
Sprint is disabled while the resource is depleted.
Platformer2DController
Side-scrolling movement with gravity, jumping, and optional wall mechanics.
Ideal for platformers ranging from tight precision games to floaty adventure
titles. Supports double-jump (via maxJumps), coyote time for
forgiving ledge jumps, and input buffering for responsive controls.
| Field | Type | Default | Description |
|---|---|---|---|
jumpForce |
f32 | 8.0 | Upward force applied on jump. |
gravity |
f32 | 20.0 | Downward acceleration. |
maxJumps |
i32 | 2 | Maximum jumps (supports double jump). |
acceleration |
f32 | 50.0 | Horizontal acceleration. |
deceleration |
f32 | 40.0 | Horizontal deceleration. |
airControl |
f32 | 0.5 | Movement control multiplier while airborne. |
coyoteTime |
f32 | 0.1 | Grace period (seconds) after leaving a platform where jump is still allowed. |
jumpBufferTime |
f32 | 0.1 | Input buffer (seconds) for pressing jump slightly before landing. |
enableWallJump |
bool | false | Allow jumping off walls. |
enableWallSlide |
bool | false | Slide down walls slowly. |
wallSlideSpeed |
f32 | 2.0 | Descent speed while wall sliding. |
wallJumpForce |
f32 | 6.0 | Force applied on wall jump. |
TopDown2DController
Overhead 2D movement with 8-directional input and optional dash. Suitable for top-down shooters, adventure games, and Zelda-style exploration. The entity can optionally rotate to face the direction of travel.
| Field | Type | Default | Description |
|---|---|---|---|
acceleration |
f32 | 30.0 | Movement acceleration. |
deceleration |
f32 | 25.0 | Movement deceleration. |
rotateToFaceMovement |
bool | true | Entity rotates to face movement direction. |
rotationSpeed |
f32 | 720.0 | Degrees per second rotation. |
enableDash |
bool | false | Enable dash/dodge ability. |
dashSpeed |
f32 | 15.0 | Dash velocity. |
dashDuration |
f32 | 0.2 | Dash length in seconds. |
dashCooldown |
f32 | 1.0 | Cooldown between dashes. |
TopDown3DController
Isometric or overhead 3D movement, similar to Diablo-style or CRPG games. Features a fixed-angle camera that follows the player and optional click-to-move navigation.
| Field | Type | Default | Description |
|---|---|---|---|
acceleration |
f32 | 30.0 | Movement acceleration. |
deceleration |
f32 | 25.0 | Movement deceleration. |
rotateToFaceMovement |
bool | true | Entity rotates to face movement direction. |
rotationSpeed |
f32 | 720.0 | Degrees per second rotation. |
cameraAngle |
f32 | 45.0 | Fixed camera angle from horizontal. |
cameraDistance |
f32 | 15.0 | Camera distance from player. |
cameraHeight |
f32 | 10.0 | Camera height above player. |
lockCameraToPlayer |
bool | true | Camera follows the player. |
enableClickToMove |
bool | false | Click on ground to move (Diablo-style). |
arrivalThreshold |
f32 | 0.5 | Distance at which click-to-move stops. |
enableDash |
bool | false | Enable dash/dodge ability. |
ThirdPersonController
Over-the-shoulder camera that orbits the player. The camera supports smooth interpolation, geometry collision avoidance, and lock-on targeting for action-RPG combat. Movement is relative to the camera facing direction, so the character naturally strafes and circles targets.
| Field | Type | Default | Description |
|---|---|---|---|
acceleration |
f32 | 30.0 | Movement acceleration. |
deceleration |
f32 | 25.0 | Movement deceleration. |
jumpForce |
f32 | 8.0 | Jump strength. |
gravity |
f32 | 20.0 | Downward acceleration. |
rotateToFaceMovement |
bool | true | Character faces movement direction. |
rotateToFaceCamera |
bool | false | Character always faces camera direction. |
rotationSpeed |
f32 | 720.0 | Degrees per second rotation. |
cameraDistance |
f32 | 5.0 | Default distance from player to camera. |
cameraHeight |
f32 | 2.0 | Camera height above player. |
cameraMinDistance |
f32 | 2.0 | Minimum zoom distance. |
cameraMaxDistance |
f32 | 15.0 | Maximum zoom distance. |
cameraMinPitch |
f32 | -30.0 | Minimum vertical look angle. |
cameraMaxPitch |
f32 | 60.0 | Maximum vertical look angle. |
cameraSensitivity |
f32 | 0.15 | Mouse sensitivity for orbit. |
cameraLerpSpeed |
f32 | 20.0 | Smooth camera follow speed. |
enableCameraCollision |
bool | true | Camera avoids clipping through geometry. |
enableLockOn |
bool | false | Enable lock-on targeting system. |
lockOnRange |
f32 | 20.0 | Maximum lock-on distance. |
FirstPersonController
FPS-style camera and movement with mouse look, crouching, head bob, and
optional dungeon-crawler mode. The camera is placed at the entity position
offset by standingHeight. Sprinting temporarily increases the
field of view by sprintFOVIncrease for a sense of speed.
| Field | Type | Default | Description |
|---|---|---|---|
acceleration |
f32 | 50.0 | Movement acceleration. |
deceleration |
f32 | 40.0 | Movement deceleration. |
jumpForce |
f32 | 7.0 | Jump strength. |
gravity |
f32 | 20.0 | Downward acceleration. |
mouseSensitivity |
f32 | 2.0 | Mouse look sensitivity. |
minPitch |
f32 | -89.0 | Minimum vertical look angle. |
maxPitch |
f32 | 89.0 | Maximum vertical look angle. |
invertY |
bool | false | Invert vertical mouse axis. |
enableHeadBob |
bool | false | Subtle camera bob while walking. |
headBobFrequency |
f32 | 8.0 | Bob oscillation speed. |
headBobAmplitude |
f32 | 0.05 | Bob vertical displacement. |
enableCrouch |
bool | true | Allow crouching. |
standingHeight |
f32 | 1.8 | Camera height when standing. |
crouchingHeight |
f32 | 1.0 | Camera height when crouching. |
crouchSpeed |
f32 | 0.5 | Movement speed multiplier when crouching. |
sprintFOVIncrease |
f32 | 10.0 | FOV increase while sprinting. |
dungeonCrawlerMode |
bool | false | SMT-style movement: snap turns and facing-relative movement. |
snapTurnAngle |
f32 | 90.0 | Degrees per snap turn (A/D keys) in dungeon crawler mode. |
Enable dungeonCrawlerMode for a classic first-person dungeon
crawler experience. In this mode the A and D keys perform discrete snap turns
of snapTurnAngle degrees instead of strafing, and forward/back
movement is relative to the entity's facing direction rather than the camera.
VehicleController
Car-like physics with steering, acceleration, braking, and drift mechanics.
Uses a simplified bicycle model driven by wheelBase, with visual
body roll and pitch for a convincing driving feel without full wheel
simulation.
| Field | Type | Default | Description |
|---|---|---|---|
maxSpeed |
f32 | 30.0 | Top forward speed (units/sec). |
reverseMaxSpeed |
f32 | 10.0 | Top reverse speed. |
acceleration |
f32 | 15.0 | Engine acceleration force. |
brakeForce |
f32 | 25.0 | Brake deceleration force. |
engineBrake |
f32 | 5.0 | Deceleration when no input (engine drag). |
maxSteerAngle |
f32 | 35.0 | Maximum wheel turn angle (degrees). |
steerSpeed |
f32 | 120.0 | Steering input speed (degrees/sec). |
steerReturnSpeed |
f32 | 200.0 | Auto-center speed (degrees/sec). |
wheelBase |
f32 | 2.5 | Distance between front and rear axles. |
grip |
f32 | 1.0 | Tire grip multiplier (lower = more sliding). |
driftFactor |
f32 | 0.9 | Lateral velocity retention (1 = no drift, 0 = full drift). |
downforceMultiplier |
f32 | 0.5 | Speed-dependent downforce. |
mass |
f32 | 1000.0 | Vehicle mass in kg. |
bodyRollAmount |
f32 | 5.0 | Degrees of body roll in turns (visual). |
bodyPitchAmount |
f32 | 3.0 | Degrees of body pitch on accel/brake (visual). |
PossessableComponent
Allows the player to switch which entity they control at runtime. Attach this
component to any entity that has a controller, and the player can possess and
unpossess it during gameplay. When possession transfers, the camera smoothly
blends to the new entity over transitionDuration seconds.
| Field | Type | Default | Description |
|---|---|---|---|
isPossessed |
bool | false | Currently controlled by the player. |
autoDetect |
bool | true | Auto-detect controller type on possess. |
playerIndex |
i32 | 0 | Which player (0–3) can possess this entity. |
possessRange |
f32 | 5.0 | Maximum distance to possess (0 = unlimited). |
promptText |
string | "Press E to enter" | UI prompt shown when in range. |
transitionDuration |
f32 | 0.3 | Camera blend time on possess/unpossess. |
disableOnUnpossess |
bool | true | Disable controller when not possessed. |
2D Components
TEGE provides dedicated 2D rendering components for sprite-based games.
These work alongside the engine's scene classification system — scenes
containing only 2D components are automatically classified as
Scene2D, which skips the shadow pipeline for better performance.
Sprite2DComponent
Renders a 2D sprite from a texture or sprite sheet region. Sprites are sorted
by sortingLayer first, then by orderInLayer within
each layer. The pivot point controls the sprite's origin for
rotation and positioning.
| Field | Type | Default | Description |
|---|---|---|---|
texturePath |
string | "" | Sprite texture path. |
srcX |
f32 | 0 | Source rectangle X position in texture (for sprite sheets). |
srcY |
f32 | 0 | Source rectangle Y position in texture. |
srcWidth |
f32 | 0 | Source rectangle width (0 = full texture width). |
srcHeight |
f32 | 0 | Source rectangle height (0 = full texture height). |
size |
Vector2 | (1, 1) | Display size in world units. |
pivot |
Vector2 | (0.5, 0.5) | Pivot point (0–1, center by default). |
tint |
Vector3 | (1, 1, 1) | Color tint. |
alpha |
f32 | 1.0 | Opacity. |
sortingLayer |
i32 | 0 | Render order (layer). |
orderInLayer |
i32 | 0 | Render order within layer. |
flipX |
bool | false | Flip sprite horizontally. |
flipY |
bool | false | Flip sprite vertically. |
visible |
bool | true | Visibility toggle. |
AnimatedSprite2DComponent
Sprite sheet animation with per-frame timing. Each frame specifies a source
rectangle and duration, allowing variable frame rates within a single
animation. Attach alongside a Sprite2DComponent — the
animated sprite system updates the parent sprite's source rectangle each frame.
| Field | Type | Default | Description |
|---|---|---|---|
frames |
list | [] | List of frames, each with srcX, srcY, and duration (seconds). |
currentFrame |
u32 | 0 | Current frame index. |
playing |
bool | true | Whether animation is playing. |
loop |
bool | true | Loop animation. |
playbackSpeed |
f32 | 1.0 | Speed multiplier. |
TilemapComponent
Grid-based tile rendering for retro-style 2D games. The component stores a
flat array of tile indices that map into a tileset texture. A value of
-1 represents an empty tile. Collision data is stored in a
parallel boolean array.
| Field | Type | Default | Description |
|---|---|---|---|
tiles |
list | [] | Flat array of tile indices (-1 = empty). |
width |
u32 | 0 | Grid width in tiles. |
height |
u32 | 0 | Grid height in tiles. |
tilesetPath |
string | "" | Path to tileset texture. |
tileWidth |
f32 | 16 | Tile width in pixels within the tileset. |
tileHeight |
f32 | 16 | Tile height in pixels within the tileset. |
tilesetColumns |
u32 | 16 | Number of tile columns in tileset. |
worldTileWidth |
f32 | 1.0 | Width of each tile in world units. |
worldTileHeight |
f32 | 1.0 | Height of each tile in world units. |
hasCollision |
bool | false | Enable tile collision. |
collisionMask |
list | [] | Per-tile boolean: which tiles are solid. |
Helper methods: GetTile(x, y) returns the tile index at the
given grid coordinate, and SetTile(x, y, tileIndex) updates it
at runtime.
Camera2DBoundsComponent
Constrains a 2D camera within world-space boundaries, with smooth follow and zoom control. Attach to a camera entity to prevent the view from scrolling beyond the level edges.
| Field | Type | Default | Description |
|---|---|---|---|
useBounds |
bool | false | Enable boundary constraints. |
minBounds |
Vector2 | (0, 0) | Minimum world-space boundary. |
maxBounds |
Vector2 | (0, 0) | Maximum world-space boundary. |
boundsPadding |
f32 | 0.0 | Padding inside bounds. |
followTarget |
Entity | 0 | Entity for the camera to follow. |
followSmoothing |
f32 | 5.0 | Follow smoothing speed (higher = faster). |
followOffset |
Vector2 | (0, 0) | Offset from follow target. |
minZoom |
f32 | 0.5 | Minimum zoom level. |
maxZoom |
f32 | 3.0 | Maximum zoom level. |
currentZoom |
f32 | 1.0 | Current zoom level. |
Audio Components
TEGE's audio system is built on miniaudio and provides 3D spatial audio, volume falloff, looping, and priority-based voice management. For advanced spatialization, the engine optionally integrates with Steam Audio for HRTF-based binaural rendering, occlusion, and environmental reverb.
AudioSourceComponent
Plays audio clips with 3D spatialization support. Each audio source can be
positioned in the world and will attenuate based on distance from the active
AudioListenerComponent.
| Field | Type | Default | Description |
|---|---|---|---|
clipPath |
string | "" | Path to the audio file. |
volume |
f32 | 1.0 | Playback volume (0–1). |
pitch |
f32 | 1.0 | Playback pitch (1.0 = normal). |
minDistance |
f32 | 1.0 | Distance at which sound is at full volume. |
maxDistance |
f32 | 500.0 | Distance at which sound reaches minimum volume. |
playOnAwake |
bool | false | Automatically start playing when play mode begins. |
loop |
bool | false | Loop the clip. |
is3D |
bool | true | Enable 3D spatial audio. |
spatialBlend |
f32 | 1.0 | Blend between 2D (0) and 3D (1) spatialization. |
rolloff |
enum | Logarithmic | Volume falloff curve: Logarithmic, Linear, or Custom. |
priority |
i32 | 128 | Playback priority (lower = higher priority when too many sounds are playing). |
AudioListenerComponent
Defines the "ears" of the scene. Typically attached to the player or camera
entity. Only one active listener should exist at a time — if multiple
listeners have isActive set to true, the first one
found in the entity list takes precedence.
| Field | Type | Default | Description |
|---|---|---|---|
isActive |
bool | true | Whether this listener receives audio. |
volumeScale |
f32 | 1.0 | Master volume scale for this listener. |
Steam Audio Integration
When built with the ENJIN_AUDIO_STEAM_AUDIO CMake flag enabled,
TEGE integrates the Steam Audio SDK for physics-based audio processing. This
provides:
- HRTF binaural rendering — head-related transfer function filtering for realistic headphone spatialization.
- Occlusion and transmission — sounds are attenuated when blocked by geometry, with material-dependent transmission.
- Environmental reverb — automatic reverb based on room geometry and surface materials.
Steam Audio processing is handled by SteamAudioProcessor,
which runs as a post-process on the audio mix. No additional components are
needed — it automatically enhances all 3D audio sources when enabled.
Gameplay Components
TEGE ships with a comprehensive set of gameplay-ready components covering health and damage, resources, interaction, item collection, inventory management, spawning, and timers. These components work together to build complete game loops without writing a single line of code.
HealthComponent
Tracks hit points, shield, regeneration, and invulnerability. Shield points absorb damage before health. Both health and shield support independent regeneration with configurable delays after taking damage.
| Field | Type | Default | Description |
|---|---|---|---|
maxHealth |
f32 | 100.0 | Maximum HP. |
currentHealth |
f32 | 100.0 | Current HP. |
regenRate |
f32 | 0.0 | HP regenerated per second (0 = no regen). |
regenDelay |
f32 | 3.0 | Seconds after taking damage before regeneration starts. |
isInvulnerable |
bool | false | Immune to damage. |
invulnerabilityTime |
f32 | 0.0 | Seconds of invulnerability after taking a hit. |
maxShield |
f32 | 0.0 | Maximum shield points (absorbs damage before health). |
currentShield |
f32 | 0.0 | Current shield points. |
shieldRegenRate |
f32 | 0.0 | Shield regenerated per second. |
shieldRegenDelay |
f32 | 5.0 | Seconds after damage before shield regeneration. |
onDamageNotify |
Entity | 0 | Entity to notify when damaged. |
onDeathNotify |
Entity | 0 | Entity to notify on death. |
onHealNotify |
Entity | 0 | Entity to notify on heal. |
Helper methods: GetHealthPercent() (0–1),
GetShieldPercent() (0–1), IsFullHealth().
DamageComponent
Attach to projectiles, hazards, or weapons to deal damage to entities with a
HealthComponent. Supports one-shot, per-entity, and continuous
damage modes. The damage type interacts with
DamageResistanceComponent multipliers.
| Field | Type | Default | Description |
|---|---|---|---|
damage |
f32 | 10.0 | Damage amount. |
knockbackForce |
f32 | 0.0 | Knockback force on hit. |
destroyOnHit |
bool | true | Destroy this entity after dealing damage. |
damageOnce |
bool | true | Only damage each entity once. |
damageInterval |
f32 | 0.0 | For continuous damage (lava, poison): seconds between ticks. |
type |
enum | Physical | Damage type: Physical, Fire, Ice, Electric, Poison, Magic. |
DamageResistanceComponent
Per-type damage multipliers. Pair with HealthComponent to create
resistances and weaknesses. When an entity takes damage, the incoming amount
is multiplied by the corresponding resistance value before being applied.
| Field | Type | Default | Description |
|---|---|---|---|
physicalMult |
f32 | 1.0 | Physical damage multiplier. |
fireMult |
f32 | 1.0 | Fire damage multiplier. |
iceMult |
f32 | 1.0 | Ice damage multiplier. |
electricMult |
f32 | 1.0 | Electric damage multiplier. |
poisonMult |
f32 | 1.0 | Poison damage multiplier. |
magicMult |
f32 | 1.0 | Magic damage multiplier. |
Resistance values: 1.0 = normal damage, 0.0 =
immune, 2.0 = double damage (weakness). Any positive value is
valid. For example, a fire elemental might use
fireMult = 0.0 and iceMult = 2.0.
ResourceComponent
A generic resource bar for stamina, mana, energy, or any depletable value.
Integrates with character controllers for sprint and jump costs. When the
resource is depleted, it stays in the depleted state until
regeneration reaches depletedThreshold, preventing rapid
sprint toggling.
| Field | Type | Default | Description |
|---|---|---|---|
resourceName |
string | "Stamina" | Display name for the resource. |
maxValue |
f32 | 100.0 | Maximum resource capacity. |
currentValue |
f32 | 100.0 | Current resource amount. |
regenRate |
f32 | 10.0 | Regeneration per second. |
regenDelay |
f32 | 1.0 | Seconds after use before regeneration begins. |
depleted |
bool | false | True when value reaches 0. Stays true until depletedThreshold is reached. |
depletedThreshold |
f32 | 20.0 | Must regenerate to this value before depleted clears. |
sprintCostPerSec |
f32 | 15.0 | Resource consumed per second while sprinting. |
jumpCost |
f32 | 20.0 | Resource consumed per jump. |
dashCost |
f32 | 25.0 | Resource consumed per dash. |
attackCost |
f32 | 0.0 | Resource consumed per attack. |
Helper methods: GetPercent() (0–1),
TryConsume(amount) (returns false if insufficient),
Regenerate(deltaTime). Auto-regeneration happens automatically
each frame. Controllers check TryConsume() before allowing
sprint/jump actions.
InteractableComponent
Makes an entity interactable by the player (doors, NPCs, switches, chests,
etc.). When the player is within interactionRange and facing the
entity (if requiresLookAt is enabled), a UI prompt is displayed.
| Field | Type | Default | Description |
|---|---|---|---|
promptText |
string | "Press E to interact" | Text shown when player is in range. |
interactionRange |
f32 | 2.0 | Maximum interaction distance. |
requiresLookAt |
bool | true | Player must be facing the object. |
lookAtAngle |
f32 | 45.0 | Cone angle (degrees) for look-at check. |
isEnabled |
bool | true | Whether interaction is currently available. |
singleUse |
bool | false | Disable after first interaction. |
highlightOnHover |
bool | true | Visual highlight when player is in range. |
highlightColor |
Vector3 | (1, 1, 0) | Highlight color (default: yellow). |
onInteractNotify |
Entity | 0 | Entity to notify on interaction. |
PickupComponent
Collectible items that the player can pick up. Supports six built-in types plus a custom type with a string identifier. Pickups can optionally magnetize toward the player, respawn after collection, and display floating bob and spin animations.
| Field | Type | Default | Description |
|---|---|---|---|
type |
enum | Coin | Pickup type: Health, Ammo, Coin, Key, Powerup, Custom. |
value |
f32 | 1.0 | Amount to give on pickup. |
customId |
string | "" | Identifier for custom item types. |
pickupRange |
f32 | 1.0 | Distance at which pickup is collected. |
destroyOnPickup |
bool | true | Remove entity after collection. |
magnetToPlayer |
bool | false | Auto-attract toward the player. |
magnetRange |
f32 | 3.0 | Distance at which magnet effect begins. |
magnetSpeed |
f32 | 10.0 | Speed of magnet attraction. |
canRespawn |
bool | false | Respawn after being collected. |
respawnTime |
f32 | 10.0 | Seconds before respawning. |
bobSpeed |
f32 | 2.0 | Visual floating bob animation speed. |
bobHeight |
f32 | 0.2 | Bob vertical displacement. |
rotationSpeed |
f32 | 90.0 | Visual spin speed (degrees/sec). |
InventoryComponent
Manages an item inventory with slots, currency, and keys. Each slot holds an
item ID, a quantity, and a maximum stack size. The keys list is
checked by LockComponent to determine if a door or chest can be
opened.
| Field | Type | Default | Description |
|---|---|---|---|
slots |
list | [] | List of inventory slots, each with itemId, quantity, maxStack. |
maxSlots |
usize | 20 | Maximum number of inventory slots. |
coins |
i32 | 0 | Coin currency count. |
gems |
i32 | 0 | Gem currency count. |
keys |
list | [] | List of key ID strings (used by LockComponent). |
SpawnPointComponent
Defines where and how entities are spawned in the scene. Spawn points can
instantiate prefabs on play start, after a delay, or on a repeating timer.
Use spawnRadius to add positional randomness around the spawn
location.
| Field | Type | Default | Description |
|---|---|---|---|
spawnId |
string | "" | Identifier for this spawn point. |
prefabToSpawn |
string | "" | Prefab name to instantiate. |
spawnOnStart |
bool | false | Spawn immediately when play begins. |
spawnDelay |
f32 | 0.0 | Delay before first spawn (seconds). |
respawnTime |
f32 | 0.0 | Time between respawns (0 = no respawn). |
maxSpawns |
i32 | -1 | Maximum spawn count (-1 = unlimited). |
spawnRadius |
f32 | 0.0 | Random position variance within radius. |
randomRotation |
bool | false | Randomize spawned entity rotation. |
TimerComponent
A general-purpose countdown timer that can notify another entity on completion. Useful for delayed actions, cooldowns, wave spawning intervals, and timed events.
| Field | Type | Default | Description |
|---|---|---|---|
duration |
f32 | 1.0 | Timer duration in seconds. |
elapsed |
f32 | 0.0 | Current elapsed time. |
isRunning |
bool | false | Whether the timer is active. |
loop |
bool | false | Restart automatically on completion. |
autoStart |
bool | false | Begin counting when play starts. |
onCompleteNotify |
Entity | 0 | Entity to notify when timer finishes. |
Helper queries: GetProgress() returns a 0–1 normalized
value, GetRemaining() returns seconds left, and
IsComplete() returns true once the timer has finished.
Gameplay Systems
Puzzle mechanics, dialogue, save system, HUD, cinematics, networking, environment effects, terrain, and advanced components.
Puzzle and Level Design
TEGE provides a rich set of puzzle and level-design components for building interactive environments. From locked doors and pushable crates to conveyor belts and moving platforms, these components can be combined to create everything from Sokoban-style block puzzles to side-scrolling platformer levels.
LockComponent
Represents a locked entity (door, gate, chest) that requires a key to open. The key is
matched against the player's InventoryComponent. Three open modes control how
the lock behaves once unlocked.
| Field | Type | Default | Description |
|---|---|---|---|
requiredKey | string | "" | Key ID that unlocks this entity. Matched against keys held in the player's InventoryComponent. |
isLocked | bool | true | Whether the lock is currently locked. |
consumeKey | bool | false | Remove the key from the player's inventory on use. |
autoOpen | bool | false | Open automatically when a player carrying the correct key enters interaction range. |
interactRange | f32 | 2.0 | Maximum interaction distance in world units. |
openMode | enum | Toggle | Toggle (open/close), OpenOnly (stays open permanently), or Timed (closes automatically after openDuration). |
openDuration | f32 | 5.0 | Seconds before the door closes again in Timed mode. |
closedPosition | Vector3 | varies | World-space position when closed (lerp target). |
openPosition | Vector3 | varies | World-space position when open (lerp target). |
closedRotation | Vector3 | (0, 0, 0) | Euler rotation when closed. |
openRotation | Vector3 | (0, 0, 0) | Euler rotation when open. |
openSpeed | f32 | 3.0 | Lerp speed for the open/close animation. |
lockedPrompt | string | "Requires key" | UI prompt shown when the player interacts while the lock is active. |
unlockedPrompt | string | "Press E to open" | UI prompt shown when the player has the required key. |
In Toggle mode the same interaction alternates between open and closed states. In
Timed mode the door automatically returns to the closed position after
openDuration seconds.
PushableComponent
Makes an entity pushable by the player or other forces. Enable gridSnap for
Sokoban-style block puzzles where crates snap to discrete grid cells.
| Field | Type | Default | Description |
|---|---|---|---|
mass | f32 | 1.0 | Heavier objects are slower to push. |
pushSpeed | f32 | 3.0 | Movement speed when being pushed. |
friction | f32 | 0.9 | Velocity damping per frame (0 = instant stop, 1 = no friction). |
gridSnap | bool | false | Snap movement to grid cells (Sokoban-style). |
gridCellSize | f32 | 1.0 | Size of each grid cell in world units. |
gridMoveSpeed | f32 | 6.0 | Lerp speed for cell-to-cell movement. |
pushableX | bool | true | Allow pushing along the X axis. |
pushableZ | bool | true | Allow pushing along the Z axis. |
pushableY | bool | false | Allow pushing along the Y axis (vertical). |
canBePushedOff | bool | false | Allow pushing the object off ledges. |
SwitchComponent
Pressure plates, toggles, one-shot triggers, timed switches, and sequence pads that
activate linked entities. When isActive changes, all entities in
linkedEntities receive an activation event.
| Field | Type | Default | Description |
|---|---|---|---|
type | enum | PressurePlate | PressurePlate, Toggle, OneShot, Timed, or Sequence. |
isActive | bool | false | Current activation state. |
requiredTag | string | "" | Only entities with this tag can activate the switch (empty = any entity). |
activationWeight | f32 | 0.0 | Minimum mass for pressure plates (0 = any weight triggers it). |
activeDuration | f32 | 5.0 | How long the switch stays active in Timed mode. |
sequenceIndex | i32 | 0 | Position in the activation sequence (for Sequence mode). |
sequenceGroup | i32 | 0 | Which sequence group this switch belongs to. |
linkedEntities | list | [] | Entities controlled by this switch (doors, lights, traps, etc.). |
offPosition | Vector3 | varies | Visual position when inactive. |
onPosition | Vector3 | varies | Visual position when active. |
transitionSpeed | f32 | 8.0 | Visual transition lerp speed. |
promptText | string | "Press E" | Interaction prompt text. |
In Sequence mode, switches must be activated in order of their
sequenceIndex within the same sequenceGroup. Activating a
switch out of order resets the entire sequence.
GoalZoneComponent
Target area for puzzle completion: Sokoban push targets, stand-on zones, item deposits,
checkpoints, and level exits. When all goals in a goalGroup are satisfied, the
group fires a completion event.
| Field | Type | Default | Description |
|---|---|---|---|
type | enum | PushTarget | PushTarget, StandOn, ItemDeposit, Checkpoint, or LevelExit. |
requiredTag | string | "" | Entity tag that satisfies this goal (e.g., "crate"). |
requiredItem | string | "" | Item ID required for ItemDeposit goals. |
isSatisfied | bool | false | Whether the goal condition is currently met. |
goalGroup | i32 | 0 | Group ID. All goals in a group must be satisfied for the group to complete. |
inactiveColor | Vector3 | gray | Visual feedback color when the goal is unsatisfied. |
activeColor | Vector3 | green | Visual feedback color when the goal is satisfied. |
nextScene | string | "" | Scene to transition to when activated (for LevelExit goals). |
ConveyorComponent
Moves entities along a direction while they overlap the conveyor volume, like a conveyor belt. Can affect the player, pushable objects, or both.
| Field | Type | Default | Description |
|---|---|---|---|
direction | Vector3 | (1, 0, 0) | Movement direction (normalized). |
speed | f32 | 3.0 | Movement speed in world units per second. |
affectsPlayer | bool | true | Whether the conveyor moves the player. |
affectsPushables | bool | true | Whether the conveyor moves pushable objects. |
isActive | bool | true | Toggle the conveyor on or off. Link to a SwitchComponent for interactive control. |
TeleporterComponent
Instantly moves entities to a target position when they enter the teleporter volume. Supports bidirectional links between two teleporters and an optional cooldown to prevent ping-pong re-activation.
| Field | Type | Default | Description |
|---|---|---|---|
targetPosition | Vector3 | (0, 0, 0) | Destination position in world space. |
targetRotation | Vector3 | (0, 0, 0) | Destination rotation (Euler angles in degrees). |
linkedTeleporter | Entity | 0 | Partner entity for bidirectional teleportation. |
cooldown | f32 | 1.0 | Seconds before the teleporter can be used again. |
preserveVelocity | bool | false | Keep the entity's velocity after teleporting. |
requiredTag | string | "" | Only entities with this tag can teleport (empty = any entity). |
DestructibleComponent
An entity that can be destroyed by damage or interaction. Supports pickup drops, screen shake on hit, and optional respawning.
| Field | Type | Default | Description |
|---|---|---|---|
health | f32 | 1.0 | Hit points before destruction. |
destroyOnHit | bool | true | Destroy immediately on any hit (one-hit breakable). |
spawnPickup | bool | false | Drop an item when destroyed. |
pickupId | string | "" | ID of the item to drop. |
pickupCount | i32 | 1 | Number of items to drop. |
canRespawn | bool | false | Respawn after being destroyed. |
respawnTime | f32 | 10.0 | Seconds before respawn. |
shakeOnHit | f32 | 0.1 | Screen/entity shake intensity on hit. |
MovingPlatformComponent
A platform that travels between a list of waypoints, optionally carrying entities standing on it. Four movement modes cover most level-design patterns.
| Field | Type | Default | Description |
|---|---|---|---|
waypoints | list | [] | Ordered list of Vector3 positions the platform visits. |
speed | f32 | 2.0 | Movement speed in world units per second. |
waitTime | f32 | 1.0 | Pause duration at each waypoint (seconds). |
mode | enum | PingPong | Loop (A-B-C-A-B), PingPong (A-B-C-B-A), OneWay (A-B-C then stop), or Triggered (moves only when activated by a switch). |
carryEntities | bool | true | Entities standing on the platform move with it. |
For Triggered mode, link a SwitchComponent to the platform
entity via linkedEntities. The platform advances one waypoint each time the
switch is activated.
State and Dialogue
The state and dialogue systems let you build interactive NPCs, branching conversations, and general-purpose state machines for game logic and AI.
StateMachineComponent
A general-purpose state machine for game logic, AI, or animation. States are identified by string names. Named parameters (float, int, bool) can be used by scripts and visual scripts to drive transitions.
| Field | Type | Default | Description |
|---|---|---|---|
currentState | string | "idle" | Name of the current state. |
previousState | string | "" | Name of the previous state (set automatically on transition). |
stateTimer | f32 | 0.0 | Time spent in the current state (seconds). Reset on each transition. |
stateJustChanged | bool | false | True on the first frame of a new state. Cleared automatically on the next frame. |
floatParams | list | [] | Named float parameters (key-value pairs). |
intParams | list | [] | Named integer parameters. |
boolParams | list | [] | Named boolean parameters. |
Methods
| Method | Description |
|---|---|
SetState(name) | Transition to a new state. Sets previousState, resets stateTimer, and sets stateJustChanged = true. |
SetFloat(name, value) | Set a named float parameter. |
GetFloat(name) | Get a named float parameter (returns 0 if not found). |
SetBool(name, value) | Set a named boolean parameter. |
GetBool(name) | Get a named boolean parameter (returns false if not found). |
DialogueComponent
Retro RPG-style dialogue system with a typewriter text effect and branching choices. Attach to an NPC or interactive object. The dialogue system renders lines sequentially, one character at a time, with an optional per-character sound effect.
| Field | Type | Default | Description |
|---|---|---|---|
dialogueLines | list | [] | Ordered list of text strings for sequential display. |
charDelay | f32 | 0.05 | Seconds between characters (typewriter speed). |
speakerName | string | "" | Name of the speaking character, displayed above the dialogue text. |
portraitPath | string | "" | Path to a character portrait image. |
typeSound | string | "" | Audio clip path for the typewriter click effect. |
playTypeSound | bool | true | Play the typewriter sound per character. |
choices | list | [] | Branching choices. Each entry has text (display label) and nextDialogueId (entity to jump to). |
DialogueBoxComponent
Automatically builds a UICanvas-based dialogue overlay. Attach alongside a
DialogueComponent and a UICanvasComponent on the same entity. The
system creates and synchronizes all UI elements (speaker label, text area, portrait, choice
buttons, and continue indicator) automatically. Settings are organized into five groups in
the Inspector.
Box Layout
| Field | Type | Default | Description |
|---|---|---|---|
boxHeight | f32 | 200.0 | Height of the dialogue panel in pixels. |
boxMargin | f32 | 20.0 | Margin from screen edges. |
boxPadding | f32 | 16.0 | Interior padding. |
boxColor | Vector3 | (0.05, 0.05, 0.08) | Background color of the panel. |
boxAlpha | f32 | 0.92 | Panel opacity (0 = fully transparent, 1 = fully opaque). |
boxBorderRadius | f32 | 8.0 | Corner rounding radius in pixels. |
Text Style
| Field | Type | Default | Description |
|---|---|---|---|
speakerFontSize | f32 | 20.0 | Font size for the speaker name. |
defaultSpeakerColor | Vector3 | (0.9, 0.85, 0.5) | Default color for the speaker name text. |
textFontSize | f32 | 17.0 | Font size for dialogue body text. |
textColor | Vector3 | (0.9, 0.9, 0.9) | Dialogue text color. |
Portrait
| Field | Type | Default | Description |
|---|---|---|---|
showPortrait | bool | true | Show the character portrait image. |
portraitSize | f32 | 96.0 | Portrait dimensions in pixels (square). |
Choices
| Field | Type | Default | Description |
|---|---|---|---|
choiceFontSize | f32 | 16.0 | Font size for choice buttons. |
choiceColor | Vector3 | (0.7, 0.7, 0.7) | Default choice text color. |
choiceHighlightColor | Vector3 | (1.0, 0.9, 0.3) | Highlighted choice text color. |
Continue Indicator
| Field | Type | Default | Description |
|---|---|---|---|
showContinueIndicator | bool | true | Show the blinking "continue" indicator when the current line is fully typed. |
continueText | string | ">" | Text content of the continue indicator. |
continueBlinkRate | f32 | 2.0 | Blink frequency in Hz. |
Save System
TEGE provides a comprehensive tiered save system that supports everything from per-scene state (enemies killed, doors opened) to permanent cross-run progression (unlocks, achievements). The system is built around three persistence tiers, 20 save slots, and pluggable cloud-sync backends.
SaveDataComponent
Marks an entity for persistence in the tiered save system. Controls which transform fields are saved, the persistence tier, custom tags for filtering, and key-value data for game-specific state.
| Field | Type | Default | Description |
|---|---|---|---|
savePosition | bool | true | Save the entity's position. |
saveRotation | bool | true | Save the entity's rotation. |
saveScale | bool | false | Save the entity's scale. |
saveEnabled | bool | true | Whether saving is enabled for this entity. |
tier | PersistenceTier | RunState | Persistence tier: SceneState, RunState, or MetaProgression. See the tier table below. |
tags | list | [] | Custom string tags for filtering entities during save/load. |
customData | list | [] | Key-value string pairs for game-specific data. |
Methods
| Method | Description |
|---|---|
SetData(key, value) | Store a key-value pair in customData. Overwrites if the key already exists. |
GetData(key, defaultValue) | Retrieve a value by key. Returns defaultValue if not found. |
HasTag(tag) | Returns true if the entity has the specified tag. |
SaveLoadMenuComponent
In-game save/load grid overlay. Add this component to any entity to enable a pause-menu-style save/load UI during play mode. The UI renders as a grid of save slots with Save, Load, and Delete buttons.
| Field | Type | Default | Description |
|---|---|---|---|
showOnPause | bool | true | Automatically show the overlay when the game is paused. |
allowManualSave | bool | true | Show "Save" buttons on each slot. |
allowManualLoad | bool | true | Show "Load" buttons on occupied slots. |
allowDelete | bool | true | Show "Delete" buttons on occupied slots. |
showAutoSaves | bool | true | Show the auto-save slots (17-19) in the grid. |
columnsPerRow | i32 | 4 | Number of columns in the slot grid layout. |
headerText | string | "Save / Load Game" | Header text displayed above the grid. |
TieredSaveSystem
The engine's tiered save system organizes persisted data into three tiers based on how long
the data should survive. Each entity's SaveDataComponent specifies which tier
it belongs to.
Persistence Tiers
| Tier | Lifetime | Example Data |
|---|---|---|
| SceneState | Per-scene within a run. Resets on new run. | Enemies killed, doors opened, chests looted. |
| RunState | Per-run. Resets on new game. | Player health, inventory, quest progress. |
| MetaProgression | Permanent across all runs. | Unlocks, achievements, meta-currencies. |
Per-scene, resets on new run] S --> T2[RunState
Per-run, resets on new game] S --> T3[MetaProgression
Permanent across runs] T1 --> E1[Enemies killed
Doors opened
Chests looted] T2 --> E2[Player health
Inventory
Quest progress] T3 --> E3[Unlocks
Achievements
Meta-currencies]
Save Slots
The system provides 20 save slots: 17 manual save slots (0-16) and 3 rotating auto-save slots (17-19). Auto-save fires on a configurable timed interval (default 5 minutes), on scene transitions, and on checkpoint calls.
Meta-Progression
A separate meta.enjsave file stores permanent key-value data (float, int, bool,
string) that survives across all runs and save slot deletion. Use this for unlockable
characters, achievement flags, lifetime statistics, and meta-currencies.
Cloud Sync Backends
Save backends are pluggable via the ISaveBackend interface. Three backends ship
with the engine:
| Backend | Description |
|---|---|
| LocalSaveBackend | Filesystem-based (default). Saves to the local disk. |
| NewgroundsSaveBackend | Wraps NG.io cloud saves for web-published games. |
| SteamSaveBackend | Uses Steam Cloud via ISteamRemoteStorage. Requires the ENJIN_STEAM CMake flag. |
Open the Save Debug panel from View > Tools > Save Debug to inspect all 20 save slots, view meta-progression key-value tables, configure auto-save intervals, and trigger manual cloud sync.
QuestStateComponent
Tracks quest progress for RPG and narrative games. Attach to an entity that represents a quest.
The QuestSystem updates timeElapsed automatically while a quest is
active.
| Field | Type | Default | Description |
|---|---|---|---|
questId | string | "" | Unique quest identifier. |
status | enum | NotStarted | NotStarted, Active, Completed, or Failed. |
currentObjective | i32 | 0 | Index of the current objective within the quest. |
objectiveFlags | list | [] | Named boolean flags for individual objective completion. |
timeElapsed | f32 | 0.0 | Total time since the quest was started (seconds). |
QuestFlowComponent
Visual node-graph-based quest authoring for complex, branching quests. While
QuestStateComponent works for simple linear quests,
QuestFlowComponent provides a visual editor (accessible from the Inspector)
for designing quest flows with conditions, branching, delays, rewards, and events.
Authored Fields (Serialized)
| Field | Type | Default | Description |
|---|---|---|---|
questId | string | "" | Unique quest identifier. |
questTitle | string | "" | Display name for the quest. |
questDescription | string | "" | Quest description text. |
enabled | bool | true | Whether the quest flow is active. |
startNodeId | NodeId | 0 | Entry-point node (created automatically). |
graph | NodeGraphData | -- | Visual graph layout (nodes, pins, links). |
Runtime State (Not Serialized)
| Field | Type | Description |
|---|---|---|
status | enum | Inactive, Active, Completed, or Failed. |
activeNodes | set | Nodes currently being processed. |
completedNodes | set | Nodes that have finished execution. |
nodeTimers | map | Accumulated time for Delay nodes. |
nodeCounters | map | Progress counters for Objective nodes. |
The Quest Flow visual editor opens directly in the Inspector when a
QuestFlowComponent is selected. It supports the same node graph editing
controls as the Visual Script editor (drag, connect, delete, undo/redo).
HUD and UI
TEGE provides two complementary UI systems: HUD widgets for quick data-bound overlays (health bars, labels, markers), and a full UICanvas system for building complete in-game menus and interfaces.
HUDWidgetComponent
Displays data-bound UI elements such as health bars, resource bars, labels, objective markers, crosshairs, and minimaps. Widgets can be screen-space (fixed position) or world-space (billboarded above entities).
| Field | Type | Default | Description |
|---|---|---|---|
type | enum | HealthBar | HealthBar, ResourceBar, Label, ObjectiveMarker, Crosshair, or Minimap. |
visible | bool | true | Widget visibility. |
screenSpace | bool | true | true = fixed screen position; false = world-space billboard. |
anchorX | f32 | 0.05 | Horizontal screen position (normalized 0-1). |
anchorY | f32 | 0.05 | Vertical screen position (normalized 0-1). |
width | f32 | 0.2 | Widget width (normalized 0-1 of screen). |
height | f32 | 0.03 | Widget height (normalized 0-1 of screen). |
fillColor | Vector3 | (0.2, 0.8, 0.2) | Bar fill color. |
bgColor | Vector3 | (0.2, 0.2, 0.2) | Bar background color. |
textColor | Vector3 | (1, 1, 1) | Text color. |
fontSize | f32 | 16.0 | Font size for text widgets. |
text | string | "" | Label text content (for Label type). |
sourceEntity | Entity | 0 | Entity to read data from (0 = self). |
bindField | string | "" | Field to bind: "health", "stamina", "custom". |
worldOffset | Vector3 | (0, 2, 0) | Offset from entity position for world-space widgets. |
maxRenderDistance | f32 | 50.0 | Maximum camera distance for world-space widget visibility. |
UICanvasComponent
A full retained-mode UI system. Attach a UICanvasComponent to any entity to
give it a tree of UI elements rendered as an overlay during play mode. The canvas provides a
design resolution, a scale mode, and a theme for consistent styling.
| Field | Type | Default | Description |
|---|---|---|---|
canvasName | string | "Canvas" | Display name for this canvas. |
visible | bool | true | Canvas visibility toggle. |
sortOrder | i32 | 0 | Render order. Higher values render on top. |
designWidth | f32 | 1920.0 | Reference design width for layout calculations. |
designHeight | f32 | 1080.0 | Reference design height for layout calculations. |
scaleMode | enum | ScaleWithScreenSize | ScaleWithScreenSize (auto-scale to match design resolution), ConstantPixelSize (1:1 pixel mapping), or ConstantPhysicalSize (DPI-aware). |
theme | UITheme | default | Color and style theme applied to all child elements. |
elements | list | [] | Flat vector of UIElement nodes. Tree structure is encoded via parentId/childIds on each element. |
UIElement Types
Each element in a UICanvasComponent has a widget type that determines its
appearance and interaction behavior:
| Type | Description |
|---|---|
| Panel | Container element with background color, border, and corner radius. Used for grouping and layout. |
| Button | Clickable element with text label. Fires callback on click, supports hover/pressed states. |
| Label | Text display element with configurable font size, color, and alignment. |
| Image | Displays a texture. Supports SVG files via the texture resolver. |
| ProgressBar | Horizontal fill bar with configurable fill and background colors. |
| Slider | Draggable value selector with min/max range. |
| Checkbox | Boolean toggle with check mark indicator. |
| Toggle | On/off switch with sliding indicator. |
UISystem
The UISystem handles four responsibilities for all active canvases each frame:
- Layout — resolves anchors, pivots, margins, and the element tree hierarchy into screen-space rectangles.
- Render — draws all visible elements as ImGui draw commands in the Game View overlay.
- Input — processes mouse clicks, hover states, and drag events, dispatching them to the correct element.
- Focus navigation — manages keyboard/gamepad focus traversal for accessible UI control.
Focus Navigation
UICanvas supports full keyboard and gamepad navigation for in-game UI, enabling
accessible menu control without a mouse:
| Input | Action |
|---|---|
| Tab / Shift+Tab | Move focus forward/backward through focusable elements (ordered by tabOrder). |
| Arrow Keys / D-Pad | Navigate between elements with key repeat support. |
| Enter / Space / Gamepad A | Activate the focused element (button press, checkbox toggle). |
| Left / Right | Adjust slider values on focused slider elements. |
Focus indicators are rendered as an outset rounded-rect border around the focused element,
using the theme's inputFocused color or a per-element focusColor
override. Elements can be marked as focusable/unfocusable via the focusable flag
and ordered with tabOrder (0 = auto from element order).
Cinematic and Animation
TEGE provides a complete animation and cinematic toolset: scripted camera sequences with waypoint interpolation, a skeletal animation state machine with blending, a bone hierarchy for skinned meshes, and a timeline system for keyframing any property over time.
CinematicCameraComponent
Scripted camera sequences with waypoints, easing curves, and hold times. Use for intro
fly-throughs, cutscenes, and dramatic reveals. The CinematicSystem interpolates
the camera between waypoints during play mode.
| Field | Type | Default | Description |
|---|---|---|---|
waypoints | list | [] | Ordered list of camera waypoints (see waypoint fields below). |
loop | bool | false | Loop the sequence when it reaches the end. |
autoPlay | bool | false | Start playing automatically when play mode begins. |
hideHUD | bool | true | Hide HUD widgets during the cinematic. |
disableInput | bool | true | Disable player input during the cinematic. |
onCompleteNotify | Entity | 0 | Entity to notify when the sequence completes. |
onWaypointReachNotify | Entity | 0 | Entity to notify each time a waypoint is reached. |
Waypoint Fields
| Field | Type | Description |
|---|---|---|
position | Vector3 | Camera position at this waypoint. |
lookAt | Vector3 | World-space point the camera looks at. |
fov | f32 | Field of view at this waypoint (default: 60). |
duration | f32 | Time in seconds to travel from the previous waypoint to this one. |
holdTime | f32 | Time to pause at this waypoint before continuing. |
easing | enum | Interpolation curve: Linear, EaseIn, EaseOut, EaseInOut, or SmashCut (instant jump). |
AnimatorComponent
Drives skeletal animation playback with a state machine. Each state maps to an animation
clip, and transitions between states can be blended over a configurable duration. The
AnimatorComponent reads bone transforms from the SkeletonComponent
on the same entity and uploads them to the GPU bone SSBO (binding 7) for vertex skinning.
SkeletonComponent
Stores the bone hierarchy for skinned meshes. Populated automatically when importing glTF
models that contain skeletal data. Each bone stores its name, parent index, inverse bind
matrix, and current local/world transforms. The AnimatorComponent writes to
these transforms each frame; the RenderSystem reads them for GPU upload.
TimelineComponent
A general-purpose keyframe animation system that can animate any entity property over time.
Add a TimelineComponent to any entity and configure tracks with keyframes.
Track Types
| Track Type | Description |
|---|---|
| Property | Animate any component field (position, rotation, scale, material properties, etc.). |
| Event | Fire callbacks at specific timestamps. |
| Animation | Play or blend skeletal animations at specific points in the timeline. |
Playback Controls
- Play / Pause / Stop — standard playback controls.
- Loop — restart when reaching the end.
- Ping-Pong — play forward then backward.
- Speed — playback rate multiplier.
Easing Functions
Keyframes support five interpolation curves: Linear, EaseIn,
EaseOut, EaseInOut, and Step (instant jump to the
next keyframe value).
Networking
TEGE includes a built-in LAN multiplayer system with entity replication, interpolation, client-side prediction, and remote procedure calls. The networking layer is designed for local-area games with up to 64 players.
NetworkIdentityComponent
Marks an entity for network replication. The NetworkSystem assigns a unique
networkId at runtime and tracks ownership so that only the owning client can
author state updates for the entity.
| Field | Type | Default | Description |
|---|---|---|---|
networkId | u32 | 0 | Unique network identifier (assigned by NetworkSystem at runtime). |
ownerId | u8 | 0xFF | Player ID of the owner (0xFF = unowned/server-owned). |
isLocallyOwned | bool | false | Runtime flag. true if the local client owns this entity. |
syncTransform | bool | true | Automatically synchronize position and rotation over the network. |
syncInterval | f32 | 0.05 | Seconds between sync updates (20 Hz default). |
NetworkTransformComponent
Stores network synchronization state for interpolation and client-side prediction. The
NetworkSystem writes to this component on remote entities and reads from it to
smoothly interpolate between sync snapshots.
| Field | Type | Description |
|---|---|---|
lastSyncedPosition | Vector3 | Most recent position received from the network. |
lastSyncedRotation | Quaternion | Most recent rotation received from the network. |
lastSyncedScale | Vector3 | Most recent scale received from the network. |
networkVelocity | Vector3 | Velocity used for dead-reckoning prediction. |
interpStartPosition | Vector3 | Interpolation start position (previous snapshot). |
interpStartRotation | Quaternion | Interpolation start rotation. |
interpProgress | f32 | Current interpolation progress (0 to 1). |
interpDuration | f32 | Duration of one interpolation step (matches syncInterval). |
predictionError | Vector3 | Accumulated prediction error for correction blending. |
correctionBlend | f32 | Blend factor for smoothing prediction corrections. |
LAN Multiplayer Overview
The multiplayer system operates over UDP on the local network. One player hosts the session; others join by IP address. Key concepts:
- Host/Join — The host creates a session on a configurable port (default 7777). Clients connect by entering the host's IP address.
- Entity Ownership — Each replicated entity has an
ownerId. Only the owning client sends authoritative state updates. Other clients receive and interpolate. - RPCs (Remote Procedure Calls) — Scripts can invoke functions on remote clients via named RPCs. Both AngelScript and visual script bindings are provided (
Host Game,Join Game,Disconnect,Call RPCnodes). - Delta Sync — The
NetworkSystemsends state updates at 20 Hz by default, with HMAC-SHA256 authentication for packet integrity. - Client-Side Prediction — Locally owned entities are simulated immediately; prediction errors are smoothly corrected when authoritative state arrives.
Network Configuration
Network settings are loaded from config/network_settings.json at startup. The
same settings can be edited visually from Settings > Project > Networking
in the editor.
{
"port": 7777,
"maxPlayers": 16,
"serverIP": "127.0.0.1",
"syncRate": 0.05,
"rateLimit": {
"maxPacketsPerSecond": 200.0,
"maxBytesPerSecond": 131072.0,
"burstPackets": 50.0,
"burstBytes": 65536.0
},
"security": {
"maxViolations": 10,
"violationWindowSeconds": 10.0,
"banSeconds": 30.0,
"kickOnViolation": true
}
}
The rateLimit block controls per-sender packet and bandwidth throttling with a
token-bucket burst allowance. The security block determines how many violations
within a rolling window will trigger a temporary ban and optional kick. For competitive or
high-traffic games, raise maxBytesPerSecond, burstBytes, and/or
maxPacketsPerSecond to match your netcode needs.
Environment and Effects
TEGE includes a suite of environment components for defining weather zones, temperature regions, custom gravity fields, water/fluid volumes, camera overrides, and particle effects. These components are volume-based: attach them to entities and the engine evaluates which volumes overlap the player or other entities each frame.
WeatherZoneComponent
Defines a bounding-box region with per-zone weather overrides. When the camera or player enters this zone, the scene weather switches to the zone's settings. Higher-priority zones take precedence when zones overlap.
| Field | Type | Default | Description |
|---|---|---|---|
halfExtents | Vector3 | (20, 20, 20) | Bounding box half-extents (centered on entity position). |
weatherType | u32 | 0 | Weather preset: 0=Clear, 1=Cloudy, 2=Rain, 3=HeavyRain, 4=Snow, 5=Fog, 6=Storm. |
rainIntensity | f32 | 0.7 | Rain particle intensity. |
snowIntensity | f32 | 0.7 | Snow particle intensity. |
fogDensity | f32 | 0.0 | Fog density (0 = no fog). |
fogColor | Vector3 | (0.5, 0.5, 0.6) | Fog color. |
fogStart | f32 | 20.0 | Fog start distance. |
fogEnd | f32 | 100.0 | Fog end distance (fully opaque). |
windDirection | Vector3 | (0.2, 0, 0.1) | Wind direction vector (affects rain/snow particle drift). |
windStrength | f32 | 1.0 | Wind strength multiplier. |
lightningEnabled | bool | true | Enable lightning flashes during storm weather. |
lightningMinInterval | f32 | 2.0 | Minimum seconds between lightning strikes. |
lightningMaxInterval | f32 | 10.0 | Maximum seconds between lightning strikes. |
priority | i32 | 0 | Override priority. Higher values take precedence when zones overlap. |
TemperatureZoneComponent
Defines a region with a specific temperature. Below 0 degrees Celsius, the zone produces snow
and ice effects; above 5 degrees, rain. Temperature zones also drive water freeze/thaw
mechanics on overlapping WaterVolumeComponent entities.
| Field | Type | Default | Description |
|---|---|---|---|
halfExtents | Vector3 | (20, 20, 20) | Bounding box half-extents. |
temperature | f32 | 15.0 | Temperature in Celsius. Below 0 = freezing (snow/ice), 0-5 = near-freezing (sleet), above 5 = warm (rain). |
priority | i32 | 0 | Override priority for overlapping zones. |
GravityZoneComponent
Overrides gravity for entities within the zone. Supports directional gravity (e.g., sideways
rooms), point gravity (toward the zone center, Mario Galaxy-style), and zero-G (set
gravityStrength to 0).
| Field | Type | Default | Description |
|---|---|---|---|
shape | enum | Box | Box (AABB) or Sphere (radius = halfExtents.x). |
mode | enum | Directional | Directional (uniform direction) or Point (pull toward zone center). |
halfExtents | Vector3 | (10, 10, 10) | Bounding box half-extents (or sphere radius via halfExtents.x). |
gravityDirection | Vector3 | (0, -1, 0) | Gravity direction for Directional mode (normalized). |
gravityStrength | f32 | 9.81 | Gravity magnitude in m/s². Set to 0 for zero-G. |
priority | i32 | 0 | Override priority for overlapping zones. |
isActive | bool | true | Toggle the gravity zone on or off. |
WaterVolumeComponent
Defines a water body with Gerstner wave rendering, shore foam, and freeze/thaw mechanics.
The entity's Y position defines the water surface level; halfExtents defines
the horizontal area and depth below the surface.
| Field | Type | Default | Description |
|---|---|---|---|
halfExtents | Vector3 | (50, 5, 50) | Volume half-extents. X/Z = horizontal area, Y = depth below surface. |
waterType | enum | Lake | Preset: Lake, Ocean, River, or Pond. |
waterColor | Vector3 | (0.1, 0.3, 0.5) | Base water color. |
opacity | f32 | 0.7 | Water surface opacity. |
waveSpeed | f32 | 1.0 | Wave animation speed. |
waveHeight | f32 | 0.2 | Wave amplitude. |
enableShore | bool | true | Enable shore foam rendering. |
shoreWidth | f32 | 0.15 | Normalized edge distance for foam (0-0.5). |
foamIntensity | f32 | 0.6 | Foam opacity (0-1). |
foamScale | f32 | 8.0 | Noise scale for the foam pattern. |
shoreColor | Vector3 | (0.3, 0.6, 0.7) | Shallow water tint. |
freezeRate | f32 | 0.3 | Freeze speed per second (driven by overlapping TemperatureZoneComponent). |
thawRate | f32 | 0.5 | Thaw speed per second. |
iceColor | Vector3 | (0.7, 0.85, 0.95) | Surface color when frozen. |
iceOpacity | f32 | 0.95 | Surface opacity when frozen. |
priority | i32 | 0 | Override priority for overlapping volumes. |
CameraTriggerComponent
A camera override volume. When the player enters this zone, the game camera smoothly
transitions to the specified target camera entity over blendTime seconds.
Useful for fixed-angle rooms, dramatic reveal shots, and side-scrolling camera locks.
| Field | Type | Default | Description |
|---|---|---|---|
halfExtents | Vector3 | (10, 10, 10) | Trigger volume half-extents. |
targetCamera | Entity | INVALID | Camera entity to activate when the player enters the zone. |
priority | i32 | 0 | Override priority for overlapping triggers. |
blendTime | f32 | 0.5 | Camera transition duration in seconds. |
ParticleEmitterComponent
Emits particles with configurable shape, lifetime, color gradients, and forces. Supports continuous emission, burst emission, and texture sheet animation.
| Field | Type | Default | Description |
|---|---|---|---|
isPlaying | bool | false | Whether particles are currently being emitted. |
playOnAwake | bool | true | Start emitting when play mode begins. |
loop | bool | true | Loop emission continuously. |
emissionRate | f32 | 10.0 | Particles emitted per second (continuous mode). |
burstCount | i32 | 0 | Number of particles in an instant burst. |
burstInterval | f32 | 0.0 | Seconds between bursts (0 = single burst). |
lifetime | f32 | 2.0 | Particle lifetime in seconds. |
lifetimeVariance | f32 | 0.5 | Random lifetime variation (+/-). |
startSpeed | f32 | 5.0 | Initial particle speed. |
speedVariance | f32 | 1.0 | Random speed variation (+/-). |
startSize | f32 | 0.5 | Particle size at birth. |
endSize | f32 | 0.1 | Particle size at death. |
startColor | Vector3 | (1, 1, 1) | Particle color at birth. |
endColor | Vector3 | (1, 1, 1) | Particle color at death. |
startAlpha | f32 | 1.0 | Particle opacity at birth. |
endAlpha | f32 | 0.0 | Particle opacity at death. |
shape | enum | Cone | Emitter shape: Point, Sphere, Hemisphere, Cone, or Box. |
shapeRadius | f32 | 0.1 | Emitter shape radius. |
coneAngle | f32 | 30.0 | Cone emission angle in degrees (for Cone shape). |
gravity | Vector3 | (0, -9.8, 0) | Gravity force applied to particles. |
drag | f32 | 0.0 | Air resistance (velocity damping per second). |
texturePath | string | "" | Particle texture path (empty = default white quad). |
Vegetation and Terrain
TEGE provides terrain components for both 3D heightmap landscapes and 2D side-scrolling terrain profiles, plus a vegetation system for wind-animated foliage.
TerrainComponent
A grid-based 3D heightmap terrain with multi-layer texture splatting. The terrain mesh is
automatically regenerated by the RenderSystem whenever meshDirty is
set to true. Supports up to 4 texture layers blended via a splatmap.
| Field | Type | Default | Description |
|---|---|---|---|
gridWidth | u32 | 64 | Number of grid cells along the X axis. |
gridHeight | u32 | 64 | Number of grid cells along the Z axis. |
cellSize | f32 | 1.0 | World-space size of each grid cell. |
maxHeight | f32 | 20.0 | Maximum terrain height. |
heightmap | vector<f32> | [] | Height values (gridWidth * gridHeight entries). |
splatmap | vector<f32> | [] | Texture blend weights (gridWidth * gridHeight * 4 entries, RGBA per cell). |
layers[0..3] | TextureLayer | -- | Four texture layers. Each has a texturePath and tileScale. |
meshDirty | bool | true | Set to true to trigger mesh regeneration. |
Methods
| Method | Description |
|---|---|
GetHeight(x, z) | Returns the height at grid coordinates (x, z). Returns 0 if out of bounds. |
SetHeight(x, z, h) | Sets the height at (x, z) and sets meshDirty = true. |
InitializeFlat(height) | Fills the entire heightmap with a uniform height and initializes the splatmap (layer 0 = 100%). |
Terrain2DComponent
A polyline-based 2D terrain for side-scrolling games. Control points define the surface profile; a filled mesh is generated below the surface to a configurable depth. Collision can be auto-generated from the terrain shape.
| Field | Type | Default | Description |
|---|---|---|---|
controlPoints | vector<Vector2> | [] | XY positions defining the surface, auto-sorted by X. |
depth | f32 | 5.0 | Fill depth below the surface. |
uvScale | f32 | 1.0 | UV coordinate scaling for the surface texture. |
texturePath | string | "" | Surface texture path. |
autoColliders | bool | true | Automatically generate collision geometry from the terrain shape. |
VegetationComponent
Tag component for trees, bushes, and other foliage. When attached to a mesh entity, enables GPU-driven wind sway in the vertex shader. The vertex color red channel controls per-vertex sway weight (trunk = 0, leaves/branches = 1), allowing realistic deformation where the base stays anchored while the canopy sways.
| Field | Type | Default | Description |
|---|---|---|---|
swayStrength | f32 | 1.0 | Wind sway intensity multiplier. |
swayFrequency | f32 | 1.0 | Wind sway oscillation frequency. |
useVertexColorWeight | bool | true | Use the vertex color red channel as per-vertex sway amplitude. |
The VegetationComponent works with any mesh. Paint vertex colors in your 3D
modeling tool (red channel = sway weight) before importing the glTF model. The engine's wind
system (WindSystem) provides the global wind direction and strength used by the
sway shader.
Advanced Components
TEGE includes several advanced components for scripting, object pooling, audio, level of detail, and specialized simulation systems.
ScriptComponent
Attaches AngelScript behavior to an entity. Each entity can have multiple script attachments.
Scripts receive lifecycle callbacks (OnCreate, OnUpdate,
OnDestroy, collision/trigger events) and have access to the full engine API
through registered bindings.
| Field | Type | Default | Description |
|---|---|---|---|
scriptPath | string | "" | Path to the AngelScript file (e.g., scripts/PlayerController.as). |
className | string | "" | The AngelScript class to instantiate from the script file. |
properties | list | [] | Exposed property values editable in the Inspector (Int, Float, Bool, String, Vector2/3/4, Entity, Enum). |
enabled | bool | true | Toggle the script on or off. |
Scripts are hot-reloaded during play mode. The engine polls the script directory every 30 frames for file changes and automatically recompiles modified scripts without stopping playback.
VisualScriptComponent
Blueprint-style visual node graph for gameplay logic. Provides a no-code alternative to AngelScript for common gameplay patterns. The visual script editor (accessible from the Inspector) supports drag-and-drop node placement, pin connections, variable management, and a built-in debugger with breakpoints and execution highlighting.
The component stores the full node graph (nodes, pins, links), local variables, event-to-node mappings, and per-node metadata. Over 140 node types are available across categories including Events, Flow Control, Math, Entity, Physics, Audio, Animation, Gameplay, and Networking.
PoolableComponent
Marks an entity as part of an object pool for efficient reuse. Common uses include bullets,
particle effects, enemies, and pickups. The ObjectPool system manages activation,
deactivation, and lifetime tracking.
| Field | Type | Default | Description |
|---|---|---|---|
poolId | string | "" | Pool identifier (objects with the same ID share a pool). |
isActive | bool | false | Whether this pooled object is currently active in the world. |
lifetime | f32 | 0.0 | Auto-return to pool after this many seconds (0 = infinite, manually returned). |
activeTime | f32 | 0.0 | Time since activation (runtime, auto-incremented). |
spawnedBy | Entity | 0 | Entity that spawned/activated this pooled object. |
FootstepComponent
Surface-aware footstep sounds. Plays different audio clips based on the surface material the
character is walking on. The FootstepSystem detects the surface tag from terrain
or collider data and selects the matching sound.
| Field | Type | Default | Description |
|---|---|---|---|
surfaceSounds | list | [] | List of surface-sound mappings. Each entry has surfaceTag, walkSound, runSound, and volumeScale. |
defaultWalkSound | string | "" | Fallback walk sound when no surface tag matches. |
defaultRunSound | string | "" | Fallback run sound. |
walkStepInterval | f32 | 0.5 | Seconds between footstep sounds when walking. |
runStepInterval | f32 | 0.3 | Seconds between footstep sounds when running. |
volume | f32 | 0.8 | Master footstep volume (0-1). |
pitchVariance | f32 | 0.1 | Random pitch variation for natural-sounding footsteps. |
Surface Sound Mapping
| Field | Type | Description |
|---|---|---|
surfaceTag | string | Surface identifier (e.g., "grass", "stone", "wood", "metal", "water"). |
walkSound | string | Audio clip path for walking. |
runSound | string | Audio clip path for running. |
volumeScale | f32 | Per-surface volume multiplier. |
LODComponent
Level-of-detail management with up to 5 LOD levels. The engine automatically switches between
mesh simplification levels based on camera distance. LOD meshes can be auto-generated from the
original mesh using the built-in MeshSimplifier, or assigned manually.
| Field | Type | Default | Description |
|---|---|---|---|
levelCount | i32 | 0 | Number of populated LOD levels (0 = no LOD). |
baseDistance | f32 | 10.0 | Camera distance for the LOD 0 to LOD 1 transition. |
distanceMultiplier | f32 | 2.0 | Each successive LOD level transitions at N times the previous distance. |
activeLOD | i32 | 0 | Currently displayed LOD level (runtime). |
enabled | bool | true | Enable/disable LOD switching. |
autoGenerated | bool | false | Whether LOD meshes were auto-generated by the MeshSimplifier. |
reductionRatios | array[5] | [1.0, 0.5, 0.25, 0.12, 0.06] | Fraction of original vertices to keep at each LOD level (LOD 0 = full detail). |
hysteresisRatio | f32 | 0.1 | Dead-zone ratio around each LOD transition distance. A value of 0.1 means 10% hysteresis, preventing rapid LOD flickering when the camera is near a boundary. |
useScreenSize | bool | true | When true, LOD selection uses screen-space projected size (scale-aware) instead of raw camera distance. More accurate for objects at varying scales. |
LODLevel Fields
| Field | Type | Description |
|---|---|---|
mesh | MeshComponent | Simplified mesh data for this level. |
maxDistance | f32 | Camera distance threshold for transitioning to the next LOD. |
vertexCount | u32 | Vertex count (cached for display in the Inspector). |
triangleCount | u32 | Triangle count (cached for display). |
reductionRatio | f32 | Fraction of original mesh retained (0.0 - 1.0). |
Other Advanced Components
The following specialized components are available for advanced use cases:
| Component | Description |
|---|---|
| ElementalComponent | Unified elemental system with dot-product particle architecture. Supports fire, ice, electric, poison, and magic elemental interactions between entities. |
| CurlNoiseFieldComponent | Procedural 3D curl-noise flow field for driving particle motion, wind effects, and fluid-like simulations. |
| FractureComponent | Runtime mesh fracture for destructible objects. Generates debris pieces from the original mesh on impact. |
| IKComponent | Inverse kinematics for skeletal meshes. Supports foot placement, hand targeting, and look-at constraints. |
| ResourceComponent | Generic resource bar (stamina, mana, energy). Auto-regenerates each frame. Integrates with character controllers for sprint/jump/dash costs. |
Editor Tools
Built-in tools for content creation and game design.
Settings Window
The Settings window is a unified configuration panel accessed via
View > Settings. It consolidates all engine, project, and
per-scene options into a single window with three tabs:
System, Project, and Scene.
You can also open it programmatically with OpenSettings(tab) to
jump directly to a specific tab.
System Tab
System-level settings that apply globally across all projects. These are saved
persistently to disk in JSON format (on Windows, under
%APPDATA%/enjin/).
| Category | Settings |
|---|---|
| Camera | Fly camera speed, sensitivity, near/far clip planes, FOV, inversion toggles. |
| Editor Performance | Target frame rate, VSync, editor idle throttle, stats overlay toggle. |
| External IDE | Path to external code editor for opening scripts (e.g., VS Code, Notepad++). |
| Accessibility | 11 editor themes (Dark, Light, Classic, Solarized, Nord, Dracula, Monokai, Gruvbox, One Dark, High Contrast, Custom). Colorblind simulation modes (Protanopia, Deuteranopia, Tritanopia). Reduced-motion toggle to disable animations. Subtitle sizing. Custom accent colors. |
| Fonts | Font size scaling for the entire editor UI. Affects all ImGui text rendering. |
Project Tab
Project-wide settings that are saved in the .enjinproject manifest
file. These apply to the entire project regardless of which scene is loaded.
| Category | Settings |
|---|---|
| Project Mode | Choose between 2D, 3D, or Mixed. Determines default physics backend selection, render pipeline, and available templates. |
| Window Icon | Browse for a PNG file, click Apply to set a custom window icon. Use Clear to revert to the OS default. The path is persisted in the project file. |
| Physics Backend | Select physics engine: Auto (Jolt for 3D/Mixed, Box2D for 2D), Jolt, Box2D, or Simple. |
| Frame Rate | Target frame rate for the game player. Does not affect the editor itself. |
| Audio | Channel count, master volume, Steam Audio HRTF enable/disable. |
| Collision Groups |
Define up to 32 named collision groups. Each collider entity has
categoryBits and collisionMask bitmasks.
Collisions are bilateral: both entities must accept each other
(A.categoryBits & B.collisionMask && B.categoryBits & A.collisionMask).
|
| Build Config | Output directory, window title, resolution, fullscreen default, and asset packing options for the standalone player export. |
Scene Tab
Per-scene settings that are serialized with each .enjscene file.
When you switch scenes, these settings change accordingly.
| Category | Settings |
|---|---|
| Skybox | Mode selection: Solid Color, Procedural (gradient sky with top/horizon/bottom colors and sun direction), or Cubemap. Procedural includes 5 presets (Default, Sunset, Overcast, Night, Toxic). |
| Shadows | Enable/disable, shadow map resolution, PCF filtering quality, CSM cascade count, bias. |
| Ambient Lighting | Ambient color and intensity. Applied to all objects as a base illumination level. |
| Cel Shading | Enable/disable, number of shading bands, edge detection threshold, outline color and width. |
| Display Options | Wireframe mode, grid visibility, gizmo visibility, debug overlays. |
| Ray Tracing | Per-effect toggles (shadows, reflections, AO, GI, translucency, caustics), SVGF denoiser parameters (temporal alpha, a-trous iterations), path tracer SPP. Only available on RT-capable hardware. |
| Light Probes | SH light probe grid placement, L2 spherical harmonics baking, probe visualization. |
| Post Processing | Bloom, vignette, color grading, FXAA, film grain, depth of field, tilt-shift, stipple/dither, SSAO, god rays, contact shadows, caustics, fog shafts. |
| Retro Effects | CRT scanlines, pixelation, dithering patterns, color palette reduction. Applied as global post-processing. |
| Environment | Weather: rain, snow, fog, storm with lightning. World Time: day/night cycle with configurable speed, sun position, and sky color transitions. Wind: global wind direction and strength affecting weather, vegetation, and grass. |
Settings in the System tab persist across all projects and sessions.
Project and Scene settings are saved with their respective files. Use
OpenSettings(2) in code to jump directly to the Scene tab
(0 = System, 1 = Project, 2 = Scene).
Keyboard Shortcuts
TEGE provides a comprehensive set of keyboard shortcuts for fast editor navigation and entity manipulation. All shortcuts are active when the editor viewport has focus.
Gizmo and Transform
| Key | Action |
|---|---|
| 1 | Translate gizmo |
| 2 | Rotate gizmo |
| 3 | Scale gizmo |
| 4 | Toggle local / world space |
Camera Navigation
| Key | Action |
|---|---|
| W A S D | Fly camera movement (forward, left, backward, right) |
| Space / E | Camera up |
| Q / Ctrl | Camera down |
| Shift | Sprint (faster fly camera speed) |
| Hold RMB + Mouse | Look around (orbit camera) |
| Scroll wheel | Adjust fly camera speed |
| F | Focus camera on selection centroid |
Selection
| Key | Action |
|---|---|
| Left-click | Select entity (viewport or hierarchy) |
| Double-click | Focus on entity |
| Ctrl + click | Toggle entity in/out of multi-selection |
| Shift + click | Range select in hierarchy (from primary to clicked) |
| Drag in viewport | Marquee / rubber-band selection |
Entity Editing
| Key | Action |
|---|---|
| Delete | Delete all selected entities |
| Ctrl + D | Duplicate all selected entities |
| Ctrl + X | Cut entity |
| Ctrl + C | Copy entity |
| Ctrl + V | Paste entity |
| Ctrl + Z | Undo |
| Ctrl + Y | Redo |
File and Global
| Key | Action |
|---|---|
| Ctrl + S | Save scene |
| Ctrl + O | Open scene |
| Ctrl + I | Import model |
| Ctrl + P | Command palette (fuzzy search with 25+ commands) |
The Command Palette (Ctrl + P) provides fuzzy search across all editor actions. Type a command name like “Report Bug”, “Send Feedback”, or “Settings” to quickly access any feature without memorizing its shortcut.
Asset Browser
The Asset Browser provides a visual interface for browsing, searching, and managing project files. Open it from the View menu or use the default docked panel layout.
Layout
The panel is divided into two areas:
- Toolbar — search bar, grid/list toggle button, and a thumbnail size slider.
- Content Area — file cards displayed in either grid or list view.
Features
| Feature | Description |
|---|---|
| Search | Case-insensitive filter by file name. Results update in real time as you type. |
| Grid View | Thumbnail cards with file type labels and color coding for quick visual identification. |
| List View | Compact rows showing file name, type label, and file size. |
| Thumbnails | Image files (.png, .jpg, .bmp, .tga, .svg) display a thumbnail preview. |
| Hover Preview | Hovering an image file shows a larger 256px tooltip preview. |
| Drag & Drop | Drag files from the browser to other panels. The payload type is ASSET_PATH. |
| Thumbnail Size | Adjustable slider from 48px to 200px to balance detail and density. |
File Type Labels
Files are automatically categorized and color-coded based on their extension:
| Label | Extensions | Color |
|---|---|---|
| IMG | .png, .jpg, .jpeg, .bmp, .tga, .svg |
Teal |
| 3D | .gltf, .glb, .fbx, .obj, .dae |
Blue |
| SCN | .enjscene |
Green |
| SHD | .vert, .frag, .comp, .glsl |
Yellow |
| AS | .as |
Orange |
| SFX | .wav, .mp3, .ogg, .flac |
Purple |
| PFB | .enjprefab |
Cyan |
SVG Support
TEGE supports loading SVG vector images at runtime via the integrated nanosvg library. SVG files are rasterized to textures at load time and can be used anywhere a regular image texture is accepted, including UIElement Image widgets in UI canvases. The Asset Browser shows SVG files with thumbnail previews alongside raster images.
Pixel Editor
The Pixel Editor is a built-in sprite creation tool for making pixel art directly in the engine. Open it from View > Tools > Pixel Editor.
Drawing Tools
| Tool | Description |
|---|---|
| Pencil | Draw individual pixels with the current color. |
| Eraser | Erase pixels to transparent. |
| Line | Draw straight lines between two points. |
| Rectangle | Draw filled or outlined rectangles. |
| Circle | Draw filled or outlined circles. |
| Fill | Flood-fill a contiguous area with the current color. |
| Color Picker | Sample a color from the canvas and set it as the active color. |
| Select | Rectangular selection for copy, paste, and move operations. |
Layers
The Pixel Editor supports a full layer system:
- Create, delete, reorder, and rename layers freely.
- Toggle layer visibility and adjust opacity per layer.
- Layers composite top-to-bottom in the order shown in the layer panel.
Retro Presets
Quick-apply classic console color palettes and resolution constraints for authentic retro aesthetics. Available presets include:
- NES — 54-color palette with 256×240 resolution.
- Game Boy — 4-shade green palette with 160×144 resolution.
- SNES — Extended palette with 256×224 resolution.
Onion Skinning
When working with animation frames, onion skinning displays ghost images of adjacent frames to help you create smooth motion. Configure the number of previous and next frames shown, along with their opacity.
Animation Timeline
A timeline bar at the bottom of the editor enables frame-by-frame animation authoring:
- Add, remove, and reorder frames in the timeline.
- Set per-frame duration for variable timing.
- Preview animation playback directly in the editor.
Undo / Redo
Full undo/redo support for all drawing operations. Use Ctrl + Z to undo and Ctrl + Y to redo.
Export
| Format | Description |
|---|---|
| Export as PNG | Saves the current canvas to disk as a PNG file via stb_image_write. |
| Export as Prefab | Generates a sprite sheet image plus a .enjprefab file ready for immediate use in the engine as a sprite or animated sprite entity. |
Sprite Sheet Importer
The Sprite Sheet Importer slices existing sprite sheet images into individual frames for animation. Open it from View > Tools > Sprite Sheet Importer.
Import Modes
| Mode | Description |
|---|---|
| Grid | Specify cell width and height. The importer divides the sheet into a uniform grid. Optional padding between cells. |
| Auto Detect | Automatically detects sprite boundaries by analyzing alpha transparency. Works well for irregular sprite layouts. |
Workflow
- Load a sprite sheet image (PNG, JPG, BMP, or TGA).
- Choose Grid or Auto Detect mode.
- For Grid mode, enter the cell dimensions and optional padding values.
- Preview the detected frames overlaid on the source image. Frames are highlighted with colored outlines.
- Confirm to create individual sprite frames usable by
SpriteAnimationComponent.
Auto Detect mode works best with sprite sheets that have a fully transparent background. If your sheet uses a solid-color background, convert it to transparency first or use Grid mode instead.
Vector Drawing Editor
A built-in vector drawing editor for creating 2D art assets directly in the engine. Access it via Tools > Vector Drawing Editor.
Shape Tools
The editor provides 8 tools for creating and manipulating vector shapes:
| Tool | Description |
|---|---|
| Select | Click to select shapes. Drag to move. Handles for resize and rotation. |
| Line | Draw straight lines between two points. |
| Rectangle | Draw rectangles and squares (hold Shift for square). |
| Ellipse | Draw ellipses and circles (hold Shift for circle). |
| Pen | Freehand drawing for organic shapes. |
| Bezier | Cubic bezier curves with control point handles. |
| Star | N-pointed stars with configurable inner/outer radius and point count. |
| Polygon | Regular polygons with configurable side count (triangle, pentagon, hexagon, etc.). |
Editor Features
- Layer system — add, remove, and reorder layers for organizing complex drawings.
- Undo / Redo — 50 levels of history for non-destructive editing.
- Snap to grid — configurable grid size for precise alignment.
- Zoom and pan — mouse wheel for zoom, middle mouse drag for pan.
- Property panel — edit fill color, stroke color, and stroke width for the selected shape.
- SVG export — export your drawing as SVG for use in web applications or re-import into TEGE.
Terrain Editor
TEGE provides interactive terrain sculpting directly in the editor viewport for both 3D heightmap terrain and 2D polyline terrain.
3D Terrain Workflow
- Create an entity and add a TerrainComponent via the Inspector’s Add Component button.
- Set the desired Grid Width, Grid Height, and Cell Size in the Inspector.
- Click Initialize Flat to allocate the heightmap.
- Enable Edit Mode in the Terrain Brush section of the Inspector.
- Select a Brush Mode and adjust parameters.
- Click and drag on the terrain in the viewport to sculpt.
Brush Modes
| Mode | Effect |
|---|---|
| Raise | Increases height under the brush. Hold the mouse to continuously raise terrain. |
| Lower | Decreases height under the brush. |
| Flatten | Blends terrain height toward a target value set via the Flatten Height slider. |
| Smooth | Blends each cell toward its neighbor average, reducing sharp peaks and valleys. |
| Paint | Paints splatmap weights for the selected texture layer (0–3). Weights are automatically normalized to sum to 1.0. |
Brush Parameters
| Parameter | Range | Description |
|---|---|---|
| Radius | 0.5 – 50.0 | Brush size in world units. |
| Strength | 0.01 – 10.0 | Intensity of the brush effect per frame. |
| Falloff | 0.0 – 1.0 | How quickly the effect fades from center to edge. 0 = uniform circle, 1 = full smoothstep falloff. |
| Flatten Height | 0.0 – maxHeight | Target height for Flatten mode. |
| Paint Layer | 0 – 3 | Which splatmap layer to paint (corresponds to one of the 4 texture layers). |
Texture Layers
Each terrain supports 4 texture layers. Configure them in the Inspector under Texture Layers:
- Load Texture — select a PNG, JPG, BMP, or TGA file for the layer.
- Tile Scale — how many times the texture repeats across the terrain surface.
Use the Paint brush mode to blend between layers. By default, layer 0 covers the entire terrain at 100%.
Brush Cursor Feedback
When Edit Mode is active and the mouse hovers over the terrain, the Inspector
displays the brush world coordinates: Brush: (X, Y, Z). The
editor casts a ray from the mouse position using
ScenePicker::ScreenToRay(), marches along in half-cell-size
steps, and refines the hit point with a binary search for sub-cell accuracy.
2D Terrain
- Create an entity and add a Terrain2DComponent.
- Use the Inspector to add control points (click Add Point), or edit existing point positions with the drag fields.
- Enable Edit Mode (Drag Points) in the Inspector.
- Click near a control point in the viewport and drag to reposition it.
- Points are automatically re-sorted by X after each move.
While terrain Edit Mode is active, viewport picking is disabled — left-clicking sculpts terrain instead of selecting entities. This prevents accidentally deselecting the terrain entity while painting. The transform gizmo still works normally. Uncheck the Edit Mode checkbox to return to normal entity selection.
Quest Flow Editor
The Quest Flow Editor is a visual node-graph tool for designing complex,
branching quests. It builds on the same NodeGraphEditor framework
used by the Behavior Tree and Visual Script editors. Open it from
View > Tools > Quest Flow, or select an entity with a
QuestFlowComponent and click Open Editor in the
Inspector.
Node Types
The Quest Flow system provides 8 node types organized into 3 categories:
Flow Nodes
| Node | Color | Pins | Description |
|---|---|---|---|
| Start | Green | 1 output (Next) | Entry point for the quest. Created automatically and cannot be deleted. Activates when the quest begins. |
| End | Red | 1 input (In) | Terminates the quest. Set endStatus to completed or failed. |
| Delay | Grey | 1 input (In), 1 output (Next) | Waits for duration seconds before continuing to the next node. |
| Event | Teal | 1 input (In), 1 output (Next) | Fires a named event string (eventName) for script integration, then continues. |
Objective Nodes
| Node | Color | Pins | Description |
|---|---|---|---|
| Objective | Blue | 1 input (In), 1 output (Done) | A task the player must complete. Tracks progress via nodeCounters against targetCount. |
Objective node properties:
| Property | Description |
|---|---|
description |
Human-readable objective text shown to the player. |
objectiveType |
kill, collect, reach, interact, or custom. |
targetCount |
Number of completions required (default: 1). |
targetTag |
Tag to match against for auto-tracking objective progress. |
Logic Nodes
| Node | Color | Pins | Description |
|---|---|---|---|
| Condition | Orange | 1 input, 2 outputs (True / False) | Checks a game state condition and routes execution accordingly. |
| Branch | Purple | 1 input, 2 outputs (True / False) | Identical to Condition; use for readability when branching quest paths. |
| Reward | Gold | 1 input (In), 1 output (Next) | Grants a reward (logged to console), then continues to the next node. |
Condition and Branch properties:
| Property | Description |
|---|---|
conditionType |
hasItem, questComplete, variable, or custom. |
key |
The variable or item key to check. |
operator |
Comparison operator: ==, !=, <, >, <=, >=. |
value |
The value to compare against. |
Reward properties:
| Property | Description |
|---|---|
rewardType |
xp, item, currency, or custom. |
amount |
Quantity to grant. |
itemId |
Item identifier (used when rewardType is item). |
Editor Layout
The editor window is divided into three areas:
- Toolbar (top) — Auto Layout and Fit All buttons.
- Graph Canvas (left) — the node graph where you create and connect nodes. Right-click to open a context menu with Flow, Objectives, and Logic categories.
- Inspector Panel (right, 280px) — quest info fields (ID, title, description) and properties for the currently selected node.
Connecting Nodes
Drag from an output pin to an input pin to create a link. Validation rules ensure graph integrity:
- Links connect Flow output to Flow input only.
- Each input pin accepts at most 1 incoming link.
- The Start node allows at most 1 outgoing link.
- Self-links are not allowed.
Play Mode Visualization
When you enter Play mode, all QuestFlowComponent runtime state
is reset and enabled quests automatically begin processing from their Start
node. The graph walker advances each frame:
- Start — immediately completes and activates its output.
- Objective — waits until its counter reaches
targetCount. - Condition / Branch — evaluates and routes to True or False output.
- Reward — logs the grant and continues.
- Delay — accumulates time and continues when elapsed.
- Event — fires the named event and continues.
- End — sets the quest status and stops processing.
Live status is visualized on each node: yellow = active, green = completed, grey = unreached. The inspector shows live status, active node count, and objective progress. When Play mode stops, all runtime state is cleared.
Auto Layout
Click Auto Layout to arrange nodes in a top-down tree layout starting from the Start node. Orphaned (unconnected) nodes are placed below the tree.
Example: Simple Fetch Quest
Start --> Objective ("Collect 5 herbs", targetCount=5)
--> Reward (xp, amount=200)
--> End (completed)
Example: Branching Quest
Start --> Objective ("Talk to the merchant")
--> Branch (conditionType=hasItem, key="gold", operator=">=", value="100")
True --> Reward (item, itemId="sword") --> End (completed)
False --> Objective ("Earn more gold") --> Reward (item, itemId="sword") --> End (completed)
Behavior Tree Editor
The Behavior Tree (BT) editor provides a visual tool for designing AI logic
as hierarchical trees of tasks, conditions, and decorators. Open it from
View > Tools > Behavior Tree, or select an entity with
a BehaviorTreeComponent and click Open Editor
in the Inspector.
Node Types
The BT system provides 20 node types in 4 categories, each color-coded in the editor:
Composite Nodes (Blue)
| Node | Description |
|---|---|
| Sequence | Runs children left-to-right. Fails on first failure. Succeeds if all children succeed. |
| Selector | Runs children left-to-right. Succeeds on first success. Fails if all children fail. |
| Parallel | Runs all children simultaneously. Configurable success/failure policy. |
| RandomSelector | Picks a random child to run. |
| RandomSequence | Runs all children in random order. |
Decorator Nodes (Purple)
| Node | Description |
|---|---|
| Inverter | Flips the child’s success/failure result. |
| Repeater | Repeats the child N times (or indefinitely if N = 0). |
| RepeatUntilFail | Repeats the child until it returns failure. |
| Succeeder | Always returns success regardless of the child’s result. |
| Cooldown | Prevents the child from running again for a configurable time duration. |
| TimeLimit | Fails the child if it runs longer than a specified time limit. |
Action Nodes (Green)
| Node | Description |
|---|---|
| MoveTo | Moves the entity toward a target position using navmesh pathfinding when available. |
| Wait | Waits for a specified duration in seconds. |
| PlayAnimation | Triggers an animation clip on the entity’s AnimatorComponent. |
| SetBlackboard | Writes a value to the shared blackboard. |
| Log | Prints a message to the console for debugging. |
Condition Nodes (Orange)
| Node | Description |
|---|---|
| CheckBlackboard | Checks a blackboard value against a condition expression. |
| IsInRange | Checks if a target entity is within a specified distance. |
| HasLineOfSight | Checks for an unobstructed path to the target via raycasting. |
| Custom | User-defined condition with a custom key, evaluated by script logic. |
Blackboard
The blackboard is a key-value store shared across all nodes in a behavior tree. Edit default values in the Blackboard section of the BT editor panel. Keys store strings that are interpreted as floats, booleans, or entity references at runtime.
Use SetBlackboard action nodes or AngelScript bindings to write
values, and CheckBlackboard condition nodes to read and evaluate
them during tree execution.
Play Mode Visualization
During Play mode, the BT editor shows live status for each node with colored indicators:
| Indicator | Meaning |
|---|---|
| Green dot | Node succeeded this tick. |
| Yellow dot | Node is running (in progress). |
| Red dot | Node failed this tick. |
| Grey dot | Node was not reached. |
Auto Layout
Click Auto Layout to arrange the tree in a top-down hierarchy from the root node. The layout algorithm spaces nodes evenly and handles subtree widths so branches do not overlap.
Visual Script Editor
TEGE includes a full Blueprint-style visual scripting system for creating
game logic without writing code. Open it from View > Tools >
Visual Script, or select an entity with a
VisualScriptComponent and click Open Editor in
the Inspector. Right-click on the canvas to add nodes from the categorized
context menu, then connect them by dragging from output pins to input pins.
Node Categories
The visual script system provides 80+ built-in nodes organized into 16+ categories:
| Category | Nodes | Description |
|---|---|---|
| Events | On Start, On Update | Entry points that fire once at initialization or every frame. |
| Flow Control | Branch, Sequence, Delay, For Loop, While Loop, Do Once, Gate, Flip Flop | Control execution flow with conditions, loops, and gates. |
| Variables | Get Variable, Set Variable, Get Self | Read and write named variables on the script’s blackboard. |
| Math | Add, Subtract, Multiply, Divide, Modulo, Power, Sqrt, Abs, Min, Max, Clamp, Lerp, Floor, Ceil, Round, Sin, Cos, Tan, Atan2, Random Float, Random Int, Negate | Arithmetic and trigonometric operations. |
| Logic | Greater Than, Less Than, Equal, Not Equal, Greater or Equal, Less or Equal, Not, And, Or, Nand, Xor | Boolean comparison and logic gate operations. |
| Transform | Get/Set Position, Get/Set Rotation, Get/Set Scale, Translate, Rotate, Look At | Manipulate entity transforms in world or local space. |
| Vector | Make Vector3, Break Vector3, Vector Length, Normalize, Dot Product, Cross Product, Distance, Lerp Vector | 3D vector construction, decomposition, and math. |
| Entity | Find Entity, Destroy Entity, Spawn Entity, Is Valid, Get Name, Has Component | Entity lifecycle management and queries. |
| Physics | Add Force, Add Impulse, Set/Get Velocity, Set Gravity Scale, Raycast, Sphere Check, Box Check | Physics simulation, forces, and spatial queries. |
| Health | Get Health, Set Health, Damage | Health and damage system integration. |
| Collision | On Collision Enter/Exit, On Trigger Enter/Exit | Collision and trigger event handlers. |
| Audio | Play Audio, Stop Audio, Is Audio Playing, Set Audio Volume, Wait For Audio | Sound playback control and synchronization. |
| Animation | Play Animation, Set/Get Animation Speed, Wait For Animation | Skeletal animation playback control. |
| Debug | Print String, Print Warning, Print Error | Console output for runtime debugging. |
| Functions | Function Entry, Function Return, Call Function | Reusable subgraph functions with input/output pins. |
| Script | Call Script | Call AngelScript functions from visual scripts. |
| Gameplay | Save To Slot, Load From Slot, Delete Slot, Checkpoint, Meta Set/Get Float, Weather Set/Get, Quest Start/Complete/Query, Cinematic Play/Stop, Particle Play/Stop/Burst, Destructible Damage, Prefab Instantiate, UI Set/Clear Focus, Localization Get | Save system, weather, quests, cinematics, particles, destructibles, prefabs, UI focus, and localization. |
| Physics 2D | Raycast 2D, Overlap Circle 2D, Add Force 2D, Set Velocity 2D, Set Gravity 2D | 2D physics queries, forces, and gravity control. |
| Networking | Host Game, Join Game, Disconnect, Is Connected, Get Player Count, Call RPC | LAN multiplayer session management and remote procedure calls. |
Debugger
The visual script debugger helps you step through execution in Play mode:
| Feature | Description |
|---|---|
| Breakpoints | Click the left margin of any node to toggle a breakpoint (red dot). Execution pauses when a breakpoint is hit. |
| Conditional Breakpoints | Press Shift + F9 on a node to set a condition expression and/or hit count threshold. |
| Step Through | When paused, use Step Over, Step Into, and Step Out to advance execution one node at a time. |
| Watch Window | View variable values in real-time while paused at a breakpoint. |
| Call Stack | See the current execution path through function calls (maximum depth: 32). |
| Execution Timeline | Profiler view showing which nodes executed each frame and their duration. |
Subgraph Functions
Create reusable logic blocks as functions:
- Use the Functions panel to create a new function with a name.
- The function gets a Function Entry node (with configurable input pins) and one or more Function Return nodes.
- Call the function from any graph using a Call Function node.
- Functions support up to 32 levels of nested calls.
AngelScript Interop
Visual scripts can call AngelScript functions via the Call Script node, and AngelScript can trigger visual script execution through these bound functions:
// Trigger a named event on an entity's visual script
VisualScript_SendEvent(entity, eventName);
// Set a variable on the script's blackboard
VisualScript_SetVariable(entity, name, value);
// Read a variable from the script's blackboard
VisualScript_GetVariable(entity, name);
Dialogue Editor
TEGE includes a visual dialogue tree editor for authoring RPG-style
conversations with typewriter text, character portraits, and branching
choices. Add a DialogueComponent to any entity for dialogue
data, and optionally attach a DialogueBoxComponent alongside a
UICanvasComponent to automatically create a styled dialogue box
overlay. Open the editor from View > Tools > Dialogue
Editor.
Node Types
The dialogue tree system provides 7 node types for authoring branching conversations:
| Node Type | Description |
|---|---|
| Say | NPC speaks a line of dialogue. Displays with typewriter effect and optional character portrait. |
| Choice | Player chooses from a list of options (up to 6 choices). Each choice links to a different branch. |
| Condition | Branch the conversation based on game state (e.g., inventory, quest progress, variables). |
| SetVariable | Set a dialogue variable for tracking conversation state (e.g., askedAboutQuest = true). |
| Event | Fire a game event via the EntityEventBus for script integration. |
| Jump | Jump to another node in the tree, enabling loops and shared branches. |
| End | End the conversation. The dialogue box closes and control returns to the player. |
DialogueBoxComponent
Attach a DialogueBoxComponent alongside the
DialogueComponent to get automatic UI rendering:
- Speaker name label with configurable font size and color.
- Text display with typewriter effect and configurable character delay.
- Character portrait image with adjustable size.
- Choice buttons (up to 6) with highlight colors.
- Continue indicator with configurable blink rate and text.
The inspector groups settings into collapsible sections: Box Layout, Text Style, Portrait, Choices, and Continue Indicator.
Animation Timeline
The timeline system allows keyframing entity properties over time for
cutscenes, animated UI elements, environmental effects, and any other
time-based behavior. Add a TimelineComponent to any entity,
configure tracks with keyframes, and control playback from the editor or
scripts.
Track Types
| Track Type | Description |
|---|---|
| Property | Animate any component field over time: position, rotation, scale, material properties, light intensity, and more. Keyframes are interpolated between values. |
| Event | Fire callbacks at specific timestamps. Useful for triggering sound effects, particle bursts, or script functions at precise moments. |
| Animation | Play or blend skeletal animations. Control which animation clip is active and how it transitions. |
Playback Controls
| Control | Description |
|---|---|
| Play / Pause / Stop | Standard playback controls. Stop resets the timeline to the beginning. |
| Loop | Restart playback from the beginning when reaching the end. |
| Ping-Pong | Play forward, then play backward, repeating indefinitely. |
| Speed | Playback rate multiplier. 1.0 = normal speed, 0.5 = half speed, 2.0 = double speed. |
Easing Functions
Each keyframe supports one of 5 easing functions that control the interpolation curve between values:
| Function | Description |
|---|---|
| Linear | Constant rate of change. No acceleration or deceleration. |
| EaseIn | Starts slow and accelerates toward the target value. |
| EaseOut | Starts fast and decelerates toward the target value. |
| EaseInOut | Starts slow, speeds up in the middle, and slows down at the end. |
| Step | Jumps instantly to the target value with no interpolation. |
Procedural Generation
TEGE includes a comprehensive procedural generation system with 9+ algorithms, a node-based pipeline editor with 38 node types, and a room prefab assembler. Open the Procedural Generation panel from View > Tools > Procedural. The panel provides an algorithm dropdown, parameter sliders, seed input, a 256×256 ImGui canvas preview, and an “Apply to Tilemap” button.
Room Prefab System
Rooms are defined as JSON files with the following properties:
- Size — room dimensions in grid units.
- Connection points — doorways and openings where rooms can snap together, with directional constraints.
- Tags — categorization labels such as
"start","boss","corridor", or"treasure". - Weight — probability weight for random selection (higher weight = more likely to be chosen).
Generation Parameters
| Parameter | Description |
|---|---|
| Seed | Random seed for reproducible generation. The same seed with the same parameters always produces identical output. |
| Room Count | Target number of rooms to generate. |
| Room Prefab Set | Which set of JSON room definitions to use as the building blocks. |
Algorithms
The engine ships with 9 standalone procedural generation algorithms, all accessible from the editor panel, AngelScript bindings, and visual script nodes:
| Algorithm | Description |
|---|---|
| Cellular Automata | Cave generation using Moore neighborhood birth/death rules. Configurable birth and survival thresholds. |
| Random Walker | Dungeon carving with directional bias and turn chance parameters. |
| BSP (Binary Space Partition) | Room-corridor dungeon generation via recursive space splitting. Produces rectangular rooms connected by hallways. |
| Diamond-Square | Heightmap terrain generation using midpoint displacement with configurable roughness. |
| Fractal Terrain | fBm octave stacking with ridged multifractal. Includes hydraulic erosion via droplet simulation and thermal erosion via talus angle. |
| L-System | String rewriting with turtle graphics interpretation (F/+/-/[/] commands). Advanced 3D turtle with yaw/pitch/roll, stochastic production rules, and branch radius decay for vegetation generation. |
| Wave Function Collapse (WFC) | Tile-based generation with adjacency constraints, entropy-based collapse, and backtracking for guaranteed solvability. |
| Voronoi | Region generation using Euclidean, Manhattan, or Chebyshev distance metrics. Outputs a region ID grid for biome or territory assignment. |
| Grammar | Shape grammars for procedural building generation with weighted rule selection. |
Node-Based Pipeline Editor
The procedural generation pipeline editor provides 38 node types for composing complex generation workflows visually. Nodes can be chained together to combine algorithms — for example, generating a BSP dungeon layout, applying cellular automata for cave rooms, using Voronoi for biome assignment, and finishing with L-system vegetation placement.
Simulation-Driven Generation
Beyond traditional algorithms, TEGE supports advanced simulation-based generation techniques:
- Reaction-Diffusion — Gray-Scott model with 9 presets (Mitosis Spots, Coral Growth, Fingerprints, Leopard, Labyrinth, Worm Holes, Bubble Packing, Spirals, Custom). Outputs RGBA8 textures and heightmaps.
- Cellular Automata Geometry — 7 CA rules (Game of Life, HighLife, Day and Night, Seeds, Brian’s Brain, Rule 110, Diamoeba) with 3 mesh output modes: Voxels (greedy face culling), Marching Cubes, and Point Cloud.
- Physarum Slime Mold — 50K+ agent simulation with trail map diffusion/decay, 5 presets (Classic Slime, Branching Network, Dense Web, Tendrils, Pulsating), and bake-to-texture export.
- Fluid-Terrain Coupling — fluid simulation density/velocity grids drive terrain heightmap modification via erosion and accumulation modes.
Forest Generation
The Procedural panel includes a one-click forest generation tool with 4 forest presets:
- Mixed — balanced variety of tree types.
- Dense Conifer — tightly packed evergreen forests.
- Deciduous Park — spaced broadleaf trees with open areas.
- Sparse Savanna — widely distributed trees with grass.
Each preset creates TreeVolumeComponent,
ShrubVolumeComponent, and GrassVolumeComponent
entities with appropriate density settings. Area radius and per-type density
sliders are configurable.
Scripting
AngelScript programming and visual scripting.
AngelScript Basics
TEGE uses AngelScript as its primary scripting language. Scripts are attached
to entities via the ScriptComponent and receive lifecycle callbacks similar to
game-object behaviours in other engines. The scripting layer is sandboxed with a one-million
instruction limit per execution slice, ensuring a rogue script cannot freeze the editor or
the player runtime.
ScriptComponent
Each entity can have multiple scripts attached. Every script attachment specifies four fields:
| Field | Type | Description |
|---|---|---|
scriptPath |
string | Relative path to the .as file, e.g. scripts/PlayerController.as. |
className |
string | The AngelScript class to instantiate from that file. |
properties |
map | Key-value pairs of exposed properties editable in the Inspector. |
enabled |
bool | Toggle the script on or off without removing it. |
Because an entity can carry multiple scripts, you can compose behaviours: one script for movement, another for combat, a third for audio cues, and so on.
TegeBehavior Base Class
Every gameplay script inherits from the TegeBehavior base class. This base class
provides the self handle (the entity ID the script is attached to) and exposes
all lifecycle callbacks. You do not need to implement every callback; only override the ones
your script requires.
class MyScript : TegeBehavior {
void OnUpdate(float dt) {
// your per-frame logic here
}
}
Lifecycle Callbacks
| Callback | When It Fires |
|---|---|
void OnCreate() |
When the script instance is first created (on entering play mode). |
void OnStart() |
Once, on the first frame after creation. |
void OnUpdate(float dt) |
Every frame, with the variable delta time. |
void OnFixedUpdate(float dt) |
At a fixed timestep (60 Hz by default). Use for physics-driven logic. |
void OnLateUpdate(float dt) |
After all OnUpdate calls have completed. Ideal for camera follow logic. |
void OnDestroy() |
When the entity is destroyed or play mode stops. |
void OnEnable() |
When the script is enabled (including the first enable after creation). |
void OnDisable() |
When the script is disabled. |
void OnCollisionEnter(Entity other) |
When a physics collision begins. |
void OnCollisionStay(Entity other) |
While a physics collision persists each frame. |
void OnCollisionExit(Entity other) |
When a physics collision ends. |
void OnTriggerEnter(Entity other) |
When entering a trigger (sensor) zone. |
void OnTriggerExit(Entity other) |
When leaving a trigger (sensor) zone. |
Execution Order Per Frame
Understanding the execution order is critical for avoiding timing bugs. The script system processes all scripts in the following deterministic order every frame:
- Hot Reload Check — Every 30 frames, the engine polls the script directory for modified
.asfiles. Changed scripts are recompiled and running instances are updated without stopping play mode. - New Scripts — Any scripts added since the last frame run
CreateInstance→OnCreate→OnEnable. - Unstarted Scripts — Scripts that have been created but have not yet received their first frame call
OnStart. - Fixed Timestep Loop — Zero or more calls to
OnFixedUpdate(fixedDt)depending on accumulated time. - OnUpdate — Every active script receives
OnUpdate(deltaTime). - Coroutine Scheduler — Pending coroutines are resumed based on their yield condition.
- OnLateUpdate — Every active script receives
OnLateUpdate(deltaTime).
Script Properties
Properties declared as public fields on a TegeBehavior subclass are automatically
exposed in the editor Inspector. The following types are supported:
| Type | Inspector Widget | Notes |
|---|---|---|
Int |
Integer drag / input | Supports range hints via metadata. |
Float |
Float drag / input | Supports range hints and step size. |
Bool |
Checkbox | — |
String |
Text field | — |
Vector2 |
XY float fields | — |
Vector3 |
XYZ float fields | — |
Vector4 |
XYZW float fields | Can also be used for colour with alpha. |
Entity |
Entity picker / drag-drop | Stores the target entity ID. |
Enum |
Dropdown | AngelScript enums are displayed as named options. |
Properties can have range hints and tooltips defined in metadata. These are read by the Inspector to configure drag speed, min/max bounds, and tooltip hover text.
Hot Reload
During play mode, the script engine polls the script directory for file changes every
30 frames. When a modified .as file is detected, the engine
automatically recompiles it and updates all running instances without stopping play mode.
This enables a rapid iteration workflow: edit a script in your external editor, save it,
and see the changes reflected in the running game within half a second.
Hot reload preserves exposed property values. If you change a property's default in the script, instances that have been customised in the Inspector will keep their Inspector values. Only new instances pick up the new defaults.
Example Script
class PlayerBehavior : TegeBehavior {
float speed = 5.0;
void OnUpdate(float dt) {
Vector3 pos = Entity_GetPosition(self);
if (Input_GetKey(Key_W))
pos.z -= speed * dt;
if (Input_GetKey(Key_S))
pos.z += speed * dt;
if (Input_GetKey(Key_A))
pos.x -= speed * dt;
if (Input_GetKey(Key_D))
pos.x += speed * dt;
Entity_SetPosition(self, pos);
}
}
This script moves the entity in the XZ plane using WASD keys. The speed property
appears in the Inspector and can be tweaked without editing the script file.
Complete API Reference
TEGE exposes approximately 686 bindings to AngelScript, covering every major
engine subsystem. This section organises them by category. Function signatures use AngelScript
syntax; uint64 parameters represent entity IDs (the self handle is
always available inside a TegeBehavior script).
In the tables below, related overloads (e.g. get/set pairs, masked variants) are grouped on a single row to keep the reference compact. All functions listed are globally accessible from any script.
Math Types
Four value types are registered for 2D, 3D, and 4D math. They support standard arithmetic
operators (+, -, *, /) and unary negation.
| Type | Properties / Methods |
|---|---|
Vector2 |
x, y, Length(), Normalized(), Dot(Vector2). Operators: + - * /, unary -. |
Vector3 |
x, y, z, Length(), Normalized(), Dot(Vector3), Cross(Vector3). Operators: + - * /, unary -. |
Vector4 |
x, y, z, w. Useful for colours with alpha or homogeneous coordinates. |
Quaternion |
x, y, z, w, Rotate(Vector3), Normalized(), Inverse(), ToEuler(). Operators: * (composition).Statics: Quaternion_Identity(), Quaternion_FromEuler(Vector3), Quaternion_Slerp(q1, q2, t).
|
Global Math Functions
| Function | Description |
|---|---|
float Abs(float) | Absolute value. |
float Sin(float), Cos(float), Tan(float) | Trigonometric functions (radians). |
float Asin(float), Acos(float), Atan2(float y, float x) | Inverse trigonometry. |
float Sqrt(float) | Square root. |
float Pow(float base, float exp) | Exponentiation. |
float Floor(float), Ceil(float), Round(float) | Rounding functions. |
float Min(float, float), Max(float, float) | Minimum and maximum. |
float Clamp(float value, float min, float max) | Clamp a value to a range. |
float Lerp(float a, float b, float t) | Linear interpolation. |
float MoveTowards(float current, float target, float maxDelta) | Move towards a target value by at most maxDelta. |
float Sign(float) | Returns -1, 0, or 1. |
float Random() | Random float in [0, 1]. |
float RandomRange(float min, float max) | Random float in [min, max]. |
int RandomInt(int min, int max) | Random integer in [min, max]. |
float Radians(float deg), Degrees(float rad) | Angle conversion. |
float PI() | Returns the constant pi (3.14159...). |
Entity & Transform
| Function | Description |
|---|---|
Vector3 Entity_GetPosition(uint64), Entity_SetPosition(uint64, Vector3) | Get or set world position. |
Vector3 Entity_GetRotation(uint64), Entity_SetRotation(uint64, Vector3) | Get or set rotation in degrees (Euler angles). |
Vector3 Entity_GetScale(uint64), Entity_SetScale(uint64, Vector3) | Get or set scale. |
string Entity_GetName(uint64) | Get the entity's display name. |
Entity_SetVisible(uint64, bool), bool Entity_IsVisible(uint64) | Toggle entity visibility. |
EntityHandle class — object wrapper around an entity ID:IsValid(), GetID(), GetPosition() / SetPosition(),
GetRotation() / SetRotation(), GetScale() / SetScale(),
GetName(), HasTag(string).
|
|
TransformProxy — convenience accessors:position, rotation, scale (read/write),
forward, right, up (read-only directional vectors).
|
|
Scene Management
| Function | Description |
|---|---|
uint64 Scene_FindEntity(string name) | Find an entity by name. Returns 0 if not found. |
uint64 Scene_FindEntityByTag(string tag) | Find the first entity with a given tag. |
Scene_DestroyEntity(uint64) | Queue an entity for destruction (deferred to next frame). |
uint64 Scene_Instantiate(), Scene_InstantiateNamed(string), Scene_InstantiateAt(Vector3) | Create a new entity, optionally with a name or position. |
bool Scene_IsValid(uint64) | Check if an entity ID is still valid. |
int Scene_GetEntityCount() | Total number of entities in the current scene. |
Scene_GetEntityName(uint64), Scene_SetEntityName(uint64, string) | Read or change an entity's name. |
Scene_AddTag(uint64, string), Scene_RemoveTag(uint64, string), Scene_HasTag(uint64, string) | Tag management per entity. |
Scene_LoadScene(string) | Load a scene by name (triggers a full scene transition). |
string Scene_GetCurrentScene() | Get the name of the currently loaded scene. |
Time
| Function | Description |
|---|---|
float Time_GetDeltaTime() | Time in seconds since the last frame. |
float Time_GetFixedDeltaTime() | Fixed timestep interval (default 1/60). |
float Time_GetTime() | Total elapsed time since play mode started. |
float Time_GetTimeScale(), Time_SetTimeScale(float) | Get or set the global time scale (1.0 = normal, 0.0 = paused). |
uint Time_GetFrameCount() | Number of frames rendered since play mode started. |
Debug
| Function | Description |
|---|---|
Debug_Log(string) | Print an info-level message to the console. |
Debug_LogWarning(string) | Print a warning-level message. |
Debug_LogError(string) | Print an error-level message. |
Input
Keyboard
| Function | Description |
|---|---|
bool Input_GetKey(int keyCode) | True while the key is held down. |
bool Input_GetKeyDown(int keyCode) | True on the frame the key is first pressed. |
bool Input_GetKeyUp(int keyCode) | True on the frame the key is released. |
Key constants: Key_A through Key_Z, Key_Num0–Key_Num9,
Key_F1–Key_F12, Key_Space, Key_Escape,
Key_Enter, Key_Tab, Key_Backspace, arrow keys
(Key_Up, Key_Down, Key_Left, Key_Right),
Key_Shift, Key_Control, Key_Alt.
Mouse
| Function | Description |
|---|---|
bool Input_GetMouseButton(int btn), Input_GetMouseButtonDown(int), Input_GetMouseButtonUp(int) | Mouse button state. MouseBtn: Left=0, Right=1, Middle=2. |
Vector2 Input_GetMousePosition() | Current mouse position in screen coordinates. |
Vector2 Input_GetMouseDelta() | Mouse movement since last frame. |
float Input_GetScrollDelta() | Mouse scroll wheel delta. |
bool Input_IsMouseCaptured(), Input_SetMouseCaptured(bool) | Lock/unlock the mouse cursor for first-person controls. |
Gamepad
| Function | Description |
|---|---|
bool Input_IsGamepadConnected(int index) | Check if a gamepad is connected at the given index. |
bool Input_GetGamepadButton(int pad, int btn), Input_GetGamepadButtonDown(int, int) | Gamepad button state. GamepadBtn: A, B, X, Y, bumpers, back, start, D-pad. |
float Input_GetGamepadAxis(int pad, int axis) | Axis value (-1 to 1). GamepadAx: LeftX, LeftY, RightX, RightY, triggers. |
Vector2 Input_GetGamepadLeftStick(int), Input_GetGamepadRightStick(int) | Combined stick vector. |
float Input_GetGamepadLeftTrigger(int), Input_GetGamepadRightTrigger(int) | Trigger values (0 to 1). |
Physics (3D)
| Function | Description |
|---|---|
bool Physics_Raycast(Vector3 origin, Vector3 dir, float maxDist) | Cast a ray and return true on hit. |
bool Physics_RaycastHit(Vector3 origin, Vector3 dir, float maxDist, RaycastHit &out hit) | Cast a ray and populate a RaycastHit struct (point, normal, distance, entity). |
bool Physics_CheckSphere(Vector3 center, float radius) | Check if any collider overlaps a sphere. |
bool Physics_CheckBox(Vector3 center, Vector3 halfExtents) | Check if any collider overlaps a box. |
Masked overloads — all four queries accept an additional uint layerMask parameter for collision group filtering. | |
Physics_AddForce(uint64, Vector3) | Apply a continuous force to a rigidbody. |
Physics_AddImpulse(uint64, Vector3) | Apply an instant impulse. |
Physics_SetVelocity(uint64, Vector3), Vector3 Physics_GetVelocity(uint64) | Directly set or read the linear velocity. |
Physics_SetGravityScale(uint64, float) | Per-body gravity multiplier. |
Physics 2D
| Function | Description |
|---|---|
bool Physics2D_Raycast(float oX, oY, float dX, dY, float maxDist) | Cast a 2D ray. Returns true on hit. |
bool Physics2D_RaycastMask(..., uint mask) | 2D raycast with collision mask filter. |
bool Physics2D_RaycastHit(..., Vector2 &out point, Vector2 &out normal, float &out dist, uint64 &out entity) | Full 2D raycast returning hit information. |
bool Physics2D_RaycastHitMask(..., uint mask, ...) | Full 2D raycast with collision mask. |
uint64 Physics2D_OverlapCircle(float cx, cy, float radius) | Check for any body in a circle. Returns entity ID or 0. |
uint64 Physics2D_OverlapCircleMask(..., uint mask) | Circle overlap with collision mask. |
uint64 Physics2D_OverlapBox(float cx, cy, float hw, hh) | Check for any body in an AABB. Returns entity ID or 0. |
uint64 Physics2D_OverlapBoxMask(..., uint mask) | Box overlap with collision mask. |
Physics2D_AddForce(uint64, float fx, fy) | Apply a continuous force to a 2D rigidbody. |
Physics2D_AddImpulse(uint64, float ix, iy) | Apply an instant impulse. |
Physics2D_SetVelocity(uint64, float vx, vy), Vector2 Physics2D_GetVelocity(uint64) | Set or get 2D linear velocity. |
Physics2D_SetGravity(float gx, gy), Vector2 Physics2D_GetGravity() | Set or get global 2D gravity. |
Physics2D_SetGravityScale(uint64, float) | Per-body gravity multiplier. |
Audio
| Function | Description |
|---|---|
Audio_Play(uint64) | Play the audio source on an entity. |
Audio_PlayAtPosition(string path, Vector3 pos) | Play a sound file at a world position (one-shot, 3D spatialized). |
Audio_Stop(uint64) | Stop an entity's audio source. |
Audio_StopAll() | Stop all playing audio. |
Audio_SetVolume(uint64, float), Audio_SetPitch(uint64, float) | Set volume or pitch on an entity's audio source. |
bool Audio_IsPlaying(uint64) | Check if an entity's audio source is currently playing. |
Audio_SetMasterVolume(float), float Audio_GetMasterVolume() | Global master volume control. |
Audio_SetChannelVolume(uint8 ch, float), float Audio_GetChannelVolume(uint8) | Per-channel volume. Channels: SFX=0, Music=1, UI=2, Voice=3. |
Audio_StopChannel(uint8) | Stop all audio on a specific channel. |
Component Access
Health
| Function | Description |
|---|---|
float Health_Get(uint64), float Health_GetMax(uint64) | Current and maximum health. |
Health_SetCurrent(uint64, float) | Set the current health value directly. |
Health_Damage(uint64, float amount) | Apply damage (subtracts from current health). |
Material (PBR + SSS)
| Function | Description |
|---|---|
Material_SetBaseColor(uint64, Vector3), Vector3 Material_GetBaseColor(uint64) | Albedo colour (linear RGB). |
Material_SetMetallic(uint64, float), Material_SetRoughness(uint64, float) | PBR metallic and roughness values (0–1). |
Material_SetTransmission / GetTransmission(uint64, float) | Transmission factor for translucent materials. |
Material_SetIOR / GetIOR(uint64, float) | Index of refraction. |
Material_SetThickness / GetThickness(uint64, float) | Thickness for thin-surface transmission. |
Material_SetSSSIntensity / GetSSSIntensity(uint64, float) | Subsurface scattering intensity. |
Material_SetSSSRadius / GetSSSRadius(uint64, float) | Subsurface scattering radius. |
Material_SetSSSColor / GetSSSColor(uint64, Vector3) | Subsurface scattering colour. |
Light, Camera, Audio, Animation, Controller
| Function | Description |
|---|---|
Light_SetColor(uint64, Vector3), Light_SetIntensity(uint64, float) | Light colour and brightness. |
Camera_SetFOV(uint64, float), float Camera_GetFOV(uint64) | Camera field of view in degrees. |
AudioSource_Play(uint64), AudioSource_Stop(uint64) | Direct control of an AudioSource component. |
AudioSource_SetClip(uint64, string), AudioSource_SetVolume(uint64, float) | Change the clip or volume on an audio source. |
Animator_Play(uint64, string animName) | Play a named animation clip. |
Animator_SetSpeed(uint64, float) | Animation playback speed multiplier. |
Controller_SetMoveSpeed(uint64, float), Vector3 Controller_GetVelocity(uint64) | Works with all 5 controller types. |
Camera 2D
| Function | Description |
|---|---|
Camera2D_Shake(uint64, float intensity, float duration) | Trigger a camera shake effect. |
Camera2D_GetZoom / SetZoom(uint64, float) | Camera zoom level. |
Camera2D_AddTarget / RemoveTarget(uint64 camera, uint64 target) | Multi-target follow (split-screen friendly). |
Camera2D_ClearTargets(uint64) | Remove all follow targets. |
Camera2D_SetDeadZone(uint64, float w, float h) | Dead zone size before camera begins to follow. |
Camera2D_SetLookAhead(uint64, float distance, float smoothing) | Predictive look-ahead based on movement direction. |
Camera2D_SetFollowTarget / GetFollowTarget(uint64, uint64) | Single-target follow shortcut. |
State Machine
| Function | Description |
|---|---|
SM_AddState(uint64, string) | Register a named state. |
SM_AddTransition(uint64, string from, string to) | Add a transition between states. |
SM_SetState / GetCurrentState / GetPreviousState(uint64) | Force or query the current/previous state. |
float SM_GetStateTime(uint64) | Time spent in the current state. |
SM_SendTrigger(uint64, string) | Fire a named trigger to evaluate transitions. |
SM_SetBool / GetBool(uint64, string, bool) | Boolean parameter for transition conditions. |
SM_SetFloat / GetFloat(uint64, string, float) | Float parameter for transition conditions. |
SM_SetInt / GetInt(uint64, string, int) | Integer parameter for transition conditions. |
SM_HasState(uint64, string) | Check if a state exists. |
SM_SetOnEnter / SetOnUpdate / SetOnExit(uint64, string state, string func) | Bind script callbacks to state lifecycle. |
SM_GetOnEnter / GetOnUpdate / GetOnExit(uint64, string state) | Query currently bound callbacks. |
HasComponent Checks
Boolean existence checks for common component types:
HasComponent_Health(uint64),
HasComponent_Light(uint64),
HasComponent_Camera(uint64),
HasComponent_Material(uint64),
HasComponent_AudioSource(uint64),
HasComponent_Rigidbody(uint64),
HasComponent_BoxCollider(uint64),
HasComponent_Animator(uint64).
Tweening
| Function | Description |
|---|---|
uint Tween_Position(uint64, Vector3 target, float duration, int easing) | Animate position to target. Returns tween index. |
uint Tween_Rotation(uint64, Vector3 target, float, int) | Animate rotation (Euler degrees). |
uint Tween_Scale(uint64, Vector3 target, float, int) | Animate scale. |
uint Tween_Color(uint64, Vector3 target, float, int) | Animate material base colour. |
uint Tween_Opacity(uint64, float target, float duration, int easing) | Animate opacity. |
uint Tween_Float(uint64, float start, float end, float duration, int easing) | Generic float interpolation (no component write). Read with Tween_GetValue. |
Tween_SetOnComplete(uint64, uint tweenIndex, string funcName) | Set a callback function to fire when the tween finishes. |
Tween_SetDelay(uint64, uint tweenIndex, float delay) | Delay before the tween starts. |
float Tween_GetValue(uint64, uint tweenIndex) | Read the current interpolated value of a float tween. |
Tween_StopAll(uint64) | Stop and clear all active tweens on an entity. |
Coroutines & Events
| Function | Description |
|---|---|
StartCoroutine(string funcName) | Begin executing a coroutine function by name. |
YieldSeconds(float) | Pause coroutine for a time delay. |
YieldFrames(uint) | Pause coroutine for a number of frames. |
YieldEndOfFrame() | Resume at the end of the current frame. |
| Function | Description |
|---|---|
EventData class — key-value payload for events:SetFloat / GetFloat(string key, float),
SetInt / GetInt(string key, int),
SetString / GetString(string key, string),
SetEntity / GetEntity(string key, uint64).
|
|
uint Events_Listen(string eventName, EventCallback@ cb) | Register a listener for named events. Returns listener ID. |
Events_Send(string eventName, EventData@ data) | Dispatch an event to all listeners for that name. |
Events_Broadcast(EventData@ data) | Dispatch to all listeners regardless of event name. |
Noise
Procedural noise functions for terrain generation, visual effects, and randomisation. Value, Perlin, and Simplex noise return values in [-1, 1]. Worley noise returns [0, 1]. FBM and Billow return [-1, 1]. Ridged noise returns [0, ~2].
| Function | Description |
|---|---|
float Noise_Value2D(x, y, seed), Noise_Value3D(x, y, z, seed) | Value noise (blocky, fast). |
float Noise_Perlin2D(x, y, seed), Noise_Perlin3D(x, y, z, seed) | Classic Perlin noise. |
float Noise_Simplex2D(x, y, seed), Noise_Simplex3D(x, y, z, seed) | Simplex noise (less directional bias). |
float Noise_Worley2D(x, y, seed), Noise_Worley3D(x, y, z, seed) | Worley (cellular) noise. |
float Noise_FBM2D(x, y, octaves, lacunarity, persistence, frequency, seed) | Fractal Brownian Motion (2D). Also available as FBM3D. |
float Noise_Ridged2D(...), Noise_Ridged3D(...) | Ridged multi-fractal noise (mountain ridges). |
float Noise_Billow2D(...), Noise_Billow3D(...) | Billow noise (cloud-like, puffy). |
float Noise_DomainWarp2D(x, y, warpStrength, frequency, seed) | Domain warping (2D). Also available as DomainWarp3D. |
Rendering
| Function | Description |
|---|---|
Render_SetShadowsEnabled(bool), bool Render_IsShadowsEnabled() | Toggle shadow rendering. |
Render_SetShadowDistance / GetShadowDistance(float) | Maximum shadow draw distance. |
Render_SetShadowStrength / GetShadowStrength(float) | Shadow darkness (0 = invisible, 1 = full black). |
Render_SetAmbientIntensity / GetAmbientIntensity(float) | Global ambient light intensity. |
Render_SetAmbientColor / GetAmbientColor(Vector3) | Ambient light colour. |
Render_SetFogDensity / GetFogDensity(float) | Exponential fog density. |
Render_SetFogColor / GetFogColor(Vector3) | Fog colour. |
Render_SetFogStart / GetFogStart(float), Render_SetFogEnd / GetFogEnd(float) | Linear fog start and end distances. |
Render_SetFogHeightFalloff / GetFogHeightFalloff(float) | Height-based fog falloff. |
Render_SetSnowIntensity / GetSnowIntensity(float) | Snow accumulation intensity. |
Render_SetRainActive / IsRainActive(bool) | Toggle screen rain effect. |
Render_SetWorldCurvature / GetWorldCurvature(float) | World curvature effect strength (Animal Crossing style). |
Render_SetWireframeEnabled / IsWireframeEnabled(bool) | Toggle wireframe rendering mode. |
Post-Processing
All PostProcess_ functions return sensible defaults if post-processing is
unavailable (e.g. in a minimal Player build).
Tone Mapping & Exposure
| Function | Description |
|---|---|
PostProcess_SetToneMapping / GetToneMapping(int) | Tone mapping operator (enum). |
PostProcess_SetExposure / GetExposure(float) | Exposure adjustment. |
PostProcess_SetGamma / GetGamma(float) | Gamma correction. |
Bloom
| Function | Description |
|---|---|
PostProcess_SetBloomEnabled / IsBloomEnabled(bool) | Toggle bloom effect. |
PostProcess_SetBloomThreshold / GetBloomThreshold(float) | Brightness threshold above which pixels bloom. |
PostProcess_SetBloomIntensity / GetBloomIntensity(float) | Bloom brightness multiplier. |
Vignette
| Function | Description |
|---|---|
PostProcess_SetVignetteEnabled / IsVignetteEnabled(bool) | Toggle vignette darkening at screen edges. |
PostProcess_SetVignetteIntensity / GetVignetteIntensity(float) | How strong the vignette is. |
PostProcess_SetVignetteSmoothness / GetVignetteSmoothness(float) | Falloff softness. |
Chromatic Aberration
| Function | Description |
|---|---|
PostProcess_SetChromaticAberrationEnabled / IsChromaticAberrationEnabled(bool) | Toggle chromatic aberration. |
PostProcess_SetChromaticAberrationIntensity / GetChromaticAberrationIntensity(float) | Aberration strength. |
Color Grading
| Function | Description |
|---|---|
PostProcess_SetColorFilter / GetColorFilter(Vector3) | Multiplicative colour tint. |
PostProcess_SetSaturation / GetSaturation(float) | Colour saturation (0 = grayscale). |
PostProcess_SetContrast / GetContrast(float) | Image contrast. |
PostProcess_SetBrightness / GetBrightness(float) | Image brightness offset. |
Film Grain & FXAA
| Function | Description |
|---|---|
PostProcess_SetFilmGrainEnabled / IsFilmGrainEnabled(bool) | Toggle film grain noise. |
PostProcess_SetFilmGrainIntensity / GetFilmGrainIntensity(float) | Film grain strength. |
PostProcess_SetFXAAEnabled / IsFXAAEnabled(bool) | Toggle fast approximate anti-aliasing. |
God Rays
| Function | Description |
|---|---|
PostProcess_SetGodRaysEnabled / IsGodRaysEnabled(bool) | Toggle screen-space god rays. |
PostProcess_SetGodRaysIntensity / GetGodRaysIntensity(float) | God rays brightness multiplier. |
PostProcess_SetGodRaysSamples / GetGodRaysSamples(int) | Radial blur sample count (default 64). |
SSAO
| Function | Description |
|---|---|
PostProcess_SetSSAOEnabled / IsSSAOEnabled(bool) | Toggle screen-space ambient occlusion. |
PostProcess_SetSSAORadius / GetSSAORadius(float) | Hemisphere sampling radius (world units). |
PostProcess_SetSSAOIntensity / GetSSAOIntensity(float) | Occlusion intensity multiplier. |
Contact Shadows
| Function | Description |
|---|---|
PostProcess_SetContactShadowsEnabled / IsContactShadowsEnabled(bool) | Toggle contact shadows. |
PostProcess_SetContactShadowsIntensity / GetContactShadowsIntensity(float) | Contact shadow darkness. |
Fake Caustics
| Function | Description |
|---|---|
PostProcess_SetCausticsEnabled / IsCausticsEnabled(bool) | Toggle fake caustics. |
PostProcess_SetCausticsIntensity / GetCausticsIntensity(float) | Caustics brightness. |
PostProcess_SetCausticsWaterY / GetCausticsWaterY(float) | Water surface Y position (caustics render below this). |
Fog Shafts
| Function | Description |
|---|---|
PostProcess_SetFogShaftsEnabled / IsFogShaftsEnabled(bool) | Toggle volumetric fog shafts. |
PostProcess_SetFogShaftsIntensity / GetFogShaftsIntensity(float) | Fog shaft brightness. |
PostProcess_SetFogShaftsMaxDistance / GetFogShaftsMaxDistance(float) | Max ray march distance (world units). |
Dialogue
| Function | Description |
|---|---|
Dialogue_Start(uint64) | Begin a dialogue on an entity with a DialogueTreeComponent. |
Dialogue_Advance(uint64) | Advance to the next dialogue node. |
Dialogue_Choose(uint64, int choiceIndex) | Select a branching choice. |
Dialogue_SetVariable(uint64, string key, string value) | Set a dialogue variable for conditional branches. |
string Dialogue_GetVariable(uint64, string key) | Read a dialogue variable. |
bool Dialogue_IsActive(uint64) | Check if a dialogue is currently in progress. |
string Dialogue_GetCurrentText(uint64) | Get the current dialogue line text. |
string Dialogue_GetCurrentSpeaker(uint64) | Get the current speaker name. |
int Dialogue_GetChoiceCount(uint64) | Number of choices available at the current node. |
string Dialogue_GetChoiceText(uint64, int index) | Text of a specific choice option. |
Save System
Save Slots
| Function | Description |
|---|---|
bool SaveGame_ToSlot(int slot) | Save current game state to slot 0–19. Returns success. |
bool SaveGame_FromSlot(int slot) | Load game state from a slot. Returns success. |
bool SaveGame_DeleteSlot(int slot) | Delete save data in a slot. Returns success. |
SaveGame_Checkpoint() | Create a checkpoint save (writes to next rotating auto-save slot). |
Meta-Progression
Permanent key-value storage that survives across runs and save-slot deletion. Use for unlock flags, achievement counters, and new-game-plus state.
| Function | Description |
|---|---|
Meta_SetFloat(string key, float), float Meta_GetFloat(string key, float fallback) | Float values. |
Meta_SetInt(string key, int), int Meta_GetInt(string key, int fallback) | Integer values. |
Meta_SetBool(string key, bool), bool Meta_GetBool(string key, bool fallback) | Boolean values. |
Meta_SetString(string key, string), string Meta_GetString(string key, string fallback) | String values. |
Meta_Save() | Force-write meta-progression to disk immediately. |
Auto-Save
| Function | Description |
|---|---|
AutoSave_Enable(bool) | Enable or disable timed auto-save. |
AutoSave_SetInterval(float seconds) | Auto-save interval in seconds (default: 300). |
Weather System
| Function | Description |
|---|---|
Weather_Set(int type, float transitionTime = 2.0) | Change weather. Types: 0=Clear, 1=Cloudy, 2=Rain, 3=HeavyRain, 4=Snow, 5=Fog, 6=Storm. |
int Weather_Get() | Current weather type as integer. |
Weather_SetRainIntensity / GetRainIntensity(float) | Rain intensity (0–1). |
Weather_SetSnowIntensity / GetSnowIntensity(float) | Snow intensity (0–1). |
Weather_SetFogDensity / GetFogDensity(float) | Fog density (0–1). |
Weather_SetFogColor(float r, g, b) | Fog colour RGB. |
Weather_SetFogRange(float start, float end) | Fog start/end distances. |
Weather_SetWind(float dirX, dirY, dirZ, float strength) | Wind direction and strength. |
bool Weather_IsLightning() | True if lightning is currently active. |
bool Weather_LightningJustFired() | True for one frame when a bolt triggers (use for SFX timing). |
Weather_SetLightningInterval(float minSec, float maxSec) | Random interval range between lightning bolts. |
Particle System
| Function | Description |
|---|---|
Particle_Play(uint64), Particle_Stop(uint64) | Start or stop a particle emitter. |
bool Particle_IsPlaying(uint64) | Check if an emitter is active. |
Particle_SetEmissionRate / GetEmissionRate(uint64, float) | Particles per second. |
Particle_Burst(uint64, int count) | Emit a burst of particles instantly. |
Particle_SetLifetime(uint64, float) | Particle lifetime in seconds. |
Particle_SetSpeed(uint64, float) | Particle start speed. |
Particle_SetSize(uint64, float start, float end) | Size over lifetime. |
Particle_SetColor(uint64, float sr, sg, sb, float er, eg, eb) | Start and end colour RGB. |
Particle_SetAlpha(uint64, float start, float end) | Alpha fade over lifetime. |
Particle_SetLoop(uint64, bool) | Enable or disable looping. |
Particle_SetGravity(uint64, float gx, gy, gz) | Per-emitter gravity vector. |
Particle_ApplyPreset(uint64, string name) | Apply a named preset: "Fire", "Smoke", "Sparks", "Snow", "Rain", "Magic", "Explosion", "Water Splash", "Blood/Sap", "Lava", "Fountain", "Drip". |
HUD Widgets
| Function | Description |
|---|---|
HUD_SetVisible(uint64, bool), bool HUD_IsVisible(uint64) | Show or hide a HUD widget. |
HUD_SetText(uint64, string), string HUD_GetText(uint64) | Set or get display text. |
HUD_SetValue(uint64, float current, float max) | Set bar current/max values. |
float HUD_GetValue(uint64), float HUD_GetMaxValue(uint64) | Read bar values. |
HUD_SetFillColor(uint64, float r, g, b) | Bar fill colour. |
HUD_SetTextColor(uint64, float r, g, b) | Label text colour. |
HUD_SetPosition(uint64, float anchorX, float anchorY) | Screen position (0–1 normalized). |
HUD_SetSize(uint64, float width, float height) | Widget dimensions (normalized). |
HUD_SetFontSize(uint64, float) | Font size in pixels. |
HUD_SetBindField(uint64, string) | Data binding field ("health", "stamina", "custom"). |
UI Canvas
| Function | Description |
|---|---|
UI_SetCanvasVisible(uint64, bool), bool UI_IsCanvasVisible(uint64) | Show or hide a canvas. |
UI_SetCanvasSortOrder(uint64, int) | Set canvas render order (higher = on top). |
UI_SetText(uint64, int elemId, string), string UI_GetText(uint64, int) | Set or get text on a label or button. |
UI_SetElementVisible(uint64, int, bool), bool UI_IsElementVisible(uint64, int) | Show or hide a specific element. |
UI_SetElementEnabled(uint64, int, bool) | Enable or disable an element. |
UI_SetProgress(uint64, int, float), float UI_GetProgress(uint64, int) | Progress bar value (0–1). |
UI_SetSliderValue(uint64, int, float), float UI_GetSliderValue(uint64, int) | Slider value. |
UI_SetChecked(uint64, int, bool), bool UI_IsChecked(uint64, int) | Checkbox / toggle state. |
UI_SetImagePath(uint64, int, string) | Change an image element's texture. |
UI_SetImageAlpha(uint64, int, float) | Image transparency (0–1). |
UI_SetBgColor(uint64, int, float r, g, b, float a) | Element background colour with alpha. |
UI_SetTextColor(uint64, int, float r, g, b) | Element text colour. |
bool UI_IsHovered(uint64, int), bool UI_IsPressed(uint64, int) | Interaction state queries. |
UI_SetFocus(uint64, int elemId) | Set keyboard/gamepad focus to a specific element. |
UI_ClearFocus(uint64) | Remove focus from all elements on a canvas. |
int UI_GetFocusedElement(uint64) | Get the currently focused element ID (0 = none). |
bool UI_IsFocused(uint64, int) | Check if a specific element has focus. |
UI_SetTabOrder(uint64, int elemId, int order) | Set explicit tab order (0 = auto). |
UI_SetFocusable(uint64, int elemId, bool) | Set whether an element can receive focus. |
Quest System
| Function | Description |
|---|---|
Quest_Start(string questId) | Start a quest by ID. |
Quest_CompleteObjective(string questId, int objectiveIndex) | Complete a specific objective within a quest. |
Quest_Fail(string questId) | Fail a quest. |
bool Quest_IsActive(string questId) | Check if a quest is currently active. |
bool Quest_IsComplete(string questId) | Check if a quest is fully completed. |
Cinematics
| Function | Description |
|---|---|
Cinematic_Play(uint64 entity) | Start a cinematic camera on an entity with CinematicCameraComponent. |
Cinematic_Stop(uint64 entity) | Stop a playing cinematic. |
bool Cinematic_IsPlaying() | Check if any cinematic is currently playing. |
Object Pool
| Function | Description |
|---|---|
uint64 Pool_Acquire(string poolId) | Get an entity from a pool. Returns entity ID or 0 if pool is empty. |
Pool_Release(string poolId, uint64 entity) | Return an entity to its pool. |
Destructible System
| Function | Description |
|---|---|
Destructible_Destroy(uint64, float dirX, dirY, dirZ, float force) | Trigger destruction with a directional force. |
Destructible_ApplyDamage(uint64, float damage) | Apply damage (destroys automatically if health is depleted). |
Destructible_ApplyDamageAt(uint64, float damage, float px, py, pz) | Apply damage at a specific world position. |
Prefab System
| Function | Description |
|---|---|
uint64 Prefab_Instantiate(string path, float x, y, z) | Load and instantiate a .enjprefab at a position. Returns root entity ID. |
uint64 Prefab_InstantiateEx(string path, float px, py, pz, float rx, ry, rz, float sx, sy, sz) | Instantiate with position, rotation, and scale. |
bool Prefab_IsPrefabInstance(uint64) | Check if an entity is a prefab instance root. |
Prefab_Unpack(uint64) | Disconnect a prefab instance from its source prefab. |
Level Streaming
| Function | Description |
|---|---|
Streaming_ForceLoad(string chunkId) | Synchronously load a streaming chunk by ID. |
Streaming_ForceUnload(string chunkId) | Unload a streaming chunk. |
int Streaming_GetState(string chunkId) | Chunk state: 0=Unloaded, 1=Loading, 2=Loaded, 3=Unloading. |
bool Streaming_IsLoaded(string chunkId) | Check if a chunk is currently loaded. |
int Streaming_GetLoadedCount() | Number of currently loaded chunks. |
Streaming_SetEnabled(bool) | Enable or disable the streaming system. |
Localization
| Function | Description |
|---|---|
string Loc_Get(string key) | Look up a localised string by key for the current locale. |
string Loc_GetWithFallback(string key, string fallback) | Look up with a fallback if the key is missing. |
Loc_SetLocale(string localeCode) | Switch the active locale (e.g. "en", "fr", "ja"). |
string Loc_GetLocale() | Get the current locale code. |
bool Loc_HasString(string key) | Check if a key exists in the current locale. |
Input Actions
The Input Action system provides an abstraction layer over raw input, mapping logical actions
to physical keys and gamepad buttons. Actions are defined by the GameAction enum:
| Value | Action | Value | Action |
|---|---|---|---|
| 0 | MoveForward | 9 | Attack |
| 1 | MoveBack | 10 | Block |
| 2 | MoveLeft | 11 | Pause |
| 3 | MoveRight | 12 | LookUp |
| 4 | Jump | 13 | LookDown |
| 5 | Sprint | 14 | LookLeft |
| 6 | Crouch | 15 | LookRight |
| 7 | Dash | 16 | CameraZoomIn |
| 8 | Interact | 17 | CameraZoomOut |
Query
| Function | Description |
|---|---|
bool InputAction_IsDown(int action) | True while the action is held. |
bool InputAction_IsPressed(int action) | True on the frame the action is first pressed. |
bool InputAction_IsReleased(int action) | True on the frame the action is released. |
float InputAction_GetValue(int action) | Analog value (0.0–1.0). |
Vector2 InputAction_GetMovement() | Combined WASD/stick movement vector. |
Sensitivity
| Function | Description |
|---|---|
InputAction_SetSensitivity(int action, float) | Set sensitivity multiplier for an action. |
float InputAction_GetMouseSensitivity() | Global mouse sensitivity. |
InputAction_SetMouseSensitivity(float) | Set global mouse sensitivity. |
Toggle Settings
| Function | Description |
|---|---|
bool InputAction_IsSprintToggle(), InputAction_SetSprintToggle(bool) | Sprint toggle vs hold mode. |
bool InputAction_IsCrouchToggle(), InputAction_SetCrouchToggle(bool) | Crouch toggle vs hold mode. |
Rebinding
| Function | Description |
|---|---|
InputAction_Rebind(int actionIndex, int keyCode) | Rebind an action to a new key. |
int InputAction_PollNextKey() | Poll for the next key press (for rebind UI). Returns -1 if none. |
Display Helpers
| Function | Description |
|---|---|
int InputAction_GetCount() | Total number of registered actions. |
string InputAction_GetName(int index) | Display name of an action. |
string InputAction_GetBindingName(int index) | Display name of the current key binding. |
Presets
| Function | Description |
|---|---|
InputAction_ApplyLeftHandOnly() | Apply left-hand-only key layout. |
InputAction_ApplyRightHandOnly() | Apply right-hand-only key layout. |
InputAction_ApplyGamepadOnly() | Apply gamepad-only layout. |
InputAction_ResetDefaults() | Reset all bindings to defaults. |
Networking
LAN multiplayer bindings. The NetworkRole enum defines: None=0, Host=1, Client=2.
| Function | Description |
|---|---|
Net_HostGame(int port) | Start hosting a game on the given port. |
Net_JoinGame(string address, int port) | Connect to a host. |
Net_Disconnect() | Disconnect from the current session. |
bool Net_IsConnected() | Check if connected to a session. |
bool Net_IsHost() | Check if this peer is the host. |
int Net_GetRole() | Get current NetworkRole enum value. |
int Net_GetLocalPlayerId() | This peer's player ID. |
int Net_GetPlayerCount() | Total connected player count. |
float Net_GetPing() | Round-trip latency in milliseconds. |
float Net_GetPacketLoss() | Packet loss percentage (0–1). |
Net_SetReady(bool) | Set lobby ready state. |
int Net_GetLobbyPlayerCount() | Number of players in the lobby. |
string Net_GetLobbyPlayerName(int index) | Lobby player name by index. |
bool Net_GetLobbyPlayerReady(int index) | Check if a lobby player is ready. |
Net_RegisterEntity(uint64) | Register an entity for network replication. |
Net_UnregisterEntity(uint64) | Stop replicating an entity. |
Net_RequestOwnership(uint64) | Request ownership of a networked entity. |
Net_CallRPC(string name, string data, int targetId) | Send an RPC to a specific player. |
Net_CallRPCAll(string name, string data) | Broadcast an RPC to all players. |
Net_RegisterRPCHandler(string name) | Register an RPC handler. Received RPCs fire "__rpc_" + name via ScriptEventBus. |
Text Component
| Function | Description |
|---|---|
Text_SetContent(uint64, string), string Text_GetContent(uint64) | Set or get text content (triggers re-rasterisation). |
Text_SetFontSize(uint64, float) | Font size in pixels. |
Text_SetColor(uint64, float r, g, b) | Text colour RGB. |
Text_SetBgColor(uint64, float r, g, b) | Background colour RGB. |
Text_SetBgOpacity(uint64, float) | Background opacity (0–1). |
Text_SetAlignment(uint64, int) | Horizontal alignment: 0=Left, 1=Center, 2=Right. |
Text_SetWrapWidth(uint64, float) | Word wrap width in pixels. |
Coroutines and Events
Coroutines and events are two mechanisms for writing time-based and decoupled game logic. Coroutines let you spread sequential logic across multiple frames without complex state machines, while events let scripts communicate without direct references to each other.
Coroutines
A coroutine is a function that can pause its execution and resume on a later frame. This is invaluable for sequences like "wait 2 seconds, then spawn an enemy, then wait 1 second, then play a sound." Without coroutines, you would need manual timers and state tracking.
Yield Functions
| Function | Description |
|---|---|
StartCoroutine(string funcName) | Begin executing a coroutine by function name. The function must exist on the same script class. |
YieldSeconds(float seconds) | Pause the coroutine for a real-time delay (affected by time scale). |
YieldFrames(uint count) | Pause for a specific number of frames. |
YieldEndOfFrame() | Resume at the end of the current frame, after all OnLateUpdate calls. |
Example: Spawn Wave
class WaveSpawner : TegeBehavior {
int waveCount = 3;
float spawnDelay = 1.5;
void OnStart() {
StartCoroutine("SpawnWaves");
}
void SpawnWaves() {
for (int i = 0; i < waveCount; i++) {
Debug_Log("Spawning wave " + (i + 1));
// Spawn 5 enemies per wave
for (int j = 0; j < 5; j++) {
float x = RandomRange(-10.0, 10.0);
float z = RandomRange(-10.0, 10.0);
Scene_InstantiateAt(Vector3(x, 0, z));
YieldFrames(5); // small delay between spawns
}
Debug_Log("Wave " + (i + 1) + " complete. Waiting...");
YieldSeconds(spawnDelay);
}
Debug_Log("All waves complete!");
}
}
Coroutines are automatically stopped when the entity is destroyed or when play mode ends. You do not need to manually clean them up.
ScriptEventBus
The ScriptEventBus enables decoupled communication between scripts. Instead of scripts holding direct references to each other, they communicate by sending and listening for named events with typed payloads.
EventData Class
The EventData class is a key-value container that carries typed data with events:
| Method | Description |
|---|---|
SetFloat(string key, float value), float GetFloat(string key) | Store or retrieve a float value. |
SetInt(string key, int value), int GetInt(string key) | Store or retrieve an integer value. |
SetString(string key, string value), string GetString(string key) | Store or retrieve a string value. |
SetEntity(string key, uint64 value), uint64 GetEntity(string key) | Store or retrieve an entity reference. |
Sending and Listening
| Function | Description |
|---|---|
uint Events_Listen(string eventName, EventCallback@ callback) | Register a listener for events with the given name. Returns a listener ID. |
Events_Send(string eventName, EventData@ data) | Dispatch an event to all listeners registered for that name. |
Events_Broadcast(EventData@ data) | Dispatch an event to all listeners regardless of event name. |
Example: Damage Event
// HealthDisplay.as - listens for damage events
class HealthDisplay : TegeBehavior {
void OnCreate() {
Events_Listen("player_damaged", @OnPlayerDamaged);
}
void OnPlayerDamaged(EventData@ data) {
float remaining = data.GetFloat("health");
HUD_SetValue(self, remaining, 100.0);
if (remaining < 25.0)
HUD_SetFillColor(self, 1.0, 0.0, 0.0); // red
}
}
// PlayerCombat.as - sends damage events
class PlayerCombat : TegeBehavior {
float health = 100.0;
void TakeDamage(float amount) {
health -= amount;
EventData data;
data.SetFloat("health", health);
data.SetEntity("victim", self);
Events_Send("player_damaged", @data);
}
}
EntityEventBus (C++)
For C++ gameplay code, TEGE provides the EntityEventBus, a decoupled event
system with the same key-value payload model as the script-side event bus:
- Supports named events with key-value payloads (floats, ints, strings, entity references).
- Send — immediate dispatch to all listeners for the event name.
- SendDeferred — queues the event for dispatch at the end of the current frame, useful for avoiding issues with listeners modifying the entity graph during iteration.
- Broadcast — sends to all listeners regardless of event name.
- Listeners are automatically cleaned up when their associated entities are destroyed, preventing dangling callbacks.
Visual Scripting
TEGE includes a full Blueprint-style visual scripting system for creating game logic without writing code. It is ideal for designers, rapid prototyping, and simple entity behaviours. The visual script editor is accessible from View > Tools > Visual Script or by clicking Open Editor on a Visual Script component in the Inspector.
Getting Started
- Select an entity and add the Visual Script component from Add Component > Scripting > Visual Script.
- Click Open Editor in the Inspector to open the visual scripting panel.
- Right-click on the canvas to open the categorised context menu and add nodes.
- Connect nodes by dragging from output pins to input pins. White pins carry execution flow; coloured pins carry data.
You can drag a wire from an output pin into empty space to open the context menu pre-filtered to compatible node types.
Node Categories
The visual script system provides 80+ built-in nodes organised into the following categories:
| Category | Key Nodes | Description |
|---|---|---|
| Events | On Start, On Update | Entry points that fire once or every frame. |
| Flow Control | Branch, Sequence, Delay, For Loop, While Loop, Do Once, Gate, Flip Flop | Control execution flow with conditions and loops. |
| Variables | Get Variable, Set Variable, Get Self | Read/write named variables on the script's blackboard. |
| Math | Add, Subtract, Multiply, Divide, Modulo, Power, Sqrt, Abs, Min, Max, Clamp, Lerp, Floor, Ceil, Round, Sin, Cos, Tan, Atan2, Random Float, Random Int, Negate | Arithmetic and trigonometric operations. |
| Logic | Greater Than, Less Than, Equal, Not Equal, Greater or Equal, Less or Equal, Not, And, Or, Nand, Xor | Boolean comparison and logic gates. |
| Transform | Get/Set Position, Get/Set Rotation, Get/Set Scale, Translate, Rotate, Look At | Manipulate entity transforms. |
| Vector | Make Vector3, Break Vector3, Vector Length, Normalize, Dot Product, Cross Product, Distance, Lerp Vector | 3D vector operations. |
| Entity | Find Entity, Destroy Entity, Spawn Entity, Is Valid, Get Name, Has Component | Entity lifecycle and queries. |
| Physics | Add Force, Add Impulse, Set/Get Velocity, Set Gravity Scale, Raycast, Sphere Check, Box Check | Physics simulation and spatial queries. |
| Physics 2D | Raycast 2D, Overlap Circle 2D, Add Force 2D, Set Velocity 2D, Set Gravity 2D | 2D physics queries, forces, and gravity control. |
| Health | Get Health, Set Health, Damage | Health/damage system integration. |
| Collision | On Collision Enter/Exit, On Trigger Enter/Exit | Collision and trigger event handlers. |
| Audio | Play Audio, Stop Audio, Is Audio Playing, Set Audio Volume, Wait For Audio | Sound playback control. |
| Animation | Play Animation, Set/Get Animation Speed, Wait For Animation | Skeletal animation control. |
| Debug | Print String, Print Warning, Print Error | Console output for debugging. |
| Functions | Function Entry, Function Return, Call Function | Reusable subgraph functions. |
| Script | Call Script | Call AngelScript functions from visual scripts. |
| Gameplay | Save/Load/Delete Slot, Checkpoint, Meta Get/Set, Weather, Quest, Cinematic, Particle, Destructible, Prefab, UI Focus, Localization | Gameplay systems: save/load, weather, quests, cinematics, particles, destructibles, prefabs, UI focus, and localisation. |
| Networking | Host Game, Join Game, Disconnect, Is Connected, Get Player Count, Call RPC | LAN multiplayer session management and RPC calls. |
Debugger
The visual script debugger helps you step through execution in Play mode, making it easy to track down logic errors and understand execution flow.
| Feature | Description |
|---|---|
| Breakpoints | Click the left margin of any node to toggle a breakpoint (red dot). Execution pauses when a breakpoint is hit. |
| Conditional Breakpoints | Press Shift+F9 on a node to set a condition expression and/or hit count threshold. The breakpoint only fires when the condition is true. |
| Step Through | When paused at a breakpoint, use Step Over, Step Into, and Step Out to advance execution node by node. |
| Watch Window | View variable values in real-time while paused. Shows all blackboard variables and their current values. |
| Call Stack | See the current execution path through function calls. Maximum depth of 32 nested calls. |
| Execution Timeline | A profiler view showing which nodes executed each frame and their duration. Useful for identifying performance bottlenecks. |
Subgraph Functions
Create reusable logic by defining functions within a visual script:
- Use the Functions panel to create a new function with a name.
- The function gets a Function Entry node (with configurable input pins) and one or more Function Return nodes.
- Call the function from any graph using a Call Function node.
- Functions support up to 32 levels of nested calls.
Use subgraph functions for repeated patterns like "find nearest enemy", "apply knockback", or "check line of sight". They keep your main graph clean and reduce duplication.
AngelScript Interop
Visual scripts and AngelScript scripts can communicate bidirectionally:
- Visual → AngelScript: Use the Call Script node to invoke AngelScript functions from a visual script graph.
- AngelScript → Visual: AngelScript can trigger visual script execution and exchange data via three functions:
| Function | Description |
|---|---|
VisualScript_SendEvent(uint64 entity, string eventName) | Trigger a named event on the entity's visual script. The event fires an "On Event" node matching the name. |
VisualScript_SetVariable(uint64 entity, string name, float value) | Set a variable on the visual script's blackboard from AngelScript. |
float VisualScript_GetVariable(uint64 entity, string name) | Read a variable from the visual script's blackboard. |
This interop makes it possible to build hybrid systems: performance-critical logic in AngelScript, with high-level flow and sequencing managed visually.
Rendering and Effects
Vulkan rendering pipeline, materials, ray tracing, and visual effects.
Rendering Pipeline
TEGE uses a custom Vulkan-based renderer built from scratch. The renderer drives every pixel you see in the editor viewport and in exported games. It supports PBR materials, multi-light shadow mapping, skeletal animation with GPU skinning, instanced rendering, a full ray tracing pipeline on supported hardware, and GPU-driven performance optimizations including clustered forward lighting, two-phase HiZ occlusion culling, variable rate shading, virtual texturing, and visibility buffer rendering.
Three-Pass Pipeline
Every frame, the renderer executes three major passes in sequence: the shadow pass, the main render pass, and the post-process pass. The shadow pass generates depth maps for each active light source. The main pass renders all visible geometry with PBR shading and lighting. The post-process pass applies screen-space effects, tone mapping, and the final output to the swapchain.
Shadow mapping supports three light types: directional lights use 4-cascade CSM (Cascaded Shadow Maps), point lights use cubemap shadow maps, and spot lights use a 2D shadow map array. All shadow maps use PCF (Percentage-Closer Filtering) for soft edges.
Scene Classification
Each frame, the renderer calls ClassifySceneComposition() to determine the rendering
mode based on what entities are present in the scene. This drives automatic pipeline optimizations
that avoid unnecessary work:
| Mode | Entities Present | Behavior |
|---|---|---|
| Scene2D | Sprites and tilemaps only | Shadow passes skipped entirely. Minimal LightingUBO. Normal map descriptors skipped. |
| Scene2_5D | Sprites + lights (no 3D meshes) | Shadows skipped, but full lighting UBO is populated for lit sprites. |
| Scene3D | 3D meshes present | Full pipeline: all shadow passes, full lighting, normal maps, ray tracing (if enabled). |
Scene classification happens automatically every frame. You do not need to set the mode manually. Adding a single 3D mesh to a 2D scene will upgrade it to Scene3D for that frame.
Descriptor Bindings
The main pipeline uses a single descriptor set (set 0) with up to 18 bindings that supply all per-frame, per-material, and GPU-driven data to the shaders:
| Binding | Stage | Content |
|---|---|---|
| 0 | Vertex | View/Projection UBO |
| 1 | Vertex + Fragment | Lighting UBO (multi-light arrays) |
| 2 | Fragment | Material UBO |
| 3 | Fragment | Base color texture sampler |
| 4 | Fragment | Shadow map sampler (array) |
| 5 | Fragment | Height map (parallax mapping) |
| 6 | Fragment | Normal map |
| 7 | Vertex | Bone matrix SSBO (skeletal animation) |
| 8 | Fragment | Metallic-roughness texture sampler |
| 9 | Fragment | Emissive texture sampler |
| 10 | Fragment | Point shadow cubemap samplers |
| 11 | Fragment | Spot shadow map samplers |
| 12 | Fragment | Shadow data SSBO |
| 13 | Vertex + Fragment | Object data SSBO |
| 14 | Fragment | Cluster grid SSBO (clustered lighting) |
| 15 | Fragment | Cluster light index SSBO (clustered lighting) |
| 16 | Fragment | Virtual texture indirection texture |
| 17 | Fragment | Virtual texture physical atlas |
Per-entity texture descriptors (bindings 3, 5, 6) and the bone buffer (binding 7) are cached via
m_LastBound state. The main render loop sorts entities by
MaterialComponent::cachedTextureKey so identical materials draw consecutively,
minimizing descriptor writes.
Push Constants (128 Bytes)
Per-object data is uploaded via Vulkan push constants, which are faster than uniform buffers for small, frequently-changing data. The 128-byte layout is:
| Field | Size | Description |
|---|---|---|
model |
64 bytes | 4×4 model matrix (world transform). |
baseColor + metallic |
16 bytes | Base color (RGB) and metallic factor (float). |
emissiveColor + roughness |
16 bytes | Emissive color (RGB) and roughness factor (float). |
emissiveStrength, opacity, alphaCutoff, flags |
16 bytes | Material parameters and bit-packed flags integer. |
parallaxScale + padding |
16 bytes | Parallax depth for height-mapped materials. |
Flags Bit Layout
The flags field is a 32-bit integer that packs rendering options, texture presence
indicators, and retro effect settings into a single value:
| Bits | Purpose | Values |
|---|---|---|
| 0–2 | Render flags | Double-sided, cast shadows, receive shadows |
| 3 | Skinned mesh | 1 = GPU-skinned (reads bone SSBO) |
| 8–9 | Alpha mode | 0 = Opaque, 1 = Mask, 2 = Blend |
| 10 | Has height texture | Enables parallax mapping in fragment shader |
| 12 | UV quantize | Quantizes UVs for retro look |
| 13 | Gouraud only | Per-vertex lighting instead of per-fragment |
| 16–19 | Texture flags | Base color, normal, metallic-roughness, emissive presence |
| 20–23 | Retro flags | Flat shading, affine texturing, vertex snapping, stipple transparency |
| 24–28 | Vertex snap resolution | Grid resolution divided by 8 (80–320 range) |
| 29–31 | Shadow dither pattern | Pattern index for dithered shadow transitions |
GPU Performance Optimizations
TEGE includes several advanced GPU-driven performance systems. These are controlled by CMake feature flags and activate automatically on supported hardware.
GPU Two-Phase HiZ Occlusion Culling
A GPU-driven occlusion culling pipeline that runs entirely on the GPU via compute shaders. In phase 1, objects that were visible last frame are tested against the previous frame's hierarchical depth buffer (HiZ pyramid) and drawn immediately. In phase 2, the depth buffer from phase 1 is used to build a new HiZ pyramid, and previously-culled objects are re-tested — any newly visible objects are drawn in a second pass. This eliminates most CPU-side visibility queries while avoiding one-frame-late artifacts.
Clustered Forward Lighting
The view frustum is divided into a 16×9×24 3D grid of clusters with exponential depth distribution. Two compute shaders run before the main render pass: one to calculate cluster AABBs from the inverse projection matrix, and one to assign each light to the clusters it overlaps. During shading, each fragment looks up its cluster (bindings 14–15) and iterates only the lights assigned to that cluster instead of all active lights. This supports up to 1024 simultaneous lights efficiently.
ENJIN_CLUSTERED_LIGHTING — ON by default.
Variable Rate Shading (VRS)
Uses the VK_KHR_fragment_shading_rate extension to dynamically adjust per-tile
shading rates. A compute shader generates a shading rate image each frame based on the selected
mode:
| Mode | Behavior |
|---|---|
| Peripheral | Reduces shading rate at screen edges (foveated-style). |
| ContentAdaptive | Reduces rate in low-detail regions (low luminance variance). |
| MotionBased | Reduces rate for fast-moving pixels. |
| Full | Combines peripheral + content-adaptive + motion-based. |
ENJIN_VRS — OFF by default. Requires GPU support for
VK_KHR_fragment_shading_rate.
Virtual Texturing
A page-based texture streaming system that decouples virtual texture resolution from physical GPU memory. Textures up to 64K×64K are divided into 128×128 pixel pages. A feedback pass determines which pages are visible at what mip level, and a background thread streams pages into an 8K physical atlas. An indirection texture (binding 16) maps virtual page coordinates to their physical atlas location (binding 17). An LRU page cache evicts unused pages when the atlas is full.
ENJIN_VIRTUAL_TEXTURING — OFF by default.
Visibility Buffer Rendering
An alternative rendering path that decouples geometry complexity from shading cost. In
pass 1 (visibility), an ultra-thin geometry pass writes only triangle ID and
instance ID to an R32G32_UINT render target with no material evaluation. In
pass 2 (resolve), a full-screen compute shader fetches vertex data, computes
barycentrics, evaluates materials, and performs lighting. Every pixel is shaded exactly once,
naturally eliminating overdraw.
ENJIN_VISIBILITY_BUFFER — OFF by default.
Additional Optimizations
- 64-bit material sort keys — Entities are sorted by a combined pipeline/material key to minimize descriptor writes and state changes.
- Async compute overlap — Culling and cluster assignment run on async compute queues, overlapping with the previous frame's presentation.
- Per-frame linear allocator — A
FrameAllocatorprovides bump-pointer allocation for transient per-frame data, reset at frame boundaries with zero overhead. - LOD hysteresis — Dead-zone around LOD transition boundaries prevents rapid flickering. Screen-space sizing mode uses projected size for scale-aware selection.
Materials and Shaders
TEGE uses a physically-based rendering (PBR) material model. Every MaterialComponent
exposes a set of properties that map directly to the metallic-roughness workflow used by
industry-standard tools like Blender, Substance Painter, and glTF.
PBR Material Properties
| Property | Type | Description |
|---|---|---|
| Base Color | RGB + Texture | The albedo color of the surface. A texture map (binding 3) multiplies with the constant color. |
| Metallic | Float (0–1) | 0 = dielectric (plastic, wood), 1 = metal (gold, chrome). Controls Fresnel response. |
| Roughness | Float (0–1) | 0 = mirror-smooth, 1 = fully diffuse. Controls specular highlight spread. |
| Normal Map | Texture | Tangent-space normal map (binding 6) for surface detail without extra geometry. |
| Height Map | Texture | Grayscale height map (binding 5) for parallax occlusion mapping. Depth controlled by parallaxScale. |
| Emissive | RGB + Strength | Self-illumination color and intensity. Does not cast light by itself, but contributes to bloom. |
| Opacity | Float (0–1) | Surface transparency. Combined with alpha mode (Opaque / Mask / Blend) from the flags field. |
| Alpha Cutoff | Float | Threshold for alpha-test mode (Mask). Pixels below this alpha are discarded. |
Advanced material properties include transmission and IOR
for glass-like refraction, thickness for thin-surface transmission,
and subsurface scattering parameters (sssIntensity,
sssRadius, sssColor) for skin, wax, and foliage. The GPU-side
MaterialGPU struct is 80 bytes.
Shader Hot-Reload
During development, the RenderSystem watches the Engine/shaders/
directory via a FileWatcher. When a shader source file changes on disk, the
system automatically recompiles it to SPIR-V and recreates the affected pipeline. This allows
you to edit shaders in an external editor and see results immediately in the viewport without
restarting the engine.
Shader Compilation Workflow
Shaders are written in GLSL and stored in Engine/shaders/. For production builds,
they are compiled to SPIR-V and then embedded as C++ byte arrays in ShaderData.h.
The workflow is:
- Edit the shader source file (e.g.,
Engine/shaders/triangle.vertortriangle.frag). - Compile to SPIR-V using
glslangValidator. - Convert the
.spvbinary to a C++ byte array and updateShaderData.h. - Rebuild the engine.
# Compile vertex shader
glslangValidator -V Engine/shaders/triangle.vert -o Engine/shaders/triangle.vert.spv
# Compile fragment shader
glslangValidator -V Engine/shaders/triangle.frag -o Engine/shaders/triangle.frag.spv
During development, shader hot-reload means you rarely need to run these commands manually. The full compile-embed-rebuild cycle is only required when preparing a release build or when the engine itself needs to bundle the shader bytecode.
Ray Tracing
TEGE includes a full Vulkan ray tracing pipeline for hybrid raster+RT rendering. The system detects RT hardware support at startup and gracefully falls back to raster-only rendering on unsupported GPUs. When available, ray tracing provides physically-accurate shadows, reflections, ambient occlusion, and global illumination that would be impossible with screen-space approximations alone.
Hardware Requirements
| Vendor | Minimum GPU |
|---|---|
| NVIDIA | GeForce RTX 20xx series or newer |
| AMD | Radeon RX 6000 series or newer |
| Intel | Arc series |
The following Vulkan extensions are required:
VK_KHR_ray_tracing_pipeline,
VK_KHR_acceleration_structure,
VK_KHR_deferred_host_operations, and
VK_KHR_buffer_device_address.
The editor's Ray Tracing panel (Settings > Scene > Ray Tracing) shows a green
"Supported" or red "Not Supported" indicator based on the detected GPU capabilities.
Hybrid Mode (Raster + RT)
In Hybrid mode, primary visibility is handled by the rasterizer (main render pass), while four RT effects run as additional ray dispatch passes. Each effect can be independently enabled or disabled with its own configuration sliders and a composite strength control:
| Effect | Output Format | Settings |
|---|---|---|
| RT Shadows | R16F | Max distance, shadow radius |
| RT Reflections | RGBA16F | Max distance, roughness threshold |
| RT Ambient Occlusion | R16F | Radius, power |
| RT Global Illumination | RGBA16F | Bounce count, intensity |
Composite strength sliders control the blend factor for each effect when composited into the final HDR image. Setting a strength to zero effectively disables that effect's contribution without stopping the ray dispatch.
Path Tracing Mode
Path Tracing mode replaces the hybrid pipeline with a progressive, full path tracer for reference-quality rendering:
| Setting | Description |
|---|---|
| Max Bounces | Maximum ray bounce depth (default 8). Higher values improve indirect lighting accuracy at the cost of performance. |
| Target SPP | Target samples per pixel for convergence. The renderer accumulates samples over multiple frames. |
| Progress Bar | Shows current SPP / target SPP in the editor panel. |
| Converged Indicator | Displays when the target SPP has been reached and the image has stabilized. |
| Reset Button | Clears the accumulation buffer. Automatically resets on camera or scene changes. |
SVGF Denoiser
Raw ray-traced output is inherently noisy at low sample counts. The SVGF (Spatiotemporal Variance-Guided Filtering) denoiser smooths this noise via a three-pass compute pipeline:
- Temporal Accumulation — blends the current frame with the history buffer using motion vectors. A configurable alpha controls the blend weight (lower alpha = more temporal reuse, less noise, but more ghosting).
- Variance Estimation — computes per-pixel variance from luminance moments to guide the spatial filter's aggressiveness.
- A-Trous Wavelet Filter — an edge-preserving spatial filter that runs multiple iterations (default 5) at increasing kernel sizes. Preserves geometric edges while aggressively smoothing noise in flat regions.
An alternative OIDN denoiser (Intel Open Image Denoise) is available as a
CMake option (ENJIN_RAYTRACING_OIDN, off by default). OIDN uses neural-network
denoising and can produce cleaner results at the cost of higher latency.
Pipeline Architecture
- BLAS (Bottom-Level Acceleration Structure) — one per unique mesh, cached by mesh hash. Built lazily when new meshes appear in the scene.
- TLAS (Top-Level Acceleration Structure) — rebuilt each frame from entity transforms. Uses UPDATE mode when only transforms have changed (no new geometry) for faster rebuilds.
- RT Dispatch — after the shadow pass, before the main render pass. Each enabled effect dispatches its own ray generation shader.
- SVGF Denoise — 3-pass compute shader smooths the noisy RT output.
- RT Compositor — a fullscreen compute shader that multiplies shadows, adds reflections, multiplies AO, and adds GI into the scene HDR buffer.
The RT pipeline only runs for 3D scenes (SceneRenderMode::Scene3D). 2D and 2.5D
scenes skip ray tracing entirely with no performance impact.
RT Descriptor Set (Set 1)
The ray tracing pipeline uses its own descriptor set (set 1), separate from the main raster pipeline's set 0. It provides access to the acceleration structure, scene buffers, RT output images, and geometry data:
| Binding | Type | Content |
|---|---|---|
| 0 | Acceleration Structure | TLAS (top-level acceleration structure) |
| 1 | Storage Image | Scene HDR buffer |
| 2 | Combined Image Sampler | Depth buffer |
| 3 | Combined Image Sampler | World normals |
| 4 | Combined Image Sampler | Motion vectors |
| 5 | Storage Image | RT Shadow output |
| 6 | Storage Image | RT Reflection output |
| 7 | Storage Image | RT AO output |
| 8 | Storage Image | RT GI output |
| 9 | Storage Buffer | Material data |
| 10 | Storage Buffer | Vertex data |
| 11 | Storage Buffer | Index data |
| 12 | Storage Buffer | Per-instance transforms |
| 13 | Uniform Buffer | Light data |
The RT pipeline uses 20 GLSL shaders stored in Engine/shaders/:
rt_common.glsl (shared utilities),
ray generation / miss / closest-hit shaders for each effect
(rt_shadow, rt_reflect, rt_ao, rt_gi,
rt_pathtrace), the three SVGF compute shaders
(svgf_temporal.comp, svgf_variance.comp, svgf_atrous.comp),
and the compositor (rt_composite.comp).
Post-Processing
Post-processing effects are applied after the main render pass, operating on the full-screen
HDR buffer before tone mapping and output. Configure all effects from
Settings > Scene > Post Processing. Effects are saved per-scene and
can be blended spatially using PostProcessVolumeComponent.
Standard Post-Processing Effects
| Effect | Parameters | Description |
|---|---|---|
| Bloom | Threshold, intensity, radius | Bright areas bleed light into surrounding pixels, simulating camera lens glow. |
| Vignette | Intensity, smoothness | Darkens screen edges for a cinematic or vintage look. |
| Color Grading | Exposure, contrast, saturation, temperature | Global color correction. Exposure controls overall brightness; temperature shifts warm/cool. |
| FXAA | Toggle (on/off) | Fast Approximate Anti-Aliasing. Smooths jagged edges in a single post-process pass. |
| Film Grain | Intensity | Adds animated noise for a film or analog video aesthetic. |
| Depth of Field | Focus distance, aperture, range | Blurs foreground and background based on distance from the focal plane. |
| Tilt-Shift | Focus position, blur size, band width | Selective focus blur that simulates a tilt-shift lens, creating a miniature-world look. |
Screen-Space Effects
Five raster-tier screen-space effects run in the post-process shader using only the scene color and depth buffer. They provide ambient occlusion, contact shadows, volumetric light, caustics, and fog without requiring ray tracing hardware. All are configurable from Settings > Scene > Post Processing and persist per-scene.
| Effect | Description | Key Parameters |
|---|---|---|
| SSAO | Depth-only hemisphere-sampled ambient occlusion with reconstructed normals. | Radius, intensity, bias, samples (default 16) |
| Contact Shadows | Screen-space ray march toward the light source in the depth buffer for fine shadow detail. | Ray length, march steps (default 16), intensity |
| Fake Caustics | Procedural animated Voronoi pattern projected below a configurable water plane Y height. | Intensity, scale, speed, water Y |
| God Rays | Screen-space radial blur from the projected sun position (GPU Gems 3 style). | Intensity, decay, density, samples (default 64), weight |
| Fog Shafts | Noisy volumetric-look fog via ray marching through the depth buffer. | Intensity, density, decay, samples (default 16), max distance |
All sample counts are tunable. Estimated total cost is approximately 3 ms at 1080p on a GTX 1060-class GPU with default settings. Each effect can be enabled or disabled individually.
Effect Chain Order
All screen-space effects run in HDR before tone mapping. The order is fixed to ensure correct compositing:
- SSAO (multiply)
- Contact Shadows (multiply)
- Caustics (additive)
- God Rays (additive)
- Fog Shafts (blend)
- Depth of Field
- Tilt-Shift
- Tone Mapping
PostProcessVolume Blending
Spatial post-processing blending is achieved through PostProcessVolumeComponent,
which allows different areas of your scene to have different post-processing settings.
| Property | Description |
|---|---|
| Shape | Box or Sphere. Defines the volume's spatial extent. |
| Priority | Higher-priority volumes override lower ones when overlapping. |
| Blend Radius | Smoothstep blend radius for gradual transitions at volume boundaries. |
| Override Mask | 24-bit selective override mask. Each bit controls which effect group the volume overrides. Bits 19–23 correspond to the five screen-space effects. |
| Global Volume | When enabled, the volume affects the entire scene regardless of shape and position. |
Use a global PostProcessVolume with low priority as your scene's baseline settings, then add local volumes with higher priority for area-specific overrides (e.g., darker exposure inside a cave, warmer temperature near a fireplace).
Retro Effects
TEGE provides a suite of retro rendering effects that let you recreate the look of classic gaming hardware. These effects are split into two categories: per-material settings that apply to individual objects, and post-process effects that apply globally to the entire screen.
Per-Material Retro Flags
These are set on individual MaterialComponent instances via the inspector.
They are packed into bits 20–23 of the push constant flags field and evaluated in the
vertex and fragment shaders:
| Effect | Description |
|---|---|
| Flat Shading | Faceted, low-poly look. Normals are computed per-face rather than interpolated across vertices, producing hard edges on every triangle. |
| Affine Texturing | PS1-style texture warping. Disables perspective-correct texture interpolation, causing textures to warp and swim as the camera moves. |
| Vertex Snapping | PS1-style vertex jittering. Snaps vertex positions to a configurable grid (80–320 resolution). Lower values produce more visible snapping. Resolution is stored in bits 24–28 of the flags field, divided by 8. |
| Stipple Transparency | Dithered transparency pattern. Instead of alpha blending, transparency is achieved by discarding pixels in a regular pattern. |
| UV Quantize | Quantizes texture coordinates to produce a pixelated, low-resolution texture look (bit 12 of flags). |
| Gouraud Only | Forces per-vertex lighting instead of per-fragment, producing the smooth-shaded but low-fidelity look of early 3D hardware (bit 13 of flags). |
Post-Process Retro Effects
These are global effects configured from Settings > Scene > Retro Effects. They apply to the entire rendered image after the main render pass:
| Effect | Description |
|---|---|
| CRT Scanlines | Horizontal scanline overlay that simulates a CRT monitor. Adjustable line thickness and opacity. |
| Dithering | Ordered dithering pattern applied to the final image. Simulates limited color depth displays. |
| Color Quantization | Reduces the color palette to a configurable number of levels per channel, reproducing the banding of 8-bit or 16-bit era graphics. |
| Resolution Downscaling | Renders the scene at a lower internal resolution and upscales with nearest-neighbor filtering for a chunky pixel look. |
Dithered Gradient Rendering
Per-material dithered gradient rendering converts smooth shading into banded, dithered steps.
This is configured on each MaterialComponent:
| Property | Type | Description |
|---|---|---|
ditherGradient |
bool | Enable dithered gradient rendering on this material. |
ditherGradientBands |
int (2–8) | Number of discrete shading bands. Fewer bands produce a more stylized cel-shaded look. |
ditherGradientPattern |
int (0–5) | Dither pattern index. Six built-in patterns provide different noise characteristics at band transitions. |
Skybox and Environment
TEGE provides a comprehensive environment system covering skyboxes, weather, water, world time, and wind. All settings are configured from Settings > Scene > Environment (and the Skybox section in the same tab).
Skybox Types
| Type | Description |
|---|---|
| None | No skybox rendered. The background is the clear color. |
| Procedural | Gradient sky generated from top, horizon, and bottom colors plus sun direction. Five built-in presets available. |
| Solid Color | Single flat color fills the background. Useful for stylized or indoor scenes. |
| Cubemap | Six-face cubemap textures for realistic sky imagery (photographic or painted). |
Procedural Presets
Five built-in presets configure the procedural sky colors and sun direction with a single click:
| Preset | Description |
|---|---|
| Midday | Bright blue sky with high sun. |
| Sunset | Orange/red horizon with low sun. |
| Dawn | Soft pink/purple with early sun. |
| Night | Dark blue/black sky. |
| Overcast | Gray, even lighting. |
Cubemap Configuration
When using the Cubemap skybox type, provide paths to six face textures:
| Face | Direction |
|---|---|
| 1 | Right (+X) |
| 2 | Left (−X) |
| 3 | Top (+Y) |
| 4 | Bottom (−Y) |
| 5 | Front (+Z) |
| 6 | Back (−Z) |
All skybox types support a Y-axis rotation slider (0–360 degrees) to orient the sky relative to your scene.
Weather
Weather effects are configured from Settings > Scene > Environment. Four weather types are available:
| Effect | Description |
|---|---|
| Rain | Falling rain particles with configurable intensity. |
| Snow | Falling snowflakes with gentle drift. |
| Fog | Distance-based fog with configurable color and density. |
| Storm | Rain combined with toggleable lightning flashes and thunder timing. |
Per-zone weather overrides are possible via WeatherZoneComponent on entities,
allowing different areas of your scene to have different weather conditions (e.g., a cave
interior that is dry while it rains outside).
Water
3D water plane rendering provides realistic water surfaces with the following features:
- Gerstner Waves — physically-based wave simulation with configurable amplitude and frequency for realistic ocean movement.
- Shore Foam — foam effect at water edges where the water plane intersects scene geometry.
- Freeze System — water can freeze over time, transitioning from liquid to ice with a visual effect.
- Ocean Mode — extended water plane for open-water scenes that tiles to the horizon.
World Time
A day/night cycle system with configurable speed. As time advances, the sun position and sky colors change accordingly, transitioning through dawn, midday, sunset, and night. Configure from Settings > Scene > Environment.
Wind System
A global wind system that affects multiple engine subsystems:
- Weather Particles — rain and snow direction and speed are influenced by wind strength and direction.
- Vegetation Sway — trees, shrubs, and flowers respond to wind with procedural sway animation.
- Instanced Grass — grass blades rendered via GPU instancing include wind-driven animation baked into the vertex shader.
Effects Gallery
Beyond the rendering pipeline and post-processing, TEGE provides several specialized visual effects systems for common game scenarios.
Weather System
The weather system supports seven weather types that can be set per-scene or per-zone:
| Weather Type | Description |
|---|---|
| Clear | No weather effects. Default state. |
| Cloudy | Overcast sky with reduced ambient light. |
| Rain | Light rain with particle effects and optional puddle reflections. |
| Heavy Rain | Dense rain with reduced visibility and stronger wind influence. |
| Snow | Snowfall with gentle drift and optional ground accumulation. |
| Fog | Dense atmospheric fog with distance-based falloff. |
| Storm | Heavy rain with lightning flashes, thunder, and increased wind. |
Weather can be changed at runtime via AngelScript (Weather_Set() /
Weather_Get()) or Visual Script nodes.
Particle System
TEGE's particle system uses CPU simulation for particle logic (emission, lifetime, forces)
combined with GPU-instanced billboard rendering for efficient drawing. Each
ParticleEmitterComponent can manage up to 16,384 particles.
Emitter shapes include Point, Sphere, Hemisphere, Cone, and Box.
Twelve built-in presets are available from the inspector dropdown and can be applied via
scripting with Particle_ApplyPreset():
| Preset | Preset | Preset |
|---|---|---|
| Fire | Smoke | Sparks |
| Snow | Rain | Magic |
| Explosion | Water Splash | Blood/Sap |
| Lava | Fountain | Drip |
Each preset configures emission rate, lifetime, speed, colors, gravity, drag, and shape to produce the named effect. Presets serve as starting points—all properties remain fully editable after applying a preset.
Vegetation
TEGE provides specialized rendering for vegetation:
- Instanced Grass — grass blades are rendered via the
GrassRendererusing GPU instancing with a dedicated grass vertex/fragment shader (grass.vert/grass.frag). Wind sway is computed in the vertex shader using the global wind direction and strength. - Trees and Shrubs — rendered as standard mesh entities or billboards
(
BillboardComponentwith Y-axis lock). Wind sway is applied via the material wind flag (bit 4 of the flags field). - Flowers — the
FlowerSystemhandles flower and small vegetation animation with procedural sway.
Destructible System
The DestructibleSystem provides runtime mesh fracturing when entities with a
DestructibleComponent take enough damage. Four fracture patterns are available:
| Pattern | Description |
|---|---|
| Voronoi | Irregular, organic-looking fracture based on Voronoi cell decomposition. Best for natural materials like stone and wood. |
| Grid | Regular grid-based fracture producing uniform rectangular pieces. Good for walls, floors, and man-made structures. |
| Radial | Fracture radiating outward from the impact point. Creates a shattered-glass look centered on where damage was applied. |
| Shatter | Random, chaotic fracture producing many irregular debris pieces. Suitable for glass, ice, and brittle materials. |
Debris pieces are spawned as physics-enabled entities that interact with the scene.
The DestructibleComponent also supports pickup spawning on destruction,
respawning after a configurable delay, and screen shake on hit.
Building and Distribution
Packaging and distributing your game.
Build Pipeline
TEGE includes a complete build pipeline for packaging your game into a standalone, distributable executable. The pipeline handles asset validation, compression, packing, and integrity verification in a single automated process.
Build Dialog
Open the build dialog from the editor menu. Configure the following settings before building:
| Setting | Description |
|---|---|
| Project Path | Path to the .enjinproject file. |
| Output Directory | Where to write the built game files. |
| Window Title | Title displayed in the game window's title bar. |
| Window Width / Height | Default window resolution (e.g., 1280×720). |
| Fullscreen | Whether the game launches in fullscreen mode. |
| Build Key | Obfuscation key for the asset pack. A default key is used if left empty. |
Build Phases
When you press Build, the pipeline executes six phases in sequence. A progress callback displays the current phase and completion percentage in the editor:
- Scan Project — reads the
.enjinprojectmanifest and lists all scenes referenced by the project. - Validate Assets — parses each scene JSON, collects all referenced assets (textures, models, scripts, audio), and verifies they exist on disk. Missing assets are reported as errors.
- Pack Assets — compresses and packs all validated assets into a
.enjpakarchive file. - Copy Player — copies the standalone
EnjinPlayerexecutable to the output directory. - Write Build Manifest — writes
_build/manifest.jsoninto the pack with the window title, resolution, fullscreen flag, and start scene information. - Verify Build — reads back the
.enjpakarchive and verifies all CRC32 checksums for data integrity.
.enjpak Archive Format
The .enjpak format is a custom archive designed for fast loading in the game player:
| Feature | Description |
|---|---|
| Magic Header | ENJPAK10 — 8-byte identifier at the start of the file. |
| Compression | Per-file data compression to reduce archive size. |
| XOR Obfuscation | Per-file obfuscation with the configurable build key. Default key: enjin_default_pack_key_2025. |
| CRC32 Integrity | Each file in the archive has a CRC32 checksum verified on read. |
The XOR obfuscation is not cryptographically secure. It prevents casual inspection of packed assets but should not be relied upon for DRM or sensitive content protection.
Distribution Formats
On Windows, TEGE ships with an Inno Setup installer script
(installer/EnjinSetup.iss). To build the installer, run:
"C:\Program Files (x86)\Inno Setup 6\ISCC.exe" installer\EnjinSetup.iss
The Inno Setup installer provides:
- Start Menu and desktop shortcuts for the editor.
- File associations (
.enjinopens in Editor). - Component selection (Editor, Player, Shaders, Scripts, Documentation).
- LZMA2 compression for small download size.
- A standard Windows uninstaller.
For cross-platform distribution or CI pipelines, CMake/CPack is also available:
| Format | Platform | Command |
|---|---|---|
| ZIP | Windows | cd build && cpack -G ZIP |
| TGZ | macOS / Linux | cd build && cpack -G TGZ |
| DEB | Linux | cd build && cpack -G DEB |
Standalone Player
The built game consists of exactly two files. No additional runtime, framework, or DLL is required:
| File | Description |
|---|---|
EnjinPlayer.exe |
Standalone executable. Contains the full engine runtime but no editor UI (no ImGui). |
game.enjpak |
Packed asset archive containing all scenes, textures, models, scripts, and audio. |
Player Startup Sequence
When the player executable launches, it follows this sequence:
- Load Pack — opens
game.enjpakfrom its own directory and verifies CRC32 checksums. - Read Manifest — reads the build manifest for window configuration (title, resolution, fullscreen flag, start scene).
- Initialize Vulkan — creates the Vulkan instance, device, and swapchain with the configured window settings.
- Run Game Loop — loads the start scene and enters the main loop. No editor UI is loaded; only game systems run.
Built-In Player Features
The standalone player includes a GameMenuSystem that automatically provides:
- Title Screen — auto-generated from the build manifest's window title.
- Pause Menu — accessible during gameplay for resume, settings, and quit.
Distribution
To distribute your game, ship both files together. The player expects game.enjpak
in the same directory as the executable. No installer is strictly required—both files can
be placed in a single folder and zipped for distribution. For a more polished experience, use
the Inno Setup installer (see Distribution Formats).
HTML5 Export
TEGE can export your project as a web-ready HTML5 application, suitable for embedding on websites, game portals, and platforms like Newgrounds. Access the export dialog via Build > Export HTML5.
Generated Files
| File | Purpose |
|---|---|
index.html |
Main page with canvas element, Module configuration, and fullscreen support. |
preloader.js |
Loading progress bar with click-to-play audio interstitial (required by browsers for auto-play policy compliance). |
style.css |
Responsive scaling, preloader styling, and fullscreen layout. |
Export Dialog
The export modal dialog provides the following options:
- Output Directory — where the generated web files are written.
- Window Title — sets the HTML page title and the canvas label.
- Resolution — canvas width and height in pixels.
- Embed Code Generation — generates ready-to-use
<iframe>embed code, compatible with Newgrounds and other game portal embed systems.
The exported application uses responsive scaling to fill the browser viewport while maintaining the configured aspect ratio.
Newgrounds Integration
TEGE includes built-in support for the Newgrounds.io API, enabling session management, achievements (medals), scoreboards, and cloud saves for web-published games. Configuration is done via the Newgrounds tab in the Flash Timeline panel.
AngelScript Functions
The following AngelScript functions are available for interacting with the Newgrounds.io API at runtime:
| Function | Description |
|---|---|
NG_Connect(appId, encKey) |
Initialize the Newgrounds.io connection with your application ID and encryption key. |
NG_IsConnected() |
Returns true if the connection to Newgrounds.io is active. |
NG_CheckSession() |
Validate the current user session. Call after NG_Connect to verify the user is logged in. |
NG_UnlockMedal(medalId) |
Unlock an achievement (medal) by its numeric ID. The medal must be configured on the Newgrounds.io dashboard. |
NG_PostScore(boardId, value) |
Submit a high score to the specified scoreboard. The board must exist on the Newgrounds.io dashboard. |
NG_GetPassportUrl() |
Returns the Newgrounds Passport login URL. Open this in the user's browser for authentication. |
NG_GetUserName() |
Returns the logged-in Newgrounds username, or an empty string if not authenticated. |
NG_SaveSlot(slotId, data) |
Save a string to a cloud save slot. Slots are configured on the Newgrounds.io dashboard. |
NG_LoadSlot(slotId) |
Load a string from a cloud save slot. Returns the saved data or an empty string if the slot is empty. |
Usage Example
// Initialize Newgrounds connection in OnStart()
void OnStart() {
NG_Connect("12345:abcdef", "encryption_key_here");
}
// Check session and unlock a medal
void OnUpdate(float dt) {
if (NG_IsConnected()) {
// Unlock medal #1234 when player reaches the goal
if (playerReachedGoal) {
NG_UnlockMedal(1234);
}
}
}
// Submit a high score when the game ends
void OnGameOver(int score) {
if (NG_IsConnected()) {
NG_PostScore(5678, score);
}
}
// Cloud save/load
void SaveProgress(const string &in data) {
NG_SaveSlot(1, data);
}
string LoadProgress() {
return NG_LoadSlot(1);
}
The Newgrounds API works in both HTML5 exports and the standalone player. For web builds,
the session is automatically detected from the Newgrounds portal. For standalone builds,
use NG_GetPassportUrl() to direct users to the browser-based login flow.
Advanced Topics
Architecture, physics, accessibility, and engine internals.
55. Architecture Overview
TEGE is structured as a layered architecture with strict dependency direction: upper layers depend on lower layers, never the reverse. The four layers — from bottom to top — are the Vulkan API Layer, the Core Layer, the Engine Layer, and the Application Layer.
Layer Responsibilities
| Layer | Contents | Directory |
|---|---|---|
| Application | Editor (ImGui), standalone Player, custom runtime hosts. | Editor/, Player/ |
| Engine | Renderer, ECS, Physics, Audio, Scripting, Scene, Effects, Gameplay, AI, Animation, Networking, Build, Debug, Plugin, GUI, VisualScript, Procedural. | Engine/ |
| Core | Memory allocators (Stack, Pool, Linear), math library (Vector, Matrix, Quaternion, Spline, Noise), thread-safe logging, platform abstraction, window management, input handling. | Core/ |
| Vulkan API | Instance, device, queues, command buffers, swapchain, descriptor sets, pipelines. | Engine/…/Renderer/Vulkan/ |
Key Systems
| System | Description |
|---|---|
| Rendering | Vulkan PBR renderer with cascaded shadow maps, skeletal animation (GPU skinning), instanced grass, OIT, post-processing (20+ effects), full ray tracing pipeline (hybrid raster+RT, path tracing, SVGF/OIDN/OptiX denoisers), GPU two-phase HiZ occlusion culling, clustered forward lighting (1024 lights), variable rate shading, virtual texturing, and visibility buffer rendering. |
| ECS | 70+ component types managed by ECS::World. Thread-safe structural ops, deferred entity destruction, and data-oriented iteration. |
| Physics | Pluggable backends via IPhysicsBackend/IPhysicsBackend2D: Jolt v5.2.0 (3D), Box2D v3.0.0 (2D), SimplePhysics (legacy). Collision filtering, 6 joint types, gravity zones, CCD. |
| Scripting | AngelScript VM with ~686 bindings, hot-reload, coroutines, event bus. Visual scripting with 143+ nodes and a step-through debugger. |
| Editor | 20+ ImGui panels, multi-select, undo/redo, 44 templates, terrain brushes, command palette, play-mode diff. |
| Scene | JSON serialization for 70+ component types, project manifests, scene transitions (Fade, Cross Fade), additive loading. |
| Effects | Weather (rain, snow, fog, storms), Gerstner wave water, particle systems, retro effects, wind, seasonal weather. |
| Gameplay | Tiered save system, quest system, HUD, cinematics, footstep audio, destructibles, object pooling, localization, dialogue assets. |
| Assets | glTF/GLB native loader, FBX/OBJ/DAE via Assimp v5.4.3, prefab system, build pipeline with .enjpak packing, Inno Setup installer. |
| Debug | Profiler with per-scope timings, FPS counter, frame-time graphs, draw-call and memory counters. |
Design Patterns
-
Component-based architecture — Entities are
u64IDs. Components are plain data structs. Systems contain all logic and operate on components. This separation keeps data cache-friendly and logic composable. - Data-oriented design — Components are stored contiguously per type for efficient iteration. Systems iterate over component arrays rather than per-entity virtual dispatch.
- Data-driven design — Scenes, project manifests, room prefabs, dialogue trees, save data, and build configurations are all JSON. This keeps content editable outside the engine and simplifies serialization.
- Pluggable backends — Physics, audio, save storage, and rendering use abstract interfaces so implementations can be swapped without changing consuming code.
56. Physics Backend Selection
TEGE provides three physics backends behind a unified interface. The
PhysicsBackendFactory selects the appropriate backend
automatically based on the project’s mode, or you can force a
specific backend in code or via CMake.
Backend Comparison
| Backend | Dimension | Interface | Features |
|---|---|---|---|
| Jolt v5.2.0 | 3D | IPhysicsBackend |
Full rigid body simulation, 6 joint types (Distance, Hinge, BallSocket, Spring, Fixed, Slider), bilateral collision filtering, gravity zones, CCD via LinearCast, thread-safe contact events. |
| Box2D v3.0.0 | 2D | IPhysicsBackend2D |
2D dynamics, 5 joint types (Revolute, Prismatic, Distance, Rope, Weld), sensors, bilateral collision filtering, CCD, multi-threaded sub-stepping. |
| SimplePhysics | 3D/2D | IPhysicsBackend / IPhysicsBackend2D |
Legacy backend. Spatial hash grid broad-phase, impulse-based solver, 6 joint types (3D). Compile-guarded; can be disabled via CMake. |
CMake Options
| Option | Default | Effect |
|---|---|---|
ENJIN_PHYSICS_JOLT |
ON | Compiles Jolt v5.2.0. When ON, Auto selects Jolt for 3D/Mixed modes. |
ENJIN_PHYSICS_BOX2D |
ON | Compiles Box2D v3.0.0. When ON, Auto selects Box2D for 2D/Mixed modes. |
ENJIN_PHYSICS_SIMPLE |
ON | Compiles SimplePhysics legacy backend. Can be set to OFF to retire legacy code. |
PhysicsBackendType enum values: Auto,
Jolt, Box2D, Simple. Use
PhysicsBackendFactory::CreatePhysicsBackend(type, mode) or
CreatePhysicsBackend2D(type, mode) to create a backend.
Helper functions IsJoltAvailable(),
IsBox2DAvailable(), and IsSimpleAvailable()
report compile-time availability.
57. Accessibility
TEGE includes comprehensive accessibility features configurable from the Settings window, System tab (View > Settings > System Settings). Settings are saved persistently to disk in JSON format.
Editor Themes
Eleven themes are available, including four standard themes and seven retro console-inspired themes:
| Theme | Description |
|---|---|
| Dark | Default dark theme with sage green accents. |
| Light | Light background theme. |
| High Contrast Dark | High-contrast dark for low vision. |
| High Contrast Light | High-contrast light for low vision. |
| SNES | Super Nintendo inspired — deep purple and indigo tones with lavender accents. |
| PS2 | PlayStation 2 inspired — dark blue with PS2-signature blue accents. |
| Xbox | Xbox inspired — dark charcoal with Xbox green accents. |
| Dreamcast | Dreamcast inspired — warm grey-blues with Dreamcast orange-red accents. |
| Sega Saturn | Sega Saturn inspired — dark blue-greys with Saturn blue accents. |
| GBA | Game Boy Advance inspired — dark teal-grey with GBA purple accents. |
| DS | Nintendo DS inspired — slate grey with DS red accents. |
Custom Accent Colors
Beyond the built-in themes, you can fully customize the editor’s accent colors from Settings > System > Accent Colors. An Enable Custom Colors checkbox activates per-color overrides. Eleven accent color fields are available:
- Button, Button Hover, Button Active
- Check Mark
- Slider Grab, Slider Grab Active
- Resize Grip
- Text Selected
- Drag Drop Target
- Tab Active, Tab Hovered
Each field has a color picker with alpha. Reset to Defaults restores the default accent colors for the current theme. Custom accent colors are saved persistently and apply to any base theme.
Colorblind Modes
GPU-accelerated colorblind correction via Daltonization in the post-process shader. Eight modes are supported, with a strength slider (0–1) controlling correction intensity:
| Mode | Description |
|---|---|
| Off | No correction. |
| Protanopia | Red-blind (full). |
| Protanomaly | Red-weak (partial). |
| Deuteranopia | Green-blind (full). |
| Deuteranomaly | Green-weak (partial). |
| Tritanopia | Blue-blind (full). |
| Tritanomaly | Blue-weak (partial). |
| Achromatopsia | Total color blindness. |
Remappable Input
The InputActionMap system provides semantic game actions that
can be rebound at runtime. Actions are mapped to keys and buttons rather than
hard-coded. Input mappings are saved as JSON and persist between sessions.
- Hold/Toggle modes for sprint and crouch.
- One-handed presets: left-hand only, right-hand only, or gamepad only.
18 Game Actions:
| Action | Action | Action |
|---|---|---|
| MoveForward | MoveBack | MoveLeft |
| MoveRight | Jump | Sprint |
| Crouch | Dash | Interact |
| Attack | Block | Pause |
| LookUp | LookDown | LookLeft |
| LookRight | CameraZoomIn | CameraZoomOut |
22 AngelScript bindings are available for scripting input actions at
runtime — see the Scripting API reference for the full
InputAction_* function list (query, sensitivity, toggle,
rebinding, display, presets).
Reduced Motion
- Weather particle reduction — fewer particles for rain, snow, and effects.
- Disable head bob — removes the camera bob from FirstPersonController.
- Disable screen shake — suppresses all screen shake effects.
- Disable FOV effects — prevents FOV changes (sprint zoom, etc.).
Subtitles and Captions
The SubtitleSystem provides an overlay for dialogue and
environmental audio:
- Configurable font size (16–48 px).
- Adjustable background opacity for readability.
- Speaker names toggle.
- Direction indicators showing where sound is coming from.
- Separate toggle for closed captions (environmental sounds).
Content Warnings
The ContentWarningSystem provides per-scene content flags.
Scenes can be tagged with content warning flags, and a dismissable overlay
appears before the scene loads. Players acknowledge warnings before
continuing.
Quick Presets
Four one-click presets configure multiple accessibility settings at once:
| Preset | What It Does |
|---|---|
| Low Vision | Large UI, high contrast theme, large subtitles. |
| Motor Impaired | Toggle modes for sprint/crouch, reduced input requirements. |
| Photosensitive | Reduced motion, disabled screen shake, disabled FOV effects. |
| Reset All | Restores all settings to defaults. |
UICanvas Focus Navigation
UICanvas supports full keyboard and gamepad navigation for in-game UI, enabling accessible menu control without a mouse:
| Input | Action |
|---|---|
| Tab / Shift+Tab | Move focus forward/backward through focusable elements (ordered by tabOrder). |
| Arrow Keys / D-Pad | Navigate between elements with key repeat support. |
| Enter / Space / Gamepad A | Activate the focused element (button press, checkbox toggle). |
| Left / Right | Adjust slider values on focused slider elements. |
Focus indicators are rendered as an outset rounded-rect border around the
focused element, using the theme’s inputFocused color or
a per-element focusColor override. Elements can be marked as
focusable/unfocusable via the focusable flag and ordered with
tabOrder (0 = auto from element order).
AngelScript bindings:
UI_SetFocus(), UI_ClearFocus(),
UI_GetFocusedElement(), UI_IsFocused(),
UI_SetTabOrder(), UI_SetFocusable().
Mouse Input Settings
| Setting | Description |
|---|---|
| Raw mouse input | Bypasses OS mouse acceleration for 1:1 input (toggle, default: on). |
| Mouse smoothing | Temporal smoothing for mouse movement (0.0 = none, 1.0 = heavy). |
| Mouse sensitivity | Global mouse sensitivity multiplier. |
58. Splitscreen
TEGE supports splitscreen rendering for local multiplayer games with 2-player and 4-player configurations.
Supported Configurations
| Mode | Layout |
|---|---|
| 2-player | Screen split horizontally (top/bottom) or vertically (left/right). |
| 4-player | Screen divided into four quadrants. |
How It Works
-
Each player’s camera uses
CameraComponentviewport fields (viewportX,viewportY,viewportWidth,viewportHeight) to define its portion of the screen. - Per-viewport uniform buffers ensure each camera renders with its own view/projection matrices.
-
Character controllers use the
gamepadIndexfield (0–3) to assign each player to a different gamepad.
4-Player Viewport Layout
| Player | viewportX | viewportY | viewportWidth | viewportHeight |
|---|---|---|---|---|
| 1 | 0.0 | 0.0 | 0.5 | 0.5 |
| 2 | 0.5 | 0.0 | 0.5 | 0.5 |
| 3 | 0.0 | 0.5 | 0.5 | 0.5 |
| 4 | 0.5 | 0.5 | 0.5 | 0.5 |
The Arena Fighter template demonstrates 2-player splitscreen with per-player cameras, health, stamina, and arena walls. The same technique scales to 4-player by adjusting viewport fields accordingly.
59. Level Streaming
For large worlds, the StreamingManager loads and unloads scene
chunks based on camera distance. This keeps memory usage bounded while
allowing seamless traversal of large environments.
StreamingChunk
Each chunk defines:
| Field | Type | Description |
|---|---|---|
center | Vector3 | Center of the chunk’s spatial bounds. |
halfExtents | Vector3 | Half-size of the chunk’s bounding box. |
loadDistance | f32 | Distance at which the chunk starts loading. |
unloadDistance | f32 | Distance at which the chunk is released from memory. |
scenePath | string | Path to the .enjin scene file for this chunk. |
Components
- StreamingVolumeComponent — placed on entities to define chunk boundaries in the scene.
- StreamingPortalComponent — connects two chunks (doorways, corridors) for seamless transitions between loaded regions.
Priority System
Chunks are loaded in priority order to prevent frame drops:
| Priority | Use Case |
|---|---|
| Critical | The chunk the player is currently inside. Always loaded first. |
| High | Chunks immediately adjacent to the player. |
| Normal | Chunks within load distance but not adjacent. |
| Low | Background pre-loading for distant chunks. |
The system limits concurrent loads to prevent frame drops. Async chunk
loading is performed via SceneSerializer.
Debug Overlay
Enable the streaming debug overlay to visualize chunk states (Unloaded, Loading, Loaded, Unloading) and the current load queue. This is invaluable for tuning load/unload distances and diagnosing streaming hitches.
60. Plugin System
TEGE supports dynamic plugins loaded at runtime via shared libraries. Plugins can extend the engine with custom systems, editor panels, or gameplay logic.
IPlugin Interface
Implement the IPlugin interface to create a plugin:
class MyPlugin : public Enjin::Plugin::IPlugin {
public:
const char* GetName() override { return "My Plugin"; }
const char* GetVersion() override { return "1.0"; }
void OnLoad() override {
// Initialization: register systems, allocate resources
}
void OnUnload() override {
// Cleanup: release resources
}
void OnUpdate(f32 deltaTime) override {
// Called every frame while the plugin is active
}
};
Plugin Manifest
Create a plugin.json alongside the shared library:
{
"name": "My Plugin",
"version": "1.0",
"dependencies": []
}
The dependencies array lists other plugin names that must be
loaded before this one. The plugin loader resolves the dependency order
automatically.
Editor Panel
The Plugin Manager panel (View > Plugins) shows loaded plugins, their version and status, and provides Load / Unload controls. Plugins can be hot-reloaded during development by unloading, recompiling the shared library, and loading again.
61. Profiler and Debug Tools
Open the profiler via View > Profiler in the editor menu.
Profiler Display
The profiler panel displays:
- FPS and average frame time.
- Frame time graph — a 240-frame rolling window showing per-frame timing.
- System breakdown — Render, Physics, Scripting, ECS, Audio shown as progress bars indicating percentage of total frame time.
- Counters — draw calls, entity count, triangle count, memory usage.
- Detailed scopes — an expandable table showing per-scope last/avg/max times and call counts.
Adding Profile Scopes
In C++ code, use the profiling macros to instrument your systems:
#include "Enjin/Debug/Profiler.h"
void MySystem::Update(f32 deltaTime) {
ENJIN_PROFILE_SCOPE("MySystem::Update");
// Your system logic here...
for (auto entity : entities) {
ENJIN_PROFILE_SCOPE("ProcessEntity");
ProcessEntity(entity, deltaTime);
}
}
void MySystem::Render() {
ENJIN_PROFILE_FUNCTION(); // Automatically uses the function name
// ...
}
ENJIN_PROFILE_SCOPE("name") times the enclosing scope and
reports results to the profiler singleton. Use
ENJIN_PROFILE_FUNCTION() as shorthand to automatically use the
current function name as the scope label.
62. Security
TEGE defines trust zones documented in .enjin-boundaries.json
to classify subsystems by risk level and enforce appropriate validation
discipline.
Trust Zones
| Zone | Risk | Key Rule |
|---|---|---|
| security-critical | HIGH | Networking, script engine, asset packer/reader, scene serializer, plugin loader. Validate everything. |
| trust-boundary | HIGH | ScriptBindings, SceneSerializer, AssetReader, NetworkSerializer. Validation MUST happen here. |
| user-api | MEDIUM | ECS components, ScriptBindings (686+ functions), VS NodeRegistry, InputAction. Additions safe; removals break scripts. |
| editor-internal | LOW-MED | EditorLayer, panels, PlayMode. Still validate file paths and JSON. |
| renderer-internals | LOW | Vulkan, RayTracing, PostProcessing. Always check VkResult. |
| gameplay-runtime | LOW-MED | Physics, audio, AI, save/load. Cap iterations, guard divide-by-zero. |
| foundation | LOW | Core math, memory, logging, platform. Widest blast radius — changes here affect everything. |
Scene File Validation
All scene files are JSON. The deserializer validates array sizes before
allocation and uses .contains() checks before accessing keys
to prevent crashes from malformed or hand-edited scene files.
Script Sandbox
AngelScript is sandboxed from the filesystem and network. A
1 million instruction limit prevents infinite loops from
locking the engine. Script #include paths are resolved
relative to the script directory.
Asset Pack Security
The .enjpak format uses XOR obfuscation with a configurable
key (default: enjin_default_pack_key_2025) and CRC32 checksums
for data integrity verification.
XOR obfuscation is not cryptographically secure. It deters casual inspection but will not withstand determined reverse engineering. Do not rely on it for DRM or protection of sensitive assets. CRC32 provides integrity checking only, not tamper resistance.
General Practices
- Validate enum casts from deserialized integers to prevent out-of-range values.
- Sanitize file paths to prevent directory traversal attacks.
- Cap allocation sizes to prevent memory exhaustion from malformed data.
- Clamp loop bounds in glTF/GLB import to allocated buffer sizes.
- Bounds-check all sizes and offsets in
.enjpakagainst file size.
Reference
Quick reference tables and supplementary information.
Appendix A: Templates Reference
TEGE provides 23 built-in startup templates organized into 5 categories. When you create a new project, the template selector offers these starting points. Each template creates the appropriate entities (ground, lights, player, camera) and pre-configures component values for its genre.
Foundations
| Template | Description |
|---|---|
| Blank | Empty scene with directional light, procedural skybox, and FXAA. |
| 2D Platformer | Side-scrolling with wall jump, floating platforms, coin tween, torch particles. |
| 2D Top-Down Action | Overhead 2D with dash, health, AI patrol enemy, health pickup. |
| 3D Third Person | Over-the-shoulder camera with shadows, obstacle cubes, point light, bloom. |
| 3D First Person | FPS camera in an L-shaped corridor with warm point light and vignette. |
Genre Showcases
| Template | Description |
|---|---|
| Sokoban Puzzle | Pushable crates with grid snap, 3 goal plates, switch door, top-down 3D camera. |
| Survival | Temperature zones, weather zones, campfire particles, stamina, fog, hazard zone. |
| RPG Village | NPC dialogue, chest pickup, house/fences, lantern point light. |
| Horror | Flashlight (spot light with follow), fog, dark ambient, collectible notes, door switch. |
| Vehicle Racing | VehicleController with chase camera, track barriers, checkpoint/finish goal zones, cinematic camera. |
| PS1 RPG | Retro effects (pixelation, dither, color quantization, 320x240), flat shading, save point with magic particles. |
| Arena Fighter | 2-player splitscreen with per-player cameras, health + stamina, arena walls. |
Systems Deep-Dives
| Template | Description |
|---|---|
| Physics Playground | Ramp, 5 rigidbodies (spheres/cubes/capsule), gravity zone (point mode), conveyor, moving platform. |
| Dialogue & Narrative | 3 NPCs with dialogue, quest state entity, dialogue box component, branching conversation notes. |
| Save System Demo | 3-tier persistence demo: RunState collectibles, SceneState checkpoint, MetaProgression stats, save/load menu. |
| Visual Scripting | 3 entities with VisualScriptComponent, switch, particle effect, guide notes for node editor. |
| UI Canvas Demo | UICanvasComponent, HUD health bar widget, guide notes for the UI editor. |
Retro & Flash
| Template | Description |
|---|---|
| Point & Click | Adventure game with background, 3 click hotspots, inventory UI canvas, dialogue descriptions. |
| Bullet Hell | Fast top-down 2D, enemy spawner with particles, bullet pool, boundary walls. |
| Idle/Clicker | Click target with scale tween feedback, UI canvas, MetaProgression save data. |
Advanced
| Template | Description |
|---|---|
| Planet Gravity | Spherical planet with point gravity zone, surface-aligned controller, dark space skybox. |
| Dungeon Crawler | Grid-based FPS with snap turns, L-shaped corridor walls, skeleton enemy, treasure, torch lights. |
| Accessibility Menu | In-game accessibility settings: subtitle toggle + size, colorblind toggle, reduced motion, input sensitivity. All controls use UICanvas focus navigation. |
Appendix B: Type Conventions
TEGE uses fixed-width type aliases throughout the codebase and exposed APIs.
These are defined in Core/include/Enjin/Platform/Types.h.
| Alias | C++ Type | Size |
|---|---|---|
u8 | uint8_t | 1 byte |
u16 | uint16_t | 2 bytes |
u32 | uint32_t | 4 bytes |
u64 | uint64_t | 8 bytes |
i8 | int8_t | 1 byte |
i16 | int16_t | 2 bytes |
i32 | int32_t | 4 bytes |
i64 | int64_t | 8 bytes |
f32 | float | 4 bytes |
f64 | double | 8 bytes |
usize | size_t | Platform-dependent |
Appendix C: Namespace Reference
All engine types are organized under the Enjin root namespace.
The following table lists every sub-namespace and its purpose.
| Namespace | Purpose |
|---|---|
Enjin::Core | Application, window, input fundamentals. |
Enjin::Math | Vector, Matrix, Quaternion, Spline math. |
Enjin::Renderer | Vulkan renderer, pipeline, buffers, skybox. |
Enjin::ECS | Entity-Component-System, World, Entity, all components. |
Enjin::Editor | Editor layer, play mode, settings, performance stats. |
Enjin::Effects | Weather, water, retro effects, world time, seasonal weather, wind. |
Enjin::Accessibility | Colorblind filter, subtitle system, content warnings, runtime settings. |
Enjin::InputSystem | Remappable input action map. Uses InputSystem:: to avoid collision with Enjin::Input. |
Enjin::Build | Build pipeline, asset packer, asset reader, build report. |
Enjin::Physics | SimplePhysics, PhysicsWorld, ConstraintSolver, joints. |
Enjin::Scripting | AngelScript engine, script system, coroutines, script event bus. |
Enjin::Gameplay | HUD, quest, quest flow, footstep, cinematic, and object pool systems. |
Enjin::Debug | Profiler, scope timers, frame data. |
Enjin::Plugin | Plugin system, hot-reload. |
Enjin::Animation | Timeline/sequencer system. |
Enjin::AI | AI behaviors, navmesh, A* pathfinding, behavior trees. |
Enjin::GUI | UI canvas, UI elements, UI system, dialogue tree rendering. |
Enjin::VisualScript | Visual scripting node definitions, registry, executor, debugger. |
Appendix D: File Formats
TEGE uses several custom file formats alongside standard image, model, and audio files.
| Extension | Format | Description |
|---|---|---|
.enjin |
JSON | Scene file. Contains all entities, components, and scene settings. |
.enjinproject |
JSON | Project manifest. Lists scenes, build indices, start scene, project settings. |
.enjpak |
Binary | Asset pack archive. Magic header ENJPAK10, per-file compression, XOR obfuscation, CRC32 integrity. |
.enjdlg |
JSON | Dialogue tree asset. Stores dialogue nodes, branches, and conditions. |
.enjprefab |
JSON | Prefab file. Serialized entity hierarchy with per-instance overrides. |
.enjdata |
JSON | Save data file. Stores game state, collectibles, and progression. |
.enjsave |
JSON | Save slot file. Contains tiered save data (SceneState, RunState, MetaProgression). |
Appendix E: Troubleshooting
Common build and runtime issues with their solutions:
| Problem | Solution |
|---|---|
| Vulkan not found | Install the Vulkan SDK and ensure the VULKAN_SDK environment variable is set. Restart your terminal after installation. |
| GLFW not found | GLFW is fetched automatically by CMake via FetchContent. If the download fails, check your internet connection or manually clone GLFW into third_party/glfw. |
| Shader compiler not found | Ensure glslangValidator is on your PATH. It ships with the Vulkan SDK under the Bin/ directory. |
| C++20 not supported | TEGE requires C++20. Use MSVC 2019 (v16.10+), GCC 10+, or Clang 12+. Update your compiler if you see errors about std::format, concepts, or designated initializers. |
| Linker errors (unresolved symbols) | Re-run CMake configuration after adding new source files: cd build && cmake ... Ensure all required third-party libraries are built. |
| CMake version too old | TEGE requires CMake 3.20 or later. Download the latest version from cmake.org. |
| Black screen on launch | Verify your GPU supports Vulkan 1.2+. Update your graphics drivers. Check the console output for Vulkan validation layer errors. |
| Asset pack fails to load | Ensure game.enjpak is in the same directory as EnjinPlayer.exe. Verify the pack was built with a matching build key. CRC32 errors indicate file corruption. |
| Script compilation errors | Check the Console panel for AngelScript error messages with line numbers. Ensure your script class name matches the class name specified in the ScriptComponent. |
| Physics objects fall through ground | Ensure both entities have collider components and that their categoryBits / collisionMask bitmasks allow collision. Check that the ground entity has a collider, not just a mesh. |
Appendix F: Keyboard Shortcut Cheatsheet
| Category | Key | Action |
|---|---|---|
| Gizmos | 1 | Translate gizmo |
2 | Rotate gizmo | |
3 | Scale gizmo | |
| Space | 4 | Toggle local/world space |
| Camera | W A S D | Fly camera movement |
Space / E | Camera up | |
Q / Ctrl | Camera down | |
Shift | Sprint (faster fly camera) | |
Hold RMB + Mouse | Look around | |
| Scroll wheel | Adjust fly camera speed | |
| Selection | Left-click | Select entity |
| Double-click | Focus on entity | |
Ctrl + click | Toggle entity in multi-selection | |
Shift + click | Range select in hierarchy | |
| Drag in viewport | Marquee / rubber-band selection | |
| Editing | Delete | Delete selected entities |
Ctrl+D | Duplicate selected entities | |
F | Focus camera on selection | |
Ctrl+Z | Undo | |
Ctrl+Y | Redo | |
| Clipboard | Ctrl+X | Cut entity |
Ctrl+C | Copy entity | |
Ctrl+V | Paste entity | |
Ctrl+P | Command palette | |
| File | Ctrl+S | Save scene |
Ctrl+O | Open scene | |
Ctrl+I | Import model |