James Kingston Clarke

Introducing Konsol

A library for building in-game consoles Godot in C#

Written by James Clarke on

#c# #godot #dev

A command console for Godot in C#

Whilst developing games as side-projects, I always inevitably get distracted by building cool systems in the game, and not actually the game itself. Obviously this leads to no games being released, but it does lead to lots of fun projects being built!

My most recent game required a fairly basic in-game console, and so I wanted to build one!

Contribution is more than welcome!

Basic Usage

using Konsol;

var d = new Dispatcher();

d.Register(new Command().Literal("ping").Then(((args, context) =>
{
    Console.WriteLine("pong!");
    return context;
})));

d.Register(new Command().Literal("tp").Arg("x").Arg("y").Then(((args,context) =>
{
    Console.WriteLine($"Teleporting to {args["x"]}, {args["y"]}");
    return context;
})));

d.Exec("ping");
d.Exec("tp -100 235");

Passing context to command handlers

A particular situation arose where I needed to call some in game code from my method that was dependent on the context of the command caller.

Take for example a basic ping command where you enter ping and it prints pong to the terminal. You could implement that like this

d.Register(new Command().Literal("ping").Then((args =>
{
    globalTerminal.Println("pong")
})));

However, what happens if you need to print to the specific terminal that the command was called from?

This is why I introduced the Context type to the library. This type is extensible and is used to store contextual information that’s passed down into the command handlers.

class MyGameCommandContext : Context {

    private Terminal terminal;

    public MyGameCommandContext(Terminal terminal){
        this.terminal = terminal;
    }

    public void Println(string msg){
        terminal.Println(msg);
    }
}

var d = new Dispatcher();

d.Register(new Command().Literal("ping").Then(((args, ctx) =>{
    (ctx as MyGameCommandContext).Println("pong");
})));

d.Exec("ping", new MyGameCommandContex(terminal));