SenL Posted March 28, 2015 Share Posted March 28, 2015 (edited) 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 endend 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:127scripts/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 = falsescripts/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: 198A0E98scripts/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 = falsescripts/scheduler.lua:398 in (global) RunScheduler (Lua) <396-404> tick = 1085scripts/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 March 28, 2015 by SenL Link to comment Share on other sites More sharing options...
DarkXero Posted March 28, 2015 Share Posted March 28, 2015 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 More sharing options...
SenL Posted March 28, 2015 Author Share Posted March 28, 2015 (edited) 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 March 28, 2015 by SenL Link to comment Share on other sites More sharing options...
DarkXero Posted March 28, 2015 Share Posted March 28, 2015 If _playerlink equals a player, then you are trying to save an entity.Try saving the userid of a player. Link to comment Share on other sites More sharing options...
SenL Posted March 28, 2015 Author Share Posted March 28, 2015 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 More sharing options...
DarkXero Posted March 28, 2015 Share Posted March 28, 2015 http://steamcommunity.com/sharedfiles/filedetails/?id=404161345Example: 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 More sharing options...
SenL Posted March 29, 2015 Author Share Posted March 29, 2015 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 More sharing options...
DarkXero Posted April 6, 2015 Share Posted April 6, 2015 inst.searchtask = inst:DoPeriodicTask(1, function() if inst._playerlink == nil then for k, v in pairs(AllPlayers) do ... inst.playerlink = v end else inst.searchtask:Cancel() inst.searchtask = nil end end) Link to comment Share on other sites More sharing options...
SenL Posted April 15, 2015 Author Share Posted April 15, 2015 Works.Thank you. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now