DUXPLIMA Documentation

Hooks and the API

Reacting to trolls, and firing them from your own code.

Two ways to connect this system to the rest of your game: a hook that tells you what happened, and an API that lets you make things happen.

The hook

Configuration/Server/Hooks.luau ships empty. Add a function and it is called.

local Hooks = {}

function Hooks.OnTrollApplied(by: Player, key: string, scope: string, victims: { Player })
    print(by.Name .. " used " .. key .. " on " .. #victims .. " players")
end

return Hooks
Argument
byWho paid
keyKill, Slow, Freeze, Fire, Fling, Explode or Kick
scope"One" or "All"
victimsWho it actually reached
victims is who it landed on, not who was aimed at

An everyone troll fired at a server of ten with three immune players gives you seven victims. A single-target troll on somebody without a character gives you none, and the hook does not fire at all.

That is the number to log, not the number you might infer from the scope.

The hook fires once per troll, after it has landed on at least one player.

Hook rules

It runs inside pcallA mistake in your code prints a warning, it does not stall the system
Its return value is ignoredA hook observes; it cannot block or change a troll
It is server sideThe file lives in Configuration/Server and is never replicated

Things to build on it

function Hooks.OnTrollApplied(by, key, scope, victims)
    myLeaderboard:Add(by, "TrollsBought", 1)

    for _, victim in victims do
        myStats:Add(victim, "TimesTrolled", 1)
    end

    if scope == "All" then
        myWebhook:Post(by.Name .. " used " .. key .. " on the whole server")
    end
end

A server-wide troll counter, a "most trolled player" board, a log of who spent what, an achievement for surviving an explosion. All of it belongs here rather than inside the system.

The API

The system registers named actions your own server code can call.

local API = require(game.ServerScriptService.uxrTrollSystem.Core.Server.API)

API.OnReady(function()
    API.Call("ApplyTroll", "Freeze", "All", nil, nil)
end)
ActionArgumentsDoes
ApplyTrollkey, scope, target, byFires a troll with no purchase
GrantCreditplayer, key, scopeGives a player a free go

ApplyTroll returns true if it landed on anybody.

ArgumentFor scope = "One"For scope = "All"
targetThe victimIgnored
byWho to credit in chat and the hook. OptionalRequired

Passing by as nil on a single-target troll applies the effect silently: no chat line and no hook.

ApplyTroll bypasses everything except immunity

No purchase, no cooldown, no rate limit. Immunity is still respected, because it is checked inside the effect path.

That makes it right for an event script, a boss mechanic or a staff command, and wrong for anything a player can trigger directly.

GrantCredit is the compensation tool: a player whose purchase went wrong, or a reward from a quest of yours.

API.Call("GrantCredit", player, "Explode", "One")

Their next Explode button reads FREE (1) and costs nothing.

Waiting for readiness

API.IsReady()
API.OnReady(callback)
API.Actions()

Services start in order, and calling an action before the system is ready raises an error telling you to wrap the call in OnReady.

OnReady runs your callback immediately if the system is already up, so it is always safe to use.

API.Actions() lists the registered action names, which is a quick way to confirm the system started as expected.

Uses worth building

IdeaHow
A boss that freezes the arenaAPI.Call("ApplyTroll", "Freeze", "All", nil, bossOwner)
A staff commandAPI.Call("ApplyTroll", "Kick", "One", target, admin)
A round-end fireworks momentApplyTroll with Fling on everyone
Compensating a failed purchaseGrantCredit
A daily free trollGrantCredit on join, once per day

The last one is worth considering as a retention mechanic: a free go each day gets players into the panel, and the panel is where the paid buttons are.