Example:
Code: Select all
-- input.lua
-- Lines starting with "!" are part of the metaprogram.
!local DEV_MODE = true
-- Here "!()" outputs a value as a literal.
local gameData = !(parseJsonFile("game.json"))
function love.load()
initGame()
!if DEV_MODE then
initLevelEditor()
!else
setupTelemetry()
!end
end
Code: Select all
-- output.lua
-- This table is what parseJsonFile() returned.
local gameData = {classes={"Warrior","Archer","Wizard"},stats={"Health","Mana"}}
function love.load()
initGame()
initLevelEditor() -- We got this line because DEV_MODE was true.
end
More examples at GitHub
Another example relevant to LÖVE
Usage:
Code: Select all
local pp = require("preprocess")
local info, err = pp.processFile{
pathIn = "game.lua2p", -- This is the file we want to process.
pathMeta = "game.meta.lua", -- Temporary output file for the metaprogram.
pathOut = "game.lua", -- The output path.
}
if not info then
error(err)
end
print("Lines of code processed: "..info.lineCount)
Another benefit is that you can make choices in your metaprogram about what code the final program should have. For example, during development you may have a bunch of developer-only functionality that should be excluded from a public build. (Compare this to #if/#ifdef directives in C/C++.)
Yet another benefit is that some kinds of code are simply easier to write and look nicer if the code can run in multiple steps. Some boilerplate code can be reduced, for example.
Some key points about LuaPreprocess:
- It's all Lua - metaprograms are just normal Lua.
- Simplicity - use "!" to specify what code is part of the metaprogram.
- Robustness - processed files are parsed properly.
- Pure Lua - no external dependencies.
- Can be used as a library or command line program.
Direct link to library file
Direct link to command line program
Releases
Documentation
~~~
Why did I do this?
After having published a couple of games on Steam and itch.io I knew that having a "build phase" when making games was very helpful. I could automate tasks and generally reduce a bunch of unpleasant repetitive work. A while ago I started experimenting with taking things a step further. I began to process all Lua files (and eventually images and shaders etc. too) before ever running the game, even locally. This allowed me to easily include or exclude functionality that only certain versions of the game should have/not have. For example, my game may have a developer version, a normal public version and a demo version. All I have to do now is to change a boolean and my build system spits out a different program, or set another boolean and the system spits out a Zip file for every platform and OS, ready to be published. I think any serious LÖVE game could benefit from this kind of workflow.
Also, I'm aware of other preprocessing tools for Lua but none caught my interest. *shrugs*