Getting Started
Creating a Project
Use the CLI to initialize a new project:
./build/toolchain/cli/eng_cli init ~/MyProject
This creates the project structure:
MyProject/
├── Content/
│ ├── Scenes/ # Scene files (.scene)
│ ├── Scripts/ # C++ scripts (.cpp + .scriptasset)
│ ├── Prefabs/ # Reusable prefabs (.prefab)
│ └── Materials/ # Material assets
├── Library/ # Cooked cache (meshes, textures, compiled scripts)
└── Build/ # Player output
Creating a Scene
./build/toolchain/cli/eng_cli new-scene ~/MyProject Main
This creates Content/Scenes/Main.scene with a default scene structure.
Bundled Player Prefabs
New projects include two bundled prefabs in Content/Prefabs/:
- Player.prefab — Basic player with CharacterController, capsule collider, and first-person camera
- animatedPlayer.prefab — Animated player with SkinnedMeshComponent, AnimatorComponent with locomotion blend tree, and CharacterController
Instantiate either prefab to get a playable character immediately:
{
"op": "InstantiatePrefab",
"params": { "prefab_name": "Player" }
}
Or via AI: "Add a player to the scene" — the agent automatically routes to the appropriate prefab.
Adding Entities
Entities are created through typed operations. Using the CLI:
# Create a cube entity
./build/toolchain/cli/eng_cli apply-plan ~/MyProject plan.json --json
Where plan.json contains operations:
[
{
"op": "CreatePrimitive",
"params": {
"primitive_type": "Cube",
"entity_name": "MyCube",
"position": [0, 1, 0]
}
},
{
"op": "CreatePBRMaterial",
"params": {
"entity_name": "MyCube",
"base_color": [0.2, 0.5, 1.0, 1.0],
"metallic": 0.0,
"roughness": 0.4
}
}
]
Or use the AI Agent to do it with natural language:
./build/toolchain/cli/eng_cli agent ~/MyProject Main \
--prompt "Create a blue cube at position 0,1,0 with smooth PBR material"
Writing Scripts
Scripts are C++ files that get hot-reloaded at runtime. Create one:
./build/toolchain/cli/eng_cli apply-plan ~/MyProject - --json <<'EOF'
[{
"op": "CreateScript",
"params": {
"script_name": "Spinner",
"template_type": "empty"
}
}]
EOF
Then edit Content/Scripts/Spinner.cpp:
#include <eng/sdk/script_context.hpp>
#include <cmath>
extern "C" {
void OnStart(ScriptContext* ctx) {
ctx->log_message(ctx, "Spinner started!");
}
void OnUpdate(ScriptContext* ctx) {
float dt = ctx->get_delta_time();
float rot[4];
ctx->get_rotation(ctx->self, rot);
// Rotate around Y axis
float angle = dt * 1.0f;
float half = angle * 0.5f;
float sin_half = sinf(half);
float cos_half = cosf(half);
// Multiply quaternions (current * delta)
float new_rot[4] = {
rot[0] * cos_half + rot[2] * sin_half,
rot[1] * cos_half + rot[3] * sin_half,
rot[2] * cos_half - rot[0] * sin_half,
rot[3] * cos_half - rot[1] * sin_half
};
ctx->set_rotation(ctx->self, new_rot);
}
void OnDestroy(ScriptContext* ctx) {}
}
Compiling and Attaching Scripts
# Compile all scripts
./build/toolchain/cli/eng_cli compile-scripts ~/MyProject
# Attach to an entity
./build/toolchain/cli/eng_cli attach-script ~/MyProject Main MyCube Spinner
Play Mode
Test your scene in play mode:
# Run headless for 60 frames
./build/toolchain/cli/eng_cli play ~/MyProject Main -f 60 --verbose
# Or launch the editor with auto-play
ENG_AUTO_PLAY=1 ./build/editor/eng_editor
Script Lifecycle
Every script can implement three functions:
| Function | Called | Use For |
|---|---|---|
OnStart | Once when play mode begins | Initialization, finding entities, setting up state |
OnUpdate | Every frame | Game logic, movement, input handling |
OnDestroy | When play mode ends or entity is destroyed | Cleanup |
Next Steps
- Components Reference — Learn about all available components
- Scripting API — Full scripting function reference
- Operations — All typed operations for building scenes
- AI Agent — Use natural language to build scenes