GDevelop-extensions icon indicating copy to clipboard operation
GDevelop-extensions copied to clipboard

[Reviewed] [FireBullet] Ammo management, reloading, overheat, and stats

Open tristanbob opened this issue 2 years ago • 17 comments

Fire bullets, manage ammo, reloading, and overheat mechanics.

Playable game

https://liluo.io/victrisgames/determined-haircut--fire-bulle

Project files

https://github.com/GDevelopApp/GDevelop-examples/tree/fire-bullet-example-gen3

Detailed description

Firing bullets:

  • Cooldown: Time between shots (seconds)
  • Bullet Quantity: Number of bullets created each time Fire Bullet action is used.
  • Angle Variance: Each bullet trajectory will be adjusted by a random value within this range (degrees)
  • Firing Arc: Range of angles (in degrees) that bullets will shoot. Bullets are evenly spread within this range.
  • Rotate bullet: Change the angle of each bullet to match the direction it is travelling (enabled by default)

Ammo:

  • Starting ammo
  • Max ammo
  • Shots per reload. Use 0 to disable reloading
  • Reload duration
  • Automatic reloading is enabled by default, but it can also be done manually.

Overheat:

  • Heat increase per shot. Overheat is reached when another shot would cause heat to go above 1.
  • Cooling rate per second. By default, this rate changes exponentially based on current heat value.
  • When overheated, the object cannot fire any bullets

Statistics:

  • Total bullets created
  • Total shots taken
  • Total reloads completed

Bullets:

  • Each bullet is assigned several variables that can be used for advanced object picking
  • __FireBullet.BulletID = Unique number for every bullet created
  • __FireBullet.BatchID = Unique number for all bullets created in the same frame
  • __FireBullet.BatchOrderID = Unique number for each bullet in the same batch. Can be used to identify the position in the firing arc.

tristanbob avatar Oct 16 '22 02:10 tristanbob

Errors were detected in this submission:

❌ 1 Error found in extension 'FireBullet':

  ⟶ ❌ (🔧) [Dots in sentences]: Field 'description' of the function 'HeatLevel' misses a dot at the end of the sentence!


❌ 1 Error found in extensions - please fix it before generating the registry.

github-actions[bot] avatar Oct 16 '22 02:10 github-actions[bot]

I can't find the PR for the example branch you linked.

D8H avatar Oct 18 '22 21:10 D8H

Couldn't open it in engine, but I did test the liluo game a little bit.

I didn't find any issues with that part, other than: -When you run out of ammo, but have bullets left in your "until reload" bar, you magically have bullets in your clip when you pick up ammo. If you reload with fewer bullets left than your total clip size(Shots until reload), it should fill your "shot until reload" bar only to that amount.

HelperWesley avatar Oct 19 '22 19:10 HelperWesley

I only looked at the properties.

  • What is the difference between "Unlimited ammo" and "Max ammo (Use 0 to disable..."?
  • Private properties should not have a group because it shows an empty one (it's a bug).
  • The "exponential cooling" should be a choice rather than a boolean because linear and exponential don't negate each other so other "mode" could be needed in the future (for compatibility or new features).
  • The "rate of cooling per second" is used for 2 different things. The linear and exponential cooling could have thier own property and the effects can additionnate. It will allow finer adjustments. Also, they can be over 1 as they are speed.
  • StartingAmmo doesn't have a label

D8H avatar Oct 20 '22 23:10 D8H

  • What is the difference between "Unlimited ammo" and "Max ammo (Use 0 to disable..."?

"Unlimited ammo" really means "Don't subtract ammo when shooting and allow shooting with 0 ammo". I'm open to better names, such as "RequireAmmoToShoot". What do you suggest?

"Max ammo" is used so you can pick up a large ammo clip of 20 bullets, but if you are 5 bullets below Max Ammo then your ammo will only go up by 5 bullets. "0" means no limit when picking up ammo.

  • Private properties should not have a group because it shows an empty one (it's a bug).

I will remove all groups on private properties

  • The "exponential cooling" should be a choice rather than a boolean because linear and exponential don't negate each other so other "mode" could be needed in the future (for compatibility or new features).

Ahh yes. This is similar to what we did on another extension. I will change this.

  • The "rate of cooling per second" is used for 2 different things.

What are the two things? I think it's only used to reduce heat on every frame.

The linear and exponential cooling could have their own property and the effects can additive. It will allow finer adjustments.

Yes, this provides some value in tweaking the rate of change, but I don't think it is worth the increase in user-facing complexity (more properties/functions).

Also, they can be over 1 as they are speed.

I will remove the range comment.

  • StartingAmmo doesn't have a label

Thanks, I will add one.

tristanbob avatar Oct 21 '22 00:10 tristanbob

I didn't find any issues with that part, other than: -When you run out of ammo, but have bullets left in your "until reload" bar, you magically have bullets in your clip when you pick up ammo. If you reload with fewer bullets left than your total clip size(Shots until reload), it should fill your "shot until reload" bar only to that amount.

See, this is why I count on you to test things and find stuff like this! :)
We don't want players to get free bullets!
I have added logic so that reloading will never give more ammo than is available.

I updated the game example, if you want to confirm the fix and test more:

https://liluo.io/victrisgames/extension-fire-bullet

Thanks for this review!

tristanbob avatar Oct 21 '22 02:10 tristanbob

FYI - I created a PR for the example I use to test this extension:

https://github.com/GDevelopApp/GDevelop-examples/pull/398

tristanbob avatar Oct 21 '22 02:10 tristanbob

  • The "rate of cooling per second" is used for 2 different things.

What are the two things? I think it's only used to reduce heat on every frame.

The linear and exponential cooling could have their own property and the effects can additive. It will allow finer adjustments.

Yes, this provides some value in tweaking the rate of change, but I don't think it is worth the increase in user-facing complexity (more properties/functions).

I think it will make it easier to understand. Because if the "rate of cooling per second" had a description it would be something like this: "When the cooling is linear, it reduces the heat by a fraction of the maximum heat every second and, when the cooling is exponential, it reduces the heat by a fraction of the current heat every second". The description looks almost like events. In my opinion, one property should represent only one thing and have a proper name and description for this thing.

Also, there won't be more properties because it would be 2 numbers:

  • Linear cooling rate (per second)
  • Exponential cooling rate (per second)

instead of 1 choice and 1 number.

  • Cooling method (linear, exponential)
  • Cooling rate (per second)

D8H avatar Oct 21 '22 08:10 D8H

Also, there won't be more properties because it would be 2 numbers:

  • Linear cooling rate (per second)
  • Exponential cooling rate (per second)

@D8H Ok, you sold me on the idea. :) Here is the version with this implemented:

https://liluo.io/victrisgames/extension-fire-bullet

I have pushed the updated extension to this PR.

tristanbob avatar Oct 22 '22 18:10 tristanbob

Wow, there are a lot of functions, it's a huge work.

Properties

  • Some units are surrounded by parenthesis and other ones after a comma. Should parenthesis be used everywhere?
  • Cooling properties are missing the unit: per second.
  • The "firing arc" and "angle variance" are probably in degree.
  • What do you think about a group dedicated to "reload" properties? This way they both have one checkbox and users can skip the group when it's disabled.

Events

  • Why do you use preEvent and postEvent? I guess it should works the same with everything in preEvent.
  • In the "Fire" action, some events are duplicated. A private action that only fires one bullet could be used to avoid this.
  • The exponential cooling should happens before the linear one. Otherwise, the liner one has an effect on the exponential one which makes it hard to tune.
  • About function groups, there should be a clear distinction between what is just about configuration (used 5% of the times) and what is about the state (used 95% of the times). Functions about the state can be left in the default group if there are not too many.

D8H avatar Oct 23 '22 00:10 D8H

Wow, there are a lot of functions, it's a huge work.

Thanks! My hope is that this extension can be used in the same simple way as it originally worked, but if people want more features they are just a few clicks away. :)

Properties

  • Some units are surrounded by parenthesis and other ones after a comma. Should parenthesis be used everywhere?

I am changing them to be inside parenthesis Angle variance (degrees)

  • Cooling properties are missing the unit: per second.

Added.

  • The "firing arc" and "angle variance" are probably in degree.

Added.

  • What do you think about a group dedicated to "reload" properties? This way they both have one checkbox and users can skip the group when it's disabled.

Agreed, added.

Events

  • Why do you use preEvent and postEvent? I guess it should works the same with everything in preEvent.

I'm not sure why I did that. I have moved the contents of postEvents to the beginning of preEvents.

  • In the "Fire" action, some events are duplicated. A private action that only fires one bullet could be used to avoid this.

This is a great suggestion! I was wondering how this could be improved to reduce duplicated code and I think I figured it out. I'm adding this.

  • The exponential cooling should happens before the linear one. Otherwise, the liner one has an effect on the exponential one which makes it hard to tune.

Doesn't this problem happen regardless of order? One will always affect the other. For damage reduction from armor, I performed the linear change first, mostly because this is how League of Legends does it. For now, I will change it to your suggested order.

  • About function groups, there should be a clear distinction between what is just about configuration (used 5% of the times) and what is about the state (used 95% of the times). Functions about the state can be left in the default group if there are not too many.

I will remove the group tag from the most important actions, so they are obvious to users.

tristanbob avatar Oct 23 '22 02:10 tristanbob

Here are the actions and how they are currently grouped. I think 4 primary actions is a good amount.

image

tristanbob avatar Oct 23 '22 03:10 tristanbob

@D8H I decided to add one more feature to this PR: Relative bullet speed

This should be very simple to do (simply add a permanent force equal to the current speed of the shooter) but it's not working. I realize that the ForceX() and ForceY() expressions will not detect movement from the TopDown behavior (I have thoughts related to this) but this game uses a permanent force during the dash and it doesn't seem to affect the bullet speed.

Did I miss something very simple?

image

tristanbob avatar Oct 23 '22 03:10 tristanbob

I decided to add one more feature to this PR: Relative bullet speed

This should be very simple to do (simply add a permanent force equal to the current speed of the shooter) but it's not working. I realize that the ForceX() and ForceY() expressions will not detect movement from the TopDown behavior (I have thoughts related to this) but this game uses a permanent force during the dash and it doesn't seem to affect the bullet speed.

Did I miss something very simple?

I wonder if the character speed is negligible compared to the bullet speed so it looks like it make no difference even though it works well. Try to log the object speed to see if it really has a value maybe.

D8H avatar Oct 23 '22 12:10 D8H

I wonder if the character speed is negligible compared to the bullet speed so it looks like it make no difference even though it works well.

I set bullet speed to 90% slower just to make sure this wasn't happening.

Try to log the object speed to see if it really has a value maybe.

This is a good idea.

Btw - What do you think about the idea of adding debugging logging to all extensions, perhaps as a property? EnableDebugLogs

tristanbob avatar Oct 23 '22 12:10 tristanbob

Btw - What do you think about the idea of adding debugging logging to all extensions, perhaps as a property? EnableDebugLogs

Usually, when I use logs to debug I only add what I need, too much logs make life harder. In some extensions, I left some logs in disabled events (they are not generated in the code) because I though I might need them later and didn't want to write them from scratch.

I guess that if the events are simple enough, we should not leave logs because it reduces the readability and a property to enable them would mean to include them in the final code so I would be against it.

D8H avatar Oct 23 '22 12:10 D8H

Per my discussion with @D8H and @HelperWesley I have removed relative bullet speed.

Can you review my changes based on the previous reviews?

tristanbob avatar Oct 24 '22 14:10 tristanbob

  • Do you think there should be a default value for cooling rate properties? This way when "heat increase" is set it will directly work. Same thing for firing arc and most properties that doesn't have any effect in the default configuration.
  • Can you explain how the overheat works? I find the property description a bit strange. To me, the overheat should be triggered if the player shoots and the heat reach 1.
  • The range should probably be in parenthesis instead of the explanation
  • "If Bullet Quantity is greater than 1" Should "when" be used instead of "if"? Users don't know what "Bullet Quantity" is. I doubt someone will pick that 1 is a special case "If Bullet Quantity is greater than 1" can be skipped.
  • What do you think about a "Multi-fire" property group? It's only 2 properties but they can only be understood together.

D8H avatar Oct 24 '22 23:10 D8H

  • Do you think there should be a default value for cooling rate properties? This way when "heat increase" is set it will directly work.

Yes, it will help users understand and prevent confusion. I have set these defaults:

Exponential cooling = 0.3
Linear cooling = 0.1

Same thing for firing arc and most properties that doesn't have any effect in the default configuration.

Firing arc = 45 degrees
Reload duration = 1 second
  • Can you explain how the overheat works? I find the property description a bit strange. To me, the overheat should be triggered if the player shoots and the heat reach 1.

I initially allowed shooting to happen anytime Heat was less than zero. But since I cap the Heat value at 1 (so users can easily set up heat resource bars) this meant that after a single frame of cooling, the object was no longer Overheated. I changed it so the object can only shoot if the Heat increase would result in heat being less than 1. What do you recommend for this?

  • The range should probably be in parenthesis instead of the explanation

Changed

  • "If Bullet Quantity is greater than 1" Should "when" be used instead of "if"? Users don't know what "Bullet Quantity" is. I doubt someone will pick that 1 is a special case "If Bullet Quantity is greater than 1" can be skipped.

I simply changed this to match both multi-fire properties: Multiple bullets will be evenly spaced inside the Firing Arc

  • What do you think about a "Multi-fire" property group? It's only 2 properties but they can only be understood together.

I like it, added.

tristanbob avatar Oct 27 '22 02:10 tristanbob

Errors were detected in this submission:

❌ 3 Errors found in extension 'FireBullet':

  ⟶ ❌ (🔧) [Dots in sentences]: Field 'sentence' of the function 'ResetTotalShotsFired' has a dot, but it is fobidden there!
  ⟶ ❌ (🔧) [Dots in sentences]: Field 'sentence' of the function 'ResetTotalBulletsCreated' has a dot, but it is fobidden there!
  ⟶ ❌ (🔧) [Dots in sentences]: Field 'sentence' of the function 'ResetTotalReloadsCompleted' has a dot, but it is fobidden there!


❌ 3 Errors found in extensions - please fix them before generating the registry.

github-actions[bot] avatar Oct 27 '22 14:10 github-actions[bot]

Errors were detected in this submission:

❌ 3 Errors found in extension 'FireBullet':

  ⟶ ❌ (🔧) [Dots in sentences]: Field 'sentence' of the function 'ResetTotalShotsFired' has a dot, but it is fobidden there!
  ⟶ ❌ (🔧) [Dots in sentences]: Field 'sentence' of the function 'ResetTotalBulletsCreated' has a dot, but it is fobidden there!
  ⟶ ❌ (🔧) [Dots in sentences]: Field 'sentence' of the function 'ResetTotalReloadsCompleted' has a dot, but it is fobidden there!


❌ 3 Errors found in extensions - please fix them before generating the registry.

github-actions[bot] avatar Oct 27 '22 14:10 github-actions[bot]

Thank you @D8H and @HelperWesley for your great assistance and insight when reviewing this extension!

tristanbob avatar Nov 01 '22 03:11 tristanbob