Skip to content

V2.4 - Defined Events

Compare
Choose a tag to compare
@RealityStop RealityStop released this 28 Jan 04:32
· 283 commits to master since this release

New Units!

  • Defined Event
  • Trigger Defined Event
  • Global Defined Event
  • Trigger Global Defined Event
  • Log
  • Some Value

Release video here:
IMAGE ALT TEXT HERE
Covers most of the information below.

Defined Events

Defined Events header

Defined events are a concept originally created by Discord user AFoolsDuty. We reached out and asked for permission to incorporate the units, but set them aside when the Lazlo revealed the Bolt 2 roadmap, which features an alternate Event system that would render the Defined Events unnecessary.

Recent acrid response to that choice on the Discord servers proved that you all still saw the units as valuable, so after some polish, here they are! Major thanks to AFoolsDuty for pioneering this approach to events, and giving us permission to incorporate them. We've expanded the concept, tweaked performance, and added support for defaults and type filters. None of us had thought about this idea before he presented his units, so again: as much as we've tried to present the best version of the units that we can, none of this would have happened without his ingenuity and permission.

Defined events allow you to write a tiny amount of C# code to provide the specification for the event, and the new units will manage listening, defining ports, and sorting order on the fly. Here's an example snippet of code:
code example
This is a defined event: we've written down the specification in code to specify that the TakeDamage event takes a Damage amount (as an integer), a DamageSource (as a reference to another GameObject), and whether the damage should be considered a critical hit.

We store these in a struct or class and signal that this is a IDefinedEvent. Basically, all this does is tag the struct/class for us to use and track. We use this to show just the list of IDefinedEvents in graph.

Lastly, we tag the struct/class specification with [IncludeInSettings(true)] so that Bolt knows to include this in the fuzzy finder. Whenever we add a type to Bolt using this attribute (rather than the Unit Option Wizard), we have to tell Bolt to re-index the list of Types so return to Unity and tell it to Build Unit Options.

Build Unit Options

Now, we can add a Defined Event or a Trigger Defined Event in our graph and see our new type!

Defined Events in action

The Defined Events system keeps track of the available events, their arguments, automatically builds ports, and includes pickers for common types (int, float, string, GameObject, and bool)! If you would like it to build ports for a 3rd-party type, the graph inspector includes a type dropdown that includes all types. Additionally, we include Global defined event support with two additional units:

Global Events

The Global variants don't take an event target to listen/announce on like Custom Events. Instead, these send the event to all listening units in the entire active scope of your project! To help prevent unintentional triggering of your logic, the targetted Defined Event system and the Global Defined Event system will not trigger each other. Defined Events will only listen for events sent to their event source, and Global Defined Events will only listen for events sent via a global trigger.

In addition, we retain a C# API for triggering from custom code that should be instantly reminiscent of the existing Bolt Custom Event API (available in the Bolt.Addons.Community namespace):
Defined Events API

Lastly, If you need to create events for third-party data, you can add them via the Unit Options Wizard, and then use the type filter in the Graph Inspector to select them. Unlike the dropdown on the unit, the one in the graph inspector does NOT filter to just IDefinedEvent types!

In-Editor Performance

Special note should be given on in-editor performance for large projects. While built game code always runs with better performance than working with the Unity Editor, the Defined Events (and Global Defined Events) actually disable some optimizations on themselves when running in the Unity Editor in order to support Bolt Live Editing.

Events in Bolt register to listen using an EventHook, and can provide Bolt with several pieces of information that Bolt uses to pre-sort Events into little bins so that only events that care about a particular Event get activated when an Event comes through the system. By providing more information up front, you get better pre-optimization from Bolt, which is great.

However, this event registration happens only once, so when operating in the editor, the Defined Event system does NOT provide Bolt with the extra Tag for the event type that you, the developer, chose. This allows the Bolt Live editing to work properly as you change the event types in editor to match your requirements, but comes at the cost that each Event is having to actively check for every Defined Event that they see if the event type of the event matches the one currently selected. In effect, support for Live Editing causes the Defined Event system to lose the benefit of the pre-optimization of Events when in the Unity Editor.

In particular, this affects Global Defined Events, as every Global Defined Event, on every GameObject, in every active scene has to inspect every defined event that is triggered anywhere in your active logic! Obviously, heavy use of Global Defined Events will rapidly deteriorate in-editor performance, so, either use them sparingly (chosing to use the targetted Defined Events instead, which do benefit from pre-sorting by the game object target) or disabling support for Live Editing (which enables full optimizations).

The Community Addons team recognizes that certain large game projects might encounter deteriorating performance from the Global Defined Events, and so we have included a special switch that allows you to turn OFF support for Live Editing event types in editor. Turning this option off causes all Defined Events and Global Defined Events to switch to providing the full type information to Bolt, causing proper optimization similar to what you would see from Built code.

To control this option, create a new script in your project that derives from the CommunityOptions class. This class will be found at the start up of your project and will override the default In-Editor performance.
Community Options

However, once this option has been toggles, you can no longer change the event type on the fly in play mode. Doing so simply causes the event to not fire. Exiting playmode and reentering play mode would be required for the correct event registration with Bolt to happen.

More fun stuff!

Logs
If you've used Logs much (we do during development!), having to feed in String literals or constantly using string.Format nodes gets old. So we have a new Log unit that provides a string input that can act as:

  • direct input (0 args),
  • .ToString() echoer (with 1 arg, and empty format string)
  • format string (with >0 args).

Hopefully, this makes getting functional log statements a lot smoother.

Some Value

In our quest to make mocking up graphs for sharing purposes, we have a new documentation unit to help in those circumstances where you know a value needs to be wired up, but you just don't know what.
Some Value

Also, thanks to Necka for testing, feedback, and reigning in my crazier ideas.

And that's it! Go make something awesome!