LoLa Programming Language

2021-09-23

Tiny scripting language for games

software (29) programming-language (7) zig (14)

Table of Contents
  1. Why a new language (again)?
  2. Design Constraints and Features
  3. Syntax
  4. Semantics
  5. Runtime
  6. Links

When else Heart.Break() is a tiny bit too inspiring.

Project Website: lola.random-projects.net

Select anchorWhy a new language (again)?

While playing the wonderful game else Heart.Break(), really got a hang of Sprak, the games built-in programming language.

When later working on a game project called Destoroya, me and a friend figured we wanted to have our own programming language for the player to automate and create things like vehicle controllers and such, so I searched for a programming language for that task.

The problem was: There is no real solution in that space yet. Lua, is a strong contender, but features “turing safety” only by abusing the debug features of the runtime. I wanted something where the player can create endless loops and they won’t hang the game, so I started working on a new language called Logic Language which later shortened to LoLa.

Select anchorDesign Constraints and Features

LoLa was designed to be simple, easily learnable and of low complexity. It also was required to have a runtime suitable for games, so the runtime had to be interruptible, serializable and resource constrainable.

Select anchorSyntax

I decided to go with a JavaScript-like syntax as it’s both fairly widespread and thus easy to learn:

var list = [ "Hello", "World" ];
for(text in list) {
  Print(text);
}

Select anchorSemantics

Semantic-wise I made a pretty “bold” decision to not support reference semantics beyond opaque references to something called objects. Everything else is always copying data, including arrays and strings.

This way, no unexpected side effects will happen for unexperienced programmers like “Passing an array and suddenly mutating the passed argument”:

function mutAndPrint(items)
{
    items[1] = 42;
    Print(items);
}
var list = [ 1, 2, 3 ];
mutAndPrint(list); // prints 1, 42, 3
print(list);       // prints 1, 2, 3

If you want to mutate parameters, you have to pass-and-return the values.

This decision does not always result in the optimal code, but as LoLa isn’t designed for huge programs, this is effectivley neglectible.

LoLa also has a fully dynamic type system with a small set of builtin types:

But as sometimes references are necessary, a concept of objects was introduced. An object in the LoLa sense is an opaque thing that can be passed around and you can invoke methods on it. They have no properties, fields or anything, so a LoLa object is what OOP languages usually call an interface.

Objects are meant to be the means for the programmer to communicate with other scripts, game objects or other environmental interaction except for function calls.

A RPC system might look like this:

var obj = Connect("host1.lola.example.com");
if(obj != void) {
    obj.Tell("Hello, World!");
}

Select anchorRuntime

The whole runtime of the system is implemented in Zig and was designed to fulfil the constraints from the start on.

It’s implemented as a regular stack virtual machine that is overall pretty straightforward. The virtual machine can handle several threads at a time, each thread being fully serializable at any point in time. Execution will always yield back to the VM host, and while not actively executing, a VM can be serialized. Also the full runtime environment including all object instances, and global variables can also be serialized.

This way, a running LoLa system can be paused, saved to disk and executed at an arbitrary point in time later. This feature was an important cornerstone of the architecture as Coding Games often require this feature (so players can save while their code is running).

The idea of the multithreading environment is that a player can create a full network of interconnected machines that communicate with each other. This was a requirement in Destoroya, but is now also used in the Digital Scavenger project.

Select anchorLinks