(fixed) Crash on monster boss code [0.82]

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. You may Image to help finance the hosting costs of this forum.
Post Reply
kaypy
Artisan
Posts: 187
Joined: Sun Jan 19, 2014 7:11 am

(fixed) Crash on monster boss code [0.82]

Post by kaypy »

This was tweaked in the new version, so likely a regression there?

Reason: Segmentation Fault
Stack Dump:
DSBmain
DSBgameloop
dungeon_move
party_moveto
to_tile(on_trigger)
lua_call.member_func
lua.stairsdown.on_trigger
lua.dsb_ai_boss
monster_groupup

Oddly, the stairsdown.on_trigger I have doesn't call dsb_ai_boss, so I'm guessing theres a missing function in the stack?

Code: Select all

stairsdown.on_trigger=ksm.stairs_base
The party is moving, so this will pretty much skip straight to the use_stairs case at the end

Code: Select all

function ksm.stairs_base(self, id, what)

	if (is_opby(id, what, 0)) then
		got_triggered(id, what)
	end

	if (what) then
	    local arch = dsb_find_arch(what)

	    if (arch.type == "MONSTER") then
			ksm.mon_use_stairs(self,id,what)
	    end
	    
	    if (arch.type == "THING") then
			local fly = dsb_get_flystate(what)
			
			if (not fly) then
				local lev, xc, yc, landpos = dsb_get_coords(what)
				local back_out_dir = open_facing(lev, xc, yc, landpos)
				
				-- If the stairs go up, just bump into the stairs and drop
				if (self.stairs_dir < 0) then
					local dx, dy = dsb_forward(back_out_dir)
					dsb_move(what, lev, xc+dx, yc+dy, dsb_tileshift(landpos, back_out_dir))				
				else
					local levchg = self.stairs_dir
					if (exvar[id]) then
						if (exvar[id].x) then
							xc = exvar[id].x
							levchg = 0
						end	
						if (exvar[id].y) then
							yc = exvar[id].y
							levchg = 0
						end
						if (exvar[id].lev) then 
							lev = exvar[id].lev
							levchg = 0
						end
					end
			    
					local out_dir = open_facing(lev+levchg, xc, yc, landpos)
					local dx, dy = dsb_forward(out_dir)
					
					local flip_side = false
					if (back_out_dir == landpos) then
						flip_side = true
					end
					
					local newpos = dsb_tileshift(out_dir, out_dir)
					if (flip_side) then
						newpos = dsb_tileshift(newpos, ((out_dir+1)%4))
					end
					
					-- In actual DM, this check doesn't exist. If you throw something down
					-- the stairs, it lands at the bottom... if there is a wall down there,
					-- the item will be stuck in the wall. This is, in my opinion, a bug.
					-- The simplest fix is to just not let it go down the stairs.
					if (dsb_get_cell(lev+levchg, xc+dx, yc+dy)) then
						local bdx, bdy = dsb_forward(back_out_dir)
						dsb_move(what, lev, xc+bdx, yc+bdy, dsb_tileshift(landpos, back_out_dir))	
					else
						dsb_move(what, lev+levchg, xc+dx, yc+dy, newpos)		
					end
					
				end
			end
		end
	else	
		ksm.use_stairs(self, id)
	end
end
I think the actual damage happens in the monster tracking section here

Code: Select all

function ksm.use_stairs(stairs_arch, id)

	if (exvar[id] and exvar[id].temp_disabled) then
		return false
	end
		
	if (exvar[id].ksm_targstair) then
		exvar[exvar[id].ksm_targstair].temp_disabled = true
		dsb_delay_func(END_OF_FRAME, function()
			exvar[exvar[id].ksm_targstair].temp_disabled = nil
		end)
	end
	
	-- Any monsters tracking the party should head for the stairway
	local pz,px,py,pf = dsb_party_coords()
	for monid in dsb_insts() do
		local arch = dsb_find_arch(monid)
		if (arch.type == "MONSTER" and
				dsb_ai_boss(monid) == monid) then
		end		
		if (arch.type == "MONSTER" and
				dsb_ai_boss(monid) == monid and
				dsb_ai(monid,AI_SEE_PARTY,QUERY) and
				(not dsb_ai(monid, AI_FEAR, QUERY))) then
			add_monster_target(monid,15,px,py)
		end
	end
	
	
	if (exvar[id].sound) then
		dsb_sound(snd[exvar[id].sound])
	end	
	dsb_party_place(exvar[id].lev, exvar[id].x, exvar[id].y, exvar[id].ksm_otherdir)
		
	return true
end
edit: Oh, and I should note I hadn't made any code changes since a full runthrough in 0.81
Friends don't let friends eat worm round
kaypy
Artisan
Posts: 187
Joined: Sun Jan 19, 2014 7:11 am

Re: Crash on monster boss code [0.82]

Post by kaypy »

So I tried to make a simplified reproduction, but I'm not getting the same result. I'll see if I can reproduce it in the original dungeon next.

The following does **not** crash

dungeon.lua

Code: Select all

---DSB ESB---
--[[ Autogenerated by ESB.
 Trying to edit this file by hand may not give you
 particularly good results.
]]

dsb_text2map(0, 10, 10, 100, 1, {
"0000000000",
"0000000000",
"0000000000",
"0001110000",
"0111111100",
"0001110000",
"0001110000",
"0001110000",
"0001110000",
"0000000000"} )
dsb_level_wallset(0, wallset.default)
dsb_text2map(1, 10, 10, 0, 1, {
"0000000000",
"0000000000",
"0111110000",
"0111010000",
"0111111100",
"0111010000",
"0111110000",
"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(38)
dsb_spawn(26, "tattered_shirt", CHARACTER, test, 3, 0)
dsb_spawn(27, "tattered_pants", CHARACTER, test, 4, 0)
dsb_spawn(11, "button_blue", 0, 3, 2, 2)
dsb_spawn(9, "sconce_full", 0, 5, 2, 2)
dsb_spawn(35, "torch", IN_OBJ, 9, 0, 0)
dsb_objset(35, false, false, 0, 0, 500, 0, 0)
dsb_spawn(3, "outside", 0, 0, 4, 1)
dsb_spawn(4, "doorframe", 0, 1, 4, 4)
dsb_spawn(21, "door_black", 0, 1, 4, 4)
dsb_spawn(1, "stairsdown", 0, 7, 4, 4)
dsb_spawn(8, "doorframe", 0, 3, 5, 4)
dsb_spawn(20, "door_ra", 0, 3, 5, 4)
dsb_spawn(12, "doorframe", 0, 4, 5, 4)
dsb_spawn(22, "door_ra", 0, 4, 5, 4)
dsb_spawn(13, "doorframe", 0, 5, 5, 4)
dsb_spawn(23, "door_ra", 0, 5, 5, 4)
dsb_spawn(38, "giggler", 0, 3, 7, 3)
dsb_spawn(24, "giggler", 0, 4, 7, 0)
dsb_spawn(25, "giggler", 0, 4, 8, 4)
dsb_spawn(10, "sconce_full", 1, 0, 2, 1)
dsb_spawn(37, "torch", IN_OBJ, 10, 0, 0)
dsb_objset(37, false, false, 0, 0, 500, 0, 0)
dsb_spawn(32, "helm_darc", 1, 2, 3, 1)
dsb_spawn(31, "torsoplate_darc", 1, 2, 3, 2)
dsb_spawn(30, "shield_darc", 1, 2, 4, 1)
dsb_spawn(29, "legplate_darc", 1, 2, 4, 2)
dsb_spawn(5, "doorframe", 1, 4, 4, 4)
dsb_spawn(33, "door_portcullis", 1, 4, 4, 4)
dsb_spawn(6, "doorbutton", 1, 4, 4, 4)
dsb_spawn(2, "stairsup", 1, 7, 4, 4)
dsb_spawn(28, "footplate_darc", 1, 2, 5, 1)
dsb_spawn(7, "sconce_full", 1, 0, 6, 1)
dsb_spawn(36, "torch", IN_OBJ, 7, 0, 0)
dsb_objset(36, false, false, 0, 0, 500, 0, 0)
exvar = {
[6] = { target = 33 },
[7] = { release = true },
[9] = { release = true },
[10] = { release = true },
[11] = { func = "testboss" },
}
dsb_spawnburst_end()
EDITOR_FLAGS = 255
dsb_champion_toparty(0, 1)
dsb_party_place(0, 2, 4, 1)
startup.lua

Code: Select all

function testboss(id, what, data_parm)
	__log("testboss")
	for monid in dsb_insts() do
		local arch = dsb_find_arch(monid)
		if (arch.type == "MONSTER" and
				dsb_ai_boss(monid) == monid) then
		end		
		if (arch.type == "MONSTER" and
				dsb_ai_boss(monid) == monid and
				dsb_ai(monid,AI_SEE_PARTY,QUERY) and
				(not dsb_ai(monid, AI_FEAR, QUERY))) then
			add_monster_target(monid,15,5,8)
		end
	end
end
Friends don't let friends eat worm round
kaypy
Artisan
Posts: 187
Joined: Sun Jan 19, 2014 7:11 am

Re: Crash on monster boss code [0.82]

Post by kaypy »

Tweaking my use_stairs code to

Code: Select all

	...
	__log("ust")
	local pz,px,py,pf = dsb_party_coords()
	for monid in dsb_insts() do
		local arch = dsb_find_arch(monid)
		if (arch.type == "MONSTER") then
			__log(tostring(monid))
		end		
		if (arch.type == "MONSTER" and
				dsb_ai_boss(monid) == monid) then
		end		
		if (arch.type == "MONSTER" and
				dsb_ai_boss(monid) == monid and
				dsb_ai(monid,AI_SEE_PARTY,QUERY) and
				(not dsb_ai(monid, AI_FEAR, QUERY))) then
			add_monster_target(monid,15,px,py)
		end
	end
	__log("!ust")
	...
I get log output

Code: Select all

Lua: ust
Lua: 9295
Lua: 9296
Lua: 9297
Lua: 9298
Lua: 9299
Lua: 9300
Lua: 9301
Lua: 9302
Lua: 9303
Lua: 9304
Lua: 9305
Lua: 9307
Lua: 9308
Lua: 9309
Lua: 9312
Lua: 9313
Lua: 9314
Lua: 9315
Lua: 9316
Lua: 9317
Lua: 9318
Lua: 9319
Lua: 9320
Lua: 9321
Lua: 9322
Lua: 9324
Lua: 9325
Lua: 9326
Lua: 9329
Lua: 9330
Lua: 9331
Lua: 9332
Lua: 9333
Lua: 9334
Lua: 9336
Lua: 9337
Lua: 9338
Lua: 9339
Lua: 9340
Lua: 9341
Lua: 9342
Lua: 9343
Lua: 9344
Lua: 9345
Lua: 9346
Lua: 9347
Lua: 9348
Lua: 9349
Lua: 9350
Lua: 9351
Lua: 9352
Lua: 9353
Lua: 9354
Lua: 9355
Lua: 9356
Lua: 9357
Lua: 9358
Lua: 9359
Lua: 9360
Lua: 9361
Lua: 9362
Lua: 9363
Lua: 9364
Lua: 9365
Lua: 9366
Lua: 9367
Lua: 9368
Lua: 9369
Lua: 9370
Lua: 9371
Lua: 9372
Lua: 9373
Lua: 9374
Lua: 9375
Lua: 9376
Lua: 9377
Lua: 9378
Lua: 9379
Lua: 9380
Lua: 9381
Lua: 9382
Lua: 9383
Lua: 9384
Lua: 9385
Lua: 9386
Lua: 9387
Lua: 9388
Lua: 9389
Lua: 9390
Lua: 9391
Lua: 9392
Lua: 9393
Lua: 9394
Lua: 9395
Lua: 9396
Lua: 9397
Lua: 9398
Lua: 9399
Lua: 9400
Lua: 9401
Lua: 9402
Lua: 9403
Lua: 9404
Lua: 9405
Lua: 9406
Lua: 9407
Lua: 9408
Lua: 9409
Lua: 9410
Lua: 9411
Lua: 9412
Lua: 9413
Lua: 9414
Lua: 9415
Lua: 9416
Lua: 9417
Lua: 9418
Lua: 9419
Lua: 9420
Lua: 9421
Lua: 9422
Lua: 9423
Lua: 9424
Lua: 9425
Lua: 9426
Lua: 9427
Lua: 9428
Lua: 9430
PROGRAM CRASH!
edit: Finding that critter on the map, I notice there is a reasonable possibility that it could wind up in teleporter limbo. Would that break the new boss code?
Friends don't let friends eat worm round
kaypy
Artisan
Posts: 187
Joined: Sun Jan 19, 2014 7:11 am

Re: Crash on monster boss code [0.82]

Post by kaypy »

Code: Select all

Lua: 9425 @ 1 22 28 2
Lua: 9426 @ 1 22 28 1
Lua: 9427 @ 1 5 3 0
Lua: 9428 @ 1 25 5 0
Lua: 9430 @ -5 0 0 0
PROGRAM CRASH!
Yeah I'm thinking something doesn't work if the monster is in limbo?

edit It sometimes works in limbo too though, and I cant get my minimal version to crash by piling monsters in a teleporter...
Friends don't let friends eat worm round
User avatar
Sophia
Concise and Honest
Posts: 4306
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: Crash on monster boss code [0.82]

Post by Sophia »

This bug is actually older, although the new code might have made it surface. Thanks for all your helpful debugging information.

The real issue here is that the C function monster_groupup doesn't do anything sensible when the monsters aren't on a physical tile in the dungeon. It skips the whole groupup check if the monster was centered before it went into limbo, which is why it works sometimes, and teleporter limbo has a special extra parameter to its function call that specifically protects it from any of this nonsense.

I've fixed the problem by breaking your code. :mrgreen: Calling dsb_ai_boss on a monster not in the physical dungeon will now spit out a Lua error.

It's easy enough for you to fix. You can either:
:arrow: Call dsb_ai_boss(id, true), which skips most of the validation and just returns whatever the monster's boss was before. This is what the teleporter code does, but the answer may not be particularly useful for your use case.

:arrow: Call dsb_get_coords on each monster and only interact with the ones that are actually in the dungeon. This is probably a better idea if you plan on trying to give them targets and such.

Here's a new .exe for you to try: dsb83test
kaypy
Artisan
Posts: 187
Joined: Sun Jan 19, 2014 7:11 am

Re: (fixed) Crash on monster boss code [0.82]

Post by kaypy »

Thanks. I'll give it a try

Yeah it probably doesn't make too much sense to instruct monsters to head to a stairway when they aren't actually in the dungeon 8-)

...

Works for me now. Of course, only processing the monsters in the dungeon would also bypass the error anyway, so first I tried the dsb_ai_monster(id, true) which no longer has any crashes.

Then I made it only attempt to process monsters on the right level.
Friends don't let friends eat worm round
Post Reply