Page 1 of 1

(fixed) Pits and triggers bug

Posted: Thu Sep 08, 2016 1:59 pm
by kaypy
Hi

If you have a const-weight trigger on a pit, then the party will trigger it stepping onto the tile, but not untrigger it when plummeting to the next level. The same applies to using a rope.

Simple test case:

Code: Select all

dsb_text2map(0, 10, 10, 100, 1, {
"1000110000",
"1000110000",
"1000100000",
"1111111100",
"0000110000",
"0000110000",
"0000000000",
"0000000000",
"0000000000",
"0000000000"} )
dsb_level_wallset(0, wallset.default)
dsb_text2map(1, 10, 10, 0, 1, {
"0000000000",
"0000000000",
"0000000000",
"0000111100",
"0000110000",
"0000110000",
"0000000000",
"0000000000",
"0000000000",
"0000000000"} )
dsb_level_wallset(1, wallset.default)
dsb_add_champion(1, "test", "port_mophus", "TEST", "", 1000, 1000, 1000, 400, 400, 400, 400, 400, 400, 400, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0})
ch_exvar = {
}
dsb_spawnburst_begin(24)
dsb_spawn(2, "doorframe", 0, 4, 2, 4)
dsb_spawn(20, "door_portcullis", 0, 4, 2, 4)
dsb_spawn(22, "torch", 0, 4, 3, 3)
dsb_set_charge(22, 500)
dsb_spawn(21, "rope", 0, 5, 3, 2)
dsb_spawn(5, "stairsdown", 0, 7, 3, 4)
dsb_spawn(23, "stick", 0, 4, 4, 1)
dsb_spawn(24, "stick", 0, 5, 4, 0)
dsb_spawn(1, "pit", 0, 4, 5, 4)
dsb_spawn(4, "trigger", 0, 4, 5, 4)
dsb_spawn(3, "trigger", 0, 5, 5, 4)
dsb_spawn(8, "stairsup", 1, 7, 3, 4)
exvar = {
[3] = { opby_party = true,
const_weight = true,
target = 20,
msg = 100001,
opby_thing = true },
[4] = { opby_party = true,
target = 20,
msg = 100001,
opby_thing = true,
const_weight = true },
}
dsb_spawnburst_end()
EDITOR_FLAGS = 255
dsb_champion_toparty(0, 1)
dsb_party_place(0, 0, 0, 0)
Triggers on and next to the pit control the door. Drop an item down the pit and the door will open momentarily. Send the party down the pit and it will lock open until the reset it triggered elsewhere.

Re: Pits and triggers bug

Posted: Thu Sep 08, 2016 2:19 pm
by kaypy
Digging a bit more, this only applies if the pit is open when stepping on it. I'm thinking it could be a timing issue where the trigger and detrigger messages wind up simultaneous?

Re: Pits and triggers bug

Posted: Thu Sep 08, 2016 2:29 pm
by kaypy
Looks to be a timing issue:

Adding a logging functioncaller:
dungeon.lua:

Code: Select all

dsb_text2map(0, 10, 10, 100, 1, {
"1000110000",
"1000110000",
"1000100000",
"1111111100",
"0000110000",
"0000110000",
"0000000000",
"0000000000",
"0000000000",
"0000000000"} )
dsb_level_wallset(0, wallset.default)
dsb_text2map(1, 10, 10, 0, 1, {
"0000000000",
"0000000000",
"0000000000",
"0000111100",
"0000110000",
"0000110000",
"0000000000",
"0000000000",
"0000000000",
"0000000000"} )
dsb_level_wallset(1, wallset.default)
dsb_add_champion(1, "test", "port_mophus", "TEST", "", 1000, 1000, 1000, 400, 400, 400, 400, 400, 400, 400, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0})
ch_exvar = {
}
dsb_spawnburst_begin(24)
dsb_spawn(2, "doorframe", 0, 4, 2, 4)
dsb_spawn(20, "door_portcullis", 0, 4, 2, 4)
dsb_spawn(22, "torch", 0, 4, 3, 3)
dsb_set_charge(22, 500)
dsb_spawn(21, "rope", 0, 5, 3, 2)
dsb_spawn(5, "stairsdown", 0, 7, 3, 4)
dsb_spawn(23, "stick", 0, 4, 4, 1)
dsb_spawn(24, "stick", 0, 5, 4, 0)
dsb_spawn(6, "button_blue", 0, 6, 4, 3)
dsb_spawn(1, "pit", 0, 4, 5, 4)
dsb_spawn(4, "trigger", 0, 4, 5, 4)
dsb_spawn(3, "trigger", 0, 5, 5, 4)
dsb_spawn(7, "button_blue", 0, 4, 6, 0)
dsb_spawn(9, "function_caller", 0, 5, 6, 4)
dsb_spawn(8, "stairsup", 1, 7, 3, 4)
exvar = {
[3] = { opby_party = true,
target = 20,
msg = 100001,
opby_thing = true,
const_weight = true },
[4] = { opby_party = true,
target = { 20, 9 },
msg = 100001,
opby_thing = true,
const_weight = true },
[6] = { target = 1,
msg = 100002 },
[7] = { target = 1,
msg = 100002 },
[9] = { m_d = "ontopittrigger",
m_a = "offpittrigger" },
}
dsb_spawnburst_end()
EDITOR_FLAGS = 255
dsb_champion_toparty(0, 1)
dsb_party_place(0, 0, 0, 0)
startup.lua:

Code: Select all

function ontopittrigger()
	__log("ONTOPITTRIGGER")
	dsb_write(debug_color, "ONTOPITTRIGGER" )
end

function offpittrigger()
	__log("OFFPITTRIGGER")
	dsb_write(debug_color, "OFFPITTRIGGER" )
end
This gives
...
DUNGEON: Attempting to load
Parsing mintest2/dungeon.lua

-- here's where I step on and off a closed pit
Lua: ONTOPITTRIGGER
Lua: OFFPITTRIGGER

-- vs rope
Lua: OFFPITTRIGGER
Lua: ONTOPITTRIGGER

-- and falling
Lua: OFFPITTRIGGER
Lua: ONTOPITTRIGGER

SHUTDOWN: Shutting down...

Re: Pits and triggers bug

Posted: Thu Sep 08, 2016 3:45 pm
by kaypy
Also note that the problem only occurs if the pit is before the trigger in the object list.

Teleporters don't seem to have any problems (well, not this particular type of problem anyway). They move the party in the same way (dsb_party_place), but they don't use locks and delays.

Re: Pits and triggers bug

Posted: Thu Sep 08, 2016 8:54 pm
by Sophia
It's definitely the locks and delays that are tripping us up, here. I'll have a look at this soon.

Re: Pits and triggers bug

Posted: Fri Sep 09, 2016 5:59 am
by kaypy
OK, this just got weirder- under certain circumstances, messages can be lost entirely:

Code: Select all

dsb_text2map(0, 10, 10, 100, 1, {
"1000110000",
"1000110000",
"1000100000",
"1111111100",
"0000111000",
"0000111000",
"0000000000",
"0000000000",
"0000000000",
"0000000000"} )
dsb_level_wallset(0, wallset.default)
dsb_text2map(1, 10, 10, 0, 1, {
"0000000000",
"0000000000",
"0000000000",
"0000111100",
"0000110000",
"0000110000",
"0000000000",
"0000000000",
"0000000000",
"0000000000"} )
dsb_level_wallset(1, wallset.default)
dsb_add_champion(1, "test", "port_mophus", "TEST", "", 1000, 1000, 1000, 400, 400, 400, 400, 400, 400, 400, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0})
ch_exvar = {
}
dsb_spawnburst_begin(22)
dsb_spawn(3, "doorframe", 0, 4, 2, 4)
dsb_spawn(20, "door_portcullis", 0, 4, 2, 4)
dsb_spawn(21, "rope", 0, 2, 3, 0)
dsb_spawn(22, "torch", 0, 2, 3, 2)
dsb_set_charge(22, 500)
dsb_spawn(1, "stairsdown", 0, 7, 3, 4)
dsb_spawn(4, "button_blue", 0, 3, 4, 0)
dsb_spawn(5, "function_caller", 0, 2, 5, 4)
dsb_spawn(6, "trigger", 0, 4, 5, 4)
dsb_spawn(9, "pit", 0, 4, 5, 4)
dsb_spawn(8, "pit", 0, 5, 5, 4)
dsb_spawn(10, "trigger", 0, 5, 5, 4)
dsb_spawn(7, "trigger", 0, 6, 5, 4)
dsb_spawn(2, "stairsup", 1, 7, 3, 4)
exvar = {
[4] = { func = "printgap" },
[5] = { m_d = "offpittrigger",
m_a = "ontopittrigger",
m_t = "flippittrigger" },
[6] = { opby_party = true,
const_weight = true,
target = { 5, 5, 5 },
msg = { 100000, 100002, 100001 } },
[7] = { const_weight = true,
opby_party = true,
target = { 5, 5, 5 },
msg = { 100000, 100002, 100001 } },
[10] = { const_weight = true,
opby_party = true,
target = { 5, 5, 5 },
msg = { 100000, 100002, 100001 } },
}
dsb_spawnburst_end()
EDITOR_FLAGS = 255
dsb_champion_toparty(0, 1)
dsb_party_place(0, 0, 0, 0)

Code: Select all

function dolog(a,b,c,d,e,f)
	text = ""
	text = text .. tostring(a) .. " "
	text = text .. tostring(b) .. " "
	text = text .. tostring(c) .. " "
	text = text .. tostring(d) .. " "
	text = text .. tostring(e) .. " "
	text = text .. tostring(f)
	__log(text)
	dsb_write(debug_color, text )
end

function ontopittrigger(a,b,c,d,e)
	dolog("ONTOPITTRIGGER",a,b,c,d,e)
end

function offpittrigger(a,b,c,d,e)
	dolog("OFFPITTRIGGER",a,b,c,d,e)
end

function flippittrigger(a,b,c,d,e)
	dolog("FLIPPITTRIGGER",a,b,c,d,e)
end

function printgap()
	__log("---")
	dsb_write(debug_color, "---" )
end

function marker(a,b,c,d,e)
	dolog("MARK",a,b,c,d,e)
end
Parsing mintest2/dungeon.lua
Lua: ONTOPITTRIGGER 5 0 2 5 4
Lua: FLIPPITTRIGGER 5 0 2 5 4
Lua: OFFPITTRIGGER 5 0 2 5 4
Lua: OFFPITTRIGGER 5 0 2 5 4
Lua: FLIPPITTRIGGER 5 0 2 5 4
Lua: ONTOPITTRIGGER 5 0 2 5 4
Lua: ---
Lua: OFFPITTRIGGER 5 0 2 5 4
Lua: FLIPPITTRIGGER 5 0 2 5 4
Lua: ONTOPITTRIGGER 5 0 2 5 4
Lua: ONTOPITTRIGGER 5 0 2 5 4
Lua: OFFPITTRIGGER 5 0 2 5 4
Lua: ---
Lua: ONTOPITTRIGGER 5 0 2 5 4
Lua: FLIPPITTRIGGER 5 0 2 5 4
Lua: OFFPITTRIGGER 5 0 2 5 4
Lua: OFFPITTRIGGER 5 0 2 5 4
Lua: FLIPPITTRIGGER 5 0 2 5 4
Lua: ONTOPITTRIGGER 5 0 2 5 4
SHUTDOWN: Shutting down...
I was trying to test for "during the locked period messages are put in a queue and it needs to be a fifo", but on the middle trigger the toggle message isnt getting sent at all...

Re: Pits and triggers bug

Posted: Fri Sep 09, 2016 8:09 pm
by Sophia
Ok, this one was tricky. Thank you for the detailed bug report. All of the information you posted was really helpful in sorting this out. It saved me a lot of testing I'd have to do myself. :)

Here's what happened. You step on the square with the pit and the trigger. DSB iterates through everything on the square. The pit is first, so it locks the game. When the game is locked, messages with a 0 delay are, as you surmised, dropped into a message queue rather than delivered immediately, so the constant weight trigger's "on" message goes into the queue. Time passes. The game is unlocked, and the party gets moved off the square. The constant weight trigger's "off" message gets sent immediately thereafter; the game is no longer locked so the message is delivered immediately. The timers now run for this tick, including delivering queued messages, so the "on" message now arrives after the "off" message. Nothing exploded despite this being obviously wrong because the problem was in the message delivery code-- everything happened in the right order to the constant weight trigger itself, which is where all the sanity checking for this kind of thing is.

I've changed it so that messages queued due to a lock are now delivered immediately upon unlocking the game, and everything seems to work fine, now. You can download the updated version here.

Re: Pits and triggers bug

Posted: Sat Sep 10, 2016 6:52 am
by kaypy
Thankyou
Sophia wrote:Ok, this one was tricky. Thank you for the detailed bug report. All of the information you posted was really helpful in sorting this out. It saved me a lot of testing I'd have to do myself. :)
There's a limit to what I can do by debugging at this end, but at least I can write a really good test case. It's not like I can reasonably throw a megabyte of randomly generated dungeon at you and expect you to figure out whats going on at the halfway mark of this particular instance...

Satisfying my own curiosity in the process is a bonus 8-)