samboy / ObHack

A random map generator for Doom engine games
https://samiam.org/slump
Other
33 stars 1 forks source link

Check all use of pairs() in ObHack scripts #5

Closed samboy closed 4 years ago

samboy commented 4 years ago

Since, as per https://github.com/samboy/ObHack/issues/4 , pairs makes ObHack non-deterministic (i.e. Lua will, on two different runs, iterate table elements differently when using the pairs operator), I now need to check every place where the ObHack scripts use pairs to make sure that no output is altered by the iteration order of pairs.

There are about two dozen uses of pairs in the code:

builder.lua:1442:  for kind,func in pairs(SKY_LIGHT_FUNCS) do
builder.lua:1830:    for side,L in pairs(c.link) do
builder.lua:6004:    --   2. make paths between pairs of exits.
builder.lua:7367:       for name,info in pairs(fab_tab) do
builder.lua:7597:    for name,def in pairs(fab_tab) do
monster.lua:510:      for name,info in pairs(GAME.weapons) do
monster.lua:850:    for zzz,ndef in pairs(GAME.niceness) do
monster.lua:979:    for name,info in pairs(GAME.pickups) do
monster.lua:1351:    for name,info in pairs(GAME.weapons) do
monster.lua:1370:    for name,info in pairs(GAME.monsters) do
monster.lua:1433:        for name,mul in pairs(tab) do
monster.lua:1598:    for name,info in pairs(GAME.monsters) do
plan_dm.lua:79:  for name,prob in pairs(LIST) do
planner.lua:1540:    for b_name,CN in pairs(shared_corners) do
planner.lua:2671:        for yyy,L in pairs(c.link) do
theme.lua:66:  for name,info in pairs(GAME.monsters) do
theme.lua:87:  for name,P in pairs(fabs) do
theme.lua:149:  for name,combo in pairs(GAME.combos) do
theme.lua:208:  for name,hall in pairs(GAME.hallways) do
theme.lua:278:    for name,info in pairs(GAME.door_fabs) do
util.lua:56:  for k,_ in pairs(t) do
util.lua:66:  for k,v in pairs(t) do count = count+1 end
util.lua:82:  for k,v in pairs(t) do
util.lua:140:  for name,info in pairs(LIST) do
util.lua:263:  for k,v in pairs(tab) do count = count+1 end
writer.lua:860:    for zzz,th in pairs(thing_list) do
writer.lua:874:    for IDX,vert in pairs(vert_list) do
writer.lua:944:    for zzz,th in pairs(thing_list) do

(Here, the format is filename : line number : usage of pairs)

I need to look at all of this code, and in most cases change code like this:

for key, value in pairs(foo) do
  bar = value

To look like this:

for _, key in ipairs(sorted_table_keys(foo)) do
  bar = foo[key]

Where sorted_table_keys is a routine I wrote when fixing https://github.com/samboy/ObHack/issues/4

Ideally, if I do this two instances of ObHack with the same seed and parameters will generate byte for byte the same wad file. Right now, two instances generate wad files with the same length (the length did vary before I fixed https://github.com/samboy/ObHack/issues/4 ) but different sha-256 / shake256 sums.

samboy commented 4 years ago

In the cases where pairs is OK, add a comment about why it is OK to use pairs. For example, if we just count the number of items in a table, it doesn’t matter in what order we count them.

samboy commented 4 years ago

OK, if you make two maps with the same seed + parameters, you will get the same map.

Note that the generated .wad files still differ; it would seem glBSP puts a timestamp in the wad (which I consider a bug, but never mind, it’s not one worth fixing). The only other difference with two wads is that the checksum is different because the timestamp is different.