Replies: 1 comment 15 replies
-
|
Hey! First of all, thanks a lot for trying out Forge and for taking the time to write this question. It’s really great to see someone actually building something with it. From what I understood, you're trying to implement something similar to a “fire trail while running”, where something is spawned periodically while an ability is active. Your current approach uses a periodic Grant Effect to repeatedly grant the ability, expecting that this would drive the behavior over time. Conceptually, this makes sense at first glance, but it’s not how Grant Effects are intended to be used in Forge. About Grant EffectsA Grant Effect is responsible for giving an ability to an entity. Conceptually, it represents that the entity has "learned" or "unlocked" that ability. It is not strictly limited to happening only once, but its purpose is still about granting the ability itself, not driving its execution over time. When a Grant Effect is configured as Execute (either Instant or Periodic), it will execute its logic and grant the ability permanently. In practice, this means the ability becomes permanently available and cannot be removed. Because of that, making a Grant Effect periodic does not make the ability execute periodically. It just attempts to grant it again, which usually has no effect if the ability is already present. So your intuition is valid, but this is not the correct layer in the system to implement time-based behavior. Recommended ApproachesOption 1 (Simplest): Handle it inside the AbilityThe most straightforward solution is to grant the ability once (non-periodic), activate/deactivate it as you're already doing, and then handle the periodic spawning inside its behavior using a timer node. Example: public class HeatRushBehavior : IAbilityBehavior
{
private AbilityBehaviorContext _context;
private Timer _timer;
public void OnStarted(AbilityBehaviorContext context)
{
_context = context;
// Call on start if you want to immediately create one trail
SpawnFireTrail();
_timer = new Timer
{
WaitTime = 0.2f,
Autostart = true,
};
_timer.Timeout += SpawnFireTrail;
// This is a simple way to attach the timer to the scene tree
var tree = Engine.GetMainLoop() as SceneTree;
tree?.Root.AddChild(_timer);
}
public void OnEnded(AbilityBehaviorContext context)
{
if (_timer != null)
{
_timer.Timeout -= SpawnFireTrail;
_timer.Stop();
_timer.QueueFree();
_timer = null;
}
}
private void SpawnFireTrail()
{
// Your spawn logic here
// Call CommitAbility here if you want to consume resources every time you spawn a trail
_context.AbilityHandle.CommitAbility();
}
}This approach is simple, explicit, and gives you full control over timing and behavior. Note that you don't have to call On a separate branch I have an Option 2: Drive the behavior separately through eventsAnother approach, which makes better use of the data-oriented design, is to grant the ability once and keep it passive while something else drives its execution. For example:
In this case, the AbilityBehavior remains simple: it just spawns the trail and ends itself. Each periodic tick re-activates the ability. A nice advantage of this approach is that you can reuse the same ability in other situations by triggering the same event. If anything is unclear or you want help implementing one of these approaches, feel free to ask. Happy to help. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello there!
I've recently started using Forge for my Godot project and I fail to figure out how to implement a specific kind of ability, one where an ability is triggered periodically through an effect. If you've played Hades 2, think of the "Heat Rush" ability. Basically, once you get this ability then as long as you're running you periodically spawn on the ground some damaging surface. I've implemented one-off abilities as well as periodic effects successfully but I can't figure out how to activate a granted ability periodically through an effect.
Here's the ability definition to define the cost, cooldown and behaviour (e.g. Hades' "Heat Rush"). I've implemented it through a Godot Resource.
Here's the code granting the ability, right on my Player entity:
And here's the code where I activate the ability (e.g. starting to run)
And here's the code where I cancel the ability (e.g. when running stops)
With this code, the ability is only activated only once when the player starts running, but not periodically. I would expect it to be triggered 5 times per second as long as the player is running, as per the PeriodicData indicates.
I'm pretty sure it's just me not being able to understand the ways abilities and effects are supposed to work together but I've read through the documentation many times and tried many things, to no avail.
Can this be done and if so, where's my mistake? Thank you!
Beta Was this translation helpful? Give feedback.
All reactions