CVars & Console Commands

The Console

Chisel has a built-in developer console you can open at runtime to run commands, inspect values, and manipulate the world without recompiling. Commands are registered by creating a ConvarSubscriber anywhere in your codebase. Typing a command name followed by arguments executes the associated callback.

The engine & FPS template come with several built-in commands worth knowing about:

listcmd

Prints all registered commands to the console log.

map [name]

Loads a map by name from the Maps folder, or by full path. Use map unload to unload the current map.

timescale [value]

Sets the game's time scale. Useful for slow motion debugging.

noclip [0/1]

Toggles noclip on the player.

fov [value]

Sets the world camera field of view.

ent fire [name] ...

Manipulates a named entity. Can remove it, or read and set its position, rotation, and scale.

ent create [classname] [x,y,z]

Spawns an entity by class name at a world position.

CVars

A CVar is a named value that can be read in code and changed at runtime through the console. They are the most common way to expose tunable numbers like movement speeds, weapon values, or rendering settings without recompiling. Declare one as a static field anywhere in your project:

public static CVarFloat maxRunSpeed = new CVarFloat("pl_runspeed", 9.0f);
public static CVarInt maxAmmo = new CVarInt("wep_maxammo", 30);
public static CVarBool noclip = new CVarBool("noclip", false);

The first argument is the console name and the second is the default value. Once declared the CVar is automatically registered with the console and can be changed at any time by typing its name followed by a new value:

pl_runspeed 14
noclip 1
wep_maxammo 999

Typing the name with no arguments prints the current value and the default. The three built-in CVar types are CVarFloat, CVarInt, and CVarBool. All three have implicit conversions to their underlying type, so you can use them directly in expressions without calling GetValue():

// Both of these work identically
float speed = maxRunSpeed.GetValue();
float speed = maxRunSpeed;
Note

Declare CVars as static fields. Because ConvarSubscriber registers itself with the engine on construction, a CVar declared inside an instance method or constructor only registers when that object is created, which usually means that the command wont be registered.

Custom Console Commands

For commands that execute logic rather than just holding a value, use ConvarSubscriber directly. Like CVars, declare these as static fields so they register at startup:

public static readonly ConvarSubscriber cmdKillAll = new ConvarSubscriber("kill_all", (string[] args) =>
{
    foreach (var entity in EntityManager.entities.GetValues())
    {
        if (entity.controller is LivingActor actor)
            entity.TakeDamage(new DamageInfo { damage = 9999, damageType = -1 });
    }
    MainEngine.Instance.Console.AppendLog("Done.");
});

The callback receives a string[] of everything typed after the command name, split by spaces. If the user types mycommand foo bar 123, args will be ["foo", "bar", "123"]. You're responsible for parsing and validating them. In release builds, any exception thrown inside a command callback is caught and printed to the console log rather than crashing the game.

Write back to the console from inside a command using MainEngine.Instance.Console.AppendLog(), which is how all the built-in commands print their output.

Custom CVar Types

If you need a CVar for a type beyond float, int, or bool, use CVarType<T> directly with a custom parse function:

public static CVarType<string> playerSkin = new CVarType<string>("pl_skin", "default", (s) => s);

The third argument is a function that converts the raw console string into your type. The same print-on-no-args behavior applies, and the implicit conversion operator is available via GetValue() if you need it directly.