Recursive table serialization

Place to post guides, observations, things related to modding that are not mods themselves.
Post Reply
Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Recursive table serialization

Post by Honktown »

Have to re-do my mod a little bit because the devs detect if you try to store tables recursively and actually put nil the in the table.
@BILKA I KNOW IT WAS YOU

Code: Select all

train changed state Global:
{
  combinators = {
    [-225.5] = {
      [-161.5] = {
        entity = {
          __self = "userdata"
        },
        signal = 1,
        stop = {
          entity = {
            __self = "userdata"
          },
          unit_number = 467616
        },
        x = -225.5,
        y = -161.5
      }
    }
  },
  inventory_size = {
    ["cargo-wagon"] = 40
  },
  on_tick_combinators = {},
  players = {
    {
      combinator = nil,
      stop = nil
    }
  },
  watched_stops = {
    [467616] = {
      nil,
      entity = nil
    }
  }
}
After some sleep.
I have mods! I guess!
Link

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5206
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Empty-inventory-slot reader

Post by eradicator »

Honktown wrote:
Mon Feb 03, 2020 9:21 pm
Have to re-do my mod a little bit because the devs detect if you try to store tables recursively and actually put nil the in the table.
@BILKA I KNOW IT WAS YOU
[...]
After some sleep.
Dear Mr. Troll. Please RTFM before you start blaming random people on random threads for your own inability to correctly interpret serpent output. ><((((*>

(Edit: Moved part of the post back to the original slot-reader thread.)
Last edited by eradicator on Wed Feb 05, 2020 1:09 pm, edited 1 time in total.
Author of: Belt Planner, Hand Crank Generator, Screenshot Maker, /sudo and more.
Mod support languages: 日本語, Deutsch, English
My code in the post above is dedicated to the public domain under CC0.

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Empty-inventory-slot reader

Post by Honktown »

eradicator wrote:
Tue Feb 04, 2020 2:52 pm
Honktown wrote:
Mon Feb 03, 2020 9:21 pm
Have to re-do my mod a little bit because the devs detect if you try to store tables recursively and actually put nil the in the table.
@BILKA I KNOW IT WAS YOU
[...]
After some sleep.
Dear Mr. Troll. Please RTFM before you start blaming random people on random threads for your own inability to correctly interpret serpent output. ><((((*>
Bro, the mod isn't working because literally after I put the table in something recursively the previous reference gets nil'd. It's not serpent, I'm actually getting in-game errors that my shit is nil, when it was valid and the variable wasn't re-assigned. Recursive tables aren't serializable. It makes sense they'd have protection. I can link you the exact code, and step-by-step you'll see the engine blocking the recursion.
I have mods! I guess!
Link

Rseding91
Factorio Staff
Factorio Staff
Posts: 13209
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: Empty-inventory-slot reader

Post by Rseding91 »

Honktown wrote:
Tue Feb 04, 2020 3:07 pm
Recursive tables aren't serializable.
Yes they are.
If you want to get ahold of me I'm almost always on Discord.

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Empty-inventory-slot reader

Post by Honktown »

Rseding91 wrote:
Wed Feb 05, 2020 2:58 am
Honktown wrote:
Tue Feb 04, 2020 3:07 pm
Recursive tables aren't serializable.
Yes they are.
I don't even know what's going on anymore.
wall of log
the function
I have mods! I guess!
Link

Koub
Global Moderator
Global Moderator
Posts: 7203
Joined: Fri May 30, 2014 8:54 am
Contact:

Re: Recursive table serialization

Post by Koub »

[Koub] I Split these posts from the empty inventory slot reader thread because it started getting off topic, and became a subject of discussion of its own. I hope my limited understanding is correct.
Koub - Please consider English is not my native language.

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Recursive table serialization

Post by Honktown »

Koub wrote:
Wed Feb 05, 2020 6:57 am
[Koub] I Split these posts from the empty inventory slot reader thread because it started getting off topic, and became a subject of discussion of its own. I hope my limited understanding is correct.
The mod is for empty slot reading, but there's something weird going on. Some of my tables get replaced with nil metatables.

Code: Select all

38957.044 Error MainLoop.cpp:1195: Exception at tick 2038839: Error while running command "stops": __TrainWagonCombinators__/control.lua:25: bad argument #2 of 3 to '__index' (string expected, got number)
stack traceback:
	[C]: in function '__index'
	__TrainWagonCombinators__/control.lua:25: in function <__TrainWagonCombinators__/control.lua:19>
Edit: In particular, I can move the table containing the entity, but not the entity. It's not a recursion issue I think. there's multiple weird things.
I have mods! I guess!
Link

Bilka
Factorio Staff
Factorio Staff
Posts: 3135
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Empty-inventory-slot reader

Post by Bilka »

Honktown wrote:
Tue Feb 04, 2020 3:07 pm
It makes sense they'd have protection. I can link you the exact code, and step-by-step you'll see the engine blocking the recursion.
Please do. Explain it step by step please.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Empty-inventory-slot reader

Post by Honktown »

Bilka wrote:
Wed Feb 05, 2020 7:49 am
Honktown wrote:
Tue Feb 04, 2020 3:07 pm
It makes sense they'd have protection. I can link you the exact code, and step-by-step you'll see the engine blocking the recursion.
Please do. Explain it step by step please.
lol. Out-of-the-bigger log, some of the prints imply I can't store the entity in two places, which would allow me to have the entity in another table which also contains the entity. With more of the data being printed step-by-step, it's probably not right at all :^). Would you be upset if I admitted I am wrong?

Also, was this bullshit you. The entity wasn't being assigned at the desired index, and I get some nil that isn't that entity.

This bullshit:

Code: Select all

        global.watched_stops[pstop.unit_number].entity = pstop.entity
That line in the above code don't work.

Edit, also yeah: I'm storing the entities in recursive tables. combinator->stop with up to 5 combinators ->combinators -> the stop...
I have mods! I guess!
Link

Bilka
Factorio Staff
Factorio Staff
Posts: 3135
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Empty-inventory-slot reader

Post by Bilka »

Honktown wrote:
Wed Feb 05, 2020 8:33 am
Also, was this bullshit you. The entity wasn't being assigned at the desired index, and I get some nil that isn't that entity.

This bullshit:

Code: Select all

        global.watched_stops[pstop.unit_number].entity = pstop.entity
That line in the above code don't work.
No idea what you're talking about, assigning an entity "a" to [a.unit_number].entity works perfectly fine.
images with code execution

Oh I see, you are not using something comfirmed to be a LuaEntity, you are using pstop = global.players[pid].stop and pstop.entity. Sadly you don't log pstop or global.players so that we could find out what pstop.entity is and if it is or isn't nil.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Empty-inventory-slot reader

Post by Honktown »

Bilka wrote:
Wed Feb 05, 2020 8:46 am
Honktown wrote:
Wed Feb 05, 2020 8:33 am
Also, was this bullshit you. The entity wasn't being assigned at the desired index, and I get some nil that isn't that entity.

This bullshit:

Code: Select all

        global.watched_stops[pstop.unit_number].entity = pstop.entity
That line in the above code don't work.
No idea what you're talking about, assigning an entity "a" to [a.unit_number].entity works perfectly fine.
images with code execution

Oh I see, you are not using something comfirmed to be a LuaEntity, you are using pstop = global.players[pid].stop and pstop.entity. Sadly you don't log pstop or global.players so that we could find out what pstop.entity is and if it is or isn't nil.

Code: Select all

      stop = {
        entity = {
          __self = "userdata"
        },
        unit_number = 115861
      }

Code: Select all

      pstop = global.players[pid].stop

Code: Select all

      if pstop.entity.valid == false then
        remove_stop(pstop)
        remove_combinator_entirely(global.players[pid].combinator)
        return
      end

Code: Select all

        c.stop = pstop
        log("\nc.stop = pstop Global:\n" .. serpent.block(global))

Code: Select all

c.stop = pstop Global:
{
  combinators = {},
  inventory_size = {
    ["cargo-wagon"] = 40
  },
  on_tick_combinators = {},
  players = {
    {
      combinator = {
        entity = {
          __self = "userdata"
        },
        stop = {
          entity = {
            __self = "userdata"
          },
          unit_number = 115861
        },
        x = -48.5,
        y = -34.5
      },
      stop = nil
    }
  },
  watched_stops = {
    [115861] = {
      nil,
      entity = nil
    }
  }
}
I have mods! I guess!
Link

Bilka
Factorio Staff
Factorio Staff
Posts: 3135
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Recursive table serialization

Post by Bilka »

Code: Select all

Global:
{
  ...
  players = {
    {
      combinator = {
        entity = {
          __self = "userdata"
        },
        x = -48.5,
        y = -34.5
      },
      stop = {
        entity = {
          __self = "userdata"
        },
        unit_number = 115861
      }
    }
  },
That's not global.players[pid].stop. That's global.players[1].stop. We don't know if pid == 1. You are also still using a way to dump tables that doesn't show duplicate references properly. Just log pstop. I mean, you have your code, shouldn't be that hard.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Recursive table serialization

Post by Honktown »

https://drive.google.com/open?id=1ly49A ... bVerqxnFYH

fffffffff I sent the whole damn function. There's the whole mod.

/testgui brings up the gui. Open a combinator. Open a train station. Select 1 in the drop-down. Click the check. Use /wr_reset if you want to clear the table before hitting check again.
I have mods! I guess!
Link

Bilka
Factorio Staff
Factorio Staff
Posts: 3135
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Recursive table serialization

Post by Bilka »

Code: Select all

49.092 Script @__TrainWagonCombinators__/wagonreader/wagonreader.lua:423: 
assigned combinator and stop Global:
do
local _={players={{stop={unit_number=8,entity={__self="userdata"}},combinator={y=3.5,x=-6.5,entity={__self="userdata"},stop=nil,signal=1}}},watched_stops={nil,nil,nil,nil,nil,nil,nil,{[1]=nil,entity=nil}},combinators={[-6.5]={[3.5]=nil}},on_tick_combinators={},inventory_size={["cargo-wagon"]=80}};

local __={};
_.players[1].combinator.stop=_.players[1].stop;
_.watched_stops[8][1]=_.players[1].combinator;
_.watched_stops[8].entity=_.players[1].stop.entity;
_.combinators[-6.5][3.5]=_.players[1].combinator;
return _;
end
Seems fine to me, the references are stored properly.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Recursive table serialization

Post by Honktown »

Bilka wrote:
Wed Feb 05, 2020 9:48 am

Code: Select all

49.092 Script @__TrainWagonCombinators__/wagonreader/wagonreader.lua:423: 
assigned combinator and stop Global:
do
local _={players={{stop={unit_number=8,entity={__self="userdata"}},combinator={y=3.5,x=-6.5,entity={__self="userdata"},stop=nil,signal=1}}},watched_stops={nil,nil,nil,nil,nil,nil,nil,{[1]=nil,entity=nil}},combinators={[-6.5]={[3.5]=nil}},on_tick_combinators={},inventory_size={["cargo-wagon"]=80}};

local __={};
_.players[1].combinator.stop=_.players[1].stop;
_.watched_stops[8][1]=_.players[1].combinator;
_.watched_stops[8].entity=_.players[1].stop.entity;
_.combinators[-6.5][3.5]=_.players[1].combinator;
return _;
end
Seems fine to me, the references are stored properly.

If a train enters the watched stop, I get errors I think. I don't remember. I have to get to bed.

Edit, don't use /stops, there's a typo : P
I have mods! I guess!
Link

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Recursive table serialization

Post by Honktown »

Ahhh so many bugs. If only I had more hammers. I did the thing. Thank you for your motivation.
I have mods! I guess!
Link

Honktown
Smart Inserter
Smart Inserter
Posts: 1026
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Re: Recursive table serialization

Post by Honktown »

On topic, what would be useful is a pretty-printer for serpent.dump. I don't understand why someone would want to pretty print everything but repeated-entries OR have one long line with everything in it.

Edit: getting there. Wonder if there's an option for the varname.

Code: Select all

/c

local a = {1, nil, 3, x=1, ['true'] = 2, [not true]=3}
a[a] = a

log("\n" .. serpent.dump(a, {compact = false, nocode = true, indent = "\t"})) 

Code: Select all

4953.657 Script  local a = {1, nil, 3, x=1, ['true'] = 2, [not true]=3} a[a] = a  log("\n" .. serpent.dump(a, {compact = false, nocode = true, indent = "\t"})):1: 
do local _ = {
	[1] = 1,
	[3] = 3,
	x = 1,
	["true"] = 2,
	[false] = 3
}
local __={}
_[_] = _
return _
end
I have mods! I guess!
Link

Post Reply

Return to “Modding discussion”