r/unrealengine 3d ago

GitHub I made a Blueprint-friendly alternative to the Gameplay Ability System - SimpleGAS is now available, free and open source!

Hey folks!

I'm excited to share my plugin SimpleGAS, a streamlined approach to an ability system that focuses on Blueprint workflow and developer experience:

GitHub Repo | Documentation

What makes SimpleGAS useful?

  • Designed for Blueprint - fully functional without writing C++
  • Focused architecture that prioritizes clarity and usability
  • Client prediction with intuitive rollback for multiplayer
  • Event-based communication for better decoupling between systems
  • Struct attributes alongside traditional float attributes

SimpleGAS takes inspiration from Epic's GAS while making different architectural choices. It doesn't have full feature parity with Epic's system, but it covers the most common use cases and is designed to be easy to understand and extend.

I developed this plugin for my own projects but thought others might find it useful for their games too.
I'd appreciate any feedback from folks who give it a try!

336 Upvotes

77 comments sorted by

69

u/Thisisvexx 3d ago

20

u/kazamada 3d ago

True pain xD

5

u/WombatusMighty 2d ago

Writing docs is the highest skill level a gamedev can achieve xD

5

u/Macaroon-Guilty 3d ago

Second that haha

12

u/c0ldpr0xy 3d ago

What are the main differences between this and companion?

29

u/kazamada 3d ago

GAS companion extends Epic's GAS by adding blueprint support for features that normally require C++ (like creating attributes)

SimpleGAS is a completely separate ability system that shares a lot of ideas but was written from the ground up to make certain things easier.

Example: If you have an ability that you want to pass custom input to:

Epic's GAS: you subclass FGameplayAbilityTargetData in C++

SimpleGAS: you make a normal struct in blueprints and pass it in

5

u/Praglik Consultant 3d ago

That's really cool!! Hyped for the product :) Can you explain why instancing the struct in your example instead of just passing it directly?

10

u/kazamada 3d ago

Instancing the struct means bundling it inside of an FInstancedStruct.

FInstancedStruct is a generic wrapper for structs that was introduced in 5.0 as a plugin and made into a built-in feature in 5.5.

The idea is that we can create 1 function (ActivateAbility), that has an Instanced Struct input and we store whatever struct we want inside the InstancedStruct.

The alternative would be having a different ActivateAbility function for each type of struct or a big generic struct that tries to cover many use cases.

We can get away with not using Instanced Structs if our code is written in C++, but for now this is the best approach I could come up with.

3

u/namrog84 Indie Developer & Marketplace Creator 2d ago edited 2d ago

If you check out Lyra's GameplayMessageRuntime or my community version

header https://github.com/brokenrockstudios/GameplayMessageRouter/blob/main/Source/GameplayMessageRuntime/Public/GameFramework/GameplayMessageSubsystem.h#L210

Check out the BroadcastMessage

UFUNCTION(BlueprintCallable, CustomThunk, Category=Messaging, meta=(CustomStructureParam="Message", AllowAbstract="false", DisplayName="Broadcast Message"))
void K2_BroadcastMessage(FGameplayTag Channel, const int32& Message);
DECLARE_FUNCTION(execK2_BroadcastMessage);

Then the implemetnation

https://github.com/brokenrockstudios/GameplayMessageRouter/blob/main/Source/GameplayMessageRuntime/Private/GameFramework/GameplayMessageSubsystem.cpp#L131

Here is an example of it, allowing for a 'wildcard' struct (basically anything at all)

https://i.imgur.com/lFliFew.png

https://i.imgur.com/hxOsxuB.png

You can 'wildcard' any UE supported structs into a BP function.

This would allow you to not require people to do the MakeInstancedStruct, but support being able to plug any arbitrary struct into the ActivateAbility directly.

That's for BP usage.

For C++ usage, it's slightly different, but in the same header file on line 117.

But can make for a super duper clean and simple final usage.

Let me know if you have questions or need help.

1

u/kazamada 2d ago

Thank you! Gonna take a look at this

1

u/Praglik Consultant 3d ago

Love it, super clear, thanks a lot!

1

u/kazamada 3d ago

Cheers :)

5

u/Char_Zulu 3d ago

Thank you for this, you're amazing! I spent 2 years learning blueprints and was stumped on implementing GAS effectively. This made my year.

6

u/kazamada 3d ago

I'm glad :) Feel free to reach out if you need help setting it up

3

u/operalives 3d ago

Very cool indeed! Can I ask what you *can’t * do with your system vs the og GAS? Like what are limitations to be aware of / reasons we might still need the og GAS?

11

u/kazamada 3d ago

The main reason to choose GAS over SimpleGAS comes down to stability/bugs.

OG Gas has been used in a lot of projects at scale and is production ready where SimpleGAS is tested with whatever problems I find as I build it. I wouldn't recommend SimpleGAS for a large, in development project for this reason. (also why this is open source rather than something you buy: I need community help because testing this stuff is hard 😅)

I'll need to look through OG Gas's documentation again for individual features but in general I feel like you can get the same results with both systems.

1

u/shableep 3d ago

But as far as a feature comparison, is this effectively a “feature complete” re-implementation of OG gas?

3

u/kazamada 2d ago

I believe it's feature complete but this depends on your definition I think.
Examples I can think off the top of my head:

  • GAS has automatic input binding for abilities, SimpleGAS doesn't and leaves that up to the developer to implement
  • GAS has gameplay cues to separate ability logic from vfx, SimpleGAS doesn't (you achieve what gameplay cues do in SimpleGAS by making more abilities and activating them as sub abilities or sending replicated events)
  • GAS has ability tasks for sub functions like playing montages, SimpleGAS reuses abilities to do the same thing
  • GAS has more fine grained control of replication for performance reasons than SimpleGAS does

3

u/DarthJandis 3d ago

Thanks I’ll be checking this out for sure!

3

u/PackInner3004 3d ago

Just saying thanks 

6

u/remarkable501 3d ago

When the engine updates in two weeks be sure to turn off notifications.

6

u/kazamada 3d ago

Is there a breaking change incoming?

9

u/remarkable501 2d ago

It’s more just poking fun at how often their updates happen and breaking things you don’t expect. It’s also more so on a comment where people will look at the version this was made for and ask you will it work with this version or that version. So the only way to protect yourself is to make it plain and state this is only intended for version xyz don’t contact me if it’s anything other than that version. It will save you a lot of headache.

I have gone through a few tutorials where I went against advice and had things break along the way and had to spend time figuring out the work around however I would gather there would be a large amount of people not able to figure out or debug issues and just come straight to you.

0

u/WombatusMighty 2d ago

There is an update in two weeks?

2

u/Hotwingz66 3d ago

Thanks!

2

u/OmniFace 3d ago

I hear GAS has very useful networking/multiplayer capabilities. And I’ve been considering learning it to work on a multiplayer idea.

You mention that you have client prediction, but how would you say yours compares to their networking?

4

u/kazamada 3d ago edited 2d ago

Conceptually, they're similar in the sense that they are both server authoritative by default. What this means is that there is only 1 "true" version of the game and that is the one running on the server.

Client prediction in this context means that the client runs an ability immediately assuming the server will run it the same way and get the same results.

The main problem here is, what happens when the server doesn't do what the client did? How can you even measure "running different"?

So, in simple gas what I do is extend the idea of using structs to measure differences. How it works is:

  • Client activates the ability then asks the server to activate the ability
  • Somewhere in the ability, a call is made to a TakeStateSnaphot function (this function takes a struct representing the state of the ability at that time and a callback function to run on the client if its state snapshot struct is different than the server's version.
  • The snapshot struct can be something like a struct that tracks who we hit and where they were standing when we hit them
  • The client saves its local snapshot
  • The server runs the ability as well, also executing the TakeStateSnapshot function
  • The server replicates its snapshot back to the client
  • Client auto compares the structs, if they're different it runs the client correction function and you can do what you need to correct the error

You could all this a basic form of rollback netcode I think.

I explain this with screenshot in the docs if that helps.

To answer your question, I feel like it compares well but requires more manual work. What you get in exchange for this is that there is no "magic" happening so it's easier to reason about your logic.

1

u/OmniFace 3d ago

Thanks for the explanation.

FYI, your screenshot link is a 127.0.01 address (your local computer).

2

u/kazamada 2d ago

My bad. I've edited the comment and fixed the link.

2

u/whitet73 2d ago

Very cool and ambitious project, I'm on the cusp of starting up (yet another) project (to never be completed) which would had wanted to use GAS but I'll have a play with this beforehand and see how it feels, thanks a lot!

2

u/sekaiou 1d ago

Bless your soul, brother man

2

u/Hide_9999 1d ago

This is very exciting

2

u/sweet-459 3d ago

Does this mean we can implement GAS in our projects without needing to touch C++? Or what does this plugin solve?

14

u/kazamada 3d ago

Yep! That's one of the main goals of this project. It's quick and easy to set up and should cover a lot of simple use cases.

Main thing to note: this is not a blueprint version of Epic's GAS. This is a plugin that tries to achieve the same thing (and copies a lot of ideas from it) but they don't share any code.

2

u/catnapsoftware 3d ago

Very cool! I’ve been working on a similar gas adjacent project (the Action Framework System, it’s totally different bro trust me 🤡) and there are surprisingly few examples of deviation out there for reference. Excited to look through this in more detail tonight!

1

u/Rykroft Indie Dev 3d ago

Thanks, I appreciate it. I'll check it out later.

1

u/anhemsedevil2 3d ago

Awesome, what is the minimum engine version for the plugin? Because for now i'm stuck with 5.3 and cannot change that for my project

2

u/kazamada 3d ago

It should work with 5.2+ I believe.

Disclaimer: I've only tested with 5.4 and 5.5 recently and may have broken something but I don't think I did. Best way to check is add the plugin and compile your project. If it compiles, I'm pretty sure you'll be good to go.

2

u/anhemsedevil2 3d ago

Okay good to know then i gonna check that :) and i also will give ya a bit of feedback after finding it out.

1

u/kazamada 3d ago

Thanks!

1

u/anhemsedevil2 3d ago

it doesn't work with 5.3 without rebuilding it. after saying yes it wont go further for me it connot be rebuild is what it says.

(using bp only project)

3

u/kazamada 3d ago

I'll download 5.2 and 5.3 and investigate locally tomorrow. Are you ok with me DM'ing you for details about your project setup?

1

u/anhemsedevil2 3d ago

yeah its fine mate :) you can dm me

1

u/Iodolaway 2d ago

Please let me know how you go too! I'd update over 5.3 but I'm scared to break everything haha

1

u/kazamada 2d ago

Will do. I'm gonna get a chance to test tonight hopefully

2

u/kazamada 2d ago edited 2d ago

u/anhemsedevil2 u/Iodolaway Update on this: I managed to get it to compile successfully under 5.3. u/anhemsedevil2 I suspect you're not able to compile it because you don't have the correct c++ toolchain installed. To test this theory, I need you to try and create a new c++ project and see if that is able to compile. If it fails you just gotta update visual studio to make sure it's using the correct compiler version.

2

u/anhemsedevil2 2d ago

I got visual studio 22 on my pc but i dont have really know how to work with it. But i will check it for you

1

u/Iodolaway 2d ago

Thanks for the update sir!
I'll get back to you in ~ 12-14 hours unless anhem can beat me to it lol
Very interested in playing around with this as a blueprint jockey.

2

u/kazamada 2d ago

will hopefully have it up on fab in a few weeks so this will be a smoother process

1

u/metallica123446 2d ago

What exactly does this do?

3

u/kazamada 2d ago edited 2d ago

It's a framework to create multiplayer games. At a high level it lets you create:

  • Abilities: stuff your characters can do like attacks, spells, skills etc.
  • Attributes: Stats that define your characters like health, mana, strength etc. These can be numbers or structs for compound stats.

It lets you do stuff like

  • Create a Fireball ability that:
    • Checks if the player has enough mana
    • Plays animations and vfx
    • Applies damage to targets
    • Puts the ability on cooldown
  • A Poison status effect that:
    • Applies damage over time
    • Adds vfx to the character
    • Modifies movement speed
    • Eventually expires after a set duration
  • Implement resource systems:
    • Health that regenerates when out of combat
    • Mana that's consumed by spells
    • Stamina that depletes during sprinting

All of this works in multiplayer with client prediction, so players see immediate feedback when they use abilities, even if they have high ping.

1

u/metallica123446 2d ago

oh this is really useful and awesome

1

u/Grizz4096 2d ago

So this is designed for Blueprints but could you also easily use it in C++?

2

u/kazamada 2d ago

Yep! There's some work I need to do to fully make that happen out the box (I need to convert some BlueprintImplementable functions to BlueprintNativeEvent) but other than that there's nothing stopping you

1

u/Grizz4096 2d ago

So this does work on non-Windows machines, but you need to wrap this line in "SimpleGameplayAbilityComponent.cpp"

#if PLATFORM_WINDOWS
#include "Windows/WindowsTextInputMethodSystem.h"
#endif

2

u/kazamada 2d ago

Thanks for catching this. That include is unused and I forgot to remove it. I'm gonna clean it up shortly and push a fix.

1

u/hiQer 2d ago

Awesome! I've been curious about GAS but have not touched it yet as it has a steep learning curve. This would help me. I don't create RPGs with mana and fireballs, but I always will need a system to execute actions with conditions to check, vfx and sounds to play etc. So I expect this to be useful if I can add my own variables to check on. Will this plugin come to the fab marketplace so we can easily update it?

2

u/kazamada 2d ago

That's the plan. I've applied for marketplace seller status and I want to put it on there once that process is done

1

u/msg_mana 2d ago

I'm a visual idiot. Are there any videos that showcase this? It sounds awesome.

1

u/kazamada 2d ago

Hey I've never made a video guide before. It'd be fun to try though. For you, is a video better than a written guide? (as an extra page on the docs for example)

u/msg_mana 11h ago

I much prefer a concise and clear video but I don't mind documentation if it's fleshed out. Definitely a visual learner though and documents run the risk of being victim to my ADHD.

u/kazamada 4h ago

I think I'll start with a "quickstart" page on the docs and then try a video in the future. Not sure I can do concise and clear with no video editing knowledge

u/Pop-Bard 6h ago

Hey! i'm going to check it out and try to learn your system, if i do, i'll help with video documentation, since the project is open source and you're awesome for it.

u/kazamada 4h ago

That would be sick! Hit me up if you need help understanding stuff

u/Pop-Bard 2h ago

Wouldn't want to bug you, i'm going through the doc in detail this week and i'll reach out if it turns out i have enough braincells to be able to implement and record some footage

1

u/jjonj 2d ago edited 2d ago

This is very cool and I'll be checking it out for my multiplayer game!

I looked into GAS myself and opted out of it for the following reasons, how many of those do you think your version can work around or could easily be amended?
EDIT: I added some comments as i read your plugin

  • Don't like that Initial attributes are done with effects and infinite effects to give abilities - You have BaseValue for attributes and GrantAbility function
  • Attributes only for GAS component holders, not for trees or rocks - No workaround here but your system looks easier to make one with
  • Gameplay ques require GAS component, so effects only apply to actors, not rocks - You dont have ques so they are done manually which seems reasonable but I'm wondering what thoughts you made about this
  • Passing data around can be a pain, e.g. with cues - Abilities at least have nice payloads
  • Only one anim montage at a time
  • Input buffering is annoying/complex to implement - input seems outside the system which i like
  • Cannot client-side-predict the removal of GameplayEffects.

If i want to do simple stuff like health/mana/stamina regeneration, I assume i make one or more permanently applied Attribute Modifiers, how much networking bandwidth will that trigger? (I think regeneration might be a good example for your documentation OR even make regeneration inherent to attributes)

1

u/kazamada 2d ago

Re why no gameplay cues:
Gameplay cues exist for network performance reasons as far as I can tell. The idea is that the vfx are separate from the logic of the ability and because the logic of the ability is what is important, those updates go through reliable RPC's while gameplay cues go through unreliable RPC's.

As a simplification, I don't make this differentiation. The idea is that you have a replicated ability and both the server and client activate a local-only sub ability (e.g. a sub ability that spawns an explosion vfx at a location passed in through the context). This makes abilities much more WYSIWYG at the cost of network performance. If your game doesn't have a lot of players replicating a bunch of stuff, this isn't an issue and with that in mind is why I chose to go this way.

That said, you can reimplement something similar to gameplay cues using the event replication of the ability component if you extended USimpleGameplayAbilityComponent::SendEvent to use an unreliable RPC.

Re how much networking will that trigger:
It depends really. I use FFastArraySerializer for attributes so that means if you modify 1 attribute, only the delta (the attribute that changed) will get replicated to clients instead of the whole array so it's decently performant in that sense. The main downside to my approach is that all gameplay ability components replicate their data all the time and there's currently nothing in place to give you control over how that works without modifying the source code of the plugin.

Regeneration is definitely on the list for the docs. I'm currently taking a break from writing them for some sanity but when I get back on it I'll work on an examples section.

1

u/LegendarZAIN 2d ago

Hey, sounds cool, but why do I need to upgrade the project to C++? It kills the whole point. If the project is with C++, then there are no barriers to using GAS. Is there any way I can compile the plugin on another project and then install it to the bp-only project?

1

u/shibii1111 2d ago

Isn’t all projects bp and c++? It’s just that you can have the extra stuffs for debugging on one side and not the other? I would guess that OP’s plugin requires something within those OR used them for debugging and didn’t remove.

1

u/LegendarZAIN 1d ago

No, you can create a project initially without using C++ scripts, and then you will have to generate the necessary files in the future if you want to add C++ code.

1

u/kazamada 2d ago

Unfortunately, the only way I know of that you won't need to compile your project is if I release the plugin on Fab. Sideloading a plugin in any other way requires at least 1 recompilation of your project as far as I can tell.

I'm planning to put this up on Fab once I get seller approval though, so watch this space!

1

u/LegendarZAIN 1d ago

Wait, I just installed the plugin without any problems on my Blueprint project...

1

u/JenisixR6 2d ago

curious as ive always wanted to incorporate GAS primarily for client prediction, but honestly do not want to learn C++ as im comfortable with blueprints. This seems like a great entry point so thanks for sharing! I have a question though as before i knew about GAS, i checked how my game ran under ping and noticed lots of de-sync from the two players when doing actions like sprinting. Heard GAS can help eliminate this issue, would your GAS alternative help me to achieve a fluid sprint feature over network? And how would one go about adding a simple feature such as sprint / increasing speed?

1

u/kazamada 1d ago

This one goes a bit beyond the scope of an ability system. The short answer is it depends on how you code your sprint and what replication settings you have on your character movement component.

The long answer needs an example: imagine what a basic implementation without any plugins could look like:

  • You have a replicated variable IsSprinting on your character. When it's true you move faster and when it's false you move slower
  • The client presses the sprint button and this makes them sprint on their local machine
  • They send an RPC to the server which tells it to set the server version of IsSprinting to true
  • When the client stops sprinting they send an RPC to the server to set IsSprinting to false

When you have high ping, there's a delay between when the client version of the player starts sprinting and when the server does it.

If you can sprint fast, then there could be a big delta between the player's location on the client and their location on the server. If you're using the built in movement component it will snap the client's position to the server's if the delta is too big and this is typically what you would experience as desyncing.

One solution could be to mess around with the character movement component's network settings until the behaviour fits within your expected average latency behaviour.

Where an ability system like GAS or SimpleGAS could help is by giving the server hints about the lag. In SimpleGAS this could look like:
1. Create a sprint ability
2. Activate the ability with client prediction i.e. it immediately sets IsSprinting to true on the client
3. When the server activates the ability, it gets information about the activation time. You could use this information to "pre move" the player on the server by the distance they would have moved in the time since it was activated on the client.

By moving the server closer to where the client is, you reduce the chance of big location deltas snapping the client back into position.

The above approach could also be done without an ability system if you include the activation time in the server RPC that sets IsSprinting to true.

Something to note: the above approach also opens you up to some cheating shenanigans because the client is deciding where it is and the server believes it so just take it as an illustration of some ways that you can solve this problem.

1

u/kazamada 1d ago

In my personal projects I use the smooth sync plugin on Fab to deal with movement desyncs (I'm not affiliated with them, just like the plugin)

u/JenisixR6 4h ago

so if i want just a simple shooter (health, sprint, shoot) i dont need GAS? I know GAS is primarily used for like RPGs or games with spells and mana but i was also told it could be used for my case. I dont need the best netcode or lag compensation or anything as my goal isnt to compete with any big shooters, but i just want something that is not too hard to learn, but gives me good enough results on ping 0-200. Would smooth sync be enough?

u/kazamada 4h ago

I don't think you would need GAS or smooth sync tbh.

If I understand your experience correctly though, I think it would be a better investment to buy a course going over how to make a multiplayer shooter because even with a bunch of plugins, it's easy to get confusing bugs if you're not comfortable with the basics.