Announcement: Be excellent to each other.


Caravel Forum : DROD Boards : Bugs : Tar Babies created and dying in same turn
New Topic New Poll Post Reply
Poster Message
TFMurphy
Level: Smitemaster
Rank Points: 3118
Registered: 06-11-2007
IP: Logged

File: Tarbaby Patch.txt (11.7 KB)
Downloaded 43 times.
License: Public Domain
icon Tar Babies created and dying in same turn (+9)  
I was rereading some of the older bug reports, particularly one that I posted for RPG a while back. And it occurs to me that the unintuitive way of babies being generated and then killed during bomb explosions and other events also has effects in TCB.

First, a description of the problem. Tar is only ever removed one square at a time, and baby generation from unstable tar is dealt with at this time. There are no exceptions to this: stuff like simultaneous stabs only work because the game calculates what tar squares will be removed before it starts, and won't create babies under swords.

As a group of tar is destroyed, this leaves moments where there are pieces of tar that are going to be destroyed but are currently unstable. Currently, this tar is automatically converted into new babies. Then later, they can end up being destroyed by the same thing that caused the tar to become unstable in the first place.

As for what the current system affects... well, for starters, babies instantaneously generated and then killed by an explosion get added to the kill counter. More importantly, it fires the "Tar/Mud/Gel baby formed" events, which could cause scripts to run under conditions that weren't originally intended. Furthermore, it can cause "Monster stabbed" events if briar is destroying the newly formed babies.

In short, the order in which the tar is destroyed during something that should be considered 'instantaneous' (bomb explosions, briar, bridges over water) can cause differences in scripts.

EDIT: It can also affect whether some babies are generated at all: if a sword-wielding character is blocking where a baby will be generated, then the baby will be generated *only* if the character is destroyed by the explosion before it creates the unstable tar.

 O
 TT
 TT
DTTD
 \/

In the above example, two Decoys (D) have their swords on the final row of 2x4 piece of tar. The bomb (O) will explode destroying the decoys and all but the last row of tar. But only one baby will be created from the SW corner of tar.

===

Since this now concerns both TCB and RPG, I've been trying to think of a way to solve this. But if we try to remove *all* the tar before we generate babies, we immediately hit a big problem: backcompatibility.

TTTT   TTTT
TTTT   T***
TTTT   T***
TTTT   T***
    O

12TT   12TT   12TT   1267
3 **   3 **   3 **   3  8
T***   4 **   4 **   4 **
T***   56**   5 **   5 **


123T   123T   123T   1237
4 **   4 **   4 **   4  *
5***   5 **   5 **   5 **
T***   6***   6 **   6 **


Above is a diagram of a 4x4 piece of tar being having a 3x3 portion of itself blown up. Two rows then appear. The first row shows how baby generation currently occurs, and the second row shows how it might occur if we didn't test unstable tar until all of it is destroyed.

In the first row, each part of the explosion is dealt with going down each column, starting from the leftmost. Tar that is immediately unstable automatically generates babies, so those go first in the movement order. So when the NW corner of the explosion removes the first piece of tar, we immediately get to generate 3 babies. On the next tile, we generate three more babies (#4, #5 and #6). On the final tile in that column, we destroy baby #6.

If we destroyed all tar before processing unstable tar though, the current system is to test the 8 squares around each removed square of tar. So we'd remove all the tar, and then test the NW corner of the removed tar first, which immediately creates 5 babies. Already, a change in movement order. In short, the unexploded tar in the current code prevents certain babies from being created earlier than they might otherwise have been.

===

So, to both fix this problem *and* preserve the current movement order is somewhat problematic. The best way I can currently think of is to replace the AddNewMonster and CueEvent addition in RemoveStabbedTar with adding both the coordinates and tartype to a CoordStack/CoordIndex combination, which can then be iterated through to create the correct babies in the correct order. Furthermore, DestroyTar should be allowed to remove coordinates form this set. So you might have the following changes:

CDbRoom::RemoveStabbedTar
Click here to view the secret text

EDIT: Upon further reflection, the changes to RemoveStabbedTar would need to be more extensive, since if we removed unstable tar when creating 'babies in potentia', then additional explosions/briar growth would not detect that there is 'tar' to be destroyed on those squares, so the second routine of DestroyTar would not run. Instead, the new baby generation routine will have to use babyOrder to turn existing unstable tar into babies. This also means that we don't need babyType to store what type of baby was generated, but since we're not removing tar at this juncture, RemoveStabbedTar needs to treat 'babies in potentia' as tiles that *don't* have Tar. Changing GetTSquare to reflect this is out of the question, so I've updated the example code to try and reflect what might have to be done.

EDIT 2: The attached patch file is more accurate and has actually been compiled and undergone preliminary testing.

CDbRoom::DestroyTar
Click here to view the secret text


babyType and babyOrder would need to be part of the CDbRoom class, and I'm not entirely sure what all needs to be updated to make that happen (not as simple as just adding them to DbRooms.h, since there's a lot of initialization and variable copying done). There would also need to be a new procedure to iterate over babyOrder and create the new babies, and this would need to be called by everything that uses RemoveStabbedTar. Things like bomb explosions and briar should delay calling this new procedure until after they're done though, rather than immediately after each RemoveStabbedTar call.

One change that should probably be done though is to forbid babies from being created on water. The current test used in RemoveStabbedTar is: if (!(swordCoords.Exists(i, j) || bIsStairs(wOSquare) || bIsPit(wOSquare) || (i == wSX && j == wSY))). This means that babies can be created over water, but will immediately drown, and it also means that water can cause "Tar baby formed" events to fire even when no Tar babies live to the end of the turn, while pits can't. If we change it to prevent babies from being created on water, then that neatly fixes the problems for bridges, and so the CheckForFallingAt routine can safely attempt to create babies immediately after it destroys each piece of tarstuff.

===

In summary, I'm not entirely sure of the best way of solving this problem for both TCB and RPG, so these are my observations and understanding of it all. Hopefully it'll help.

EDIT 2: I've since coded a quick patch based on Build 84 source code, and have attached it to this post. I decided that the best variable to emulate with regards to initialization and copying was newFuses and the like, so that means one initialization in CDbRoom::Clear and one copy in CDbRoom::SetMembers. It looks to preserve movement order, and isn't causing Museum of Ooze to freak out. Haven't comprehensively tested it though. Also couldn't quickly think of a better name than babyOrder, so feel free to change that if you want.

[Last edited by TFMurphy at 11-09-2010 09:15 PM]
11-09-2010 at 12:23 PM
View Profile Send Private Message to User Show all user's posts This architect's holds Quote Reply
Someone Else
Level: Smitemaster
Avatar
Rank Points: 1304
Registered: 06-14-2005
IP: Logged
icon Re: Tar Babies created and dying in same turn (0)  
Would it be possible to keep the same behaviour, but not have the babies produced trigger death effects unless they get a turn to act?
12-07-2010 at 09:45 PM
View Profile Send Private Message to User Send Email to User Show all user's posts High Scores This architect's holds Quote Reply
TFMurphy
Level: Smitemaster
Rank Points: 3118
Registered: 06-11-2007
IP: Logged
icon Re: Tar Babies created and dying in same turn (0)  
Which behaviour? "Tar Baby Formed" events being fired? But then you have rooms where the only difference between whether an explosion creates a tar baby or not for a "Tar Baby Formed" event is whether the room's horizontally or vertically flipped.

Decoy swords preventing babies from spawning? Again, should the player really have to factor the *possibility* of swords vanishing mid-explosion? Ideally, either all swords pre-explosion should prevent tar babies from being formed, or all sword that no longer exist post-explosion should *not* prevent tar babies from formed. Any inbetween pretty much requires adding in an exception that has very little real value and is rather unintuitive to players. Not that arcane behaviour like this don't already exist in DROD, but do we really need to encourage another one? Oh, and don't be fooled by the words 'explosion' in this paragraph: the same thing happens with briar. Should the player have to take into account the *exact* way briar grows per tile?

And I would rather that any solution done for TCB should work equally well for RPG, and since RPG can have explosions that only *partially* damage, it's an easier setup altogether (and was certainly voted by the most people in that thread) to just stop tar babies from spawning until after the explosion.

===

In short, what exactly are you wanting to happen, and why? Out of the changes listed in the thread, I think the only possible one I could see argued is having swords prevent tar babies from being spawn if they were there pre-explosion (rather than removing them all and then spawning tar babies), but that's not *quite* as simple to code. (Not *horrendously* difficult, but it would essentially mean we'd need a 'pre-routine' to create a sword-map of the room before we start cutting any tar.)
12-07-2010 at 10:43 PM
View Profile Send Private Message to User Show all user's posts This architect's holds Quote Reply
mrimer
Level: Legendary Smitemaster
Avatar
Rank Points: 5058
Registered: 02-04-2003
IP: Logged
icon Re: Tar Babies created and dying in same turn (0)  
Thanks, TFMurphy! When you feel you've tested this enough on your end, please go ahead and commit your changes so we can get this into a beta build for testers to verify.

Oh -- when you're making changes in general, either please go ahead and commit them to DROD RPG also, or just let me know we need to replicate this fix for DROD RPG so the change doesn't fall through the cracks between games. Thanks again!

____________________________
Gandalf? Yes... That's what they used to call me.
Gandalf the Grey. That was my name.
I am Gandalf the White.
And I come back to you now at the turn of the tide.
12-28-2010 at 04:36 PM
View Profile Send Private Message to User Send Email to User Show all user's posts High Scores This architect's holds Quote Reply
TFMurphy
Level: Smitemaster
Rank Points: 3118
Registered: 06-11-2007
IP: Logged
icon Re: Tar Babies created and dying in same turn (+2)  
Submitted a fix to the SVN for both TCB and RPG. Events that destroy tar now wait until they're finished destroying tar before indicating that tar babies may be converted.
12-29-2010 at 01:48 AM
View Profile Send Private Message to User Show all user's posts This architect's holds Quote Reply
New Topic New Poll Post Reply
Caravel Forum : DROD Boards : Bugs : Tar Babies created and dying in same turn
Surf To:


Forum Rules:
Can I post a new topic? No
Can I reply? No
Can I read? Yes
HTML Enabled? No
UBBC Enabled? Yes
Words Filter Enable? No

Contact Us | CaravelGames.com

Powered by: tForum tForumHacks Edition b0.98.8
Originally created by Toan Huynh (Copyright © 2000)
Enhanced by the tForumHacks team and the Caravel team.