Jump to content
  • 0

[DECOHack][DSDHacked] Problems with randomizer thing


Firebert

Question

I am currently attempting to use DECOHack in order to replace every imp on a given map with one of 2 other things. Sort of similar to the RandomSpawner actor from ZDoom.

Here is my script


thing MTF_IMP free states
thing MTF_IMP "ImpRandomizer"
{
    health 1
    speed 1
    
    clear states
    States
    {
        Spawn:
            TROO AB 1 A_RandomJump(Caco, 127)
            TROO AB 1 A_RandomJump(Baron, 127)
            Loop
        Caco:
            TROO EF 1 A_SpawnObject(15)
            Stop
        Baron:	
            TROO EF 1 A_SpawnObject(16)
            Stop
    }
}

In theory, when an imp is spawned it has a chance to either spawn a cacodemon or baron and then stop. Which sort of works but for some reason it spawns two of that monster. I assume this is just a simple state timing error or something that I don't understand but I'm not sure how to fix this.

 

Secondary question: is there a way to effectively have more than two random states be selected at equal chance? Right now how it's set up it will have a 50% chance to spawn a cacodemon or to have another 50% chance to spawn a baron or to loop. Which if my simple understanding of probability serves me, will mean that if I add a third A_RandomJump in the spawn label, the third will have a smaller chance to occur than the first or second one. I assume there is some sort of equation I can use to solve this, however I am not mathematically inclined enough to figure it out.

Share this post


Link to post

5 answers to this question

Recommended Posts

  • 2

I've prototyped a similar thing once, here's a working example I adapted to replacing imp.

 

Decohack (included in wad)

#include <mbf21>
#include <friendly>
thing MTF_IMP "ImpRandomizer"
{
	-COUNTKILL		//remove spawner from kill count
    
	clear states
	States
		{
			Spawn:
				TNT1 A 1				//skip 1st frame
				TNT1 A 0 A_RandomJump(Caco, 128)	//roll #1 - 50% for Caco	
				TNT1 A 0 A_RandomJump(Rev, 128)		//roll #1 failed => roll #2 - 50% chance for rev (global chance is 25%)
				TNT1 A 1 A_SpawnObject(16)		//roll #2 failed => spawn a baron (global chance is 25%)
				Stop							
			Caco:
				TNT1 A 1 A_SpawnObject(15)		//roll #1 success
				Stop
			Rev:
				TNT1 A 1 A_SpawnObject(6)		//roll #2 success
				Stop
		}
}

As explained by others, you a) should not double frames and b) calculate probabilities correctly and make sure there is a "final" monster with 100% unconditional spawn.

Additionally, you should remove countkill flag from your spawner if you replace an existing doom enemy that has it.

I also use special TNT1 sprite name, which makes the spawner invisible, as well as 0 frame length for all RandomJump checks so they all happen simultaneously.

Edited by Doomy__Doom
clearing up attachment space, was wrong wad attached anyway lmao

Share this post


Link to post
  • 1

No idea why you're getting two monsters, but maybe I can help with the probability.

 

A_RandomJump uses a chance of jumping, going to the next line if this chance isn't met. This is different to some ZDoom functions where the probabilities are actually a "weight," or chance of a thing happening vs other items in the random list.

 

Right now, as you stated, you have a 50% chance for a caco, and then a 50% for a baron OR a loop. In other words 25% chance baron, 25% chance to do the whole thing again. This means the caco is actually more likely to occur. I don't know if this is intentional or not, but probably not; and as it is there's a small chance of an infinite loop occurring, so you should rewrite it anyhow.

 

If you want two monsters with equal chance, the odds should be 1/2 (50%) on the first one, and then 1/1 (100%) on the second one, since you've already done the 50% check once. For 3 monsters it's 1/3 (33%) on the first, 1/2 (50%) on the 2nd, and 1/1 (100%) on the third, and so on.

 

Side note: 50% chance for A_RandomJump is 128, and 100% is 256.


 

 

For unequal odds on a series of binary jumps like A_RandomJump, things start to get complicated. I actually don't know if there's a general formula, there probably is, but what you can do is write down the probabilities of all outcomes you want and then set your A_RandomJump chance based on a percentage of the probability of all remaining choices. I'm not explaining that well at all, so here's an example, lets say you want these odds of monsters spawning:

 

45% cacodemon

30% hell knight

10% baron

10% mancubus

5% trooper

 

The first one is easy, you want a 45% chance, 45% of 256 (256 * 0.45) is 115.2 so we round to 115 and use that.

 

The total chance of the remaining monsters is 55%. 30/55 is 0.545454 so that's the actual chance you want to spawn the hell knight with, multiplied by 256 it works out to be about 140.

 

25% left. 10/25 * 256 is about 102, so that's the baron.

 

10/15 * 256 is about 171, so that's the manc.

 

And then the trooper is all that's left so he gets 256, or 100% chance. (Maybe you don't even need A_RandomJump here, I don't know what coding convention is best practice in this case.)

Edited by plums

Share this post


Link to post
  • 1
2 hours ago, Firebert said:

TROO AB 1 A_RandomJump(Caco, 127)
TROO AB 1 A_RandomJump(Baron, 127)

 

So each frame letter is a different state, effectively what you have here is:

TROO A 1 A_RandomJump(Caco, 127)
TROO B 1 A_RandomJump(Caco, 127)
TROO A 1 A_RandomJump(Baron, 127)
TROO B 1 A_RandomJump(Baron, 127)

 

And so likewise for this:

TROO EF 1 A_SpawnObject(whatevs)

it's actually this:

TROO E 1 A_SpawnObject(whatevs)
TROO F 1 A_SpawnObject(whatevs)

 

Edited by Gez

Share this post


Link to post
  • 0

When you write multiple letters, it executes codepointer on every letter. This is why you get two monsters.

Also the game won't execute codepointer from the first frame

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  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...