Skip to content

Repository files navigation

LuaWrapper

A Lua scripting layer for defGameEngine. Write your game logic entirely in Lua — the wrapper exposes the full engine API as Lua types, enums, and a global app object.

Copyright 2026 defini7 and J-Starling. Licensed under the GNU General Public License v3.0.


Prerequisites

DependencyVersionSource
MSYS2 MinGW-w64 g++16.xhttps://www.msys2.org
Lua5.5MSYS2: pacman -S mingw-w64-x86_64-lua
GLFW33.xMSYS2: pacman -S mingw-w64-x86_64-glfw
sol23.3.0 (patched)https://github.com/defGameEngine/sol2

The sol2 fork at defGameEngine/sol2 includes the patches required for Lua 5.5 compatibility. Install it by copying the include/sol folder into your MSYS2 include path, e.g. C:\msys64\mingw64\include\sol.


Building

cd LuaWrapper\Build
.\build.ps1

Output: LuaWrapper\Build\Target\LuaWrapper.exe (and the required runtime DLLs alongside it).


Running a Script

LuaWrapper.exe <path\to\script.lua>

Example:

LuaWrapper.exe Assets\Demo.lua

Script Structure

Every script must define three global functions. The engine calls them in this order:

-- Called once before the first frame.-- Return true to continue, false to abort.functionOnCreate()
returntrueend-- Called every frame. dt is delta time in seconds.-- Return true to keep running, false to exit.functionOnUpdate(dt)
returntrueend-- Called once at startup to configure the window.-- Must return a configuration table.functionCreateApp()
return {
title="My Game", -- window titlesize= { 320, 240, -- screen width, height in pixels3, 3 }, -- pixel size (each logical pixel = NxN screen pixels)full_screen=false,
vsync=false,
dirty_pixel=false, -- only redraw changed pixels
}
end

The global app object (type Application) is available from OnCreate onward.


Types

Vector2i / Vector2f / Vector2d

Two-component integer, float, and double vectors.

localv=Vector2i:new(10, 20) -- constructorv.x=5v.y=15

Methods (identical for all three types):

MethodReturnsDescription
Clamp(min, max)self typeClamp both components
Lerp(other, t)self typeLinear interpolation
Distance(other)numberEuclidean distance
DotProduct(other)numberDot product
CrossProduct(other)numberCross product (Z component)
Angle(other)numberAngle between vectors (radians)
Length()numberEuclidean length
Length2()numberSquared length
ManhattanDistance(other)numberManhattan distance
Max(other)self typeComponent-wise maximum
Min(other)self typeComponent-wise minimum
Swap()self typeSwap x and y
Norm()self typeNormalised copy
Abs()self typeAbsolute value of each component
Perpendicular()self typePerpendicular vector
Floor()self typeFloor each component
Ceil()self typeCeil each component
Round()self typeRound each component
Cartesian()self typePolar → Cartesian (x=angle, y=radius)
Polar()self typeCartesian → Polar
ToString()string"(x, y)"

Operators (defined by the Lua helpers layer):

+, -, *, /, //, %, ^, unary -, ==, <, <=, tostring

Each operator accepts a number scalar on the right-hand side or another vector of the same type.


Pixel

An RGBA colour value. Each channel is a uint8 (0–255).

localp=Pixel:new(255, 128, 0, 255) -- r, g, b, ap.r=200

Methods:

MethodReturnsDescription
Lerp(other, t)PixelLinear interpolation between two colours
ToString()string"(r, g, b, a)"

Free function:

localp=PixelFloat(0.5, 0.0, 1.0, 1.0) -- channels in [0.0, 1.0]

Operators:+, -, *, /, //, tostring — channels are clamped to [0, 255].


KeyState

Returned by app:GetKey() and app:GetMouse().

FieldTypeDescription
heldboolKey is held down this frame
pressedboolKey was just pressed (first frame)
releasedboolKey was just released

Sprite

Pixel-based image (CPU-side).

locals=Sprite:new() -- emptylocals=Sprite:new(Vector2i:new(64, 64)) -- blank 64x64locals=Sprite:new("Assets/tile.png") -- load from file
MemberDescription
sizeVector2i — dimensions
pixelsRaw pixel array
MethodDescription
Create(size)Allocate blank sprite
Load(path)Load from file
Save(path, FileType)Save to file
SetPixel(x, y, Pixel) / SetPixel(Vector2i, Pixel)Write a pixel
GetPixel(x, y, WrapMethod) / GetPixel(Vector2i, WrapMethod)Read a pixel
SetPixelData(pixels)Bulk-write pixel array
Sample(u, v, SampleMethod, WrapMethod) / Sample(Vector2f, …)Sample at UV (0–1)

Texture

GPU-side texture built from a Sprite.

localt=Texture:new(sprite)
localt=Texture:new("Assets/tile.png")
MemberDescription
idInternal GL texture ID
uv_scaleVector2f — UV tiling scale
sizeVector2i — texture dimensions
MethodDescription
Load(path)Load from file
Update(sprite)Re-upload from Sprite

Graphic

A combined CPU Sprite + GPU Texture, used as a render target.

localg=Graphic:new()
localg=Graphic:new("Assets/bg.png")
localg=Graphic:new(Vector2i:new(320, 240))
MemberDescription
textureTexture*
spriteSprite*
MethodDescription
Load(path) / Load(Vector2i)Load or allocate
Save(path)Save sprite to file
UpdateTexture()Upload sprite pixels to GPU

Layer

A rendering layer returned by app:GetLayerByIndex().

PropertyTypeDescription
visibleboolWhether the layer is drawn
updateboolWhether the layer is updated
tintPixelTint colour applied over the layer
offsetVector2iLayer screen offset
sizeVector2iLayer size (read-only)
textureStructureTextureStructureGeometry mode for texture draws
pixelModePixelModePixel blending mode for this layer

Enums

Key

Used with app:GetKey(Key.X).

Space Apostrophe Comma Minus Period Slash
K0–K9 Semicolon Equal
A–Z
LeftBracket Backslash RightBracket
Escape Enter Tab Backspace Insert Del
Right Left Down Up PageUp PageDown Home End
CapsLock ScrollLock NumClock PrintScreen Pause
F1–F24
Np0–Np9 NpDecimal NpDivide NpMultiply NpSubtract NpAdd NpEnter NpEqual
LeftShift LeftControl LeftAlt LeftSuper
RightShift RightControl RightAlt RightSuper
Menu None

Button

Used with app:GetMouse(Button.X).

Left Right Wheel Mouse4 Mouse5 Mouse6 Mouse7 Mouse8

PixelMode

Used with app:SetPixelMode(PixelMode.X).

Default Alpha Mask Custom

FileType

Used with sprite:Save(path, FileType.X).

Bmp Png Jpg Tga TgaRle

SampleMethod

Used with app:SetSampleMethod and sprite:Sample.

Linear Bilinear Trilinear

WrapMethod

Used with app:SetWrapMethod and sprite:GetPixel / sprite:Sample.

None Repeat Mirror Clamp

TextureStructure

Used with app:SetTextureStructure, app:DrawTexturePolygon.

Default Fan Strip Lines LineStrip Wireframe

Colour Table

Pre-defined Pixel constants accessible as Colour.Name:

Black DarkBlue DarkGreen DarkCyan DarkRed DarkMagenta
DarkGrey DarkOrange DarkBrown DarkPurple
Orange Grey Blue Green Cyan Red Magenta Yellow White
Gold Pink Maroon Lime Brown Beige Violet Purple None

Application API

All calls go through the global app object.

Drawing — Pixels & Primitives

app:Draw(x, y, Pixel) -- draw a single pixelapp:Draw(Vector2i, Pixel)
app:DrawLine(x1, y1, x2, y2, Pixel)
app:DrawLine(Vector2i, Vector2i, Pixel)
app:DrawTriangle(x1,y1, x2,y2, x3,y3, Pixel)
app:DrawTriangle(Vector2i, Vector2i, Vector2i, Pixel)
app:FillTriangle(...)
app:DrawRectangle(x, y, w, h, Pixel)
app:DrawRectangle(Vector2i, Vector2i, Pixel)
app:FillRectangle(...)
app:DrawCircle(x, y, r, Pixel)
app:DrawCircle(Vector2i, r, Pixel)
app:FillCircle(...)
app:DrawEllipse(x, y, rx, ry, Pixel)
app:DrawEllipse(Vector2i, Vector2i, Pixel)
app:FillEllipse(...)
app:DrawString(x, y, text, Pixel, scaleX, scaleY)
app:DrawString(Vector2i, text, Pixel, Vector2i)
app:Clear(Pixel) -- clear pixel layerapp:ClearTexture(Pixel) -- clear texture layer

Drawing — Sprites

app:DrawSprite(x, y, Sprite*)
app:DrawSprite(Vector2i, Sprite*)
app:DrawPartialSprite(x, y, fx, fy, fw, fh, Sprite*)
app:DrawPartialSprite(Vector2i, Vector2i, Vector2i, Sprite*)

Drawing — Textures

app:DrawTexture(Vector2f, Texture*, scale_Vector2f, tint_Pixel)
app:DrawPartialTexture(Vector2f, Texture*, fp_Vector2f, fs_Vector2f, scale_Vector2f, tint_Pixel)
app:DrawWarpedTexture(points_table, Texture*, tint_Pixel) -- points = {Vector2f, ...}app:DrawRotatedTexture(Vector2f, Texture*, angle, center_Vector2f, scale_Vector2f, tint_Pixel)
app:DrawPartialRotatedTexture(Vector2f, Texture*, fp, fs, angle, center, scale, tint)

Drawing — Texture Geometry

app:DrawTextureLine(Vector2i, Vector2i, Pixel)
app:DrawTextureTriangle(Vector2i, Vector2i, Vector2i, Pixel)
app:FillTextureTriangle(Vector2i, Vector2i, Vector2i, Pixel)
app:DrawTextureRectangle(Vector2i, Vector2i, Pixel)
app:FillTextureRectangle(Vector2i, Vector2i, Pixel)
app:DrawTextureCircle(Vector2i, r, Pixel)
app:FillTextureCircle(Vector2i, r, Pixel)
app:DrawTextureString(Vector2i, text, Pixel, scale_Vector2f)
app:DrawTexturePolygon(vertices_table, colours_table, TextureStructure)
app:GradientTextureTriangle(Vector2i, Vector2i, Vector2i, Pixel, Pixel, Pixel)
app:GradientTextureRectangle(Vector2i, Vector2i, cTL, cTR, cBR, cBL)

Drawing — Wireframe Models

app:DrawWireFrameModel(model_table, x, y, rotation, scale, Pixel)
app:DrawWireFrameModel(model_table, Vector2f, rotation, scale, Pixel)
app:FillWireFrameModel(...)
-- model_table: array of Vector2f defining the shape outline

Render State

app:SetDrawTarget(Graphic*) -- redirect drawing to a Graphic (nil = screen)app:GetDrawTarget() -- returns Graphic* or nilapp:SetPixelMode(PixelMode)
app:GetPixelMode() -- returns PixelModeapp:SetWrapMethod(WrapMethod)
app:SetSampleMethod(SampleMethod)
app:SetTextureStructure(TextureStructure)
app:GetTextureStructure()
app:UseOnlyTextures(bool) -- disable pixel-layer renderingapp:SetFont(path) -- custom bitmap font (BMP)app:SetShader(fn) -- fn(Vector2i, Pixel src, Pixel dst) -> Pixel

Input

localks=app:GetKey(Key.A) -- returns KeyStatelocalbs=app:GetMouse(Button.Left) -- returns KeyStateapp:GetMousePos() -- returns Vector2iapp:GetMouseX() -- returns intapp:GetMouseY() -- returns intapp:GetMouseWheelDelta() -- returns intapp:CaptureText(bool) -- start/stop text capture modeapp:IsCapturingText() -- returns boolapp:GetCapturedText() -- returns stringapp:GetCursorPos() -- returns cursor position in captured textapp:IsCaps() -- returns boolapp:ClearCapturedText()

Window

app:GetScreenSize() -- returns Vector2i (logical pixels)app:GetWindowSize() -- returns Vector2i (physical pixels)app:ScreenWidth() -- returns intapp:ScreenHeight() -- returns intapp:GetInvertedScreenSize() -- returns Vector2f (1/w, 1/h)app:IsFullScreen()
app:IsVSync()
app:IsFocused()
app:IsDirtyPixel()
app:IsWindowClosed()
app:SetTitle(string)
app:SetIcon(path)
app:EnableVSync(bool)
app:EnableFullscreen(bool)
app:GetDropped() -- returns table of dropped file paths

Timer

app:GetDeltaTime() -- returns float (seconds since last frame)app:GetFPS() -- returns int

Console

app:SetConsoleBackgroundColour(Pixel)
app:ShowConsole(bool)
app:IsConsoleEnabled()
app:ClearConsole()

Layers

localid=app:CreateLayer(Vector2ioffset, Vector2isize)
localid=app:CreateLayer(Vector2ioffset, Vector2isize, boolupdate, boolvisible, Pixeltint)
app:PickLayer(id) -- set active drawing layerapp:GetPickedLayer() -- returns current layer idlocallayer=app:GetLayerByIndex(id) -- returns Layer object

States

app:PickState(id)
app:GetPickedState()
localstate=app:GetStateByIndex(id)

Helper Functions

These are injected into the Lua environment automatically before your script runs.

clamp(n, min, max) -- clamp n to [min, max]-- Installs arithmetic operators on a vector type table.-- Called automatically for Vector2i, Vector2f, Vector2d.AddVectorOperations(t)

Minimal Example

localW, H=256, 240functionCreateApp()
return { title="Hello", size= { W, H, 3, 3 } }
endfunctionOnCreate()
returntrueendfunctionOnUpdate(dt)
app:Clear(Colour.Black)
app:DrawString(10, 10, "Hello, World!", Colour.White, 1, 1)
returnnotapp:GetKey(Key.Escape).pressedend

Example Scripts

FileDescription
Assets/Demo.luaFour-page feature demo: shapes, text/pixel ops, input, vector math
Assets/Test.luaSnake game

About

A Lua powered version of the engine.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages