Kage Studio x KonsolScript Integration Brief

This document is the fast-start reference for embedding KonsolScript (libkonsolscript) inside Kage Studio. It covers the embedding API surface, language rules that affect host integration, and known gotchas. For a narrative walkthrough see embedding-guide.md.


1. Headers and Linking

Include (public surface only)

#include "kse.hpp"        // Engine class - create, run, bind
#include "kse_types.hpp"  // Value, CMD_* constants, Token, ListVar, MapVar, ArrayVar
#include "kse_watch.hpp"  // File-watch / hot-reload support

kse_dynload.hpp is internal - do not expose it or include it from Kage Studio code.

Link against libkonsolscript (static or shared depending on your build). Add konsolscript.cpp to the SRCS list if building from source.

Plain C API (optional)

konsolscript.h exposes a flat C API for FFI or plugin bridging from languages that cannot use C++ headers directly. Python bindings live in bindings/python/konsolscript.py.


2. Lifecycle

Engine creation

Engine eng;
eng.run("path/to/script.ks");

Entry point - auto-called

libkonsolscript automatically calls main() as the script entry point.

Plugins

Plugins follow the kse_<name>.dll naming convention. The host must pass a plugin search path via --plugin-path <dir>. The flag is required and settled - do not remove or alias it.


3. Language Rules That Affect Host Integration

Zero-value design - no null/nil

KonsolScript has no null or nil. Every type has a zero value: 0, "", false, or a fresh collection instance. Do not pass null pointers or expect null returns across the boundary.

ByRef output convention

Every non-void stdlib method writes its result to its last argument, which must be a pre-declared variable in the script. The return value of the call expression is not used.

// correct
Var:String _result;
String:Upper("hello", _result);   // _result is now "HELLO"

// wrong - never assign the call directly
_result = String:Upper("hello");

Host-side bindings you expose to scripts must follow the same convention if they return values.

Var declarations need semicolons

Every Var:TYPE name; line requires a trailing semicolon. A missing semicolon silently corrupts class-body parsing - it eats the next keyword as a field name. Enforce this in any script generator or template Kage Studio produces.

Dictionary, not Map

The Map module was renamed to Dictionary. Use Dictionary:New, Dictionary:Set, Dictionary:Get, etc. There is no Map: module.

Exit

Scripts exit via Konsol:Exit(code). There is no OS:Exit. If Kage Studio needs to intercept or suppress script exit, hook into the CMD_EXIT dispatch point in the engine.

Collections require a declared type

No Any or union types. Every List, Dictionary, or Array must be declared with a concrete element type: ListOf:String, DictOf:Int, etc. ListOf:String and similar forms are also valid as function parameter types.


4. Callbacks and Function References

A bare function name without () evaluates to its name as a string. This is how function references are passed.

// pass a callback by name (no parens)
Net:OnMessage(handleMsg);

The engine resolves the name at call time. Guard with isFuncName() in any host code that accepts a callback reference from a script to prevent callback hijacking.


5. Stdlib Modules Available to Scripts

Module Purpose
Math: Arithmetic, rounding, random
String: Parsing, formatting, search
Konsol: Print (single-arg), input, exit
File: Read, write, path ops
List: Ordered collections
Dictionary: Key-value collections
Net: Sockets, OnMessage, OnData
Curl: HTTP upload/download

Konsol:Print is single-argument. To print multiple values, concatenate first or call Print multiple times.

Curl: Upload throws CurlException on failure (message from curl_easy_strerror). Curl: Download returns a Boolean success flag.


6. Plugin System


7. Expression Evaluation Order (for custom operators or AST work)

evalExpr -> evalTernary -> evalLogicalOr -> evalLogicalAnd
         -> evalBitOr -> evalBitXor -> evalBitAnd
         -> evalComparison -> evalShift -> evalAddSub
         -> evalMulDiv -> evalUnary -> evalAtom

8. Key Gotchas Summary

Gotcha Rule
main() auto-called Never add an explicit call
No null/nil Use zero values
ByRef outputs Last arg is the output variable
Missing semicolons Silently corrupt class parsing
Map is gone Use Dictionary
OS:Exit does not exist Use Konsol:Exit(code)
Plugin prefix Always kse_<name>, never short name
Print is single-arg Concatenate before printing
Bare name = string ref fn (no parens) is a function reference