aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJMM889901 <41163714+JMM889901@users.noreply.github.com>2022-01-27 13:21:56 +0000
committerGitHub <noreply@github.com>2022-01-27 14:21:56 +0100
commit8ebc0a67c03886fe09c771af432683500ecabf83 (patch)
tree985b2cd15796b6a4d5142dc7653b4206fe907cb1
parent7f08b061845ca4f926b939acad6bd2dea8a7dce3 (diff)
downloadNorthstarWiki-8ebc0a67c03886fe09c771af432683500ecabf83.tar.gz
NorthstarWiki-8ebc0a67c03886fe09c771af432683500ecabf83.zip
Began adding entries for squirrel GNUT scripting (#27)
* bruh * Update what-is-squirrel.md * Create Handling-threads-and-waits.md * Update Handling-threads-and-waits.md * Update What-are-callbacks.md * i got locked out while making this * Update what-is-squirrel.md * confusion is bad * funne colors * bruh * Language moment * Update the-mod-file.md * Json moment * Update The-JSON.md * Update The-JSON.md * Update The-JSON.md * Update The-language-file.md * Update The-language-file.md * Update the-mod-file.md * Update The-language-file.md * Create The-mod-init.md * got distracted, will finish later * pain * Update The-mod-init.md * fixed typo * Rename What-are-callbacks.md to what-are-callbacks.md * Rename Loops-Functions-and-if.md to loops-functions-and-if.md * Rename docs/modding/squirrel/Setting mods/the-mod-file.md to docs/modding/squirrel/setting-mods/the-mod-file.md * Rename docs/modding/squirrel/Setting mods/The-language-file.md to docs/modding/squirrel/setting mods/the-language-file.md * Rename docs/modding/squirrel/Gamemode mods/The-mod-init.md to docs/modding/squirrel/gamemode mods/the-mod-init.md * Rename Handling-threads-and-waits.md to handling-threads-and-waits.md * Rename docs/modding/squirrel/Setting mods/The-JSON.md to docs/modding/squirrel/setting mods/the-json.md * Rename Respawns-Functions.md to respawns-functions.md * Rename docs/modding/squirrel/gamemode mods/the-mod-init.md to docs/modding/squirrel/gamemode-mods/the-mod-init.md * Rename docs/modding/squirrel/setting mods/the-json.md to docs/modding/squirrel/setting-mods/the-json.md * Rename docs/modding/squirrel/setting mods/the-language-file.md to docs/modding/squirrel/setting-mods/the-language-file.md * tables do kinda be cool tho * var is better now * bruh
-rw-r--r--docs/modding/squirrel/gamemode-mods/the-mod-init.md136
-rw-r--r--docs/modding/squirrel/handling-threads-and-waits.md65
-rw-r--r--docs/modding/squirrel/loops-functions-and-if.md67
-rw-r--r--docs/modding/squirrel/respawns-functions.md41
-rw-r--r--docs/modding/squirrel/setting-mods/the-json.md38
-rw-r--r--docs/modding/squirrel/setting-mods/the-language-file.md17
-rw-r--r--docs/modding/squirrel/setting-mods/the-mod-file.md96
-rw-r--r--docs/modding/squirrel/tables-and-arrays.md67
-rw-r--r--docs/modding/squirrel/what-are-callbacks.md85
-rw-r--r--docs/modding/squirrel/what-is-squirrel.md56
10 files changed, 668 insertions, 0 deletions
diff --git a/docs/modding/squirrel/gamemode-mods/the-mod-init.md b/docs/modding/squirrel/gamemode-mods/the-mod-init.md
new file mode 100644
index 0000000..2661429
--- /dev/null
+++ b/docs/modding/squirrel/gamemode-mods/the-mod-init.md
@@ -0,0 +1,136 @@
+Creating Gamemodes
+==================
+In this section we will be creating our custom gamemode. this is more complicated than creating setting mods however also allows for more freedom at the cost of being required clientside as well
+
+the gamemode itself
+--------------
+We are going to make a simplified version of the "infection" gamemode.
+
+Lets break it down into steps before we make the gamemode itself
+
+1. Set the gamerules such as player count, team layout and score system
+2. force all players on to 1 team at the start of the game
+3. randomly select 1 player as being the zombie
+ - equip this player with the correct weapons
+ - modify their health
+ - provide them a speedboost
+4. have players become zombies on death
+5. have players joining mid way become zombies
+6. end the game when the last player dies.
+
+Now lets breakdown the callbacks we will need
+
+for steps 2 and 5 we will need `AddCallback_OnClientConnected( PlayerJoined )` to trigger on join
+
+for step 3 we will need to `AddCallback_GameStateEnter( eGameState.Playing, StartGame )`
+
+for step 4 we need `AddCallback_OnPlayerRespawned( RespawnInfected )`
+
+and finally to decide the winner we need a new function we havent seen yet. `SetTimeoutWinnerDecisionFunc( DecideWinners )`
+
+this function is used to decide the winner when the game runs out of time by calling a function.
+
+now that we know our steps its time to start our initialisation function
+
+Initialisation function
+--------------------
+first, lets declare our game settings
+```cpp
+global function SimpleInfection_init
+void function SimpleInfection_init(){
+ SetSpawnpoint GamemodeOverrde( FFA )// This line makes the player spawn locations like those from ffa
+ SetLoadoutGracePeriodEnabled( false )// we dont want the zombies to be able to change loadouts and grab their guns, so lets disable that
+ SetWeaponDropsEnabled(false )// we dont want zombies grabbing the weapons for dead survivors, so lets disable that.
+ Riff_ForceTitanAvailability( eTitanAvailability.Never )// we dont want zombies to have titans either, so lets disable that
+ Riff_ForceBoostAvailability( eBoostAvailability.Disabled )// we also dont want the zombies grabbing smart pistols and turrets, so lets disable that
+ ClassMP_ForceDisableEpilogue( true )// As the goal is surviving till the timer runs out, we dont need the evac dropship
+```
+Next lets setup our callbacks:
+```cpp
+ AddCallback_OnClientConnected( PlayerJoined )
+ AddCallback_GameStateEnter( eGameState.Playing, StartGame )
+ AddCallback_OnPlayerRespawned( RespawnInfected )
+ SetTimeoutWinnerDecisionFunc( DecideWinners )
+}
+```
+great, now we have our gamemodes initialisation function we need a way for our callbacks to know some things, such as whether the game has started or not, you will see why later
+```cpp
+struct {
+ bool HasStarted = false
+} file
+```
+Structs like this allow us to store Values that can be accessed elsewhere in the script, without having to pass them as arguments in all our functions. we place them in a struct instead of just defining them as a global variable cannot
+be modified by a function in squirrel, wheras a struct like this one can.
+
+to access a variable in a struct you must format it using the name of the stuct followed by the variable itself, in this case `file.HasStarted`
+
+Main functions
+---------
+Now it time to start writing our callbacks
+```cpp
+void function PlayerJoined(entity player){
+ if (file.HasStarted){
+ InfectPlayer( player, player)
+ RespawnInfected( player )
+ }
+ else{
+ SetTeam( player, 0)
+ }
+}
+```
+This manages what happens when a player joins, but it calls a function we dont have yet `InfectPlayer` so lets define it now
+```cpp
+void function InfectPlayer(entity player, entity attacker){
+ SetTeam( player, 1)
+ if ((GetPlayerArrayOfteam(0).len()) == 0){
+ SetRespawnsEnabled(false)
+ SetKillcamsEnabled(false)
+ SetWinner( 1 )
+ }
+}
+```
+This function simply changes the players team, then checks if there are any survivors left, and if not sets the zombies as the winners.
+
+Now for the script that chooses the first zombie, in order to allow more time for players to join lets put a delay on it using a `thread`
+```cpp
+void function StartGame(){
+ firstinfected = GetPlayerArray()[RandomInt(GetPlayerArray().len())]
+ InfectPlayer( firstinfected, firstinfected)
+ file.HasStarted = true
+}
+```
+This function changes the file.HasStarted value to true and randomly selects a player from the player array as a target for the infectplayer function.
+
+Next lets create the function that provides the zombies the correct equipment
+```cpp
+void function RespawnInfected( entity player ){
+ if (player.GetTeam() != 1){//this makes sure players dont accidentally get given zombie weapons when first spawning as a survivor
+ return
+ }
+ //lets give them stim, followed by increased air accel
+ StimPlayer( player, 9999)
+ player.kv.airAcceleration = 2000
+ //lets give them less health than normal
+ payer.SetMaxHealth(20)
+ //lets set their loadout
+ foreach ( entity weapon in player.GetMainWeapons() )
+ player.TakeWeaponNow( weapon.GetWeaponClassName() )
+
+ foreach ( entity weapon in player.GetOffhandWeapons() )
+ player.TakeWeaponNow( weapon.GetWeaponClassName() )
+
+ player.GiveOffhandWeapon( "melee_pilot_emptyhanded", OFFHAND_MELEE )
+ //unfortunately the game requires that you have a weapon of some kind in order to use secondaries, so lets give zombies an MGL
+ player.GiveWeapon( "mp_weapon_mgl" )
+}
+```
+Finally lets define what occurs when the match ends
+```cpp
+void function DecideWinners(){
+ SetRespawnsEnabled( false )
+ SetKillcamsEnabled( false )
+ return 0
+}
+```
+Now we can save this file as _gamemode_simpleinf.gnut and place it in
+`"ourmodsname"/mod/scripts/vscripts/gamemodes`
diff --git a/docs/modding/squirrel/handling-threads-and-waits.md b/docs/modding/squirrel/handling-threads-and-waits.md
new file mode 100644
index 0000000..2086dbd
--- /dev/null
+++ b/docs/modding/squirrel/handling-threads-and-waits.md
@@ -0,0 +1,65 @@
+Timers and infinite statements
+==========================
+When using timers or infinite statements such as `while(true)` or `wait` it is important to use `thread` before the function in order to prevent crashes or freezes.
+
+What is `thread`?
+-----------
+The `thread` term is used to tell squirrel to run the following function **separately** from the rest of the game, while in a simple scripts code is run sequentially(line 1,2,3 etc)
+if a line of code would last forever or need to function in parallel to normal gameplay, such as a `wait` command, it is important to use `thread` or the game will get stuck processing that line indefinitely
+and will not move to the next lines, causing crashes or freezes.
+
+How do i use `thread`?
+-------------
+Using thread is fairly simple, if we have a function called `delayannouncement` that chooses one player as "it" 10 seconds after spawning we cannot use this function on its own, instead calling it with a thread by simply calling
+
+`thread delayannouncement()`
+
+The same applies to a `while(true)` function, for example `almostover` a function that checks every 5 seconds to see if the game has 2 or less minutes left and announces it if so.
+
+ `thread almostover()`
+
+ Example Script
+ -----------
+ lets try implement both of our scripts from the previous 2 sections, as well as a callback to trigger the script.
+
+ First, lets add our callback to the gamemodes core function.
+
+ ```cpp
+ global function GamemodeTag_Init
+
+
+ void function GamemodeTag_Init(){
+ AddCallback_GameStateEnter( eGameState.Playing, MatchStart )
+ }
+ ```
+Then lets define the function matchstart and have it simply thread our two important functions.
+ ```cpp
+ void Matchstart{
+ thread delayannouncement()
+ thread almostover()
+ }
+ ```
+This script waits 10 seconds, picks a player and announces that player as "it" however being `it` currently does nothing, we will define that later.
+ ```cpp
+ void delayannouncement(){
+ wait 10.0
+ string chosenplayer = GetPlayerArray()[RandomInt(GetPlayerArray().len())]
+ string message = chosenplayer + " is it!"
+ foreach ( entity player in GetPlayerArray() )
+ SendHudMessage( player, message, -1, 0.4, 255, 0, 0, 0, 0, 3, 0.15 )
+}
+```
+This function will now repeat endlessly, waiting 5 seconds before each repeat. make sure to add a `return` or `break` statement to prevent the message looping every 5 seconds after, unless you want that
+```cpp
+ void almostover(){
+ while(true){
+ if(GameTime_TimeLeftSeconds() < 120){
+ foreach ( entity player in GetPlayerArray() )
+ SendHudMessage( player, "Two minutes left!", -1, 0.4, 255, 0, 0, 0, 0, 3, 0.15 )
+ break
+ }
+ wait 5.0
+ }
+ }
+ ```
+You have now created and threaded both functions.
diff --git a/docs/modding/squirrel/loops-functions-and-if.md b/docs/modding/squirrel/loops-functions-and-if.md
new file mode 100644
index 0000000..3a2b8ef
--- /dev/null
+++ b/docs/modding/squirrel/loops-functions-and-if.md
@@ -0,0 +1,67 @@
+Loops, Functions and if statements
+===========================
+
+The vast majority of GNUT modding within northstar will be done through functions, so understanding the formatting of functions can be somewhat important
+
+Declaring Functions
+--------------------
+Functions in squirrel are first defined by stating both the **output** followed by the keyword **function**, for example if you wanted to define a function that returns TRUE or FALSE you would:
+
+```cpp
+bool function ReturnTrueOrFalse()
+```
+
+But what if I want my function not to give stuff, but to DO stuff? for that you can define your function as `void`, this indicated that your function does not return anything. for example:
+
+```cpp
+void function ThisDoesStuff()
+```
+
+If statements
+---------------
+If statements use a similar style to most programming languages and will execute their asigned code if the test returns the boolean value true, it is worth remembering that unlike some languages the interger 1 is NOT considered equal to the boolean true, true is also always expressed in lowercase when used by a bool function. if i wanted to have something occur if, and only if, our previous `ReturnTrueOrFalse` function returned true, then you can use:
+
+```cpp
+if(ReturnTrueOrFalse())
+```
+
+If statements are also functions however, and can be used to determine true or false on their own when provided the == (equal to?) != (not equal to) < (less than) or >(greater than) symbols, if I wanted to simulte rolling a dice and only execute code on a 5 then i could instead:
+
+```cpp
+if(RandomInt(5)+1 == 5)
+```
+
+
+Loops
+------
+Loops fall into a few categories but for our purposes we will be only using `foreach` and `while`. `foreach` loops are given a data set, such as a list, and will repeat their asigned script for each entry on that list.
+```cpp
+array<interger> someinformation = [1,2,3,4,5,6]
+foreach( interger information in someinformation)
+```
+while a `foreach` loop will occur only as many times as the length of the list. a `while` loop functions more like an `if` statement, repeating itself endlessly until the test is no longer true
+```cpp
+while(ReturnTrueOrFalse)
+```
+This script will repeat endlessly until `ReturnTrueOrFalse` returns false
+
+Formatting of actions
+-------------------
+So great, we can loop and check things, but what can we do with this information? Squirrel uses {} to denote the contense of a series of actions caused by such a statement, however single-line scripts can be used without these, and will just be assumed.
+
+For example, lets make our ReturnTrueOrFalse function, that randomly picks either true or false, first:
+```cpp
+bool function ReturnTrueOrFalse()
+ return(RandomInt(1) == 1)
+```
+As this is a 1 line function it can be executed without needing any {}, but for a longer function we might need one, now lets make a more complicated function that will use the previous script to determine true or false, then each time it returns true it will print each number in the `someinformation` array
+```cpp
+array<interger> someinformation = [1,2,3,4,5,6]
+void ThisDoesStuff(){
+ while(ReturnTrueOrFalse()){
+ foreach( interger information in someinformation){
+ print(information)
+ }
+ }
+}
+```
diff --git a/docs/modding/squirrel/respawns-functions.md b/docs/modding/squirrel/respawns-functions.md
new file mode 100644
index 0000000..0a40a25
--- /dev/null
+++ b/docs/modding/squirrel/respawns-functions.md
@@ -0,0 +1,41 @@
+Useful functions and variables from respawn
+=========================
+Throughout this guide many functions and values made by respawn will be referenced in examples, in the interest of not confusing people those functions, and other frequently used ones, will be listed and explained here
+for a full list (although without explaination) go here https://github.com/ScureX/Titanfall2-ModdingDocumentation/blob/main/AllMethodsClean.md
+
+GetplayerArray()
+----------------
+Returns and array of entities representing each player, not that it does not just return return the playername but the actual entities, as such all values associated with players can be called like his
+
+*array*.len()
+-----------------
+Returns the number of objects in an array, thats about it.
+
+GameTime_TimeLeftSeconds()
+-----------------
+returns the remaining game time
+
+weapon.GetWeaponClassName
+------------
+returns the name of a weapon entity
+
+player.functions
+============
+This section contains many functiosn that can be applied to the player entity
+
+player.GetMainWeapons()
+----------------
+returns a list of all weapons equipped by that player. this is a list of entities
+
+player.GetOffHandWeapons()
+------------
+Returns a list of all offhand weapons (grenades, boosts, abilities). this is a list of entities
+
+player.TakeWeaponNow( weaponname )
+--------------
+removes weapon of that name, best used with a foreach using the previous functions
+
+player.GiveWeapon( Weaponname, mods)
+-----------------
+gives the player a weapon, the mods field must be empty or a list of strings ["mod","mod2"]
+
diff --git a/docs/modding/squirrel/setting-mods/the-json.md b/docs/modding/squirrel/setting-mods/the-json.md
new file mode 100644
index 0000000..db80a55
--- /dev/null
+++ b/docs/modding/squirrel/setting-mods/the-json.md
@@ -0,0 +1,38 @@
+The mod.json
+============
+
+The mod.json is responsible for governing when, and where your mod is loaded, and follows a layout that is fairly complicated at first glance, but ultimately simple
+
+```json
+{
+ "Name" : "SimpleRandomiser",
+ "Description" : "SimpleRandomiser",
+ "Version": "0.1.0",
+ "LoadPriority": 1,
+```
+The script above defines the pubic and listed details of the mod
+```json
+ "Scripts": [
+ {
+ "Path": "sh_SimpleRandomiser.gnut",
+ "RunOn": "MP",
+ "ClientCallback": {
+ "After": "simplerandomiser_init"
+ },
+
+ "ServerCallback": {
+ "After": "simplerandomiser_init"
+ }
+ }
+ ],
+```
+The scirpt above defines both what functions to run, when to run them and WHERE to run them, in this case it runs your simplerandomiser_init, when on multiplayer and for both the server and the client
+```json
+ "Localisation": [
+ "resource/simplerandomiser_localisation_%language%.txt"
+ ]
+}
+```
+this defines the path to the language file
+
+name this file mod.json, and it should go in the mods root folder
diff --git a/docs/modding/squirrel/setting-mods/the-language-file.md b/docs/modding/squirrel/setting-mods/the-language-file.md
new file mode 100644
index 0000000..89adea8
--- /dev/null
+++ b/docs/modding/squirrel/setting-mods/the-language-file.md
@@ -0,0 +1,17 @@
+Language file
+=======
+This follows a fairly simple template, the only thing of note is that you often get strange behaviour using `utf-8` when saving the file instead of using `utf-16 le`
+
+```
+"lang"
+{
+ "Language" "english"
+ "Tokens"
+ {
+ "MODE_SETTING_CATEGORY_SIMPLERANDOMISER" "Simple Randomiser"
+ "SIMPLERANDOMISER" "Randomise"
+ }
+}
+```
+
+Name this file simplerandomiser_localisation_english.txt and place it in the `yourmodsname/mod/resources/` folder
diff --git a/docs/modding/squirrel/setting-mods/the-mod-file.md b/docs/modding/squirrel/setting-mods/the-mod-file.md
new file mode 100644
index 0000000..069e3e2
--- /dev/null
+++ b/docs/modding/squirrel/setting-mods/the-mod-file.md
@@ -0,0 +1,96 @@
+Mod time
+========
+lets actually get started then on making a setting mod, this will involve the making of 3 things for a simple one. a mod.json, a language file and the mod itself
+
+lets get started with the mod itself
+
+The mod
+=======
+to begin with we need to answer the simple question of "what are we making" for our example lets make a simple randomiser than randomises your weapon on each spawn.
+
+Because this is a setting mod it will only need to be installed on the serverside but it also wont appear in the browser unless the host puts it in the name.
+
+so lets get started with our **initial function**
+
+The initial function
+---------
+The initial function is the function that is called on server startup and contains 2 important things.
+the **callbacks** and the **setting buttons** to add the settings to the private match settings we need to use a new function:
+
+`AddPrivateMatchModeSettingEnum("string", "string", ["#SETTING_ENABLED", "#SETTING_ENABLED"], "0")`
+
+this might look complicated, but really its just (Category, settingname, [setting options], default value) however we use terms like "#MODE_SETTING_CATEGORY_RANDOMISER" in place of the category name so that we can create language files for different languages.
+(we will make that later)
+```cpp
+void function simplerandomiser_init(){
+ AddPrivateMatchModeSettingEnum("#MODE_SETTING_CATEGORY_SIMPLERANDOMISER", "SimpleRandomiser", ["#SETTING_ENABLED", "#SETTING_ENABLED"], "0")
+
+ #if SERVER
+ AddCallback_OnPlayerRespawned(GiveRandomGun)
+ #endif
+ }
+ ```
+As you may have noticed, checking if it is a server is a special case, so we use #if SERVER and #endif instead of the usual if(thing){stuff}
+
+Now that our initial function is created we now have the game triggering `GiveRandomGun` on spawn, but we dont have any such function, so lets make one. but before we can do that, we need to know what weapons we can equip.
+for this we define an array
+
+```cpp
+array<string> pilotWeapons = [
+ "mp_weapon_alternator_smg",
+ "mp_weapon_autopistol",
+ "mp_weapon_car",
+ "mp_weapon_dmr"]
+```
+here we have defined an array with only 4 weapons in it, you can make this list as long or as short as you like but remember to seperate all but the last item with a ,
+
+Now lets make a function to check if you enabled the setting
+```cpp
+bool
+Next lets make the randomise function:
+ bool function SimpleRandomiserEnabled()
+ return GetCurrentPlaylistVarInt("SimpleRandomiser", 0) == 1
+```
+
+Randomise function
+----------------
+As we already know its going to call GiveRandomGun on respawn, lets define that now.
+
+First we strip any existing weapons:
+```cpp
+void function GiveRandomGun(entity player){
+ foreach ( entity weapon in player.GetMainWeapons() )
+ player.TakeWeaponNow( weapon.GetWeaponClassName() )
+```
+this iterates through each weapon and removes them individually.
+
+Then lets give them a new, random weapon by selecting a random item from our previous array:
+```cpp
+ player.GiveWeapon(pilotweapons[RandomInt(pilotweapons.len())])
+```
+And done, surprisingly short script huh?
+```cpp
+void function simplerandomiser_init(){
+ AddPrivateMatchModeSettingEnum("#MODE_SETTING_CATEGORY_SIMPLERANDOMISER", "SimpleRandomiser", ["#SETTING_ENABLED", "#SETTING_ENABLED"], "0")
+
+ #if SERVER
+ AddCallback_OnPlayerRespawned(GiveRandomGun)
+ #endif
+ }
+
+array<string> pilotWeapons = [
+ "mp_weapon_alternator_smg",
+ "mp_weapon_autopistol",
+ "mp_weapon_car",
+ "mp_weapon_dmr"]
+
+void function GiveRandomGun(entity player){
+ foreach ( entity weapon in player.GetMainWeapons() )
+ player.TakeWeaponNow( weapon.GetWeaponClassName() )
+ player.GiveWeapon(pilotweapons[RandomInt(pilotweapons.len())])
+}
+```
+
+Alas **we arent done yet** We still need the **mod.json** and the **language file**
+
+Name this sh_SimpleRandomiser.gnut and place it in the `yourmodsname/mod/scripts/vscripts/` folder
diff --git a/docs/modding/squirrel/tables-and-arrays.md b/docs/modding/squirrel/tables-and-arrays.md
new file mode 100644
index 0000000..317a5d9
--- /dev/null
+++ b/docs/modding/squirrel/tables-and-arrays.md
@@ -0,0 +1,67 @@
+Tables, Arrays and storing values.
+=======================
+
+Within squirrel there are many ways to store information, but when storing an unspecified ammount of information, or storing information on a player-by-player basis, you need to use arrays or tables.
+
+Arrays
+------
+
+Arrays can store large sets of data and are indexed using numbers, starting from 0, and are declared using `array<type> arrayname` the <type> identifier can be ignored but will result in the array being of the type `var`.
+
+```cpp
+array<int> numbers = [1,2,3,4,5,6,7,8,9,10]
+
+print(numbers[0])
+>>1
+print(numbers[5])
+>>6
+```
+
+adding and removing values from arrays can be done using `.append(value)` and `.remove(index)`.
+
+additionally the index of values can be found using the `.find` function and the length by using the `.len()` function
+
+```cpp
+array<int> numbers = [1,2,3,4,5,6,7,8,9,10]
+
+print(numbers.find(3))
+>>2
+print(numbers[5])
+>>6
+numbers.remove(5)
+print(numbers[5])
+>>7
+print(numbers.len())
+>>9
+array<int> empty = []
+empty.append(5)
+print(empty[0])
+>>5
+```
+
+Tables
+---------
+Tables are similar to arrays but with one primary difference, rather than use a numerical index system tables allow you do define your own indexes, similar to pythons `dict` type.
+
+Creation of a table is done in a similar way to arrays, however may have 2 types declared for the type of the index and the type of the content, much like arrays this will default to `var` if ignored
+```cpp
+table<string, int> numberofletters = {"hello": 5}
+```
+unlike arrays however adding values to tables cannot be done using `.append` or similar means, as the index must also be declared, adding to tables is done using the `<-` operator like so.
+
+```cpp
+table<entity, int> playerkills = {}
+foreach(entity player in GetPlayerArray())
+ playerkills[player] <- 5
+```
+
+2D arrays and Tables of Arrays
+---------------
+Another attribute of tables and arrays is that they can store any value type, including tables and arrays themselves. this can be used to store an array within a table, useful if you want to store multiple values related to each index in a single variable
+
+to create a 2d array you simply define the data type as beign an array of arrays like so.
+```cpp
+array<array<int>> 2darray = [[1,2,3],[4,5,6],[7,8,9]]
+print(2darray[1][1])
+>>5
+```
diff --git a/docs/modding/squirrel/what-are-callbacks.md b/docs/modding/squirrel/what-are-callbacks.md
new file mode 100644
index 0000000..e5338fb
--- /dev/null
+++ b/docs/modding/squirrel/what-are-callbacks.md
@@ -0,0 +1,85 @@
+Callbacks in squirrel
+======================
+
+Callbacks within squirrel trigger functions when certain events occur and are defined serverside.
+
+They will also often pass arguments to those functions based on the callbacks used
+
+A few examples
+-----------
+
+```AddCallback_OnPlayerRespawned(OnRespawn)```
+
+This script will trigger the function "OnRespawn" when any player respawns, this function can be defined later in the mods file and this callback will pass one argument, the player entity that respawned
+
+
+```AddCallback_OnPlayerKilled(AddPoints)```
+
+This callback triggers the function "AddPoints" when a player is killed. this function passes 3 arguments: an entity (the attacking player), an entity (the killed player), and the damage informtion
+
+```AddCallback_OnClientConnected(Connected)```
+
+This callback triggers the function "Connected" whenever a player joins and passes 1 argument, the player entity.
+
+List of callbacks
+----------
+This is an **incomplete** list of callbacks, a better list can be found in the list of all functions:
+https://github.com/ScureX/Titanfall2-ModdingDocumentation/blob/main/AllMethodsClean.md
+
+AddCallback_EntitiesDidLoad()
+
+AddCallback_GameStateEnter(gamestate, function to trigger)
+
+AddCallback_KillReplayEnded()
+
+AddCallback_KillReplayStarted()
+
+AddCallback_LocalClientPlayerSpawned()
+
+AddCallback_LocalViewPlayerSpawned()
+
+AddCallback_MinimapEntSpawned()
+
+AddCallback_OnClientConnected()
+
+AddCallback_OnClientScriptInit()
+
+AddCallback_OnNPCKilled()
+
+AddCallback_OnPetTitanChanged()
+
+AddCallback_OnPetTitanModeChanged()
+
+AddCallback_OnPilotBecomesTitan()
+
+AddCallback_OnPlayerDisconnected()
+
+AddCallback_OnPlayerGetsNewPilotLoadout()
+
+AddCallback_OnPlayerKilled()
+
+AddCallback_OnPlayerLifeStateChanged()
+
+AddCallback_OnPlayerRespawned()
+
+AddCallback_OnSatchelPlanted()
+
+AddCallback_OnSelectedWeaponChanged()
+
+AddCallback_OnTimeShiftAbilityUsed()
+
+AddCallback_OnTimeShiftTitanAbilityUsed()
+
+AddCallback_OnTitanBecomesPilot()
+
+AddCallback_OnUseEntity()
+
+AddCallback_PlayerClassChanged()
+
+AddCallback_ScriptTriggerEnter()
+
+AddCallback_ScriptTriggerLeave()
+
+AddCallback_UseEntGainFocus()
+
+AddCallback_UseEntLoseFocus()
diff --git a/docs/modding/squirrel/what-is-squirrel.md b/docs/modding/squirrel/what-is-squirrel.md
index e69de29..9c86bd8 100644
--- a/docs/modding/squirrel/what-is-squirrel.md
+++ b/docs/modding/squirrel/what-is-squirrel.md
@@ -0,0 +1,56 @@
+What is Squirrel
+==========
+Squirrel is a programming language used in titanfall 2 and northstar mods, it is worth noting that the version of squirrel used by titanfall appears to be a modified version of the langauge
+
+File format
+----------
+
+All files using squirrel are saved as .nut or .gnut
+
+when creating mods your mod will typically be a series of functions and callbacks
+
+Squirrel as a typed language
+========
+All variables and functions in squirrel must have a type defined on declaration
+
+```cpp
+function dosomething()
+```
+
+is not acceptable and should instead be
+
+```cpp
+void function dosomething()
+```
+Similarly when declaring a variable
+```cpp
+funnynumber = 69
+```
+will not work, instead use:
+```cpp
+int funnynumber = 69
+```
+
+
+Variable types
+-------------
+
+`void`: can be used to define functions that do not return a value, but still do things. most of your functions will be void
+
+```interger```: a whole number
+
+```float```: a none-whole number.
+
+```string```: text
+
+```entity```: an entity and all its associated information
+
+```bool```: true or false (Squirrel does not treat 1 as true or 0 as false)
+
+```array```: an ordered list of items indexed from 0, increasing with the number of items such as: 0:"hello",1:1000,2:entity player ...
+
+```table```: a list of items with indexes defined on object entry such as: "word":"hello", "kilo":1000", "pilot":entity player ...
+
+```struct```: a series of attributes assigned to a structure and accessed through with structname.variablename
+
+```var```: Var typically refers to variables that lack any stated type, this will cause issues with many functions unless you use the `untyped` identifier at the start of your file, or if you use `expect type(variable)` when passing the variable to that function