grug is a minimal, strongly-typed modding language designed for long-term compatibility and "immortal" mods across platforms, from modern systems down to the NES. It features a small LALR(1) grammar, no standard library, and a lossless, whitespaceless JSON AST to enable automatic upgrading, downgrading, and cross-language transpilation. With hot reloading and full user override of backends and APIs, grug prioritizes portability, control, and permanence.
2025-03-30.20-27-59.mp4
See the YouTube video Creating grug: the perfect modding language for an introduction to the grug modding language, or read its blog post:
Here is a contrived fib-Calculator.grug that a program might have:
# This is a member variable, which means
# every entity gets its own copy of it.
count: number = 100
# The host can call this exported function.
# This function is declared by mod_api.json.
export run() {
# We calculate the first 100 values
# of the fibonacci sequence, and store them
# in a local List called `fib_numbers`.
# List is a generic class declared by mod_api.json.
fib_numbers: List[number] = _fib_list(count)
# Prints [0, 1, 1, 2, 3, 5, ...].
# This host function is declared by mod_api.json.
print_list(fib_numbers)
}
# The host can't call local functions.
# Local function names must start with an underscore.
local _fib_list(n: number) List[number] {
fib_list: List[number] = List()
# We will be memoizing (caching) the results
# to speed up computation.
memo: Dict[number, number] = Dict()
i: number = 0
while i < n {
# This .append() is a method.
fib_list.append(_fib(i, memo))
i = i + 1
}
return fib_list
}
local _fib(n: number, memo: Dict[number, number]) number {
# If we already calculated it,
# we don't have to recalculate it.
if memo.has_key(n) {
return memo.get(n)
}
result: number = n
if n > 1 {
# The fibonacci sequence is recursive:
# fib(n) = fib(n-1) + fib(n-2)
result = _fib(n - 1, memo) + _fib(n - 2, memo)
}
# Memoize the result, so that we
# won't have to recalculate it next time.
memo.set(n, result)
return result
}Create an issue before you make any pull request, as that gives everyone the chance to discuss it.
If you are planning to work on an issue, leave a comment asking to be assigned to the issue. Only work on issues that have the planned label.
grug has an issue board that can be filtered to list good first issues or planned issues.
grug implementations consist of three core components: API bindings, a grug parser frontend, and a backend execution engine.
These grug implementations by the community pass all 500+ official grug tests, and include 'Hello, world!' examples:
- grug-for-python
- grug-for-c (don't use this yet, as it's very new)
- grug-rs
- grug-for-lua
