The placement logic was mostly fine by the end. The object “disappearing” had two different causes:
First, the ride’s own BHAV scripts were deleting the group after placement. The traces showed VMRemoveObjectInstance coming from routines like Main – Bats, then every tile in the 25-tile group got DeleteQueued/DeleteNow. I patched those Haunted House BHAV branches so the ride no longer runs the self-delete path during normal placement.
Then the second issue was why it became “invisible” instead of deleted. The HauntedHouse .iff files had accidentally been rewritten in a way that preserved the object definitions and BHAVs, but destroyed the raw sprite chunks. So the game could place 25 tiles, collision/footprint worked, but the renderer had no real SPR2 image data to draw. That is why you only saw the yellow placement grid.
The key code fix was in IffFile.cs (line 260): when writing an IFF, it now uses SilentListAll() and preserves raw chunk bytes for chunks we did not actually process. Before, saving a small BHAV edit could force unrelated chunks like sprites to be decoded/rewritten, and those sprite chunks came back empty. Tiny change, huge consequence.
I also restored the HauntedHouse IFFs from clean full-size copies and reapplied only the intended BHAV placement patches. After that the runtime copies had real DGRP/SPR2 data again, so the object can both place and render. The fallback in WorldObjectProvider.cs (line 484) is extra insurance: for these Haunted ride objects, it can attach usable TS1 sprite resources if the standalone object needs them.
