C++ Scripting

Direct native scripting using ScriptContext API.

Overview

C++ Scripting in ModuEngine V6.8 provides direct access to the native ScriptContext API for developers who need fine-grained control over engine behavior. This is distinct from ModuCPP, which is a high-level scripting language that transpiles to C++ and offers a more declarative, gameplay-focused API.

If you're building game scripts, start with ModuCPP. Use native C++ scripting when you need:

  • Direct access to low-level engine systems
  • Maximum performance with no transpilation overhead
  • Deep integration with existing C++ codebases
  • Custom engine extensions and subsystems

ScriptContext API

The ScriptContext struct is the central interface for C++ scripts. It provides methods to query and modify scene objects, handle input, manage physics, and access engine subsystems.

Fundamental Methods

C++
1// Object access
2ModuNode* ScriptContext::GetObject() const;
3SceneObj* ScriptContext::GetSceneObject() const;
4
5// Transform
6void ScriptContext::SetPosition(const glm::vec3& pos);
7glm::vec3 ScriptContext::GetPosition() const;
8void ScriptContext::SetRotation(const glm::vec3& euler);
9glm::vec3 ScriptContext::GetRotation() const;
10
11// Physics (2D)
12void ScriptContext::SetRigidbody2DVelocity(const glm::vec2& vel);
13glm::vec2 ScriptContext::GetRigidbody2DVelocity() const;
14
15// Physics (3D)
16void ScriptContext::AddRigidbodyImpulse(const glm::vec3& impulse);
17void ScriptContext::SetRigidbodyVelocity(const glm::vec3& vel);

Input Queries

C++
1bool ScriptContext::IsKeyHeld(const std::string& key) const;
2bool ScriptContext::IsKeyPressed(const std::string& key) const;
3bool ScriptContext::IsKeyReleased(const std::string& key) const;
4
5glm::vec3 ScriptContext::GetMoveInputWASD(float upAxis = 0.0f, float downAxis = 0.0f) const;
6bool ScriptContext::IsSprintDown() const;
7
8float ScriptContext::GetMouseDelta(float speed = 1.0f) const;
9glm::vec2 ScriptContext::GetMousePosition() const;

Scene Queries

C++
1ModuNode* ScriptContext::FindObjectByName(const std::string& name) const;
2std::vector<ModuNode*> ScriptContext::FindObjectsByTag(const std::string& tag) const;
3
4// Children
5void ScriptContext::GetChildren(std::vector<ModuNode*>& out) const;
6ModuNode* ScriptContext::GetChild(int index) const;
7int ScriptContext::GetChildCount() const;

Native Hook Signatures

Native C++ scripts export specific hook functions that the engine calls at key points in the lifecycle.

Lifecycle Hooks

C++
1// Called when the script first loads
2extern "C" void Script_OnLoad() {
3 // Engine initialization
4}
5
6// Called when the scene object enters play mode
7extern "C" void Script_OnBegin(ScriptContext& ctx) {
8 // Setup logic
9}
10
11// Called every frame
12extern "C" void Script_OnTickUpdate(ScriptContext& ctx, float deltaTime) {
13 // Per-frame logic
14}
15
16// Called after rendering
17extern "C" void Script_OnLateUpdate(ScriptContext& ctx, float deltaTime) {
18 // Post-render logic
19}
20
21// Called when the scene object is destroyed
22extern "C" void Script_OnEnd(ScriptContext& ctx) {
23 // Cleanup
24}

Collision Hooks

C++
1extern "C" void Script_OnCollisionEnter(ScriptContext& ctx, ScriptContext& otherCtx) {
2 // Triggered when this object collides with another
3}
4
5extern "C" void Script_OnCollisionStay(ScriptContext& ctx, ScriptContext& otherCtx) {
6 // Called every frame while objects are in contact
7}
8
9extern "C" void Script_OnCollisionExit(ScriptContext& ctx, ScriptContext& otherCtx) {
10 // Triggered when collision ends
11}
12
13extern "C" void Script_OnTriggerEnter(ScriptContext& ctx, ScriptContext& otherCtx) {
14 // For trigger colliders (one-way collision)
15}

Editor Hook

C++
1// Render custom inspector UI (using ImGui)
2extern "C" void Script_OnInspector(ScriptContext& ctx) {
3 static float speed = 5.0f;
4 ImGui::SliderFloat("Speed", &speed, 0.0f, 20.0f);
5}

ImGui in Scripts

You can render immediate-mode UI (ImGui) directly from C++ scripts using the built-in ImGui integration. This is commonly used for debug visualization and inspector customization.

Basic ImGui Usage

C++
1#include <imgui.h>
2
3extern "C" void Script_OnInspector(ScriptContext& ctx) {
4 ImGui::TextWrapped("Hello from script!");
5
6 static float value = 0.5f;
7 ImGui::SliderFloat("Value", &value, 0.0f, 1.0f);
8
9 static bool enabled = false;
10 ImGui::Checkbox("Enabled", &enabled);
11
12 if (ImGui::Button("Click me!")) {
13 // Button pressed
14 }
15}

Manual Inspector

For data-driven workflows, you can manually define inspector fields using the engine's field system. These fields are serialized in the scene file and exposed in the editor.

Field Types

TypeC++ TypeEditor Widget
FloatfloatSlider / Input
IntintSlider / Input
Vec3glm::vec3XYZ Fields
Stringstd::stringText Input
BoolboolCheckbox
Object ReferenceModuNode*Drag-Drop Object
C++
1// Declare fields at the top level
2static float moveSpeed = 5.0f;
3static int maxHealth = 100;
4
5extern "C" void Script_OnInspector(ScriptContext& ctx) {
6 // Expose fields to inspector
7 ImGui::SliderFloat("Move Speed", &moveSpeed, 0.0f, 20.0f);
8 ImGui::SliderInt("Max Health", &maxHealth, 1, 500);
9}

Troubleshooting

Script not being called

Null ScriptContext

Performance Issues

  • Avoid heavy allocations in tight loops (TickUpdate)
  • Cache frequently-accessed pointers
  • Use glm::length() instead of manual distance calculations
  • Profile with the engine&apos;s built-in profiler