A downloadable tool

Get this tool and 3 more for $17.99 USD
View bundle
Buy Now$7.99 USD or more

The beating heart of your game!

Pulse - A simple to use, but powerful, signals manager.

Want damage events to update your health bar, play a sound, trigger screen shake, and bump the UI... without you personally having to reference every one of those systems and hoping that an instance exists, or the correct method is called?

Pulse is a signals and events framework for GameMaker that does exactly that. Your game broadcasts what happened, and anything that cares can react...Without the sender needing to know who is listening. 


Get the Ignition Kit bundle, featuring Pulse, Catalyst AND Statement for a discount!

Or get the Full Suite Pass bundle to get all current and future tools for one low price (price will increase each time a new tool launches, so get in early for substantial savings!)


Why you need Pulse

Because at some point in every GameMaker project, you end up repeatedly wiring 400 things together over and over in different parts of your project:

"Ok, when X happens, also tell Y... and Z... and the thing I forgot about... and the UI... and the sound... and the particles... and the save system... and..."

Pulse is how you stop doing that.

A purchase of Pulse gives you a copy of Echo free!

Instead of manually calling five different references, you send out little signals like this:

  • "Player took damage."
  • "Enemy died."
  • "Quest updated."
  • "Door unlocked."

Then anything and everything that is subscribed to one of those signals can react on its own. No awkward hand wiring. No direct references. Just clean "broadcast" and "listen" actions.


It's simple to use

At the very heart of pulse is two simple concepts:

  • Subscribe to a signal.
  • Send a signal.

That's it. You don't need to learn anything more than that if you don't want to. That pattern alone will save you from the coupling nightmare. When you need to you can branch out into all the other more advanced features, like PulseQuery(), but at it's core, Pulse is always trying to stay as simple as possible to use.

Your game can talk back

Sometimes you don't want to broadcast "something happened", sometimes you just want to ask "Ok...Who knows the answer to this?" Pulse can do that too, with queries!

Send out a PulseQuery and get a packet back that contains the responses of everything that was listening to the query and wanted to answer, simple but extremely powerful.

When your project gets bigger, Pulse is ready

Pulse gives you escape hatches for all the nasty real-world problems:

  • Query signals: ask a question ("who wants to handle this?") and collect answers, instead of inventing a new bespoke manager every time.
  • Priorities: so the important listeners runs first.
  • Consumable signals: so one listener can say "sweet, I got this" and stop the rest of the listeners from reacting.
  • Sender filters: so you can listen to "damage" from that enemy, not every enemy.
  • Queued dispatch: post events now, flush them later when it's safe.
  • Subscription groups: bind a pile of listeners to a state/room/UI panel and clean them up in one go.
  • Multiple buses: keep gameplay events, UI events, and debug events from stepping on each other.

It is harder to shoot yourself in the foot

Pulse keeps track of things, but it also tries to keep things tidy: It works with both instances and structs, uses weak references and prunes dead listeners with its garbage collector, and gives you result enums so you can tell what happened.

Your code becomes easier to read

Pulse nudges you toward code that sounds like a story. "When the player takes damage, update the health bar," or "When an enemy dies, drop loot," or "When a quest completes, play a stinger and show the banner."

Not "Ok so obj_player calls obj_ui_manager which calls update_health() which calls..."

If you want a tiny, lightweight signal system, Pulse does that. If you want an event layer that can carry a whole game without collapsing into chaos, then Pulse does that too.


What Pulse does

Instead of directly calling every system yourself, you simply broadcast a signal:

// Somewhere in gameplay code:
PulseSend(SIG_DAMAGE_TAKEN, { amount: 10 }, id);

And then you let systems subscribe and react independently:

// UI manager:
PulseSubscribe(obj_hud, SIG_DAMAGE_TAKEN, function(_data) {
    hp_bar_target = hp_bar_target - _data.amount;
});
// Audio manager:
PulseSubscribe(obj_audio, SIG_DAMAGE_TAKEN, function(_data) {
    audio_play_sound(snd_hit, 0, false);
});
// VFX manager:
PulseSubscribe(obj_vfx, SIG_DAMAGE_TAKEN, function(_data) {
    fx_screen_shake(4);
});

Same event. Multiple listeners. No hard references. No "who calls who" mess.


Key features

  • Persistent and one-shot listeners (subscribe forever, or subscribe once and auto-remove).
  • Priority ordered dispatch so important listeners run first.
  • Consumable signals so one listener can cancel the rest when appropriate.
  • Sender filters (listen to this signal only when it came from that sender).
  • Queued dispatch (post now, flush later) for safer timing.
  • Query signals (broadcast a question, collect responses) for "pick a handler" and "gather offers" style problems.
  • Listener builder API when you want tags, priorities, once, sender filters, and custom buses without a pile of parameters.
  • Subscription groups to clean up a whole bundle of listeners in one call.
  • Introspection tools for debugging: counts, dumps, and per-signal inspection.
  • Multiple independent buses via PulseController, if you want strict isolation (UI vs gameplay vs debug, etc).
  • Safety features: weak refs, pruning of dead listeners, and result enums for error checking.

Documentation

As with all of my GameMaker based tools, Pulse comes with full online documentation, including an entire API reference page and multiple common patterns that you can add to your project straight away with minimal tweaking.

Pulse Documentation


Requirements

GameMaker 2.3 or later (as long as it has structs and methods)

Echo requires 2024.8+ (as it uses gpu_set_scissor())


Support and feedback

If you run into issues or have ideas for improvements:


Part of the RefresherTowel Games Toolkits

Part of a growing suite of GameMaker tools that are designed to play nicely together. If you like this style of tooling, you might also want:

  • Whisper - make your narrative dynamic and reactive, like Hades or Crusader Kings III.
  • Catalyst - makes modifiable statistics (and general numbers) super easy.
  • Pulse - a signals and events framework (supporting queries that allow you to ask questions instead of just broadcast signals!)
  • Statement - a state machine framework (with a fully visual in-game debugger).
  • Quill - a FREE text box creator that automatically gives you advanced features like a right click context menu, proper text selection, multi-line text boxes, plus more!
  • Fate - a FREE weighted drop system with an easy to use beginner setup, but with a huge amount of advanced features hiding in the weeds.
  • Echo - advanced debug logging (level filtering, tags, optional stack traces, history dumps) that now comes with an advanced, yet easy to use debug UI builder!

Get Pulse, Catalyst, Statement and Echo in the Ignition Kit bundle for a discount! Or buy the Full Suite Pass bundle (get access to all past and future tools) in one go!

Updated 15 days ago
StatusReleased
CategoryTool
Rating
Rated 5.0 out of 5 stars
(3 total ratings)
AuthorRefresherTowel
Made withGameMaker
Tagsevent-bus, events, GameMaker, gml, publisher, pub-sub, pulse, signals, subscriber, tool
LinksDocumentation, Discord

Purchase

Get this tool and 3 more for $17.99 USD
View bundle
Buy Now$7.99 USD or more

In order to download this tool you must purchase it at or above the minimum price of $7.99 USD. You will get access to the following files:

Pulse v1.1.1 2.8 MB
Pulse v1.1.0 2.8 MB
Pulse v1.0.0 2.8 MB
Pulse v1.2.0 2.9 MB
Pulse v2.0.0 2.9 MB

Development log