Example Scripts - tayjay/SCriPt GitHub Wiki

Example Scripts

A collection of small, complete scripts showing common patterns. Drop these in SCriPt/Scripts/global unless noted otherwise.

Convention reminder: define event callbacks with a dot (function mod.fn(args)), not a colon. A colon adds a hidden self parameter and your args would arrive as nil. Use mod.on(event, callback) to register listeners that are cleaned up automatically when the script unloads.

Re-adding the Skeleton (SCP-3114)

Give Class-D a chance to spawn as SCP-3114 at the start of each round.

-- Create a module to hold our functions
scp3114 = SCriPt.Module('Scp3114')

function scp3114.load()
    -- mod.on auto-removes the listener when the script unloads
    scp3114.on(Events.Server.RoundStarted, scp3114.onRoundStarted)
end

function scp3114.onRoundStarted()
    local chance = math.random(1, 100)
    if chance <= 25 then
        local player = Players.Random()
        if player ~= nil then
            player:SetRole(RoleTypeId.Scp3114)
        end
    end
end

A custom command

By creating a SCriPt.Command inside a module, you register a command with RemoteAdmin or the client ~ console — complete with a help entry and auto-complete like any plugin command.

This client command lists every word CASSIE can say:

cassiewords = SCriPt.Module('CassieWords')

cassiewords.command = SCriPt.Command{
    type = CommandType.Client,              -- A client (~) command
    name = 'cassiewords',
    aliases = { 'cwords' },
    description = 'Get a list of words CASSIE can say.',
    permission = '',                         -- No permission required
    execute = function(args, sender)
        local words = Cassie.GetAllWords()
        return {
            response = table.concat(words, ', '),
            result = true
        }
    end
}

See the Commands page for the full command reference (including the older positional form).

Sharing code with a library

Put reusable helpers in Scripts/lib and require them from your scripts. Create Scripts/lib/announce.lua:

local announce = {}

function announce.toScps(message)
    for _, p in pairs(Players.ByTeam("SCPs")) do
        p.SendBroadcast(message, 5)
    end
end

return announce

Then use it from a script in Scripts/global:

local announce = require("announce")

motd = SCriPt.Module('Motd')

function motd.load()
    motd.on(Events.Server.RoundStarted, function()
        announce.toScps("Good luck — the humans are coming.")
    end)
end

See the Libraries page for more.

Passing tables and enum names

Thanks to type conversions, you can pass Lua tables where Unity types are expected, and enum names as strings:

teleporter = SCriPt.Module('Teleporter')

teleporter.command = SCriPt.Command{
    type = CommandType.RemoteAdmin,
    name = 'tpup',
    description = 'Teleport yourself 5 metres up and become a Tutorial.',
    permission = 'script.tpup',
    execute = function(args, sender)
        local player = sender.Player
        if player == nil then
            return { response = 'Run this in-game.', result = false }
        end
        player:SetRole("Tutorial")                 -- string -> RoleTypeId
        local p = player.Position
        player.Position = { p.x, p.y + 5, p.z }    -- table -> Vector3
        return { response = 'Up you go!', result = true }
    end
}

Persisting data

Use the Data store to keep values (including tables) between restarts:

stats = SCriPt.Module('Stats')
stats.data = Data.Get('stats')

function stats.load()
    stats.on(Events.Server.RoundEnded, stats.onRoundEnded)
end

function stats.onRoundEnded()
    stats.data['rounds_played'] = (stats.data['rounds_played'] or 0) + 1
    print("Rounds played so far: " .. stats.data['rounds_played'])
end