Jump to content

Stackoverflow or cannot dump userdata crash when onsave


Recommended Posts

I got a crash after I put "onsave" on my stingerturret.

Crash is something about stack overflow when exiting normally or "cannot dump userdata" when pressing ctrl+s (with debugkeys enabled)

 

Code in onsave is very straight forward:

local function onsave(inst, data)
  if inst._playerlink ~= nil then
    data._playerlink = inst._playerlink
  end
end
 
Code in main function:
inst.OnSave = onsave
 
I wonder what's going on...
 

Log:

 

[00:01:38]: giving 120346 - stingerturret_item
[00:01:38]: giving 120352 - stingerturret_item
[00:01:42]: stingerturret->linktoplayer linking to 119720 - wilson
[00:01:45]: stingerturret->linktoplayer linking to 119720 - wilson
[00:01:49]: Resurrector:OnSave 109767 - resurrectionstone used:nil active:nil
[00:01:49]: DeregisterResurrector
[00:01:49]: DeregisterResurrector
[00:01:49]: Resurrector:OnSave 109768 - resurrectionstone used:nil active:nil
[00:01:49]: DeregisterResurrector
[00:01:49]: DeregisterResurrector
[00:01:49]: Resurrector:OnSave 109769 - resurrectionstone used:nil active:nil
[00:01:49]: DeregisterResurrector
[00:01:49]: DeregisterResurrector
[00:01:49]: Resurrector:OnSave 109770 - resurrectionstone used:nil active:nil
[00:01:49]: DeregisterResurrector
[00:01:49]: DeregisterResurrector
[00:01:49]: Serializing user minimap to session/06800001465B335A/KU_d8EeZHlp_/minimap
[00:01:49]: Serializing user session to session/06800001465B335A/KU_d8EeZHlp_/0000000002
[00:01:49]: [string "scripts/dumper.lua"]:112: Cannot dump userdata (AnimState (608C2EC8) - unknown)
LUA ERROR stack traceback:
=[C]:-1 in (global) error © <-1--1>
scripts/dumper.lua:112 in () ? (Lua) <98-113>
   value = AnimState (608C2EC8)
   var = nil
   i = 8
=(tail call):-1 in ()  (tail) <-1--1>
scripts/dumper.lua:151 in () ? (Lua) <141-159>
   value = 119720 - wilson (valid:true)
   numidx = 1
   key = AnimState
   val = AnimState (608C2EC8)
=(tail call):-1 in ()  (tail) <-1--1>
scripts/dumper.lua:151 in () ? (Lua) <141-159>
   value = table: 49F52A70
   numidx = 1
   key = _playerlink
   val = 119720 - wilson (valid:true)
=(tail call):-1 in ()  (tail) <-1--1>
scripts/dumper.lua:151 in () ? (Lua) <141-159>
   value = table: 49F50158
   numidx = 1
   key = data
   val = table: 49F52A70
=(tail call):-1 in ()  (tail) <-1--1>
scripts/dumper.lua:151 in () ? (Lua) <141-159>
   value = table: 49F4D4A8
   numidx = 2
   key = 1
   val = table: 49F50158
=(tail call):-1 in ()  (tail) <-1--1>
scripts/dumper.lua:151 in () ? (Lua) <141-159>
   value = table: 0D9FCD48
   numidx = 1
   key = stingerturret
   val = table: 49F4D4A8
=(tail call):-1 in ()  (tail) <-1--1>
scripts/dumper.lua:151 in () ? (Lua) <141-159>
   value = table: 0D9FCD20
   numidx = 1
   key = ents
   val = table: 0D9FCD48
=(tail call):-1 in ()  (tail) <-1--1>
scripts/dumper.lua:225 in (global) DataDumper (Lua) <77-245>
   value = table: 0D9FCD20
   varname = return 
   fastmode = true
   ident = nil
   defined = table: 40662FF8
   dumplua = function - scripts/dumper.lua:214
   string_format = function - =[C]:-1
   type = function - =[C]:-1
   string_dump = function - =[C]:-1
   string_rep = function - =[C]:-1
   tostring = function - =[C]:-1
   pairs = function - =[C]:-1
   table_concat = function - =[C]:-1
   keycache = table: 40663020
   strvalcache = table: 40663048
   out = table: 40663070
   closure_cnt = 0
   fcts = table: 40663138
   test_defined = function - scripts/dumper.lua:116
   make_key = function - scripts/dumper.lua:127
scripts/mainfunctions.lua:630 in (global) SaveGame (Lua) <514-642>
   savename = survival_3
   isshutdown = nil
   cb = nil
   save = table: 0D9FCD20
   nument = 17335
   saved_ents = table: 0D9FB970
   references = table: 0D9FCA78
   new_refs = nil
   ground = 100028 - forest (valid:true)
   PRETTY_PRINT = false
scripts/saveindex.lua:599 in (method) SaveCurrent (Lua) <574-600>
   self =
      data = table: 198A0808
      current_slot = 3
   onsavedcb = nil
   isshutdown = nil
   direction = nil
   cave_num = nil
   level_number = 1
   day_number = 1
   current_mode = survival
   data = table: 198A0E98
scripts/components/autosaver.lua:38 in (field) fn (Lua) <37-40>
scripts/scheduler.lua:187 in (method) OnTick (Lua) <161-217>
   self =
      running = table: 19038430
      waitingfortick = table: 190383E0
      tasks = table: 190383B8
      waking = table: 40A380E0
      attime = table: 190385E8
      hibernating = table: 190384F8
   tick = 1085
   k = PERIODIC 100032: 1.000000
   v = true
   already_dead = false
scripts/scheduler.lua:398 in (global) RunScheduler (Lua) <396-404>
   tick = 1085
scripts/update.lua:162 in () ? (Lua) <146-213>
   dt = 0.033333335071802
   tick = 1085
   i = 1085
 
[00:01:49]: SCRIPT ERROR! Showing error screen
 
Edit: I don't see any onsave on abigail.lua ... does it turn to flower when game loads?? how does it know its playerlink?
Edited by SenL
Link to comment
Share on other sites

It's because inst._playerlink contains userdata, namely everything that you stick to inst.entity.

 

So you must do it like wendy.lua:

local function OnSave(inst, data)    if inst.abigail ~= nil then        data.abigail = inst.abigail:GetSaveRecord()    endendlocal function OnLoad(inst, data)    if data.abigail ~= nil and inst.abigail == nil then        local abigail = SpawnSaveRecord(data.abigail)        if abigail ~= nil then            abigail.SoundEmitter:PlaySound("dontstarve/common/ghost_spawn")            abigail:LinkToPlayer(inst)        end    endend
Link to comment
Share on other sites

I hope GetSaveRecord() and SpawnSaveRecord() are built-in...

Yes?

 

Edit: I found SpawnSaveRecord() in mainfunctions.lua but it seems like it's spawning prefab. I don't think I want to spawn prefab ... I just want to save and load the deployer of this turret... hm...

Edited by SenL
Link to comment
Share on other sites

Do you mean this (from soulteleporter.lua mod)

self.boundToUserid = pickuper.Network:GetUserID()

?

 

Would that work with below code:

return FindEntity(inst, 20, function(guy)
        return inst._playerlink ~= nil
            and inst.components.combat:CanTarget(guy)
            and (guy.components.combat.target == inst._playerlink or
                inst._playerlink.components.combat.target == guy)
    end)
(that's from abigail)
 
Maybe use FindEntity before that, to find matching UserID?
Link to comment
Share on other sites

http://steamcommunity.com/sharedfiles/filedetails/?id=404161345

Example: this is a mod that uses player ids to establish ownership on structures.

 

You use self.boundToUserId = deployer.Network:GetUserID() or something in a deploy function.

(That makes the guy who deploys a turret create a variable with his user id in the turret.)

The onsave and onload of the turret will keep that userid.

The turret listens to the event of people disconnecting, compares the id stored with the id exiting, and makes the link = nil if equal.

The turret listens to the event of people connecting, compares the id stored with the id coming, and makes the link = player if equal.

 

That way you keep the entity who deployed the turret, on the _playerlink variable, whenever it's on the server. So that FindEntity remains intact.

 

You can also turn _playerlink into a function that gives the player from AllPlayers that has the ID stored in the turret, and return nil if nobody was found. You would have to add () where you see inst._playerlink, to get inst._playerlink() to call it.

Link to comment
Share on other sites

I got it to work, but may not be optimal way. I didn't look at that mod but maybe should.

Here's how I did it. On "onsave", I only store the userid (inst.Network:GetUserID()) but onload I would find (in AllPlayers) first player that matches that UserID. I had problem with this because when this turret loads, no players are loaded (yet).

 

So I put below in the main function:

inst:DoTaskInTime(5, findowner(inst))

 

findowner:

inst:DoPeriodicTask(1, function()

  if inst._playerlink == nil then

    for _,v in pairs(AllPlayers) do

      ...

      inst._playerlink = v

    end

  end

 

However, I would like this to self cancel when it found the owner (inst._playerlink is no longer nil).

How do I do that?

 

Thanks.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...