I need a little help with RNG please (SOLVED)

In my game, my character shoots bullets that do damage, but I would like to make a variable that gives a 1% chance that it will be a critical hit bullet, which does double damage. It doesn’t seem to be working too well. The screenshot is down below. Can somebody please tell me how to fix this?

P.S. Critical is it’s own variable because there are ways to increase the chance of a crit hit.

Any help is appreciated. Thanks in advance.

what means doesnt work well?
the random of 100 gives you a number between 0 and 99 if you check for value < or = thsn 1 so you get a 2% chance…
You could use some text objects to help debbug and see variable values.
In your fragment of code can,t see what you do if it is a hit bullet.
use a smaller chance to see if it works and as said some text objects to check values

Okay, I made it so that if the bullets have CRIT = 1 (Which makes them critical), make then bigger. It is kinda working? Idk…
Basically, the critical bullet is only able to be the first bullet fired. Any other bullet fired afterwards is a small, non critical bullet. I can only shoot another critical bullet if I stop shooting and there are no other bullets onscreen.

This is the whole code of the critical branch. Is there a way to fix this?

I think the reason why you can only shoot one Critical bullet at a time is probably because the “For Each” event has a “Trigger Once” condition.
Because of that, it triggers once for every Bullet object in the scene - at a given time. It doesn’t trigger again for the new instances. As long as there are Bullet objects in the scene, it considers itself “triggered”, and it only “un-triggers” when there are no more Bullet objects - which would allow the “For Each” (and consequently the “Trigger Once”) events to be triggered again.

Maybe instead of using the “Trigger Once” condition you could use something like:

For each Bullet object:
If variable "CriticalBullet" of Bullet = 0
  do = RandomInRange(1, 100) to variable "CriticalBullet" of Bullet.

That should make sure it won’t keep triggering when CriticalBullet already has a value, and it will also make sure the “For Each” event will still trigger for new instances of Bullet.
Also, the “RandomInRange(1, 100)” will make sure the value returned is between 1 and 100, thus making it an actual 1% chance, and also making sure the result returned will not be 0 so that the event won’t be triggered again.
I hope this works!

I did what you said. It almost works!

What is happening now is that the bullets for some reason are normal for a second, but the next second they become critical! Why do they just change in midair like this? I feel like it’s almost done, it’s just this problem left.
Edit: WHOOPS!! My bad, I just looked over the screenshot and found out that the “Repeat For” event used the wrong variable! I feel silly now… :sweat:
Anyways, I changed the event back to the appropriate event, and I think it’s working now! Thanks for the help mate! :slight_smile:

Yay! I’m glad it worked!

My bad, I just looked over the screenshot and found out that the “Repeat For” event used the wrong variable!

I was actually just about to point that out. ^u^ I’m glad I could help!

Also, just one last thing! In the event where the condition says:

If variable "CriticalBullet" of Bullet <= GlobalVariable(Critical)

You might wanna change that “<=” to a “=” if you want a 1% chance!
“<=” Means “less than or equal to”, so any number below the value of Critical (which is 50) would also result in +1 for CRIT. That makes it a 50% chance!
If you use “=”, then only the bullets with the value of 50 in the CriticalBullet variable will get a +1 in their CRIT variable, thus making is a 1 in 100 chance - aka a 1% chance!

So it should look like this:

If variable "CriticalBullet" of Bullet = GlobalVariable(Critical)
  do = 1 to variable "CRIT" of Bullet.

A 1/100 chance!

I’m glad I could help! ^^

Thank you.
Also, the “<=” is necessary for the game because I’m making a roguelike game, and there are items that increases the chance of a critical strike. 1% is just the base chance. :slight_smile:

1 Like

Ooooh, alright! That sounds cool! I hope that goes great!

1 Like

Hey excuse me? Um… if you don’t mind, can I ask another question please?
So, I have an item in my game called “Walnut” (Idk why I chose Walnut XD). Basically, it works like this:
When the Walnut is in my inventory, the player has a chance to shoot a walnut shot (The walnut shot is the same object as my bullet, just with a different animation, so the item has a chance to change the normal bullet animation into a walnut). The walnut does extra damage than normal bullets (I can work on that part).

So, to set it up, I made it so that picking the item up increases one of the player’s object variables to test if he has the walnut. If he has the walnut give bullets a random chance to be a walnut instead (I used the same code style from the critical code).

(Note: I removed the “Trigger Once” under the “For Each” event.)
To my disappointment, it is not working properly. When I start up the game, the character is constantly shooting walnuts instead of his normal bullets, even though he didn’t even pick up the item yet.
Can you help me please? How can I make it so that bullets only have a chance to change animation if I’m carrying the specific item? Thanks in advance.

I think the reason why it isn’t working is because in the event where you assign a value to the WalnutShot variable you forgot to add a condition to check if the Walnut is in the inventory. You did it in the event above it, but you didn’t do it for the For Each event! There’s nothing stopping the For Each event from playing regardless of whether you have Walnuts or not.

Maybe drag the For Each event to be a sub-event of the one above it? Something like:

If inventory "MyStuff" contains a "Walnut"
If "Walnut" is equipped in inventory "MyStuff"
If variable "HASWALNUT" of Plushie >=1
  do = 2 to the scale of Bullet
    For  each "Bullet" object
    If variable "WallnutShot" of Bullet = 0
      do = "RandomInRange(1,3) to variable "WalnutShot" of Bullet.

If you don’t wanna do that, then at least add similar conditions to the event above it, checking if the player has Walnuts at all. If you don’t check, it’ll just always go off.

Also, I’ve been giggling at the randomness of “Walnut” for a while now, 10/10 love it

And by the way, you don’t need to use an Object Variable to check if the player has the Walnut, just the “If item is in inventory” condition should be enough. ^^ This is up to you though. I just don’t like using too many variables when there’s no need to, it gets hard to keep up with all of them!

I think the problem is that the set animation events are outside the repeat for each, they should be a subevent so on each bullet you check and set animation if not you do only for the first bullet gdevelop chose.

Okay, I did what you said:

However, it still isn’t working! :frowning: (I mean, it is a bit on an improvement however. The character only shoots walnuts when he has the item now at least…)
When I pick up the item, ALL bullets are walnuts no matter what. Even if I shoot some bullets, and then pick up the item, those bullets magically turn into walnuts!
There must be SOMETHING I’m doing wrong…

Also, if it helps, the way my character shoots bullets is that it plays an animation when the key is down. When the animation is at a certain frame, create the bullet. If this has to be changed for any reason because it’s apparently interfering with the events, then please let me know. :slight_smile:

EDIT: Yo! I think I just figured out what wasn’t working!

As it turns out, the extra object variable came in handy! What was going wrong was that I was trying to get a variable value from the SAME variable! Silly me…
I tried it out, and it’s working just like I want it to now! Either way, I still greatly appreciate your help. :slight_smile:

1 Like

I’m glad it worked to some extent! It could still have worked without the variable, though. ^^;; But I’m so glad it did work, at least!

Also, you didn’t have to copy the conditions! The sub-event obeys the same conditions as the “parent event”!
Sub-events inherit the conditions of the ones above it. So, for example, if Event 1 has the “If item is in inventory” condition, the sub-event will ALSO obey the condition! No need to copy them if they’re sub-events.

If you don’t mind, though, I still wanna break down the events on these screenshots to try and explain what was going wrong!

// Second Screenshot //
The reason why using HASWALNUT worked in that example is because the value of HASWALNUT is 1, so every single time the Random expression gives a 1 in WalnutShot, it plays. The expression can only give the values 1, 2 or 3 - so it’s a 1/3 chance. It works great, but it doesn’t NEED the HASWALNUT variable.
You didn’t need to compare it to HASWALNUT. If you replace it with just “1”, it’ll work the same - as that’s the fixed value of HASWALNUT if the Walnut is equipped.
So no, HASWALNUT is still not quite necessary! I’m sorry, I love the name of the variable though

And also, there’s nothing stopping the For Each event from playing over and over yet again. Which is why I kinda wanted you to drag it to be a sub-event.

// First Screenshot //

In the 3rd event:
If Variable WalnutShot of Bullet <= Bullet.Variable(WalnutShot)

As you’ve already pointed out, you were literally testing if WalnutShot is less or equal to WalnutShot. This is probably why every single bullet was becoming a Walnut. ^^;;
Instead, you could’ve done:
If Variable WalnutShot of Bullet = 1
Which would give the exact same result as comparing it to HASWALNUT, which is also a fixed 1 value.

And now that I think about it, there’s a chance you don’t even need a sub-event at all!
I think this is how it could’ve worked:

For each Bullet object
If inventory "MyStuff" contains a "Walnut"
If "Walnut" is equipped in inventory "MyStuff"
If variable "WalnutShot" of Bullet = 0
  do RandomInRange(1,3) to variable "WalnutShot" of Bullet

If variable "WalnutShot" of Bullet = 1
  do = 2 to the scale of Bullet
  Set animation of Bullet to "WalnutShot"

I think that would do it, without the need for sub-events or for the HASWALNUT variable, and really simplifying it into two events! ^^

I hope this helps, and sorry I took a bit to respond!

Thank you for the help mate. :slight_smile:

1 Like