Hook Functions only work when cheats are enabled.
Hook Functions are case-sensitive.
Hook Functions are a way to implement custom scripts into your VIP / Community servers.
Using Hook Functions, you can implement custom scripts to the server to modify the gameplay experience. Examples: infection event, SCPs can escape to become Serpents Hand, Class-Ds turn into Janitors if they’re in 914’s input area on the mode Fine, etc.
To open the hooks panel you have to type “/hooks” in a private/community server. Only the owners of those servers may do so, unless the co-owners hook permission is enabled.
To save your scripts you have to click on the “Save” button and the “Load” button to load your scripts.
Booleans are simply a bit that is either on or off; they are commonly returned by functions and properties and can be used to determine what your code should do or change the behaviour of instances such as Player’s.
true; // Enabled.
false; // Not enabled (disabled).
Numbers are well, numbers. They are used for storing data that can’t be simply stored as a boolean such as player count.
1234; // An integer.
-1234; // An negative integer.
12.34; // A decimal number.
Strings are a representation of letters, numbers, symbols, or all, which are declared using double quotes "
.
They are used to store data such as names.
"I am a string";
""; // An empty string.
"123"; // This is a string, not a number.
Vectors are a set of three numbers that specify a point in 3D space.
Vec3(0,0,0);
Vec3(-94,2,64);
Vec3(1,1,1);
Instances in Hook Functions are datatypes that contain data about a specific thing (such as Player Instance, which contains data about a specific player) which is represented by properties.
Instance | Type | Description |
---|---|---|
Plr.Name |
String | The name of a player. |
Plr.IsAlive |
Boolean | Whether a player is currently alive or not. |
Plr.Class |
String | The player’s class. |
Plr.Cuffed |
String or false | If the player is cuffed, it will return a string with the name of the team that cuffed the player, otherwise false. |
Plr.Health |
Number | The player’s health. |
Plr.MaxHealth |
Number | The player’s max health. |
Plr.Armor |
Number | The player’s current armor value. |
Plr.Immunity |
Number | The player’s current immunity value. |
Plr.Position |
Vector3 | Returns the position of a player. |
Plr.Holding |
String | Returns the name of the item the player is currently holding. If no item is being held, then will return as false. |
Plr.Overwatch |
Boolean | Whether a player is on overwatch/no-spawn mode or not. |
Plr.Id |
Number | Returns the player’s ROBLOX ID. |
Plr.Rank |
String | Returns the player’s rank if any, else returns nothing. Options are Helper - Mod - Admin - Coowner - If the player is the owner, this just returns "" (an empty string). |
Plr.Fuel |
Number | Returns the player’s current fuel as SCP-457. If player is not SCP-457 it will always return 0. |
Plr.Infection |
Number | Returns the player’s SCP-610 infection percentage. |
Plr.Zone |
String | Returns the zone a player is currently at. |
Plr.MoveState |
String | Returns the player’s current movestate. Valid options are: Running - Walking - Crouching - Frozen (Frozen is used by SCP-173) |
Plr.JumpPower |
Number | Returns player’s jumppower - IMPORTANT: This is currently bugged and always prints 0 |
An Operator is a symbol or a set of symbols that represent an action and are used with values to return a new value.
Arithmetic operators are simply math operations.
1 + 49; // 50 | Addition
600 - 427; // 173 | Subtraction
22 * 4; // 88 | Multiplication
100 / 5; // 20 | Division
5^2; // 25 | Exponentiation
-(-50); // 50 | Negation
Comparison Operators are Operators that compare different datatypes and can only return true
or false
.
// Can be used with all datatypes //
"Hello!" == "Bye" // false | "Equal to" Operator
"String" == 25 // false
25 != 8 // true | "Not equal to" Operator
"sus" != "innocent" // true
// Can be used only with numbers. //
314 > 50 // true | "Greater than" Operator
200 < 100 // false | "Less than" Operator
5 >= 5 // true | "Greater than or Equal to" Operator
16 <= 16 // true | "Less than or Equal to" Operator
Logical Operators are Operators that combine different values or boolean to return false or (true or a value)
// "!" Operator, This operator negates the boolean.
!true; // false
!false; // true
// "and" Operator, This operator returns true if all parts of the expression are not false.
("Hello" == "Hello") and false; // false.
true and true; // true.
((25 * 2) == 50) and (10 == 2); // false.
// "or" Operator, This operator returns true if any parts of the expression are not false.
"Hello" or false; // true.
("Hello" == "Not") and true; // true.
In Hook Functions, events are those events that trigger code inside them once their designated event happens. For example, the OnPlayerSpawn
event triggers once a player has spawned.
Events may have arguments, and may not. You will see a more in-depth explanation of every currently existing event and how to use them.
The HooksStarted
event triggers once cheats are enabled and hooks are started.
This event has no arguments.
The HooksStarted
event is useful for team-based functions such as creating teams and modifying them. It’s a better alternative to OnRoundStart
as OnRoundStart
triggers every round, and HooksStarted
only once preventing errors in the Function Hooks Logs tab.
Sometimes this event runs twice in rare occasions for unknown reasons.
// This makes a new team named "SCP-035". This is not a fully functional SCP-035, and it spawns where SCP-049 spawns.
NewTeam("SCP-035", "Black"); wait();
ModifyTeam("SCP-035", "SpawnName", "SCP-049");
ModifyTeam("SCP-035", "pants", 150150);
ModifyTeam("SCP-035", "shirt", 150150);
The RunHook
event is ran by the RunHook()
hook. (Trying to use the RunHook()
function will cause an error in the Function Hooks Logs Panel.
This event has two arguments:
Argument | Description |
---|---|
Message | It’s a message sent by the RunHook() function, which the RunHook() event uses, for example, to determine which code to run. |
Value | It’s defined by the second argument of RunHook() |
The message argument is defined by the RunHook()
's Message
. So you can do something like this:
// Any event that isn't RunHook
RunHook("Whats up", "bro");
// Runhook event
if (Message == "Whats up") {
Announce("Whats up " + Value);
}
// This will print "Whats up bro"
The OnRoundStart
event runs once a round is started. This event will run every time a round starts.
This event has no arguments.
The OnRoundStart
is useful to making functions such as custom containment breach announcements, playing audios, team-switching functions, etc.
Example Usage:
// OnRoundStart
PlayNamedAudio("breachsound");
if (#GetPlayers() > 10) {
Announce("There's more than 10 players this round!");
}
The OnRoundEnd
event runs once the round ends. It’s the counter-part of OnRoundStart
.
This event has no arguments.
This event might be useful for announcing stuff if a condition is met. For example, announcing what team won the round.
// Assuming that, in some part of you code, you have defined a global named "WinTeam" with the team that won the round.
if (GetGlobal("WinTeam")) { // Checks if the global exists
Announce(GetGlobal("WinTeam") + " has won this round!");
PlayNamedAudio("RoundEnd");
}
//
The OnNukeStart
event runs once the nuke is engaged. This doesn’t mean the code will run once nuke detonates, rather when the 90 seconds timer goes out.
This event has one argument:
Argument | Description |
---|---|
Plr | The player that activated the nuke if exists. |
Let be known that OnNukeStart
also triggers when the nuke is started with the admin panel, and once it occurs the Plr
argument wont work clearly.
This might be useful for a economy system.
// Assuming you already have a set'd economy system that works with "Credits" attribute.
SetAttribute(Plr, "Credits", GetAttribute(Plr, "Credits") + 15);
The OnNukeCancel
event triggers when the nuke is canceled via the button in the nuke room or a custom cancel button with custom rooms.
This event has one argument:
Argument | Description |
---|---|
Plr | The player that canceled the nuke. |
Example of usage:
if (Plr) { // Checks if a player actually canceled the nuke, else doesn't trigger.
Announce(Plr.Name+" has canceled the nuclear warhead!");
}
The OnNukeDetonation
event runs once the nuke is succesfully detonated. This might be useful for making functions or custom teams that, for example, become invisible/visible once nuke is detonated.
This event has no arguments.
Example of usage:
// Assuming you have a custom SCP named "SCP-966" that is transparent.
Announce("The nuclear warhead has been detonated.");
ModifyTeam("SCP-966", "Transparency", 0);
The OnPlayerSpawn
event triggers once a player spawns. This event has 2 arguments:
Argument | Description |
---|---|
Plr | The player that spawned. |
Class | The class the player has spawned as. |
Although Class
is similar to Plr.Class
, for example, if the player was previously a spectator sometimes Plr.Class
will execute before the class change occurs. Class is safer to use overall.
Example of usage:
// Gives the player a Class-D Keycard with a 1 in 15 chance if the player is a Class-D
if (Plr.Class == "Class-D") {
if (rand(1,15) == 1) {
GiveItem(Plr, "Class-D Keycard");
}
The OnPlayerDeath
event triggers once a player dies. It’s similar to OnPlayerKill
, although OnPlayerDeath
focuses on the player. This event has 3 arguments:
Argument | Description |
---|---|
Plr | The player that died. |
OldClass | The player’s class before dying. |
IsLeaving | Since leaving the game triggers the OnPlayerDeath event, this will be true if the event was triggered by someone leaving the game. |
The OnItemUsed
event triggers once a player uses any item.
This event has four arguments.
Argument | Description |
---|---|
Plr | The player that triggered the event/used a item. |
Name | The name of the item used. Returns a string. |
Target | Target is a player when the item is a melee, a access name if it’s a keycard being used on a door, otherwise this will be false. |
Similar to OnPlayerDeath
, this event triggers once a player is killed. The difference between this event and OnPlayerDeath
is that this one focuses more on both the victim and the killer. OnPlayerKill
doesn’t run if a player dies from fall damage for example or TakeDamage()
and Kill()
.
This event has 3 arguments:
Argument | Description |
---|---|
Target | The player that was killed. |
TargetOldClass | The target’s class before being killed. |
Killer | The player that killed the target. |
OnPlayerKill
can run if the player accidentally grenades themselves or somehow dies to themselves in any way.
OnPlayerChatted
triggers once a player speaks in chat. This event is useful for making commands, such as a shop command or a command that announces something.
OnPlayerChatted
has 2 arguments:
Argument | Description |
---|---|
Plr | The player that has spoken. |
Message | The message said by the player. |
Example of usage:
// Announces "Pong!" if the player says "!ping"
if (Message == "!ping") {
Announce("Pong!", Plr);
}
OnPlayerLeave
triggers once a player leaves the server. Useful to make announcements for when a owner leaves for example.
This event has two arguments:
Argument | Description |
---|---|
Plr | The player that left. |
OldClass | The player’s class before leaving |
Example of usage:
// Assuming the player was an SCP before leaving.
if (strfind(OldClass, "SCP-", 1, true)) {
Announce("A SCP has left!");
}
The OnPlayerEscapeAttempt
event runs once a player tries to escape through surface’s escape point or a custom room’s escape point.
This event has three arguments:
Argument | Description |
---|---|
Plr | The player that is trying to escape |
Cuffed | Boolean, whether the player is cuffed or not |
OldClass | Player’s class while trying to escape |
OnPlayerJoin
triggers once a player joins the server. It’s the counter-part of OnPlayerLeave
.
This event has only one argument:
Argument | Description |
---|---|
Plr | The player that joined. |
This can be useful for making an announcement when you join. Example:
if (Plr.Name == "your name") {
Announce(Plr.Name+" has joined!");
}
The OnPlayer914Upgrade
event is triggered once a player utilizes SCP-914.
This event has two arguments:
Argument | Description |
---|---|
Plr | The player that used SCP-914 |
Mode | The mode used on SCP-914. Modes are “Fine”, “VeryFine”, “Rough”, “Coarse” and “1:1” |
The ItemPassedTrough914
event triggers once an item is passed through SCP-914.
Before someone says it’s “Through” and not “Trough”, the in-game event is named like this. Blame anexpia.
This event has three arguments:
Argument | Description |
---|---|
ItemName | The name of the item passed through SCP-914 |
OutPos | Vector, the output position of the item |
Mode | The mode used for SCP-914 |
This event is currently bugged, and it was used/meant to create custom crafting recipes.
OnGrenadeExplode
triggers when a grenade is detonated/explodes.
This event has a total of four arguments:
Argument | Description |
---|---|
Type | The type of the explosion. Can be Grenade, Projectile, Rocket and nil. |
Position | Vector, the position where the explosion occurred |
Radius | Number, the radius of the explosion |
Damage | Number, the damage of the explosion |
OnPlayerPickItem
triggers once a player pickes up an item. This event is useful for making stuff such as a SCP-035 or avoiding a player being able to pick up an item unless player is an certain class.
This event has two arguments:
Argument | Description |
---|---|
Plr | The player that picked up an item. |
ItemName | The name of the picked-up item as an string. |
Variables are names that have a value associated with them that can be accessed and modified at any point in time, which can be used for storing values.
var imAVariable = "here is my value";
var iAmNil;
var breakfast = "bagels";
print breakfast; // "bagels".
breakfast = "beignets";
print breakfast; // "beignets".
Tables are a versatile tool when it comes to storing data for your scripts.
Similar to variables they can be accessed and modified at any point of the script.
To create a table, you first have to declare a class which will return an empty table.
class someclass {}
var table = someclass();
After you create a table, add key-value pairs using the square brackets []
where the key is specified inside and the corresponding value of the key is assigned by =
. The key and the value can be strings, integers, etc. You can make tables inside of tables.
class someclass {}
var table = someclass();
table[1]; = "Hello!"
table[2]; = "Greetings!"
table["Hey"]; 12345
table["Hello"]; = 67890
table[1][2]; = "How are you?"
table[2][3]; = "This is a message"
To access a table’s content you have to use the same square brackets notation and include the key.
class someclass {}
var table = someclass();
print table[1]; // Prints "Hello!"
print table[1][2]; // Prints "How are you?"
print table[2]; // Prints "Greetings!"
print table["Hey"]; // Prints 12345
print table["Hello"]; // Prints 67890
While accessing a table’s content, you can make loops through it. For example, looping through all players from a server and printing their name. Use the for
loop.
// Prints messages in this order: "Hey" "This" "Is" "A" "Message"
class someclass {}
var table = someclass();
table[1] = "Hey";
table[2] = "This";
table[3] = "Is";
table[4] = "A";
table[5] = "Message";
var x = 0;
for (var a = 1; a <= #table; a = a + 1) {
x = a;
print(table[x]);
wait();
}
// Prints the names of all the players in the server
var playerlist = GetPlayers();
var x = 0;
for (var a = 1; a <= #playerlist; a = a + 1) {
x = a;
var plr = playerlist[x];
print plr.Name;
}
Control Flow is a very important part of code, as it determines which path in your code to take if a condition is met or not.
if
Statements are conditional statements that if met, will run the code inside the statement.
If the condition for the if
statement is not met, the else
keyword can be used to run a different path in your code.
if (2 > 1) {
print "math works";
} else {
print "uh oh, math is broken";
}
while
loops are loops that run as long as the condition for it is met, if at any point the condition is not met, the loop will stop.
var a = 1;
while (a < 10) {
print a;
a = a + 1;
}
for
loops are loops that can be used to run a block of code a known number of times, unlike while
loop, which can run an indeterminate number of times.
// Prints numbers from 1 to 10
for (var a = 1; a < 10; a = a + 1) {
print a;
}
Here is an example of looping through all the players inside a server and printing their names.
var players = GetPlayers();
var x = 0;
for (var a = 1; a <= #players; a = a + 1) {
x = a;
var plr = players[x];
print plr.Name;
}
Functions are blocks of code that can be run at any point in the script, which can receive a number of arguments and return a value at the end of the execution. It is recommended to put your functions at the start of the script, although it’s not necessary.
// This function will print the result of adding a and b.
function printSum(a, b) {
print a + b;
}
// This function returns the addition of a and b.
function addPair(a, b) {
return a + b;
}
// This function returns the first argument as it is.
function identity(a) {
return a;
}
// This will run the same as 'print addPair(1, 2)`,
// since the identity function will return addPair.
print identity(addPair)(1, 2); // Prints "3".
Functions can also have functions inside of them that can only be called from the first function.
function outerFunction() {
function localFunction() {
print "I'm local!";
}
localFunction(); // This will print "I'm local!"
}
localFunction(); // This will not work as localFunction is not created in the current scope.
Functions can also return functions, as seen in Identity function and the one below, However, the latter returns a function created inside which accesses a variable contained within.
function returnFunction() {
var outside = "outside";
function inner() {
print outside;
}
return inner;
}
var fn = returnFunction();
fn(); // This will print "outside"
This function returns the remainder of a division operation.
The dividend is the number being divided, and the divisor is the number by which the dividend is being divided.
// Example of Usage
print modulus(5, 2); // This will print 1, as the remainder of 5 being divided by 2 is 1
print modulus(4, 2); // This will print 0, as the remainder of 4 being divided by 2 is nothing.
print modulus(6, 10); // This will print the dividend (6)
As shown in the example above, if the dividend is smaller than the divisor it will always return the dividend.
print modulus(5, 10); // This will print 5
Returns a pseudo-random integer located between the minimum number and the maximum number.
print rand(1,10); // Returns a random number between 1 and 10
If num is less than min, returns min.
If num is greater than max, returns max
Returns num otherwise.
print clamp(5,1,10); // Returns 5
Exponent; Equivalent to num ^ power
print pow(2,5); // returns 2^5 (32)
Returns the absolute value of num
, which is the same number but positive.
print abs(-2); // returns 2
Returns the lowest closest integer to num
print floor(2.824); // returns 2
Returns the closest integer to num
,
print round(2.7); // Returns 3
As previously mentioned, Vectors are a set of three numbers that specify a point in 3D Space.
print Vec3(3,6,2); // Returns 3,6,2
Sets the Player’s current HP to Num
// Assuming the player just spawned.
if (Plr.Class == "Class-D") {
SetHealth(Plr, 75);
}
Sets the Player’s Maximum HP to Num
// Assuming the player killed someone as SCP-096
if (Plr.Class == "SCP-096") {
SetMaxHealth(Plr, Plr.Health + 100);
}
Changes the transparency of a player. The value goes from 0 (fully visible) to 1 (fully invisible).
This function also affects the transparency of a player’s face.
// Assuming you have a custom SCP-966 class
// OnNukeDetonated
var x = 0;
var scp966s = GetPlayersInTeam("SCP-966"); // Gets the players from the SCP-966 team
for (var a = 0; x <= #scp966s; x = x + 1) {
x = a;
var plr = scp966s[x];
SetPlayerTransparency(plr, 0.85);}
}
The snippet shown above makes every player from the SCP-966 team parcially visible once nuke detonates (assuming the custom team SCP-966 exists).
Valid ammo types
Explosive
HeavyCaliber
MediumCaliber
SmallCaliber
Shells
// Gives the player 10 shotgun shells
ModifyPlayerAmmo(Plr, "Shells",10);
Drops all the ammo an player has. “Ammotype” is optional and if not provided it will drop all ammo the player has.
// This code will drop every ammo the player has
DropAmmo(Plr);
// This code will drop every ammo of "Small Caliber" the player has
DropAmmo(Plr, "SmallCaliber");
Valid ammo types
Explosive
HeavyCaliber
MediumCaliber
SmallCaliber
Shells
Sets the Player’s current Speed to Num
SetSpeed(Plr, 25);
Sets the Player’s jump force to Num
SetJump(Plr, 50);
Sets the Player’s SCP-610 infection to Num
. If 100 or over 100 player converts to an instance of SCP-610
SetInfection(Plr, 100); // Turns the player into SCP-610
Sets the Player’s armor to Minimum
if Maximum
is not provided. If Maximum
is provided, player’s armor will be set to Minimum
and the maximum armor the player can have will be set to Maximum
.
// This will set the player's armor to 50
SetArmor(Plr, 50);
// This will set the player's armor to 50, and maximum to 80
SetArmor(Plr, 80);
Sets the Player’s immunity to Num
. Immunity is in percentages and absorbs that percentage of damage. For example if it’s 50 it will absorb half of the damage. Immunity doesn’t run out when the player is hit unlike armor.
SetImmunity(Plr, 50);
Sets the player’s vest to VestName
.
Valid Vest Names are:
Light Weight Vest
Insulated Vest
Insulated Heavy Vest
SCP
(Absorbs all damage)
nil
(none)
Sets the player’s fuel number to Num
assuming the player is SCP-457.
SetFuel(Plr, 5000);
Makes player have noclip enabled.
SetNoclip(Plr, true);
Makes a player immortal. Same as SetGodmode()
.
Immortalise(Plr, true);
Makes a player immortal. Admin panel player settings’ godmode behaviour.
SetGodmode(Plr, true);
Returns a Boolean
whether player has godmode or not.
if (HasGodMode(Plr) == true) {
print Plr.Name+" has godmode!";
}
Makes player be able to bypass any door access value and open every door.
SetBypass(Plr, true);
Makes the player be in overwatch/no-spawn mode.
SetOverwatch(Plr, true);
Reduces the Player’s Health by Num
, but respects factors that may negate or reduce damage such as Armor.
// Assuming the player picked up a Cup
if (ItemName == "Cup") {
TakeDamage(Plr, 20);
}
Returns a boolean whether Player
can see Player2
. This function uses same criteria as viewing SCP-096.
// Any previous function, this is just a demonstration.
if (GetPlayerByName("Fernando121231")) { // Checks if Fernando121231 is in the server
if (CanSee(Plr, GetPlayerByName("Fernando121231")) { // If true, runs code below
Announce("You can see Fernando!", Plr);
}
}
Kills the Player for Reason. Reason will be displayed in the player’s corpse.
Kill(Plr, "Too silly"); // Kills the player and others can see the "Too silly" reason
Kicks a player. The Kick()
hook does NOT work with in-game staff such as moderators.
// Assuming this is put in the OnPlayerChatted event
if (Message == "!death") {
Kick(Plr, "Death!");
}
Set’s the Player’s Class to Name
if Name
is a valid class.
// Assuming the player just spawned as a Class-D.
if (Plr.Class == "Class-D") {
var rnum = rand(1,4);
if (rnum == 2) {
SetClass(Plr, "Serpents Hand");
}
}
Set’s the Player’s appearance to a class, sort of SCP-034 disguising.
// Makes the player look like a Janitor
SetPlayerAppearance(Plr, "Janitor");
Same behaviour of SetClass()
, although ConvertToClass()
has the advantage of keeping the player in place, and giving the ability to keep their items and clothing.
KeepInventory
and KeepClothing
must be a boolean. They are optional.
Death
is optional and makes the player see the death screen after getting converted. If Plr
is provided, they will see the death screen as if they were killed by themselves. It’s recommendable to put nil
or to not include this parameter at all.
ConvertToClass(Plr, "Class-D", true, false, nil);
Sets a player’s pants. PantsId
must be a valid asset id.
SetPants(Plr, 7477892092);
Sets a player’s shirt. ShirtId
must be a valid asset id.
SetShirt(Plr, 10922202523);
Gives the player an accessory, as long as the accessory id is a valid assetid.
AddPlayerAccessory(Plr, "Glare", 10721963880);
Removes a player’s accessory set by AddPlayerAccessory()
RemovePlayerAccessory(Plr, "Glare");
Modifies in what channel the player is talking to.
if (Message == "!SCPChannel") {
SetChannel(Plr, "SCP");
Announce("You're now talking with SCPs!", Plr);
}
Modifies player’s chat color. Must be a valid HEX
value.
// Makes player's chat color fully white.
SetChatColor(Plr, "#fffff");
Teleports the Player to a position on the map, specified by Vec3
.
// This will teleport the player 15 studs up when ran.
Teleport(Plr, Plr.Position + Vec3(0,15,0);
Does an explosion at PositionVector
which must be a valid Vector3
value. Damage
is the damage of the explosion and Radius
is the radius of the explosion. Player
is optional and assigns the explosion to a player. DeathReason
is optional and incase the explosion kills any player the Death Reason will be this.
// Makes an explosion at player's position, with a damage of 50 and radius of 10, assigning the explosion to the player. If the explosion kills anyone, the death reason will be "Boom!".
Explode(Plr.Position, 50, 10, Plr, "Boom!");
Returns a table containing all the players within a server.
// Prints everyone's name from the server
var players = GetPlayers();
var x = 0;
for (var a = 0; a <= #players; a = a + 1) {
x = a;
var plr = players[x];
print plr.Name;
}
Returns the player named Name
if they currently exist within the server.
// assuming you want to kill someone with a "!kill" command
if (sub(Message, 1, 5) == "!kill") {
var plr = GetPlayerByName(sub(Message, 5, 500));
if (plr) {
SetClass(plr, "Lobby");
}
}
Returns a table containing all the players in TeamName
if TeamName
is a valid class.
var players = GetPlayersInTeam("Class-D");
Returns a table containing all the players in a zone.
var playersinzone = GetPlayersInZone("HCZ-EZ");
// Returns all players in the High Containment and Entrance zones.
Gives the player the item named ItemName
if ItemName
is a valid item name.
This function supports multiple Items.
// This will give the player a flashlight when run.
GiveItem(Plr, "Flashlight");
// This will give the player multiple items at once.
GiveItem(Plr, "AK-47", "Flashlight", "Radio", "Medkit", "Medkit", "Grenade");
Returns true if the Plr has any item named ItemName
, else returns false.
if (HasItem(Plr, "Flashlight")) {
print Plr.Name + " Has Flashlight";
}
If the Player has an item named ItemName
, it will be removed.
RemoveItem(Plr, "Flashlight");
Forces the player to equip an item if ItemName
is a valid item and player has the item.
ForceEquip(Plr, "Flashlight");
Drops whatever the player is currently holding.
// Assuming player is holding a flashlight, it drops the flashlight.
if (Plr.Holding == "Flashlight") {
DropHeld(Plr);
}
Deletes whatever the player is currently holding.
// Assuming the player is holding a Flaslight, it deletes it.
if (Plr.Holding == "Flashlight") {
DeleteHeld(Plr);
}
Drops all of a chosen item. If ItemName
is not specified it drops everything.
DropItems(Plr, "O5 Keycard");
Clears everything in the inventory of the player.
ClearInventory(Plr);
Forces player to stop holding whatever item it was helding.
Disarm(Plr);
Cuffs a player, Reason
will show up as “YOU HAVE BEEN CUFFED BY Reason
”
If the player is in the lobby class, it will only show the reason.
Cuff(Plr, "THE HORRORS");
Uncuffs a cuffed player.
Uncuff(Plr);
// If the player is alive, it will show “YOU HAVE BEEN CUFFED BY THE HORRORS”
If the Attacker
can damage the Target
directly, returns true, else false.
// Assuming the variables "Attacker" and "Target" are valid players.
if (CanAttack(Attacker,Target)) {
print Attacker.Name+" Can Damage "+Target.Name;
}
Returns a Boolean
value whether Player1
is hostile towards Player2
.
// Assuming the variables "Attacker" and "Target" are valid players.
if (IsHostile(Attacker,Target)) {
print Attacker.Name+" is hostile towards "+Target.Name;
}
Returns a Boolean
value whether Player1
is friendly towards Player2
.
// Assuming the variables "Player!" and "SecondPlayer" are valid players.
if (IsFriendly(Player1,SecondPlayer)) {
print Player1.Name+" is friendly towards "+SecondPlayer.Name;
}
Returns a Boolean
value whether Player1
is neutral towards Player2
.
// Assuming the variables "Player" and "SecondPlayer" are valid players.
if (IsNeutral(Player,SecondPlayer)) {
print Player.Name+" is neutral towards "+SecondPlayer.Name;
}
Modifies the player’s scale. Default scales are 1.
Valid options for Scale
are:
head
height
depth
width
Returns the value of a player’s scale.
Valid options are the same as SetPlayerScale()
's
Spawns the item named ItemName
if ItemName
is a valid item name at Pos
.
SpawnItem("Flashlight",Vec3(3,5,2));
Removes all items named ItemName
from the map if ItemName
is a valid item name.
DeleteItems("Janitor Keycard");
Removes all items named ItemName
from the map. If ItemName
is not provided it will delete all items from the map.
// Clears all items
ClearItems();
// Clears all flashlights
ClearItems("Flashlight");
Returns a table with all the items within the game.
// Gives the player a random item
var items = GetItemList();
var numberrand = rand(1, #items);
var selecteditem = items[numberrand];
GiveItem(Plr, selecteditem);
// It's not needed to add so many variables. GetItemList()[rand(1, #GetItemList())] is enough but doesn't look good.
This function edit’s an item’s property. For example, it can change the recoil, it can make a gun have infinite ammunition, make it act like a railgun, etc.
The following properties work on any item.
Item Property | Type | Description |
---|---|---|
SpeedModifier | Number? | It slows you down when you hold the item by negative the number its set to. Basically: Speed = (Speed - SpeedModifier) |
Disabled | boolean? | If true, it’ll make the item non-usable, but can’t be used with guns. Even if the item has this property, it will trigger the OnItemUsed event. |
The following properties work only on items that are considered guns.
Gun Property | Type | Description |
---|---|---|
Ammo | Number | Number of ammo required to reload |
AmmoType | String | Ammo the gun will use to reload, valid ammo types are: SmallCaliber - MediumCaliber - HeavyCaliber - Explosive - Shells - Rails |
ClipSize | Number | How much ammo the gun will have |
Damage | Number | How much damage the gun will deal |
Firerate | Number | Modifies the gun’s firerate |
Recoil | Number | Modifies the gun’s recoil, higher the Number the higher your camera moves when shooting. |
Spread | Number | Modifies the gun’s spread |
Pellets | Number? | For shotguns |
Mode | String | Changes the gun’s mode, valid mode types are: Burst - Auto - Semi - Charge (Charge is like railgun) |
Special Gun Properties | Type | Description |
---|---|---|
GrenadeLauncher | Boolean? | Makes the gun act like a Grenade Launcher |
RPG | Boolean? | Makes the gun act like an RPG |
Shotgun | Boolean? | Makes the gun act like a shotgun |
Penetration | Number? | Enables penetration, penetration acts like the railguns penetration. (Through doors and people) |
PenetrateBreak | Boolean? | toggles whether penetration breaks doors |
DeathReason | String? | When someone is killed by the gun in question, the body will display this death reason. |
For Shotguns | Type | Description |
---|---|---|
Pellets | Number? | For shotguns |
For guns with Burst | Type | Description |
---|---|---|
BurstAmount | Number? | Modifies the amount of burst |
BurstControlled | Boolean? | Modifies whether burst can be controlled or not |
BurstCooldown | Number? | Modifies cooldown between bursts |
For both guns and melees | Type | Description |
---|---|---|
Heal | Number? | makes gun heal allies |
Headshot | Number | Modifies how much damage the headshot is gonna deal, which will be modified afterwards by HeadshotType |
HeadshotType | String | Modifies how the headshot works. Valid headshot types are: ad - multiply For HeadshotType , if add , Damage = (Damage + Headshot). if multiply , Damage = (Damage * Headshot) |
The following properties only work in items considered as melee weapons.
Melee Property | Type | Description |
---|---|---|
Headshot | Number | Modifies how much damage the headshot is gonna deal, which will be modified afterwards by HeadshotType |
HeadshotType | String | Modifies how the headshot works. Valid headshot types are: add - multiply For HeadshotType , if add , Damage = (Damage + Headshot). if multiply , Damage = (Damage * Headshot) |
Heal | Number? | Makes melee heal allies |
MeleeDamage | Number | Modifies the damage of Melee |
The following properties are for misc. items such as medkits, vests, etc.
Vests and Shields Properties | Type | Description |
---|---|---|
Durability | number | Modifies how much durability it has |
MaxDurability | number | Modifies max durability it can have (only for the durability bar) |
Medkits Properties | Type | Description |
---|---|---|
Heal | number | Modifies how much they Heal |
The following properties are for keycards. Although it’s only one property, it’s really useful.
Access Property | Type | Level | Description |
---|---|---|---|
Access | accesstype | accesslevel (true or number) | Modifies the access of the keycard, this works like this: ModifyItem(“Researcher Keycard”, “Access”, “cont”, true); |
If it’s not an keycard, it’ll error. true
means it’ll open any door with that access, bypassing level of access.
Valid accesstypes
are:
cont
| manage
| armory
| detonate
| checkpoint
| gate
| nuke
For accesslevel
, number means it’ll open any door with that access, but only those that are equal or below to the number.
ModifyItem("Researcher Keycard", "Access", "cont", 2);
// Now, the researcher keycard can open any doors that have cont_2 or below as access.
// However, the researcher keycard can't open any doors that have cont_3 or above as access.
You can make your custom access levels with custom rooms and doors. You’ll only have to give your door an access of whatever you want and include a number if you wish.
For example, giving a door the access wiki
without a number.
Now, give a keycard that access with value true
. If you gave this access a number (for example wiki_2
, give it a number as well)
ModifyItem("Facility Guard Keycard", "Access", "wiki", true);
// Now facility guard keycard can open all doors with the access "wiki" regardless of their access number.
ModifyItem("Facility Guard Keycard", "Access", "wiki", 2);
// Now facility guard keycard can open doors with the access "wiki_2", "wiki_1" and "wiki_0"
Returns a boolean whether a keycard is able to access a door or not.
print(CanKeycardAccess(Janitor, "manage_2"))
// Assuming the janitor can't open a manage_2 door, it'll print false.
Returns the value of a item’s property.
// Assuming UMP-45 fire rate is 2 for example.
print ("UMP-45's fire rate is " + tostring(GetItemProperty("UMP-45", "FireRate")));
// This should print "UMP-45's fire rate is 2"
Does the end win screen. Text
must be a string, and Color
is optional but must be a HEX color code.
EndRound("The Chaos Insurgency prevails", "#3D9128");
// This makes an endscreen saying "The Chaos Insurgency prevails", in a green'ish color.
Modifies the gravity of everything. The default gravity number is 50.
SetGravity(100); // Double the default gravity
Spawns a grenade that will explode. Position
is a Vec3. Type
is a string and its optional, value types are default | smoke | stun | projectile | nil (resets to default).
Owner
is a player and is optional and it’ll make so if the grenade kills anyone, it’ll show up as the Owner killed them.
ExplodeTime
is a number, it’s the time it’ll take for the grenade to explode. Damage
is also a number and it’s the damage the explosion will do. Radius
is the radius of the explosion in studs.
SpawnGrenade(Plr.Position, default, Plr, 0.5, 100, 15);
// Spawns a grenade at a player's position that explodes within 0.5 seconds of appearing, dealing 100 damage in a 15 studs radius.
Creates a popup with the specified message, if no player is specified it will be sent to all players.
This function is compatible with Rich Text.
Announce("This is a message everyone can see.");
Announce("This is a message only you can see.", Plr);
Creates a popup with the specified message, if no player is specified it will be sent to all players.
Only users with their age set to 13+ can see announcements sent AnnounceRestricted.
This function is compatible with Rich Text.
AnnounceRestricted("This is a message everyone can see.");
AnnounceRestricted("This is a message only you can see.", Plr);
Sends a message in chat containing specified message in the specified color.
SendChatMessage("This is a message everyone can see.", false, "#bbffbb");
SendChatMessage("This is a message only you can see.", Plr, "#ffbbbb");
Sends a message in chat containing specified message in the specified color.
SendChatMessageRestricted("This is a message anyone 13+ can see.", false, "#22ff22");
// Output would be "This is a message anyone 13+ can see"
SendChatMessageRestricted("This is a message only you can see.", Plr, "#ff2222");
```swift
### SetLights(value, boolean)
This function will toggle the lights on a specific zone or multiple zones at a time.
Valid values:
`A zone's name (any)` | `all` | `main`
all
toggles the lights for all zones.
main
is used by the blackout you would see in a normal gameplay.
It can also be a zone’s name, and it’ll only affect that zone only.
SetLights("hcz", false); // Starts a blackout for HCZ only
wait(120); // Waits 2 minutes
SetLights("hcz", true); // Restores the lights for HCZ
SetLights("all", false); // Starts a blackout for every zone, disabling their lights
wait(120); // Waits 2 minutes
SetLights("all", true); // Restores the lights for all zones
SetLights("main", false); // Starts a normal blackout
wait(120); // Waits 2 minutes
SetLights("main", true); // Restores the lights
Sets the lock state of the round to state
.
If true, prevents the round from ending if a win condition is met.
SetRoundlock(true); // Enables Round Lock
Sets the Fall Damage to state
.
FallDamage if true, any Player falling from a height will take damage that scales with the distance they fell.
SetFallDamage(true); // Enables Fall Damage
Changes Chat Type to type
.
type
has only two options: Proxy, Global.
SetChatType("proxy"); // Enables proximity chat
Modifies the range of Proximity chat in studs.
SetProximityRange(80); // Players can see their messages in proxy within 80 studs from each other!
Enables the Hidden Teams option that can be found in server settings. This makes so you can’t see any team color in chat, only if they are close and you can see them.
SetHiddenTeams(true);
Sets Infinite Ammo to state
.
Infinite Ammo if true, any Player reloading a gun without ammo for it will be able to reload it normally.
SetInfAmmo(true); // Enables infinite ammo
Sets whether you can open or close Doors to state
.
SetDoorsEnabled(false); // Disables doors
Sets Auto Nuke to state
.
Auto Nuke if false, Nuke will not start on its own after the round lasts for a duration.
SetAutoNukeEnabled(false); // Disables autonuke
Sets SCP-294’s Cooldown to state
.
SCP-294 Cooldown if false, Players will be able to use SCP-294 as much as they want without the 5-minute delay between each drink.
Set294CooldownEnabled(false); // Disables 294 Cooldown
Sets Decontamination to state
.
Decontamination if false, LCZ and SCZ will not experience Decontamination when 10 minutes pass.
SetDecontamination(false); // Disables Decontamination
Sets Voting to state
.
Voting if false, Players will not be able to vote for FF mode (Friendly Fire)
SetVotingEnabled(false); // Disables FF voting
Enables or disables stamina.
SetStaminaEnabled(false); // Disables stamina and players can run and jump any much they want.
Enables or disables player collisions. This makes so players can, for example, jump and make a tower or push others into the abyss.
SetPlayerCollisions(true) // Makes players be able to collide with each other
Modifies a zone’s property.
Valid properties are:
hasdaylight
- Boolean, makes the zone be able to have day time.
hasblackout
- Boolean, modifies whether the zone is affected by blackouts
daylightskyonly
- Boolean, day time doesn’t disable lights that don’t have the _daytimeignore
tag.
hasdecontamination
- Boolean, people don’t die if decontamination occurs.
ignorenuke
- Boolean, people don’t die if nuke happens
ModifyZone("hcz", "hasblackout", false); // HCZ doesn't have blackouts anymore.
Returns a boolean whether a zone exists or not.
// Assuming this zone doesn't exist, it should print false.
print DoesZoneExist("horrorcontainmentzone");
Removes all corpses of a player. If PlayerName
is not specified it will delete all ragdolls from the map. PlayerName
must be a valid Plr.Name
instance.
// Removes all corpses
ClearRagdolls();
// Removes all corpses of a player. Assuming this is put in OnPlayerChatted
if (Message == "!removecorp") {
ClearRagdolls(Plr.Name);
}
Changes Friendly Fire mode for the round to type
if type
is a valid type.
type options: REVERSE, ON, OFF
SetFF("ON"); // REVERSE, ON, OFF
Sets the event mode to true or false.
// Enables event mode
SetEventMode(true);
Does a spawnwave. Valid SpawnType
are:
sh
| goc
| mtf
| ci
IsInstant
must be a boolean. If IsInstant
is true, it does a spawnwave without animation or announcement.
// Does a MTF spawnwave
DoSpawnwave("mtf", false);
// Does a MTF spawnwave too, but without animation, announcement or audio.
DoSpawnwave("mtf", true);
Does a spawnwave animation without actually spawning a wave.
Valid AnimationType
are the same ones as DoSpawnwave()
but without sh:
goc
| mtf
| ci
// Makes the helicopter of MTF spawn and do the animation as if MTF was spawning.
DoSpawnwaveAnimation("mtf");
// Makes the GOC plane appear.
DoSpawnwaveAnimation("goc");
// Opens the gate where CI spawns and the cars enter the facility doing a CI spawn animation.
DoSpawnwaveAnimation("ci");
Enables or disables random spawns.
// Disables random spawns, so no spawnwaves occur naturally.
SetRandomSpawns(false);
Sets the time until a spawnwave in seconds. This timer goes down until 0 and spawns a team if RandomSpawns are enabled.
// If Randomspawns are enabled, this will spawn a team within 2 minutes.
SetSpawnwaveTime(120);
Returns the time in seconds until a spawnwave.
SetspawnwaveTime(20);
print GetTimeTillSpawnwave();
// Prints 20 (sometimes 19 as it takes a little bit of time to run all the code)
Sets the map to MapName
. If the round is on-going, next map will be MapName
.
To set custom maps, you have to use SetMap(CUSTOM_MapName
with the CUSTOM
suffix.
// Assuming there's a map named "Oscar"
SetMap("Oscar");
// Assuming you have a custom map named "FlatTerrain"
SetMap("CUSTOM_FlatTerrain");
Returns the name in a string of the current map.
print GetCurrentMap();
// If the current map is "Oscar", it's going to print out "Oscar".
Returns the name in a string of the next map in the map pool.
print GetNextMap();
// If the next map is "Catto", it's going to print out "Catto".
Creates a new map and adds it to the map pool in admin settings. This map will have the CUSTOM
suffix. To use it you need to include a Github Raw Link
. To do this, create a repository, name it whatever you want, create a file, paste in your map code and then copy the raw link of the file.
The Raw Github Link should look like this: (NOT FUNCTIONAL LINK)
https://raw.githubusercontent.com/YourName/RepoName/main/FileName
// Non-Functional code, it is just an example.
AddMap("FlatTerrain", "https://raw.githubusercontent.com/MyName/MyRepo/main/FlatTerrain");
Removes a map from the map pool.
RemoveMap("Qati-3");
Plays the named audio NamedAudio
.
PlayNamedAudio("horror");
Stops a currently playing named audio.
StopNamedAudio("horror");
Pauses a currently playing named audio. May be resumed with ResumeNamedAudio()
.
PauseNamedAudio("horror");
Resumes a named audio that was paused using PaseNamedAudio()
.
ResumeNamedAudio("horror");
Creates or modifies an already existing named audio. NamedAudio
parameter can be any name, SoundId
must be a valid Roblox Sound ID.
You can use SetNamedAudioId() to modify default audios, those are:
Audio Name | Description |
---|---|
shtheme | Serpent’s hand theme |
mtftheme | Mobile Task Force’s theme |
citheme | Chaos Insurgency’s theme |
goctheme | Global Occult Coalition’s theme |
mtfenter | The announcement for when MTF spawns. |
lczambience | The ambience for Light Containment Zone. |
hczambience | The ambience for High Containment Zone. |
ezambience | The ambience for Entrance Zone. |
surfaceambience | Surface’s Zone ambience |
pocketdimensionambience | Pocket Dimension’s ambience |
lobbyambience | Lobby’s ambience (Voting Phase) |
Sets the ambience for an zone.
This will error with the following zones:
Changes a named audio’s volume.
SetNamedAudioVolume("horror", 0.1);
Makes an named audio looped.
SetNamedAudioLooped("horror", true);
// Now "horror" named audio will play over and over again.
Sam as PlayNamedAudio()
but only works per-player.
// This will make only the player hear the "horror" audio.
PlayNamedAudioForPlayer(Plr, "horror");
// The entire server will hear the "horror" audio
PlayNamedAudio("horror");
Modifies an audio’s playback region. Behaviour of ROBLOX Studio’s playback region function.
SetNamedAudioPlaybackRegion("horror", 1, 2);
Modifies an audio’s loop region. Behaviour of ROBLOX Studio’s loop region function.
SetNamedAudioLoopRegion("horror", 2, 3)
Returns the assetid of an audio.
print("MTF's theme ID is: " + tostring(GetNamedAudioId("mtftheme")));
// This print's MTF theme's audio id
Sets the audio to play using PlayAudio() to id
The id
must be a valid audio asset id.
SetAudioId(206438030);
Plays the audio set through SetAudioId().
PlayAudio();
Stops the audio set through SetAudioId().
StopAudio();
If the plr
has the tag tag
, returns true, else false.
if (HasTag(Plr, "Juggernaut")) {
SetMaxHealth(Plr, 1000);
SetHealth(Plr, 1000);
}
Applies the tag tag
to a player.
tag
has to be a string.
// assuming the player spawned
if ((!strfind(Plr.Class, "SCP")) and (rand(1, 10) == 5)) {
GiveTag(Plr, "Juggernaut");
}
Removes the tag tag
from a player if they have it.
// Assuming the player just died
if (HasTag(Plr, "Juggernaut") {
RemoveTag(Plr, "Juggernaut");
}
Gives the player a tag that is visible when hovered. Replaces TRAITOR
and CUFFED
tags. You may use emojis and richtext with player tags.
// Gives the player an tag named "Hook Functions are great!" which is visible when the player is hovered by another player.
SetPlayerTag(Plr, "Hook Functions are great!");
Gives the target player an attribute.
// Assuming this script is placed within the OnItemPickedup event
if (ItemName == "Cup") {
SetAttribute(Plr, "SCP-2923", 1);
RemoveItem(Plr, "Cup");
}
Checks if a player has the requested attribute.
// Assuming the player has the attribute "SCP-2923" and has a value of 1
if (GetAttribute(Plr, "SCP-2923") == 1) {
SetSpeed(Plr, 40);
Announce("You have acquired SCP-2923-09", Plr);
}
Runs the RunHook
event. The Message
parameter will be used for RunHook
’s Message
argument and Value
for the RunHook
’s Value
argument.
The canWait
argument is a boolean and is completely optional as well as Value
. canWait
makes it wait until the event finishes running.
For example, you can do this:
// OnPlayerSpawn event
RunHook("hey there");
// RunHook event
if (Message == "hey there") {
print("someone spawned, they said: " + Message);
}
Shuts down the server and forces all the players inside to rejoin.
Shutdown()
Sets a global variable that can be accessed with GetGlobal()
. Global Variables are NOT permanent and will be resetted/deleted once the server shutdowns.
// This creates a global named "crazy" which value is 123, then printed.
SetGlobal("Crazy", 123);
var number = GetGlobal("Crazy");
print(number);
You may include variables inside globals, and can even add player instances such as Plr.Name
although it’s recommended to use SetAttribute()
.
// Creates a global named "TheChosenOne" along with a player's name. 50% chance
if (rand(1,2) == 2) {
SetGlobal("TheChosenOne"+Plr.Name, true);
print(Plr.Name+" is one of the chosen!");
}
Gets the value of a global variable and returns it if possible, else nil.
// Assuming the global "LaLa" doesn't exist, prints nil
print(GetGlobal("LaLa"));
// Prints "Hello world!"
SetGlobal("LaLa", "Hello world!");
print(GetGlobal("LaLa"));
Similar to SetGlobal() function although not the same.
// Difference between SetScopedGlobal() and SetGlobal()
SetScopedGlobal("heythere", "hello");
GetScopedGlobal("scope1", "hi"); // This will return nothing (scope doesnt exist)
GetScopedGlobal("heythere", "hi"); // This returns "hello".
GetGlobal("hi"); // This will return nothing.
Similar to GetGlobal() function although not the same.
// Difference between GetGlobal() and GetScopedGlobal()
SetScopedGlobal("heythere", "hello");
GetScopedGlobal("scope1", "hi"); // Returns nothing (scope doesnt exist)
GetScopedGlobal("heythere", "hi"); // Returns "hello"
GetGlobal("hi"); // Returns nothing
Clears a Scope set by SetScopedGlobal().
SetScopedGlobal("heythere", "hello");
GetScopedGlobal("heythere", "hi") // Returns "hello"
ClearScope("heythere");
GetScopedGlobal("heythere", "hi") // Returns nothing (scope was cleared)
Returns value
as a string if possible, else nil.
print tostring(500); // Prints "500"
Returns str
as a number if possible, else nil.
print tonumber("25"); // Prints 25
print tonumber("hi"); // Prints nil
Returns the type of value
print typeof("25"); // string
print typeof(500); // number
print typeof(tonumber("60")); // number
Returns the current time.
print tick(); // Will return a different number higher than the one before everytime it's called.
Returns in seconds the time that has passed by ever since the round has started.
Pauses execution of the code for a duration roughly equal to num
. This is useful to create scripts that have a lot of variables being simultaneously created and used as it gives times for those variables to be defined and might fix issues with “var not found”.
print "hi";
wait(2);
print "this is printed 2 seconds after";
Modifies a team’s property. List of valid PropertyNames:
Property | Type of Value | Description |
---|---|---|
BaseHealth | Number | The BaseHealth is the Starting Health all players from the team will spawn with. |
DisplayName | String | This is the name that displays to others. |
Group | Any | Group data of the team. |
GroupName | String | Name of the group the team is in. Default groups are MTF CI GOC SH SCP Class-D Facility Personnel Security Other Groups have an already set teamdata for teams within the group unless the team already has that data specified. For example SCP group makes so teams can’t jump, crouch, etc. But if you make a custom team that is able to crouch and then put it into Group “SCP” it’ll work. |
Faction | String? | Name of the faction the team belongs to. This is independant to Groups. |
Color | Color3 | Color of the team, HEX. |
Vision | Color3 | Color of the vision, HEX (SCP-1507 vision behaviour, vision adds a layer of color ontop of the screen) |
NeutralToAll | Boolean? | When loading team, this sets alliances with every team to neutral |
VestName | String? | Which vest the team spawns with, case sensitive. |
NoVisualVest | Boolean? | Does the team not show its vest upon spawning? |
Protection | Number | How much armor does the team spawn with. |
Immunity | Number | How much immunity does the team spawn with. |
BaseHealth | Number | The Starting HP for the team. |
WalkSpeed | Number | Starting speed while walking. |
JumpPower | Number | How high the player can jump. |
IsGhost | Boolean? | Makes the team go through glass and doors. SCP-106 behaviour. |
GhostPenalty | Number? | If ‘IsGhost’ = true and the person goes through doors, GhostPenalty is how much the walkspeed is affected (slows them down). |
NeutralWhenFF | Boolean? | Makes it so killing the same team doesn’t count as teamkilling when FF is on. |
IsHuman | Boolean | Toggles whether the team is a human. |
IsSCP | Boolean | Toggles whether the team is a SCP. |
BodyIsBurnable | Boolean | Toggles whether the body can be burned. Bodies with ‘IsHuman = true’ are burnable by default. |
CanSeeSCPBars | Boolean? | Shows SCP HP bars in the bottom left corner if this is set to true. |
CanManuallyUncuff | Boolean? | Toggles whether the team can uncuff a non-hostile by holding E on them. |
CanCrouch | Boolean? | Changes whether the team can crouch. |
CanSprint | Boolean? | Changes whether the team can sprint. |
CanPickup | Boolean? | Changes whether the team can pick up items. |
CanDrop | Boolean? | Changes whether the team can drop items. |
EscapeClass | String? | Which class does this team become when escaping. |
SpawnImmunity | Number? | How long does spawn immunity last. |
CanSeeHealth | Boolean | Toggles whether the team can see the HP of others when hovering over them. |
StaminaDepletionThreshold | Number? | Minimum stamina before it ‘depletes’. |
StaminaDepletionRecoveryTime | Number? | How long until stamina is usable after depletion. |
MinimumStaminaBeforeSprint | Number? | The minimum amount of stamina for sprinting. |
StaminaGain | Number? | How much stamina the team gets each frame. |
StaminaLoss | Number? | How much stamina the team loses per frame when sprinting. |
MaxStamina | Number? | The stamina cap for the team. |
JumpStaminaCost | Number? | The stamina cost for jumping. |
SprintSpeedGain | Number? | The speed increase when sprinting. Walkspeed + SprintSpeedGain. |
HasNVG | Boolean? | Does the team spawn with NVG equipped? |
HasInfiniteAmmo | Boolean? | Toggles whether the team has infinite ammo without enabling the server-wide infinite ammo setting |
HasInventory | Boolean? | Toggles whether the team has an inventory or not. |
InventoryLimit | Number? | The inventory limit for the team/how many items the team can have in its inventory. |
RemoveBodyParts | String? | Valid options are true “Hands” “Legs” - Basically which bodyparts should be removed. True removes both hands and legs. |
UserCustomization | Boolean? | Toggles adding the equipped P:SCP cosmetics and the player’s face and skin color. |
Faceless | Boolean? | Toggles the team having a face or not. |
Unattackable | Boolean? | Modifies whether this team can be damaged by other players. |
Uncuffable | Boolean? | Modifies whether this team can be cuffed. |
CantContributeToSCPCount | Boolean? | When enabled, the SCP doesn’t count for ‘SCPs killed’, ‘SCP kill reward’ and GOC’s spawn condition. |
SpawnName | String? | Backup spawn location for the team if the team doesn’t have a spawn location (For example custom teams without spawn locations in custom rooms). |
UseSpawnNameOnly | Boolean? | Forces the team to only spawn at the backup spawn locations. |
SpawnText | String | The text shown upon spawning. |
VRSpawnText | String? | Same as SpawnText but different for VR. |
legacyAccess | String? | Valid options are “checkpoint”, SCPs behaviour. |
Channel | String? | The channel the team speaks in. |
PlayerCounterType | String? | Options are “all” “enemy” “ally” |
SpawnwaveTimer | String? | Options are “full” “spawnonly” |
CanAttack | Boolean? | Toggles if the team can “melee attack”, SCP-049-2 or SCP-1770-1 or SCP-1507 behaviour. |
CanBreakBreakables | Boolean? | Toggles if the team can break breakables. Needs CanAttack=true. |
AttackCooldown | Number? | How long until you can attack again in seconds. |
Range | Number? | Range of attack. |
Damage | Number? | Damage of attack. |
HasNoClip | Boolean? | Changes whether the team has noclip enabled by default or not. |
HasBypass | Boolean? | Changes whether the team has bypass mode enabled by default or not. |
HasGodMode | Boolean? | Whether the team has GodMode by default or not. |
ShirtColor | Color3 | Modifies the color of the shirt. Use HEX color. |
PantsColor | Color3 | Modifies the color of the pants. Use HEX color. |
Shirt | Number | Modifies the shirt of the team. |
Pants | Number | Modifies the pants of the team. |
DeathReason | String | For custom attacks death reasons. |
AttackType | String | For custom attacks and death effects. Valid options are: Decay or 106 - Railgun or 096 - Fire - 173 . Decay and 106 makes the body be decayed. Railgun and 096 makes the limbs to be deattached. Fire burns the body and 173 deattaches the head. |
SCP-049 Properties | Type of Value | Description |
---|---|---|
ReviveSpeed | number | Modifies how long it takes for SCP-049 to revive a body (in seconds). |
SCP-457 Properties | Type of Value | Description |
---|---|---|
FireIterations | number | How many times someone gets damaged by the fire. |
FireDelay | number | Delay between each “fire tick” |
StartingFuel | number | The starting fuel SCP-457 spawns with. |
MaxFuel | number | The fuel cap of SCP-457. |
SCP-173 Properties | Type of Value | Description |
---|---|---|
SeenRange | number | The range of attack upon being seen as SCP-173 |
BlinkTime | number | The time it takes to teleport, in seconds. |
BlinkRange | number | How far you can teleport, in studs. |
Please note that this is a very big list. It’s recommended to copy the whole code and paste it in a editor such as Notepad++ by Don Ho for better visualizing.
Example of usage:
// Assuming the team "The Fog" has been created previously
ModifyTeam("The Fog", "GroupName", "Fog");
ModifyTeam("The Fog", "BaseHealth", 550);
ModifyTeam("The Fog", "SpawnText", "Consume them all.");
ModifyTeam("The Fog", "CanAttack", true);
ModifyTeam("The Fog", "CanBreakBreakables", true);
ModifyTeam("The Fog", "Range", 6);
ModifyTeam("The Fog", "AttackCooldown", 0.5);
ModifyTeam("The Fog", "Damage", 10);
ModifyTeam("The Fog", "Death Reason", "Consumed by the fog.");
ModifyTeam("The Fog", "HasInventory", false);
ModifyTeam("The Fog", "CanPickup", false);
ModifyTeam("The Fog", "CanPickup", false);
ModifyTeam("The Fog", "Uncuffable", false);
ModifyTeam("The Fog", "PlayerCounterType", "enemy");
This makes a basic custom team named “The Fog”. This team preset has no clothing and you will have to put them manually.
When the team is in a group and the group has set data, you don’t need to set data for the team, unless you want the team to have a specified data (For example, “Nu-7 Cadet”, is in the “Nu-7” Group, but it has different BaseHealth than the one specified in the Group’s data)
Example of said above:
CreateGroup("Nu-7");
ModifyGroup("Nu-7", "BaseHealth", 120);
NewTeam("Nu-7 Cadet", HEX COLOR HERE");
ModifyTeam("Nu-7 Cadet", "GroupName", "Nu-7");
// Right now, the Nu-7 Cadet should have 120 BaseHealth
ModifyTeam("Nu-7 Cadet", "BaseHealth", 110);
// Although the Nu-7 group has a BaseHealth set, Nu-7 Cadet now has too.
This returns the value of a team’s property. Property must be any of the properties listed above in the ModifyTeam()
function. (Click it)
print ("The fog's base health is: "+tostring(GetTeamProperty("The Fog", "BaseHealth")));
// This should print "The fog's base health is: 550"
Gives a team a default-set ammo when spawned. Valid AmmoName
s are:
Explosive
HeavyCaliber
MediumCaliber
SmallCaliber
Shells
ModifyTeamAmmo("Class-D", "MediumCaliber", 15);
// This gives the Class-D team 15 Medium Caliber ammunition.
Gives a team a default-set item in inventory when spawned. Position
must be a number and will be where the item will be located in inventory. ItemName
must be any item within the game.
ModifyTeamItems("Class-D", 1, "Class-D Keycard");
// This makes the Class-D team have a Class-D Keycard when spawned.
Even if there are no items in a position and you use a higher number, the item just go to the lowest position possible.
Example for better understanding:
ModifyTeamItems("Class-D", 1, "Class-D Keycard");
ModifyTeamItems("Class-D", 4, "Flashlight");
Class-D will have a Class-D Keycard again, but this time there’s a gap between positions.
The flashlight will just go all the way down to the second position.
You can also randomize between items for a single position.
ModifyTeamItems("Class-D", 1, "Class-D Keycard", "Flashlight", false, "Grenade", false, false, "Medkit", false);
// This will randomize class-d's first item slot.
// False means no item.
This adds or removes an highlight a Team has over another Team, highlighting everyone in the Target Team.
Options for state
ally
Adds a green highlight.
enemy
Adds a red highlight.
neutral
Adds a white highlight.
nil
Removes any highlights.
ModifyTeamHighlights("SCP-173", "Class-D", "enemy");
// Now, SCP-173's will have all Class-Ds highlighted as red.
Gives a team an accessory. Name
can be anything and it doesn’t have to be the accessory’s name. It can be for example “patchacc”.
AccessoryID
must be a valid asset id of an accessory.
There can’t be two accessories with the same name for a single team. It’ll error.
AddTeamAccessory("Fog", "Glare", 10721963880);
// This gives the team "Fog" an accessory named "Red Eye Glare".
// If you try to do it again with the same name, it'll error.
AddTeamAccessory("Fog", "Glare", 10722274383);
// This time it tries to give the team an accessory named "White Eye Glare", but it'll error.
Removes a team’s accessory as long as it’s a valid accessory set by SetTeamAccessory()
.
RemoveTeamAccessory("Fog", "Glare");
Clears the cache of a team’s appearance/accessories. Basically it resets whatever the team is wearing, and could be used to fix for example ghost accessories.
ClearTeamAppearanceCache("Fog");
Toggles the ability for team1
and team2
to attack each other.
SetTeamCanDamage("MTF Commander","MTF Cadet",true); // commander now damage cadet independent from the friendly fire policies
Resets the default attack behavior of team1
and team2
RemoveCanDamage("MTF Commander","MTF Cadet");
Creates a new team with the name TeamName
and the color StrColor
.
StrColor
must be either a BrickColor or a HEX color.
NewTeam("TeamName","Fog");
Removes an existing team with the name TeamName
.
DeleteTeam("MTF Cadet"); // MTF Cadet will no longer exist.
Returns boolean whether team TeamName
exists or not.
if (DoesTeamExist("MTF Trainee")) {
Announce("Class exists!");
} else {
Announce("Class doesn't exist");
}
// Announces "Class exists!" if "MTF Trainee" exists. Either it doesn't.
Changes if a class can attack another class.
// Options for value are Friendly, Hostile, & Neutral.
// you can also ignore the value and put true for Friendly, & false for Hostile.
SetAlliance("SCP-049-2", "SCP-049-2", false); // Allows SCP-049-2's to attack one another.
SetAlliance("MTF Cadet", "GOC Private", "Friendly"); // MTF Cadet & GOC Private are now Friendly.
Reverts two classes alliances back to their default state.
ResetAlliance("MTF Commander", "MTF Cadet");
Returns the alliance of both teams.
print GetAlliance("MTF Commander", "MTF Cadet");
// Usually this should print friendly unless you modify the team alliances.
Groups work the same as their team-only counterpart but on the groups instead.
Creates a group with the name GroupName
which can be then used by teams using ModifyTeam()
and modified with ModifyGroup()
CreateGroup("Fog");
ModifyTeam("The Fog", "GroupName", "Fog");
// Since Fog group exists, any teams can use it now.
Removes a group incase it exists.
// Assuming the "Fog" group exists
RemoveGroup("Fog");
Modifies a group’s property. It uses the same as team properties, but it applies to every team within the group as long as the team doesn’t have that property specified within its data (Also known as using ModifyTeam()
)
ModifyGroup("Fog", "BaseHealth", 550);
// All teams in the group "Fog" will have a BaseHealth 550
// Of course assuming the teams within this group don't have BaseHealth set.
Returns the value of a group’s property if possible, else nil.
var TheProperty = GetGroupProperty("Fog", "BaseHealth");
if (TheProperty) { // Checks if it exists
print("The Fog group's BaseHealth is " + tostring(TheProperty));
}
Sets the alliance between both groups to State
.
Valid State
options are:
friendly
| hostile
| neutral
Using true
will make the groups friendly, and false
hostile.
SetGroupAlliance("Fog", "SCP", "friendly");
// Makes the group "Fog" and the SCPs friendly.
Returns a table with the string split into parts based on the defined separator character(s).
var splitstring = strsplit("Hello, this is not a split string! for now.", " ")
// This will return a table containing every word including symbols next to them.
// "Hello,", "this", "is", "not", "a", "split", "string!", "for", "now."
var splitstring = strsplit("hi||bye", "|")
// this will return a table with 3 strings: "hi", "", "bye".
Receives zero or more integers and returns a string with length equal to the number of arguments that has each character has the internal numerical code equal to its corresponding argument.
print char(72, 101, 108, 108, 111); // prints "Hello"
Searches for any occurance of the pattern in text
If found, will return the start index of the pattern
Start parameter is optional and is used for indicating where to start searching.
if (match(Class, "MTF")) {
SetMaxHealth(Plr, 120);
SetHealth(Plr, 120);
} // Sets the player's health to 120 if they're any MTF class.
Returns a sub-string from startindex
to endindex
print sub("abcdefghijklmnopqrstuvwxyz", 5, 10); // prints "efghij"
Searches for any occurance of the pattern in text
If found, will return the start index of the pattern
Start parameter is optional and is used for indicating where to start searching
Plain parameters disables searching for pattern inside words
(eg: if you’re searching for like “CI” in class names, it won’t check if there’s “CI” in “Lieutenant” or "Commander, etc)
if (strfind(Class, "CI", 1, true)) {
GiveItem(Plr, "Radio");
} // Will only give the player a radio if they're CI
Returns a formatted string.
https://developer.roblox.com/en-us/articles/Format-String
print strformat("%s is %s and has %.1f HP!", "Player", "SCP-096", 2951.492);
// Will print "Player is SCP-096 and has 2951.4 HP!"
Returns a copy of the string with all characters lowercase
print lower("HeLLo WorLD!"); // Prints "hello world!"
Returns a copy of the string with all characters uppercase
print upper("HeLLo WorLD!"); // Prints "HELLO WORLD!"
Returns a copy of str in which all (or up to max) occurrences of the pattern are replaced with the given replacement.
The replacement can be one of several types, each used differently to determine the actual string:
string: The pattern is replaced with the string directly
table: The string that matched the pattern is looked up in the table as a key, and the value (string) is what replaces it, if it exists.
An optional final argument can be provided which specifies the maximum number of substitutions to make (for example, stop after 2 replacements)
print gsub("{s} is sus", "{s}", Plr.Name);
// Will print "Player is sus"
Returns the same string from the first argument, repeated by the second argument repeats
.
print strrep("hi!", 5); // "hi!" is the string, 5 is the amount of repeats.
// Will print "hi!hi!hi!hi!hi!"
Returns a reversed copy of the string
print strreverse("This text is not reversed!");
// Will print "!desrever ton si txet sihT"
The Hook Functions are based on the lox language from the book Crafting Interpreters written by Robert Nystrom. Most code examples listed here are either slightly modified or direct copies from the book.
https://craftinginterpreters.com/