function load_level(file)
    local f = file_read { file = file }

    local result = {
        classes = {
            void = { },
        },
        glossary = {
            [" "] = "void",
        },
        grid = {},
        map = {},
        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
            local l = #result.map + 1
            if result.size.x < #line then
                result.size.x = #line
            end
            result.map[l] = {}
            for i = 1, #line do
                result.map[l][i] = line:sub(i,i)
            end
        -- 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
    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][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