A designer stacks two +50% damage buffs and files a bug: the sheet says +125%, the game deals +100%. That is not a bug. Multiply (Additive) pools bonuses over 1.0, it does not compound. If your buffs should truly multiply, the fix is one dropdown: Multiply (Compound).
Quod Soler ☀️
@quodsoler.com
Lead Gameplay Programmer for Lords of the Fallen at Hexworks • I will teach you Unreal Engine • Gameplay Ability System expert, opinions are my own
Myth: GAS cooldowns track a timer. Reality: CheckCooldown asks one question: does the ASC still own a tag from GetCooldownTags()? The cooldown GE exists to grant that tag for its duration. Tag present, blocked. Tag gone, ready. There is no timer.
The scariest GAS bug is not a crash. Forget one SetByCaller value and the effect still applies: magnitude 0, one error line, every gate passes. The ability works. It just does nothing. Set every SetByCaller tag at spec build time, before you apply.
One melee hit in GAS: input reaches the ASC, the ASC checks tags, cost and cooldown, the ability plays its montage, the hit becomes an effect on the victim's ASC, Health drops on the server, a cue plays the blood. Every interaction you build is a variation of this.
Another GAS mistake! BeginPlay does not assure you that the Ability System Component is ready. For that you need to register to OnAvatarSet. Only there you should start applying logic. The ASC may be living on the Player State and the player may not have spawned yet.
If you are still having crashes on 13700k, 13900k or 14900k series CPUs I wrote a post some time ago about it. Check it an see if it helps you somehow: www.quodsoler.com/blog/how-to...
How to Fix Crashes in Unreal Engine 5 Games on Intel i7-13700K and i9-13900K Series | Quod Soler
Some intel CPUs crash when under high load in new Unreal Engine 5 games. In this post you will learn how to fix these issues.
quodsoler.com
4,002 on Twitter. 3,575 on Linkedin. 1,064 on the Newsletter. I didn't expect so many people interested in Combat Frameworks and the Gameplay Ability System. You keep showing up. I will need to keep publishing.
Sent the enemy dodge system to the newsletter yesterday: dodge chance as a GAS attribute, a roll-under decorator with three bug-born checks, and a stacking pressure effect that decays by itself. The full article is on the blog, with all the code. Link below.
My melee system has no overlap events. Every Hitbox is a capsule that remembers last frame's pose and sweeps to this frame's with SweepMultiByChannel. Sweeps give exact impact points, and a fast swing cannot tunnel through a thin enemy between frames.
Attacks through walls die to one line trace: attacker to impact point, 10% longer than the distance, on an obstacle channel. Player attacks also trace from two extra side points, so a pillar edge does not eat a swing that clearly connected. One clean trace passes the hit.
GAS can rollback predicted effects. That does not mean in can magically unspawn the cosmetic projectile you created. Track client fake projectiles and destroy them on prediction key rejection. Actors need explicit bookkeeping.
Tomorrow in the newsletter: how my enemies decide to dodge. Somewhere between the input reader and the training dummy there is a middle ground: a probability attribute, a throttled dice roll, and one stacking effect that ramps while you combo them. 4 minutes, one email.
You can always dodge on your last sliver of stamina. My activation check is Stamina > 0, deliberately not "can afford the cost", and the cost effect afterwards may leave you negative, which delays regen. You are on the player's side, ignore that, and the death feels like the game stole the input.
I usually like to encapsulate gameplay effects in a higher level of abstraction for designers. I create template for them with SetByCaller parameters. Then they can define new effects using those templates and parameters. Like WeakHeal, MediumHeal and StrongHeal.
Buffered dodges re-sample the stick at activation, not at press. The fresh reading only wins above half deflection: a decisive re-aim mid-attack redirects the queued dodge, a thumb resting on the stick does not. Players never see this rule, they simply notice that dodges go where they meant.
A Damage Meta Attribute is not a stat. Its a way to pass data to the Damage Calculation. Multiply elements can modify it. Once you need to use it, consume it and reset it. That way you simplify how damage gets dealt.
If you have random Delays in your Blueprint code you are doing something wrong. The moment you add a delay node ask yourself: "What am I actually waiting for?" In many cases you will be able to register a delegate to that thing.
Real damage should be authoritative. But hit feedback should be predicted. The worse that can happen in an action game is the client feeling like their hits don't land. You can keep most of the feedback and then make damage numbers only appear when server confirms.
GameplayEffectComponent definitions are static. They are shared by every application of a Gameplay Effect. A little bit like Anim Notify definitions, if you put state there, know that it will be shared between all of them.
"Is the player stunned?" is not a boolean on your character. It is a tag on the ASC, granted by the stun effect, gone when the effect expires. Every ability that should fail while stunned lists Combat.State.Stunned in its blocked tags. Nothing ever has to remember to reset it.
Executions in action games are two abilities, not one. The attacker runs the finisher. The victim runs "get executed", the synced montage, the camera, the ragdoll handoff. The victim doesn't need that ability all game. Inject it at the kill moment: GiveAbilityAndActivateOnce.
Tomorrow in the newsletter: the input buffering pattern I use on top of GAS. Why gameplay events are the right foundation, the gate tag, the two anim notify windows, and the one detail that took shipping a soulslike to learn. 4 minutes, one email.
Gameplay Tags are how your systems interact with GAS. You use them for State. You use them for Events. You even use them for Cues. Take good care of your Gameplay Tags hierarchy and keep it organized.
CommitAbility is where the price is paid. Costs are applied. Cooldown is initiated. Beyond this point, the ability is fully active.
How often do you really need the period of your effect to be. Do you really need mana regen to tick every frame? Or can it tick every 0.2 seconds? The UI can interpolate if needed.
Textbook GAS is fully server-authoritative, and that is how you should learn it. On shipped coop games I push more authority to the client, because responsiveness wins and teammates rarely cheat each other. A trade you earn after you understand the model, not instead of it.
A city full on untouched destructibles may deserve lazy ASC creation. A character rarely does. For tons of actors you can create the ASC when needed. You can even have a pool of them that gets reused. This allows you to keep all logic in GAS. While maintaining performance.
An entity in Unreal's Mass framework is 8 bytes: an index and a serial number. No memory, no behavior, not even a position unless a fragment gives it one. Once that clicks, the rest of the framework is just the answer to "so where does the data live?"
Health = X works in standalone and desyncs in multiplayer. Replication, prediction, clamping and stacking all hook into Gameplay Effects, and a raw attribute write bypasses every one of them at once. The fix is always the same: build a spec, apply the effect.
The data-driven half of GAS you could build yourself. The reason to adopt it is networked prediction: press the button, the ability runs instantly on the client, the server confirms or rejects afterwards. That protocol looks approachable and then eats your year.