(fixed) Pits and triggers bug

This forum is for the Lua scriptable clone of DM/CSB called Dungeon Strikes Back by Sophia. Use DSB to build your own highly customised games.

Moderator: Sophia

Forum rules
Please read the Forum rules and policies before posting.
Post Reply
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

(fixed) Pits and triggers bug

Post 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.
Friends don't let friends eat worm round
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

Re: Pits and triggers bug

Post 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?
Friends don't let friends eat worm round
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

Re: Pits and triggers bug

Post 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...
Friends don't let friends eat worm round
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

Re: Pits and triggers bug

Post 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.
Friends don't let friends eat worm round
User avatar
Sophia
Concise and Honest
Posts: 4239
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: Pits and triggers bug

Post by Sophia »

It's definitely the locks and delays that are tripping us up, here. I'll have a look at this soon.
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

Re: Pits and triggers bug

Post 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...
Friends don't let friends eat worm round
User avatar
Sophia
Concise and Honest
Posts: 4239
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: Pits and triggers bug

Post 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.
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

Re: Pits and triggers bug

Post 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-)
Friends don't let friends eat worm round
Post Reply