SwiftlyS2
Development

Using attributes

SwiftlyS2 attributes let you register commands, listeners, and hooks declaratively on methods instead of wiring every handler manually.

Registration Scope

Attribute discovery runs on registered object instances.

  • Your plugin class (the class that inherits BasePlugin) is registered by default.
  • For any additional class, call Core.Registrator.Register(instance).
public sealed class ModerationHandlers
{
	[ClientChatHookHandler]
	public HookResult OnClientChat(int playerId, string text, bool teamonly)
	{
		if (text.Contains("badword", StringComparison.OrdinalIgnoreCase))
		{
			return HookResult.Stop;
		}

		return HookResult.Continue;
	}
}

public override void Load(bool hotReload)
{
	var handlers = new ModerationHandlers();
	Core.Registrator.Register(handlers);
}

Register each handler instance once. Registering the same instance repeatedly can cause duplicate callbacks.

Signature Rules

Attribute handlers must match the expected delegate signature exactly.

  • Same parameter order and types
  • Same return type (void vs HookResult)
  • Same generic event/message type where required

If the method signature does not match, the handler will not behave as expected.

Reference

See IRegistratorService for registration behavior.

See Command and CommandAlias for command attributes.

See EventListener<T> for core event attribute listeners.

See GameEventHandler for game-event attribute hooks.

See ClientNetMessageHandler, ServerNetMessageHandler, and ServerNetMessageInternalHandler for net-message attributes.

See EntityInputHandlerAttribute and EntityOutputHandlerAttribute for entity attribute hooks.

On this page