-- Make a first 18x18 layout from the exit links preserved in the legacy saves. -- Some old test rooms share the same one-way exit, so a grid cannot represent -- every such link at once. Those rooms are still placed, but isolated, rather -- than silently overwriting a room that already occupies that neighbour. function seedWorldFromLegacyExits(world) local available = {} for _, name in ipairs(world:listRoomNames()) do available[name] = true end local legacy = {} for name in pairs(available) do local raw = readFromSource("rooms/_pre_migration_backup/" .. name .. ".sav") if raw then local ok, save = pcall(TSerial.unpack, raw) if ok and type(save) == "table" then legacy[name] = save.exits or {} end end end world.rooms, world.roomByName = {}, {} local root = available.start and "start" or world:listRoomNames()[1] if not root then return { placed = 0, links = 0, conflicts = 0 } end world:_putRoom(root, 9, 11) local queue, queued = { root }, { [root] = true } local directions = { top = { x = 0, y = -1 }, right = { x = 1, y = 0 }, bottom = { x = 0, y = 1 }, left = { x = -1, y = 0 }, } local order = { "top", "right", "bottom", "left" } local links, conflicts = 0, 0 local index = 1 while index <= #queue do local name = queue[index] local source = world:roomLocation(name) for _, exit in ipairs(order) do local target = legacy[name] and legacy[name][exit] target = target and tostring(target) local direction = directions[exit] if target and available[target] then local x, y = source.x + direction.x, source.y + direction.y local occupied, known = world:roomAt(x, y), world:roomLocation(target) if world:isInBounds(x, y) and (not occupied or occupied == target) and (not known or (known.x == x and known.y == y)) then if not known then world:_putRoom(target, x, y) end links = links + 1 if not queued[target] then table.insert(queue, target); queued[target] = true end else conflicts = conflicts + 1 end end end index = index + 1 end -- Keep every migrated room visible/selectable without creating accidental -- exits between the disconnected legacy variants. for _, name in ipairs(world:listRoomNames()) do if not world:roomLocation(name) then local placed = false for y = 1, world.height do for x = 1, world.width do if not world:roomAt(x, y) then local nearby = false for dy = -1, 1 do for dx = -1, 1 do if world:roomAt(x + dx, y + dy) then nearby = true end end end if not nearby then world:_putRoom(name, x, y); placed = true; break end end end if placed then break end end end end world:save() return { placed = #world.rooms, links = links, conflicts = conflicts } end