Skip to main content

Add-on Development

An add-on runs at custom-assembly scope. Use it for extension behavior that should start when HyperionX loads HyperionX.Custom.dll and stop when that assembly is unloaded.

DifficultyExecution scopeApplies to
AdvancedDesktop processHyperionX 1.1.10
In-process code

An add-on runs inside HyperionX and can affect platform stability. Keep the surface small, release every resource in OnUnload(), and test a failing add-on before distributing it.

Contract

Add-ons use:

using HyperionX.Core.DataCalc.Addons;

namespace HyperionX.Custom.Addons;

The base class exposes:

MemberPurpose
NameDisplay name; defaults to the class name.
VersionAdd-on version; defaults to 1.0.
IsLoadedWhether the base lifecycle completed loading.
ContextCurrent AddonContext.
OnLoad()Acquire resources and subscribe to events.
OnUnload()Unsubscribe and dispose resources.
Print(object)Write a message to the HyperionX log.

AddonContext.Dispatcher is the documented way to schedule work that must run on the desktop UI thread.

Minimal add-on

In Tools → Code Lab, select Addon → Simple addon.

using HyperionX.Core.DataCalc.Addons;

namespace HyperionX.Custom.Addons;

public class SessionLoggerAddon : AddonBase
{
public override string Name => "Session Logger";

public override string Version => "1.0";

protected override void OnLoad()
{
Print($"{Name} {Version} loaded.");
}

protected override void OnUnload()
{
Print($"{Name} unloaded.");
}
}

Save it under Custom\Addons, then build the full custom project. Code Lab emission alone does not start the add-on. Complete desktop runtime activation—use Compile Project, another runtime compile trigger, or restart HyperionX—then confirm the load message in the platform log. When the desktop runtime loads the custom assembly, it discovers concrete AddonBase subclasses, creates each one, and calls its load lifecycle.

Lifecycle

Desktop runtime compile and load

Previous add-ons: OnUnload()

Previous custom assembly unloads

New custom assembly loads

Add-on type discovered and constructed

OnLoad()

Add-on remains active

Next reload or application shutdown

OnUnload()

HyperionX isolates add-on load and unload exceptions per add-on and writes failures to the log. An add-on is retained only after OnLoad() succeeds. If OnLoad() throws, HyperionX does not later call OnUnload() for that failed instance, so OnLoad() must roll back anything it acquired before the failure.

Only successfully loaded add-ons participate in the later unload pass. Test an activation failure as well as a normal load/unload cycle.

Resource ownership pattern

Store every owned subscription or disposable so OnUnload() can reverse OnLoad().

private System.Threading.CancellationTokenSource? _stopping;

protected override void OnLoad()
{
_stopping = new System.Threading.CancellationTokenSource();
Print("Background service ready.");
}

protected override void OnUnload()
{
_stopping?.Cancel();
_stopping?.Dispose();
_stopping = null;
}

For event subscriptions, unsubscribe the same handler instance you registered. For timers, stop and dispose them. Do not leave background callbacks holding the old collectible custom assembly in memory.

UI-thread work

WPF objects must be created and mutated on the UI dispatcher.

protected override void OnLoad()
{
Context.Dispatcher?.InvokeAsync(() =>
{
Print("UI dispatcher is available.");
// Create or update documented UI integrations here.
});
}

Do not block the dispatcher with network calls, file scans, long calculations, or synchronous waits. Perform background work off-thread, then dispatch only the small UI update.

Supported boundary

The stable add-on contract in HyperionX 1.1.10 is deliberately narrow: identity, load/unload, logging, and dispatcher access. AddonContext.Session exposes the host session object, but undocumented session members are platform internals and may change. Public add-ons should not depend on an internal window, view-model, or service unless that member is documented as an extension API.

For external processes, web services, or language-independent integrations, use the local desktop API instead of an in-process add-on.

Build and recovery checklist

  • Use a public, concrete class with a public parameterless constructor.
  • Keep OnLoad() fast and exception-safe.
  • Make OnLoad() transactional: clean up partial work in its own catch or finally before rethrowing.
  • Make OnUnload() safe after any successfully completed load.
  • Unsubscribe events and cancel background work.
  • Dispatch UI access through Context.Dispatcher.
  • Never store API keys or account credentials in source.
  • Build with other custom scripts present and inspect the platform log.
  • Test repeated build/reload cycles, not only the first load.
  • If the add-on prevents a clean build, move its .cs file outside the custom tree and rebuild.

Continue with Build, test, and debug, Script lifecycle, and Risk and Security.