Jump to content

WeiDU issue: fj_are_structure breaks for areas that lack the rest encounter table


jmerry

Recommended Posts

I encountered this one when debugging an error someone brought to me; a component of mine failed with a bad read error when applied to a particular mod-added area.

In trying to debug it, I found problems. Which weren't that error. Then I looked deeper, and eventually found it. The bad read was coming in an application of fj_are_structure to add stuff. Which, since that's a function built into WeiDU, really should be stable. But the area lacked the rest encounter table, and that broke things.

Distilling from my original very complicated component, here's a nice simple version. This mini-mod will fail to install with a bad read error, when applied to a clean instance of BGEE:

Spoiler
BACKUP ~weidu_external/backup/test~
SUPPORT ~Not applicable~

// AUTO_EVAL_STRINGS

ALWAYS
	ACTION_IF ((FILE_EXISTS ~dlc/sod-dlc.zip~) OR (FILE_EXISTS ~sod-dlc.zip~)) THEN BEGIN FAIL ~DLC Merger needed~ END // Modmerge check
END

VERSION ~0.1~

//
//
// Test component
//
//

BEGIN ~Test fj_are_structure issue~
REQUIRE_PREDICATE GAME_IS ~bgee~ ~BGEE only~
	COPY_EXISTING ~AR0608.ARE~ ~override~ // Flaming Fist upstairs. Lacks rest encounter table.
		LPF fj_are_structure
		 INT_VAR
		  fj_loc_x = 350
		  fj_loc_y = 250
		  fj_spawn_num = 1
		  fj_difficulty = 2
		  fj_max_num = 1
		 STR_VAR
		  fj_structure_type = spawn
		  fj_name = ~First Spawn Point~
		  fj_cre_resref0 = FLAM11
		  fj_cre_resref1 = ~~
		  fj_cre_resref2 = ~~
		  fj_cre_resref3 = ~~
		  fj_cre_resref4 = ~~
		  fj_cre_resref5 = ~~
		  fj_cre_resref6 = ~~
		  fj_cre_resref7 = ~~
		  fj_cre_resref8 = ~~
		  fj_cre_resref9 = ~~
		END
		PATCH_PRINT ~First structure successfully added. Attempting to add second structure.
~
		LPF fj_are_structure
		 INT_VAR
		  fj_loc_x = 450
		  fj_loc_y = 450
		  fj_spawn_num = 1
		  fj_difficulty = 2
		  fj_max_num = 1
		 STR_VAR
		  fj_structure_type = spawn
		  fj_name = ~Second Spawn Point~
		  fj_cre_resref0 = FLAM11
		  fj_cre_resref1 = ~~
		  fj_cre_resref2 = ~~
		  fj_cre_resref3 = ~~
		  fj_cre_resref4 = ~~
		  fj_cre_resref5 = ~~
		  fj_cre_resref6 = ~~
		  fj_cre_resref7 = ~~
		  fj_cre_resref8 = ~~
		  fj_cre_resref9 = ~~
		END
	BUT_ONLY

 

What's going on? AR0608 lacks the 228-byte rest encounter table that most areas have. This is denoted by an offset of zero in the base version of the ARE file.

When a structure is added using fj_are_structure (a spawn point in this case), various offsets move and are recalculated. Suddenly, the entry at 0xc0 goes from 0 to the file size (1872 bytes in the original version, 2072 bytes now).

Next, we try to add another spawn point. In order to make room for it, the function reads everything that comes after the insertion point, including the rest encounter table. Needless to say, reading 228 bytes starting at the end of the file does not work. Error, component aborted.

(Tested in WeiDU version 249)

What can be done about this from a modder's perspective? First off, don't make areas that lack the rest encounter table. Even if you don't have any rest encounters for the area, filling the table with 228 bytes of zeros is much better than not having it at all. But when you're adding stuff to existing areas, a sanity check is highly recommended - read the rest encounter offset at 0xc0, and skip the area if that's either zero or the file size.

... or you can just add that empty table in before proceeding with your modifications. Duh. Why did I need someone else to point the option out to me?

WRITE_LONG 0xc0 SOURCE_SIZE
INSERT_BYTES SOURCE_SIZE 228

Seriously, that's all it takes to add an empty rest encounter table to an area. Wrap that in an appropriate conditional, then proceed to adding or removing structures. This must be done before any operations that would change the size, of course.

Edited by jmerry
Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...