Page 1 of 2

Issue with loading levels [solved]

Posted: Fri Jun 22, 2018 6:24 pm
by Schwender.exe
so I made a small level editor which I've been working on for quite some time, it does everything you'd expect one to do, lets you save/load has commands to edit things, etc. However, when trying to make a demo for my game so others could play it, I ran into an issue, when exporting it into a zip and then renaming it a .love, when I launched it, it didn't load a level like it normally does, aka it couldn't find the level. I save/load levels by using the lua file functions with tserial (lets me save tables so I don't have to manually save everything), I then load it by opening the file of levels, finding the level with the matching string/name and having it spawn all of the tiles how they were when I saved. it worked fine, however it seems that when in a .love file, it forgets how to load a level. is there a way I could save/load levels without having to have the levels file be external from the .love?

source for my save:

Code: Select all

function Editor:savelevel(filename)
  local drop = {}
  if filename == nil then
    filename = self.roomname
  else
    self.roomname = filename
  end
  filename = self.savePath.."Levels/"..filename..".lvl"
  local tiles = {}
  local doors = {}
  for i=1,#Tiles do
    if Tiles[i].args.door then
      table.insert(doors,Tiles[i])
    else
      table.insert(tiles,Tiles[i])
    end
  end
  local f = io.open(filename,"w")
  local saveString = "{"..self.roomw..","..self.roomh.."}\n"..Tserial.pack(tiles,drop,false).."\n"..Tserial.pack(doors,drop,false)
  f:write(filename,saveString)
  f:close()
  self.console_errtxt = "level \""..filename.."\" saved!"
end
and source for my load:

Code: Select all

function Editor:loadlevel(filename)
  filename = string.lower(filename)
  self.roomname = filename
  filename = self.savePath.."Levels/"..filename..".lvl"
  local line = {}
  if file_check(filename) then
    self:clearlevel()
    local f = io.open(filename)
    for lines in f:lines() do
      table.insert(line,lines)
    end
    f:close()
    self.roomw,self.roomh = string.match(tostring(line[1]),'{(%d+),(%d+)}')
    self.roomw,self.roomh = tonumber(self.roomw),tonumber(self.roomh)
    Tiles = Tserial.unpack(tostring(line[2]),true)
    if line[3] ~= nil then
      local doors = Tserial.unpack(tostring(line[3]),true)
      for d=1,#doors do
        table.insert(Tiles,doors[d])
      end
    end
    cam:setWorld(-32,-32,self.roomw+64,self.roomh+64)
    self.console_errtxt = "level \""..filename.."\" loaded!"
    for i,v in ipairs(Tiles) do
      if v.args.playerSpawn then
        player.spawnx = v.x+8
        player.spawny = v.y+8
        player.x = player.spawnx
        player.y = player.spawny
      end
    end
  else
    self.console_errtxt = "level \""..filename.."\" doesn't exist!"
  end
end

Re: Issue with loading levels (read for more info)

Posted: Fri Jun 22, 2018 6:35 pm
by grump
You can't use io.open for loading files from a love file. Use love.filesystem.read.

Re: Issue with loading levels (read for more info)

Posted: Fri Jun 22, 2018 6:47 pm
by Schwender.exe
grump wrote: Fri Jun 22, 2018 6:35 pm You can't use io.open for loading files from a love file. Use love.filesystem.read.
I re-wrote it using love.filesystem.read and it still won't load levels when it's within a .love

Re: Issue with loading levels (read for more info)

Posted: Fri Jun 22, 2018 6:55 pm
by grump
Then there's another issue in your code. Post an error message. If there is none, reduce your code to a minimal example that reproduces the problem, then post that code.

You probably want to use love.filesystem.lines, not love.filesystem.read.

Code: Select all

for line in assert(love.filesystem.lines(filename)) do
...

Re: Issue with loading levels (read for more info)

Posted: Fri Jun 22, 2018 7:30 pm
by Schwender.exe
grump wrote: Fri Jun 22, 2018 6:55 pm Then there's another issue in your code. Post an error message. If there is none, reduce your code to a minimal example that reproduces the problem, then post that code.

You probably want to use love.filesystem.lines, not love.filesystem.read.

Code: Select all

for line in assert(love.filesystem.lines(filename)) do
...
interestingly, I found no errors, it just loaded a blank level (as it usually does) which makes no sense, usually if it finds no level it displays a message, but it didn't this time either.interesting though, when trying to save a level it would crash on file:write() unless the Levels file was present in the same folder, but I want to keep the level files within the .love

Re: Issue with loading levels (read for more info)

Posted: Sat Jun 23, 2018 12:44 am
by pgimeno
You can't *save* to a file inside a .love file.

Re: Issue with loading levels (read for more info)

Posted: Sat Jun 23, 2018 1:11 am
by Schwender.exe
pgimeno wrote: Sat Jun 23, 2018 12:44 am You can't *save* to a file inside a .love file.
there's go to be some way, it can get the textures fine using love.graphics.newImage(), so it is possible, I just need to figure out how

Re: Issue with loading levels (read for more info)

Posted: Sat Jun 23, 2018 4:48 am
by zorg
Schwender.exe wrote: Sat Jun 23, 2018 1:11 am
pgimeno wrote: Sat Jun 23, 2018 12:44 am You can't *save* to a file inside a .love file.
there's got to be some way, it can get the textures fine using love.graphics.newImage(), so it is possible, I just need to figure out how
newImage, like any other constructor reads data; that is indeed possible. the fact that it can access parts of a zip archive (which is what löve files are) is one thing, but to modify it, you'd need to modify the code "from under" itself, and that's not happening. (As long as the code is running, the file is locked, which is an assumption on my end; you can't overwrite/edit the archive.)

Re: Issue with loading levels (read for more info)

Posted: Sat Jun 23, 2018 11:42 am
by Schwender.exe
zorg wrote: Sat Jun 23, 2018 4:48 am
Schwender.exe wrote: Sat Jun 23, 2018 1:11 am
pgimeno wrote: Sat Jun 23, 2018 12:44 am You can't *save* to a file inside a .love file.
there's got to be some way, it can get the textures fine using love.graphics.newImage(), so it is possible, I just need to figure out how
newImage, like any other constructor reads data; that is indeed possible. the fact that it can access parts of a zip archive (which is what löve files are) is one thing, but to modify it, you'd need to modify the code "from under" itself, and that's not happening. (As long as the code is running, the file is locked, which is an assumption on my end; you can't overwrite/edit the archive.)
ah ok, well I talked with a few other devs and I fixed the loading part after figuring out it was the "file_check(path)" function because it used io.open() to check if the file existed instead of love.filesystem.getInfo(), after changing that and changing the load functions to love.filesystem it worked like normal even when in the .love! saving levels isn't 100% required because it's a platformer game, although I could eventually release a version where the level editor is usable, all I'd have to change is the game having to access player-created files from outside the .love/.exe

Re: Issue with loading levels (read for more info)

Posted: Sat Jun 23, 2018 12:14 pm
by Nixola
zorg wrote: Sat Jun 23, 2018 4:48 am
Schwender.exe wrote: Sat Jun 23, 2018 1:11 am
pgimeno wrote: Sat Jun 23, 2018 12:44 am You can't *save* to a file inside a .love file.
there's got to be some way, it can get the textures fine using love.graphics.newImage(), so it is possible, I just need to figure out how
newImage, like any other constructor reads data; that is indeed possible. the fact that it can access parts of a zip archive (which is what löve files are) is one thing, but to modify it, you'd need to modify the code "from under" itself, and that's not happening. (As long as the code is running, the file is locked, which is an assumption on my end; you can't overwrite/edit the archive.)
It's true you can't write inside a .love file, but not for that reason. Code files aren't locked once they're loaded, you can even delete them and it'll keep running just fine; you'd have to manually reload the file for any change to apply. The reason you can't is because LÖVE simply doesn't support editing zip files, which means it can't change the .love file contents.