Repository navigation
Scripting
A guide to scripting within Classics Patch using its "Scripting Engine" plugin.
Scripts are much more efficient and versatile than the engine's shell language.
They can be used for implementing new mechanics (such as new gamemodes) without having to code your own plugins for the patch.
Right now, the only scripting language Classics Patch supports is Squirrel 3.2.
Important
Even though scripts may be used to implement custom gamemodes and other gameplay functionality for all clients on the server, the scripts are never sent and executed on the client's side, which makes them safe for any client playing on the server. All script logic is always executed on the side of the server, i.e. on the machine hosting the game. The only processing that happens on the client's side is processing of network packets that are sent by the server, which is how the game has always worked, even without Classics Patch. Likewise, any scripts that are running on the client's side will never affect the server that the client is playing on.
Caution
When writing custom gamemodes or other server-side functionality that requires sending large amounts of data in short periods of time (such as modifying values of tens or hundreds of entity properties per in-game tick), the server packet queue may be overflown and will gradually slow down the server and raise latency of every single client, including the server host on the same game/server instance!
Make sure to send as few packets as possible and only when absolutely necessary!
| Language | Syntax | Object-oriented | Dynamic types | Integer type | Float type | Boolean type | String type | Arrays | Type conversion | Global variables | Local variables | Control flow statements | Loop statements | Classes | Functions | Code nesting |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| SE1 shell | C-like | No | No | Signed 32 bits | Single precision | Same as integer | Yes | Limited | Explicit | Yes | No |
if, else, else if
|
N/A | N/A | Execution | Standard include "path" command; custom IncludeScript(<path>) function |
| Squirrel | C-like | Yes | Yes | Signed 64 bits | Single precision | Yes | Yes | Yes | Implicit, explicit | Yes | Yes |
if, else, else if, switch-case
|
while, do-while, for, foreach
|
Yes | Definition, execution, lambdas | Custom CompileScript(<path>) and IncludeScript(<path>) functions |
Squirrel is a scripting language with C-like syntax designed for games.
- Squirrel scripting language: http://squirrel-lang.org/
- Official documentation: http://squirrel-lang.org/squirreldoc/
- Valve Development Community documentation: https://developer.valvesoftware.com/wiki/Squirrel
To demonstrate how powerful custom scripts can be, examples of several custom script modules can be found here: https://github.com/SamClassicPatch/SuperProject/tree/main/Extensions/ScriptingEngine/ModuleExamples
Scripting Engine extension implements specific libraries to allow interactions with the game and the engine via scripts.
| Library | Squirrel table | Purpose |
|---|---|---|
| Core | Core |
Base classes and functions. |
| Entities | Entities |
Interactions with entities in the world. |
| File system | FileSystem |
Working with game files and binary/text data within them. |
| Input | Input |
Input polling from keyboard, mouse and joysticks. |
| Math | Math |
Classes and functions for working with 2D and 3D elements & geometry. |
| Messages | Message |
Message boxes and other information output. |
| Network | Network |
Interactions with the currently running game and the current server clients. |
| Shell | Shell |
Interactions with the engine shell. |
| Timer | Timer |
Reading current game/frame time. |
| World | World |
Interactions with the current world. |
You can automatically execute any common code inside any running script by creating .nut scripts inside the Scripts/Squirrel/Include/ directory.
Any script file in that folder will be implicitly included in the beginning of any Squirrel script (also when running them from the console or via a scr_ExecuteString() shell function) as if by calling IncludeScript().
You can create special script modules full of functions that will be executed upon specific events in the game.
Read about them on this dedicated page.
You can serialize custom data from scripts in order to save information between script uses. This can be facilitated by using the Core.LocalStorage class.
All custom data is saved as JSON configs inside the Data/ClassicsPatch/SquirrelLocalStorage/ directory within the game or the current mod (depending on the excluded directories for writing). For example, specifying the local storage "MyScriptData" will use the config at Data/ClassicsPatch/SquirrelLocalStorage/MyScriptData.json file path regardless of the running script.
Warning
All local storage configs are shared between any and all scripts. Make sure not to use generic local storage names or the names used by other scripts for serializing their data in order to avoid collision or potential loss of data from other scripts.
Designed and developed by Dreamy Cecil since 2022