Documentation menu

Embedding

Put MAKO Inside Your Own App

MAKO isn't only something you run scripts inside directly — someone else's app or game engine (written in C#) can put MAKO inside itself instead, so its own users get to write .mko scripts. This page is for that C# developer, not for someone writing .mko scripts. If you just want to write MAKO scripts, you can skip this whole section.

New to coding?

Copy the examples exactly first. Run them. Then change one number or word and run them again. You are not expected to memorize the command lists.

1

The idea, in plain terms

Picture a game engine — call it Engine. Its developer wants players to be able to script things like "spawn an enemy here" by writing MAKO instead of learning the engine's own internals. To make that possible, the Engine developer writes a small amount of C# that connects one MAKO command (like Engine.spawn) to one real function inside their engine. Once that's done, anyone writing a MAKO script for that engine can call Engine.spawn(4, 2) and it just works — the script never needs to know it's actually running C# code underneath.

2

Four steps, each doing one job

1) Make an empty list of "extra abilities" to hand to MAKO. 2) Add one entry to that list for every function you want scripts to be able to call, saying what MAKO name it should have and what C# code should actually run. 3) Tell MAKO the name of your new namespace is allowed, so using Engine; works in a script. 4) Run the actual script.

Try this code
// 1. An empty list of extra abilities
var ctx = new MakoHostContext();

// 2. One line per function a script should be able to call.
//    Left side: the name a MAKO script will use, as "Namespace.function".
//    Right side: an ordinary C# function that does the real work.
ctx.RegisterFunction("Engine.spawn", (double x, double y) => (double)engine.SpawnEntity(x, y));
ctx.RegisterFunction("Engine.delta_time", () => (double)engine.DeltaTime);

// 3. Allow "using Engine;" in a script — without this line, step 2's
//    functions exist but a script isn't allowed to reach them yet.
ctx.RegisterPackage("Engine");

// 4. Actually run a script with all of the above turned on.
var interp = new Interpreter(ctx);
interp.Run(scriptSource);

(double x, double y) => ... is C#'s short way of writing a small function, the same idea as MAKO's own fn(x, y) { ... } — it just takes two numbers and hands one back.

3

What the script author sees

None of the C# above is visible to whoever writes the actual MAKO script. To them, Engine.spawn looks and works exactly like any built-in command such as Physics3D.step — because it is one, as far as the script can tell.

Try this code
using Engine;

main() {
    id = Engine.spawn(4, 2);
    print "spawned entity " + id;
    print "delta_time: " + Engine.delta_time();
}
4

A function with more than two numbers, or a list/dict

The two-line style above only covers plain numbers, text, or true/false, and up to three of them. For anything bigger — more arguments, or a list/dict passed in — use the longer form instead: a function that receives every argument as one list and picks out what it needs by position.

Try this code
ctx.RegisterFunction("Engine.spawn_many", args => {
    double x = (double)args[0]!;
    double y = (double)args[1]!;
    List<object?> tags = (List<object?>)args[2]!;
    return (double)engine.SpawnEntity(x, y, tags);
});
5

There's no package to install yet

MAKO doesn't publish a ready-to-download package for this. Point your own C# project's project file at MAKO's source instead — either the whole thing (src/Mako/Mako.csproj), or just the non-graphics files if that's all you need (see Mako.Web.csproj for an example of picking just those).