Introduction & Making Your First Script - 505e06b2/MW2-GSC-Documentation GitHub Wiki
Notes
- The author typically uses UNIX-styled filepaths when specifying paths but inside GSC files (
#include
) you must specifically use Windows-style paths when referencing external scripts:#include ModName\file;
- Any references to the mod you will be creating will be called
ModName
and any maps referenced will be called eitherRust
or, for the game file,mp_rust
. Feel free to experiment with other maps you know / find the game file of and make sure to name your mod something descriptive but short
IW4x
For the examples used in this documentation, they should have been tested via IW4x, either natively on Windows, or on Linux via WINE. It will be essential to make sure the console is enabled - you can test this by loading the game, then pressing the key below Esc
(might be grave accent or tilde)
If the console is enabled then it can be used to reload the mod during development with \map mp_rust
. It can also be used to check the values of cvars
- To load the mod when booting the game, use the commandline parameter
+set fs_game mods/ModName
. - To start a match when booting the game, you can use the parameter
+map mp_rust
. - A shortcut to
iw4x.exe +set fs_game mods/ModName +map mp_rust
will load the mod, and will start a match on Rust, permitting the mod doesn't contain errors. If there is an error, and you are forced back to the main menu. From here you can use\map mp_rust
in the console to start a match quickly
Creating a mod
To add a new mod, place it in {IW4x Installation Folder}/mods/ModName
. Create the mods
folder if it doesn't exist and then the ModName
folder inside.
Getting a basic mod to load
If starting from scratch, create these folders from the mods folder: mods/ModName/maps/mp/gametypes/_playercards.gsc
Fill _playercards.gsc
with:
#include common_scripts\utility;
#include maps\mp\_utility;
//This function gets called by one loaded before it
//This is the convention IW have used and can be used as your point of injection - an init function in external scripts
init() {
level thread onPlayerConnect(); //this starts the thread, then continues
}
onPlayerConnect() {
while(true) {
level waittill("connected", player); //this halts the code until a player connects
player thread onPlayerSpawn(); //start a new thread, that can wait until a player spawns
//these next few lines are for making sure the connecting player's playercard is set
//this could be shortened to one line for each, but it can help others to read if you break it down
iconHandle = player maps\mp\gametypes\_persistence::statGet("cardIcon");
player SetCardIcon(iconHandle);
titleHandle = player maps\mp\gametypes\_persistence::statGet("cardTitle");
player SetCardTitle(titleHandle);
nameplateHandle = player maps\mp\gametypes\_persistence::statGet("cardNameplate");
player SetCardNameplate(nameplateHandle);
}
}
//self is "player", since it was given the context when started up
onPlayerSpawn() {
self endon("disconnect"); //forcefully stop this function if the player disconnects
while(true) {
self waittill("spawned_player"); //halt until the player has spawned
for(i = 10; i > 0; i--) {
wait 1; //wait for N seconds - 0.5 would be half a second
self iPrintLnBold(i); //put text in the center of the screen
}
wait 1;
self iPrintLnBold("^1DONE");
}
}
Why _playercards.gsc?
For a mod to load it must replace a file that already exists in the game. The specific use of _playercards.gsc
here is that the original source code is very short, so is rather easy to manage and maintain. The equivalent to this in CoD4 would be _persistence.gsc
Original _playercards.gsc
This is the clean source code that represents the original file - feel free to use this as a base
#include common_scripts\utility;
#include maps\mp\_utility;
init() {
level thread onPlayerConnect();
}
onPlayerConnect() {
while(true) {
level waittill("connected", player);
iconHandle = player maps\mp\gametypes\_persistence::statGet("cardIcon");
player SetCardIcon(iconHandle);
titleHandle = player maps\mp\gametypes\_persistence::statGet("cardTitle");
player SetCardTitle(titleHandle);
nameplateHandle = player maps\mp\gametypes\_persistence::statGet("cardNameplate");
player SetCardNameplate(nameplateHandle);
}
}
If you want to view the original scripts, there is an archive on Github. The most relevant files will be in the maps/mp
folder and below. If you do look into the other folders, there may be built-in functions that do not exist in Multiplayer as they were only intended to be used in Singleplayer and/or Spec-Ops