function load_level(file) local f = file_read { file = file } local result = { -- templates to fill the grid with classes = { -- predefined empty tile void = { }, }, -- symbol to class lookup table glossary = { [" "] = "void", }, -- grid consists of expanded classes, of size dimensions grid = {}, -- map consists of original rows of symbols that the grid is constructed from map = {}, -- maximum extends of the map, unspecified tiles are filled with "void" size = { x = 0, y = 0 }, } -- iterate over lines local section, subsection = "none", "none" local from = 1 local start, limit = string.find(f, "\n", from) while start do local line = string.sub(f, from, start - 1) -- skip over if #line == 0 or line:find("^%-%-%s*") then goto skip -- start new section elseif line:find("^@%g+") then section = line:sub(2); subsection = "none" -- decode map one line at a time elseif section == "map" then if result.size.x < #line then result.size.x = #line end result.map[#result.map + 1] = line -- templates to expand elseif section == "classes" then -- properties if line:find("^ %g+") then local _, _, property, value = line:find("^ (%g+)%s?:%s?(.*)") result.classes[subsection][property] = value goto skip end local symbol, classname = line:sub(1,1), line:sub(3) result.classes[classname] = { symbol = symbol, } result.glossary[symbol] = classname subsection = classname elseif section ~= "none" then local _, _, property, value = line:find("^(%g+)%s?:%s?(.*)") if result[section] == nil then result[section] = {} end result[section][property] = value end ::skip:: from = limit + 1 start, limit = string.find(f, "\n", from) end -- post process, expand map to grid for y = 1, #result.map do result.grid[y] = {} for x = 1, result.size.x do -- past defined for line local symbol if x > #result.map[y] then symbol = " " else symbol = result.map[y]:sub(x,x) end local class = result.classes[result.glossary[symbol]] if class["unique"] ~= nil then class.position = { x = x, y = y } end result.grid[y][x] = class ::continue:: end end result.size.y = #result.map print(result.meta.description) return result end