terminalLanguage Basics

For the purposes of these docs, we refer to CSL and the runtime/platform around it interchangeably

This page is the “data modeling” side of CSL: primitives, structs/classes, and the patterns you’ll use to represent game state cleanly.

circle-info

If you’re brand new, start with Getting Started with CSL. This page assumes you already know how to declare variables and write proc/method.

Primitive types

Numbers and bools

  • Signed integers: s8, s16, s32, s64 (alias: int == s64)

  • Unsigned integers: u8, u16, u32, u64 (alias: uint == u64)

  • Floats: f32 (alias: float), f64

  • Booleans: b8 (alias: bool), b16, b32, b64

health: int = 100;
speed: float = 6.5;
is_dead: bool = false;

Strings

string is used constantly for IDs, names, and formatting.

item_id := "sword";
log_info("picked up %", {item_id});

Vectors

v2, v3, v4 are built-in math/data types:

Enums

Enums are great for readable “mode/state” fields:

circle-info

Enum values are commonly referenced with the shorthand .VALUE when the compiler can infer the enum type.

Structs (value types)

Use structs for “plain data” you want to copy around cheaply (config, small state blobs, descriptors).

When to use a struct

  • A descriptor/config object (*_Desc)

  • Small, self-contained state you want to copy by value

  • Data you want to embed inside another type

When not to use a struct

  • Large mutable state shared across multiple systems (use a class)

  • “Identity” objects (players, items, long-lived objects) (use a class)

Classes (reference types)

Classes are reference types. Create instances with new(...).

Inheritance

You can inherit from other structs/classes:

circle-exclamation

Arrays, slices, and dynamic arrays

You’ll see three common shapes:

  • Fixed arrays: [N]T (compile-time size)

  • Slices / managed arrays: []T (a view of an array)

  • Dynamic arrays: [..]T (resizable list)

Example:

For a full guide, see Arrays and Collections.

Passing by reference (ref)

If a procedure needs to modify a value, use ref:

This is especially useful for “layout-style” APIs that progressively cut/shrink a rect:

Casting

Use expr.(T):

Type polymorphism (generic-style procs)

CSL supports polymorphic procedures using $ to deduce types at the callsite:

Types as values (typeid)

typeid is a value that represents a type at runtime and/or for polymorphic calls:

Practical modeling guidelines

  • Per-player state lives on Player. If it should differ between players, it shouldn’t be global.

  • Prefer small structs for descriptors and store runtime state in classes/components.

  • Keep server-authoritative data authoritative. If it affects gameplay, don’t compute it only on the client.

For player-specific patterns, see Adding Player Logic. For the ECS side of the world, see Entities and Components.

Last updated