The Modular Game Engine

Build games with hot-compiled scripts, real-time physics, and a fully integrated editor. Native C++, open architecture.

Modularity Engine - 2D Game EditorModularity Engine - Pixel Sprite EditorModularity Engine - 3D Model EditorModularity Engine - 3D Scene ViewModularity Engine - Landscape Environment

Choose Your Scripting Surface

All four options can drive the same 2D movement test. The difference is how much engine plumbing each layer exposes to the script author.

High-level gameplay scripting with built-in helpers.

Movement2DTest.mcpp
ModuCPP
1add ModuCPP;
2add ModuInput;
3add ModuEngine;
4
5public class Movement2DTest : ModuNode
6{
7 public float walkSpeed = 4.0f;
8 public float runSpeed = 7.0f;
9 public float acceleration = 18.0f;
10 public float drag = 8.0f;
11
12 void TickUpdate()
13 {
14 Vector2 move = input.WASDNormalized();
15 bool running = input.sprint();
16 float speed = running ? runSpeed : walkSpeed;
17
18 TryMoveRigidbody2D(ctx, move * speed, acceleration, drag, dt);
19 obj.UILabel = "ModuCPP 2D Speed: " + IntR(speed);
20 }
21}
Movement2DTest.cpp
C++
1#include "ModuCPP"
2#include <cmath>
3#include <string>
4
5namespace {
6 float walkSpeed = 4.0f;
7 float runSpeed = 7.0f;
8}
9
10void TickUpdate(ScriptContext& ctx, float dt)
11{
12 if (!ctx.object || dt <= 0.0f || !ctx.HasRigidbody2D()) return;
13
14 glm::vec3 move3 = ctx.GetMoveInputWASD(0.0f, 0.0f);
15 glm::vec2 move(move3.x, move3.z);
16
17 const float len = glm::length(move);
18 if (len > 0.0001f) {
19 move /= len;
20 }
21
22 const float speed = ctx.IsSprintDown() ? runSpeed : walkSpeed;
23 ctx.SetRigidbody2DVelocity(move * speed);
24 ctx.SetUILabel(std::string("Native C++ 2D Speed: ") + ModuCPP::IntR(speed));
25}
Movement2DManaged.cs
C#
1using System;
2
3namespace ModuCPP;
4
5public class Movement2DManaged
6{
7 private float walkSpeed = 4.0f;
8 private float runSpeed = 7.0f;
9
10 public void Begin(IntPtr ctx, float deltaTime)
11 {
12 var context = new Context(ctx);
13 context.AutoSettingsFrom(this, save: false);
14 }
15
16 public void TickUpdate(IntPtr ctx, float deltaTime)
17 {
18 var context = new Context(ctx);
19 context.AutoSettingsFrom(this, save: false);
20 if (deltaTime <= 0.0f || !context.HasRigidbody2D) return;
21
22 Vec3 move3 = context.GetMoveInputWASD(0.0f, 0.0f);
23 float length = MathF.Sqrt((move3.X * move3.X) + (move3.Z * move3.Z));
24 Vec2 move = length > 0.0001f
25 ? new Vec2(move3.X / length, move3.Z / length)
26 : new Vec2(0.0f, 0.0f);
27
28 float speed = context.IsSprintDown() ? runSpeed : walkSpeed;
29 context.Rigidbody2DVelocity = new Vec2(move.X * speed, move.Y * speed);
30 context.SetUILabel($"Managed C# 2D Speed: {speed:0}");
31 }
32}
movement_2d_test.c
C
1#include "ScriptRuntimeCAPI.h"
2#include <math.h>
3
4static float g_walkSpeed = 4.0f;
5static float g_runSpeed = 7.0f;
6
7void Modu_Begin(ModuScriptContext* ctx) {
8 if (!ctx) return;
9 Modu_AddConsoleMessage(ctx, "C bridge 2D movement test ready.", MODU_CONSOLE_INFO);
10}
11
12void Modu_TickUpdate(ModuScriptContext* ctx, float dt) {
13 if (!ctx || dt <= 0.0f) return;
14
15 ModuVec3 move = Modu_GetMoveInputWASD(ctx, 0.0f, 0.0f);
16 float len = sqrtf((move.x * move.x) + (move.z * move.z));
17 if (len > 0.0001f) {
18 move.x /= len;
19 move.z /= len;
20 } else {
21 move.x = 0.0f;
22 move.z = 0.0f;
23 }
24
25 float speed = Modu_IsSprintDown(ctx) ? g_runSpeed : g_walkSpeed;
26 ModuVec3 pos = Modu_GetPosition(ctx);
27 pos.x += move.x * speed * dt;
28 pos.z += move.z * speed * dt;
29 Modu_SetPosition(ctx, pos);
30}
ModularityModularity Engine

Native C++ engine for real-time applications.