Skip to content

Repository files navigation

Luam /luːm/

An ahead-of-time (AOT) Lua compiler for Minecraft datapacks, using Lua 5.1 as the language frontend.

Writing Datapacks by Hand Can Be Annoying

  • You are restricted to Minecraft's command syntax
  • No direct support for iteration
  • No direct support for structured data
  • Control flow is supported, but only through callback functions
  • No call stack
  • Global mutable state
  • A single "block" or unit of code must be within its own .mcfunction file
  • For advanced projects, they become amalgamations of .mcfunction and .json files
  • Data is treated as code

Why Lua?

  • Lua is easy to parse, it has a very disambiguous syntax.
  • Lua is known for being embedded in host-applications (e.g. NeoVim, Garry's Mod, Roblox)
  • Lua tables align with how data is represented in Minecraft

Similar Projects

  • Beet - a data-driven Python "development kit" for creating datapacks
  • Sandstone - a Typescript datapack library
  • ObjD - a framework for developing datapacks in the Dart programming language

Getting Started

See below on how to get started with Luam.

1. How to Install

  • Go to the releases releases page
  • Download the compiled JAR file
  • Place the JAR in a location of your choosing
  • Add the path of the JAR into your PATH (optional)
  • Test the compiler using:
~> luam --version

2. Compile from Source

Compiling from source is just as simple as installing.

  • Download the latest stable release of the source tree
  • At the root of the repository, invoke this command
~> gradlew assemble
  • If successful you should have an executable JAR file
  • Test the compiler using:
~> luam --version

Your First Script

To start off with, check the examples directory for different Lua scripts to test the features of the compiler. For example, here is the hello-world.lua snippet:

-- literally just prints 'Hello, World!'

print('Hello, World!')

Invoke the compiler (assuming cwd is examples):

~> luam hello-world.lua -o hello-world

The -o flag signals to the compiler that you want to specify a name for the datapack. It is optional, and will default to a random name if left unspecified.

  • Place the datapack in your Minecraft world data folder
  • Load up the respective Minecraft world
  • On load, you should see a message pop-up in the chat history:
[server] Hello, World!

Adding an icon

Every proffessional datapack needs to have a thumbnail.

Going back to compiling the hello-world.lua script:

~> luam hello-world.lua -i icon.png

The -i flag signals to the compiler that you want to specify a URL to an image file that will show up in the datapacks list on Minecraft.

Targetting Specific Minecraft Versions

You may want to compile for the latest version of mimecraft; or you may want to compile a different target version. By default, Luam defaults to the latest compilable version known to it. However, you can specify a minimum version for this datapack as follows:

~> luam hello-world.lua --format=48

This specifies that the datapack is runnable on Minecraft version 1.21 or later.

You may want to also specify a maximum version:

~> luam hello-world.lua --format=48,78

This specifies that the datapack is runnable on Minecraft versions 1.21 through 1.12.8.

You also cannot specify a maximum version without a minimum version.

Compiler Optimizations

To retain 100% parity with Lua 5.1, Luam optimizes tail calls as the Lua manual states it is a feature of the language.

But, by default, Luam makes no effort to optimize. The compiler always assumes an optimization level of 0, unless specified otherwise. The -O<level> flag specifies the optimization level, with the maximum being level 3. This is heavily inspired by the design of the GNU C Compiler (GCC).

A list if each optimization level, and what each enables, are listed below.

Level 0 (-O0) (Default)

  • Tail Call Optimization (TCO)

Level 1 (-O1)

  • Constant Folding (-fconst-fold)
  • Dead Branch Elimination (-fprune-dead)
  • Algebraic Simplifications (-ffast-math)
  • Function Inlining (-fsimple-inline)
    • Functions in tail call are not inlined

Level 2 (-O2)

  • Constant Propagation (-fconst-prop)
  • Dead Code Elimination (-fremove-dead-code)
  • Static Loop Optimizations (-floop-opt)
  • Aggressive Function Inlining (-faggressive-inline)
    • Functions in tail call are not inlined

Optimization levels are cumulative.

References

About

Ahead-of-Time (AOT) Lua compiler for Minecraft datapacks

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors

Languages