Page 1 of 1

[solved]Lua forgets my objects on load

Posted: Mon Jan 19, 2015 1:39 am
by Adil
I've actually solved the problem while typing this post, but I've thought I'd still post it so you see how smart am I... oh, and so that it might be of some help to people in future. :)

So, I've been making tables and assigning a single metatable, which had been defined in the different file, to them like this:

Code: Select all

function glob.class_workshop:new(entity)
	workshop=
		{entity=entity, 
		}
	setmetatable(workshop,{__index=self})
	return workshop
end
Then I've been putting these tables into saveable glob. - table like this:

Code: Select all

table.insert(glob.workshops,glob.class_workshop:new(entity))
Everything works fine from init. But when loading saved game I get error claiming that one of methods is nil. (namely workshop:check())

Code: Select all

function modupdate(tick)
	if tick%20==0 and glob.active then
		for _,workshop in ipairs(glob.workshops) do
			workshop:check()
		end
	end
end
Solved, by reassigning them their metatables during onload event:

Code: Select all

		for _,workshop in pairs(glob.workshops) do
			workshop=reset_class_workshop(workshop)
		end
where reset_class_workshop is a function defined in the same file as the metatable.

Code: Select all

function reset_class_workshop(object)
		setmetatable(object,{__index=glob.class_workshop})
	return object
end
"glob." before "class_workshop" helps nothing by the way.

Re: [solved]Lua forgets my objects on load

Posted: Tue Jan 20, 2015 9:04 am
by Choumiko
I had this issue too, solved it in the same way. While trying to solve another bug (for _hours_) i found that serpent doesn't/can't serialize metatables. As Factorio uses serpent to store the glob in the save file that error makes sense
Adil wrote:I've actually solved the problem while typing this post, but I've thought I'd still post it so you see how smart am I...
Since i just now solved another bug (after more than an hour), that shows how stupid i am :D, see if you can tell me why the second while is an endless loop ;)

Code: Select all

function FARL:findLastRail()
  local trainDir = self:calcTrainDir()
  local test = self:railBelowTrain()
  local last = test
    if trainDir % 2 == 0 then
      while test and test.name ~= "curved-rail" do
        last = test
        --fine working code omitted 
      end
      return last
    elseif trainDir % 2 == 1 then
      while test and test.name ~= "curved-rail" do
        last = test
        local _, test = getRail(last,trainDir,1)
        local pos = fixPos(test.position)
        local area = {{pos[1]-0.4,pos[2]-0.4},{pos[1]+0.4,pos[2]+0.4}}
        local found = false
        for i,rail in ipairs(game.findentitiesfiltered{area=area, name="straight-rail"}) do
          local dir = (trainDir+2)%8
          if rail.direction == dir or rail.direction == (dir+4)%8 then
            test = rail
            found = true
            break
          end
        end
        if not found then return last end
      end
      return last
    end
end
Solution