Difference between revisions of "User:Ducks/A Simple First Mod"
(→See Also) |
|||
(38 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
== Introduction == | == Introduction == | ||
+ | ETQW allows for a wide range of modifications, simply through the editing of its Definition Files (.def) and Script Files (.script). These files determine the basic properties and behaviours of almost everything that happens in-game, and can be easily edited for the creation of ETQW mods. | ||
+ | |||
'''For this tutorial you must:''' | '''For this tutorial you must:''' | ||
* Have your SDK Launcher set up correctly | * Have your SDK Launcher set up correctly | ||
* Have a good text-editor, such as Notepad | * Have a good text-editor, such as Notepad | ||
+ | * Have some scripting/programming knowledge | ||
'''This tutorial covers:''' | '''This tutorial covers:''' | ||
* How to create your own mod | * How to create your own mod | ||
− | * How to modify ETQW's .def files to change | + | * How to modify ETQW's .def files to change rockets |
* How to modify ETQW's .script files to give infinite ammo | * How to modify ETQW's .script files to give infinite ammo | ||
* How to package up your mod for release | * How to package up your mod for release | ||
Line 23: | Line 26: | ||
== Definition files (.def) == | == Definition files (.def) == | ||
− | ETQW uses .def files to store information and settings for various items, weapons and objects. The SDK has a full collection of all these files in {{filename|\SDK 1.2 Beta\base\def\}}. For example, the definition file for the GDF Rocket Launcher is {{filename|\SDK 1.2 Beta\base\def\weapons\rocketlauncher.def}}. If you open this file in Notepad, you'll see a section about models, a section about animations, and then a section containing lots of different numbers. These settings can be used to change properties of the rocket launcher, | + | ETQW uses .def files to store information and settings for various items, weapons and objects. The SDK has a full collection of all these files in {{filename|\SDK 1.2 Beta\base\def\}}. For example, the definition file for the GDF Rocket Launcher is {{filename|\SDK 1.2 Beta\base\def\weapons\rocketlauncher.def}}. If you open this file in Notepad, you'll see a section about models, a section about animations, and then a section containing lots of different numbers. These settings can be used to change properties of the rocket launcher, rockets, and damage values. |
− | These files are typically split into many sections. In the case of the Rocket Launcher file, | + | These files are typically split into many sections. In the case of the Rocket Launcher file, there are '<tt>invItemDef</tt>' sections near the top that define models and animations for the player's inventory. Later in the file there are '<tt>entityDef</tt>' which contain entity definitions, and all the numbers and values that can be tweaked with. |
− | + | For example, under '<tt>entityDef projectile_law</tt>' are all the values for seeking rockets, such as the velocity it flies at ({{keyvalue|4000 0 0}}, which means 'forward at 4000 units a second'), how long its fuse is ({{keyvalue|3}}, which means 'explode after 3 seconds if it hasn't hit anything'), and gravity ({{keyvalue|0}}, which means 'unaffected by gravity'). | |
− | There's also '<tt>entityDef projectile_law_arcing</tt>', which are the values for the non-seeking rocket, which arcs through the air because it has a | + | There's also '<tt>entityDef projectile_law_arcing</tt>', which are the values for the non-seeking rocket, which arcs through the air because it has a {{keyname|gravity}} setting of {{keyvalue|120}}. |
− | What we're going to do is change the arcing rocket so it travels really slowly, lasts really long, and | + | What we're going to do is change the entity definition for the arcing rocket so it travels really slowly, lasts really long, and isn't affected by gravity (so it won't arc.) |
− | === Copying | + | === Copying === |
− | First, we need to know which file to | + | First, we need to know which file contains the entity data we want to change - in this case, it's {{filename|\SDK 1.2 Beta\base\def\weapons\rocketlauncher.def}}. However, we shouldn't modify this file, as it's the one from the SDK and is in the wrong place for our mod. Instead, it should be copied to the 'simplemod' folder. |
− | So copy {{filename|\SDK 1.2 Beta\base\def\weapons\rocketlauncher.def}} to {{filename|\simplemod\def\weapons\rocketlauncher.def}} | + | So copy {{filename|\SDK 1.2 Beta\base\def\weapons\rocketlauncher.def}} to {{filename|\simplemod\def\weapons\rocketlauncher.def}} (you'll need to create the 'def' and 'weapons' folders yourself.) |
− | This means that when simplemod is | + | This means that when simplemod is run, although ETQW will still load all its normal files, it will see that simplemod has its own {{filename|rocketlauncher.def}} and will use that one instead of the one that comes with the game. |
− | === Editing | + | === Editing === |
Now open {{filename|\simplemod\def\weapons\rocketlauncher.def}} in Notepad, and find the section for the entity 'projectile_law_arcing'. It'll look like this: | Now open {{filename|\simplemod\def\weapons\rocketlauncher.def}} in Notepad, and find the section for the entity 'projectile_law_arcing'. It'll look like this: | ||
entityDef projectile_law_arcing { | entityDef projectile_law_arcing { | ||
− | "inherit" | + | "inherit" "projectile_rocket_base" |
− | "dmg_damage" | + | "dmg_damage" "damage_law" |
− | "dmg_splash_damage" | + | "dmg_splash_damage" "damage_law_splash" |
− | "launchFromBarrel" | + | "launchFromBarrel" "1" |
− | "health" | + | "health" "0" |
− | "velocity" | + | "velocity" "2000 0 0" |
− | "face_velocity" | + | "face_velocity" "1" |
− | "gravity" | + | "gravity" "120" |
− | "fuse" | + | "fuse" "4" |
− | "snd_fly" | + | "snd_fly" "sounds/weapons/law/fly" |
− | "fx_trail" | + | "fx_trail" "effects/base/missile_trail" |
− | "fx_explode" | + | "fx_explode" "effects/impacts/rocket/explosion_default" |
− | "fx_explode_sand" | + | "fx_explode_sand" "effects/impacts/rocket/explosion_sand" |
− | "fx_explode_metal" | + | "fx_explode_metal" "effects/impacts/rocket/explosion_metal" |
− | "fx_explode_snow" | + | "fx_explode_snow" "effects/impacts/rocket/explosion_snow" |
− | "use_air_burst" | + | "use_air_burst" "1" |
− | "fx_airburst" | + | "fx_airburst" "effects/impacts/rocket/explosion_air" |
} | } | ||
We're going to change the rocket so it travels really slowly in a straight line. | We're going to change the rocket so it travels really slowly in a straight line. | ||
− | First to make it slower, change the | + | First to make it slower, change the {{keyname|velocity}} setting from {{keyvalue|2000 0 0}} to {{keyvalue|100 0 0}}, so it only travels 100 units a second. |
− | Next, change | + | Next, change {{keyname|gravity}} from {{keyvalue|120}} to {{keyvalue|0}}, so isn't pulled down by gravity while in the air. |
− | Lastly, change | + | Lastly, change {{keyname|fuse}} from {{keyvalue|4}} to {{keyvalue|30}}, so it'll last 30 seconds before it explodes (unless it hits something first) |
This is the result: | This is the result: | ||
entityDef projectile_law_arcing { | entityDef projectile_law_arcing { | ||
− | "inherit" | + | "inherit" "projectile_rocket_base" |
− | "dmg_damage" | + | "dmg_damage" "damage_law" |
− | "dmg_splash_damage" | + | "dmg_splash_damage" "damage_law_splash" |
− | "launchFromBarrel" | + | "launchFromBarrel" "1" |
− | "health" | + | "health" "0" |
− | '''"velocity" | + | '''"velocity" "100 0 0"''' |
− | "face_velocity" | + | "face_velocity" "1" |
− | '''"gravity" | + | '''"gravity" "0"''' |
− | '''"fuse" | + | '''"fuse" "30"''' |
− | "snd_fly" | + | "snd_fly" "sounds/weapons/law/fly" |
− | "fx_trail" | + | "fx_trail" "effects/base/missile_trail" |
− | "fx_explode" | + | "fx_explode" "effects/impacts/rocket/explosion_default" |
− | "fx_explode_sand" | + | "fx_explode_sand" "effects/impacts/rocket/explosion_sand" |
− | "fx_explode_metal" | + | "fx_explode_metal" "effects/impacts/rocket/explosion_metal" |
− | "fx_explode_snow" | + | "fx_explode_snow" "effects/impacts/rocket/explosion_snow" |
− | "use_air_burst" | + | "use_air_burst" "1" |
− | "fx_airburst" | + | "fx_airburst" "effects/impacts/rocket/explosion_air" |
} | } | ||
+ | |||
+ | === Testing === | ||
+ | [[Image:simplemod_slowrocket.jpg|400px|thumb|right|A slow rocket, courtesy of editing the rocketlauncher.def file]] | ||
+ | We can test this change by loading the mod via the SDK Launcher (ensuring 'simplemod' is selected) and then loading any map via {{consolecmd|devmap}}, for example {{consolecmd|devmap island}}. | ||
+ | |||
+ | Once the map is loaded, join the GDF team as a Soldier with the rocket launcher (as that's the only weapon changed by the above file.) If you now fire a non-seeking rocket, you should find it travels very slowly, in a straight line, and lasts 30 seconds before it explodes (unless it hits something first), allowing you to run around and inspect it while it's still in the air. | ||
+ | |||
+ | ''If you edit a .def file while the game is running, use {{consolecmd|reloadDecls}} to force the game to reload all definition files. This allows you to see what effect your changes had on the game, without needing to restart it.'' | ||
+ | |||
+ | ''Be aware that for edited declarations to work, you should ensure the following cvar is set {{consolecmd|com_useBinaryDecls 2}}, which forces to engine to load your .def files rather then the binary ones shipped with the game.'' | ||
+ | |||
+ | {{clear}} | ||
== Script Files (.script) == | == Script Files (.script) == | ||
− | + | Although definition files contain settings and values of entities, they can't change the ''behaviour'' of entities. For this, you need to edit script files; all weapons, vehicles, items and projectiles are defined with script files. Script files present a 'high-level' way to access the mechanics of the game, and can be modified while the game is running. | |
+ | |||
+ | ''Script files are not be be confused with game code, which is programmed in C++ and contains all the low-level game behaviour. Many mods can be created entirely through script files. Note however that script files may be converted to C++ and compiled into a DLL for performance, but is not covered in this tutorial.'' | ||
+ | |||
+ | ETQW's scripts can be found in {{filename|\SDK 1.2 Beta\base\script\}}, and since they are normal text documents, can be opened in Notepad or any other text editor. | ||
+ | |||
+ | The most important files here are {{filename|events.script}} (which defines game code methods that are callable from script files), and the {{filename|base.script}} files in each directory. | ||
+ | |||
+ | For this bit of scripting, we're going to change the weapon script so weapons don't use up any ammo when they're fired. | ||
+ | |||
+ | === Copying === | ||
+ | First, we need to know which file to modify - in this case, it's {{filename|\SDK 1.2 Beta\base\script\weapons\base.script}}, which contains the basic behaviours shared by all weapons used in the game. However, just like .def files, we shouldn't modify this file, as it's the one from the SDK. Instead, it should be copied to {{filename|simplemod\script\weapons\base.script}}, so it's specific to our mod. | ||
+ | |||
+ | === Examining === | ||
+ | A cursory glance at this script shows that there are two methods related to ammo use - '<tt>UseAmmo</tt>' and '<tt>UseAmmo_Stroyent</tt>' - which are both called with a <tt>modIndex</tt> parameter indicating what sort of ammo to be consumed. | ||
+ | |||
+ | void weapon_base::UseAmmo( float modIndex ) { | ||
+ | if ( sys.isClient() ) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | float amount = ammoRequired( modIndex ); | ||
+ | useAmmo( ammoType( modIndex ), amount ); | ||
+ | addToClip( modIndex, -amount ); | ||
+ | } | ||
+ | |||
+ | void weapon_base::UseAmmo_Stroyent( float modIndex ) { | ||
+ | if ( sys.isClient() ) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | float amount = ammoRequired( modIndex ); | ||
+ | useAmmo( ammoType( modIndex ), amount ); | ||
+ | } | ||
+ | |||
+ | Both these methods call a few functions defined by the (C++) game code, specifically '<tt>sys.isClient</tt>', '<tt>ammoRequired</tt>', '<tt>useAmmo</tt>' and '<tt>addToClip</tt>'. We know this because these functions aren't defined in this .script file, but are present in the {{filename|events.script}} file, defined as '<tt>scriptEvent</tt>' functions. | ||
+ | |||
+ | === Editing === | ||
+ | For infinite ammo, the .script simply needs to be edited so the '<tt>useAmmo</tt>' and '<tt>addToClip</tt>' functions never get called. This can be done a number of ways, but the simplest is for these two '<tt>UseAmmo</tt>' methods to simply do nothing: | ||
+ | |||
+ | void weapon_base::UseAmmo( float modIndex ) { | ||
+ | } | ||
+ | |||
+ | void weapon_base::UseAmmo_Stroyent( float modIndex ) { | ||
+ | } | ||
+ | |||
+ | ''This could be achieved in a large number of different ways, from simply commenting out the code using standard C/C++ comment syntax, or just adding a <tt>return</tt> at the top of the method.'' | ||
+ | |||
+ | === Testing === | ||
+ | To test the script we first need to make ETQW reload the script files. This is done with {{consolecmd|reloadScript}}, which usually takes a few seconds, and means we can continue editing .script files in the background without having to quit and reload the game each time. If there are any errors or problems with the script, the ETQW console will list these problems for debugging/fixing. | ||
+ | |||
+ | If the script is compiled successfully, a message such as '<tt>Compiled 'script/main.script': 13141.5 ms</tt>' will be displayed. | ||
+ | |||
+ | ''Note that for scripts to work, the following cvar must be set: {{consolecmd|g_useCompiledScript 1}}'' | ||
+ | |||
+ | === Compiling === | ||
+ | Thanks to ETQW's built-in interpreter, scripts can be changed and tested very rapidly. However, for the final release of a mod, is is much preferable to compile the scripts into a {{filename|compiledscriptx86.dll}}, which will run much faster. | ||
+ | |||
+ | Compiling scripts requires the additional setup of a compiler, and so is not covered in this tutorial. | ||
+ | |||
+ | * See [[Generating Compiled Scripts]] for further information. | ||
+ | |||
+ | == Packaging your mod == | ||
+ | Mods can be packaged in a number of ways, but the simplest is to simply send your mod folder (in this case 'simplemod') to other people who want to run your mod, so they have the same folders and files as you. | ||
+ | |||
+ | Alternatively, all the files inside 'simplemod' can be zipped up and renamed to a PK4 file (e.g. 'simplemod001.pk4'). This is neater and tidier. | ||
− | '' | + | '''TODO''' |
− | + | == See Also == | |
+ | * [[Packaging up a Map or Mod]] |
Latest revision as of 12:08, 18 December 2007
This is the barebones guide for creating a simple mod. It won't be a terrifically amazing mod, since it will just be ETQW with a few small changes, but it will demonstrate the basic principles.
Contents
Introduction
ETQW allows for a wide range of modifications, simply through the editing of its Definition Files (.def) and Script Files (.script). These files determine the basic properties and behaviours of almost everything that happens in-game, and can be easily edited for the creation of ETQW mods.
For this tutorial you must:
- Have your SDK Launcher set up correctly
- Have a good text-editor, such as Notepad
- Have some scripting/programming knowledge
This tutorial covers:
- How to create your own mod
- How to modify ETQW's .def files to change rockets
- How to modify ETQW's .script files to give infinite ammo
- How to package up your mod for release
This tutorial does not:
- Teach you how to program scripts or edit/compile the game code
Basic setup
First, we need to create the mod folder for all the files our mod will use. When you want to send your mod to someone else, all you'll need to send them is the folder, which they can then place in their ETQW directory.
The SDK Launcher includes a button to set this up for you - the 'Create...' button. Press this, and it will ask for a mod name (preferably no spaces, like 'simplemod') and a description. Our mod is going to be called 'simplemod', described as 'a simple mod'.
This will have created a directory in your ETQW directory called 'simplemod'.
Definition files (.def)
ETQW uses .def files to store information and settings for various items, weapons and objects. The SDK has a full collection of all these files in \SDK 1.2 Beta\base\def\. For example, the definition file for the GDF Rocket Launcher is \SDK 1.2 Beta\base\def\weapons\rocketlauncher.def. If you open this file in Notepad, you'll see a section about models, a section about animations, and then a section containing lots of different numbers. These settings can be used to change properties of the rocket launcher, rockets, and damage values.
These files are typically split into many sections. In the case of the Rocket Launcher file, there are 'invItemDef' sections near the top that define models and animations for the player's inventory. Later in the file there are 'entityDef' which contain entity definitions, and all the numbers and values that can be tweaked with.
For example, under 'entityDef projectile_law' are all the values for seeking rockets, such as the velocity it flies at (4000 0 0, which means 'forward at 4000 units a second'), how long its fuse is (3, which means 'explode after 3 seconds if it hasn't hit anything'), and gravity (0, which means 'unaffected by gravity').
There's also 'entityDef projectile_law_arcing', which are the values for the non-seeking rocket, which arcs through the air because it has a gravity setting of 120.
What we're going to do is change the entity definition for the arcing rocket so it travels really slowly, lasts really long, and isn't affected by gravity (so it won't arc.)
Copying
First, we need to know which file contains the entity data we want to change - in this case, it's \SDK 1.2 Beta\base\def\weapons\rocketlauncher.def. However, we shouldn't modify this file, as it's the one from the SDK and is in the wrong place for our mod. Instead, it should be copied to the 'simplemod' folder.
So copy \SDK 1.2 Beta\base\def\weapons\rocketlauncher.def to \simplemod\def\weapons\rocketlauncher.def (you'll need to create the 'def' and 'weapons' folders yourself.)
This means that when simplemod is run, although ETQW will still load all its normal files, it will see that simplemod has its own rocketlauncher.def and will use that one instead of the one that comes with the game.
Editing
Now open \simplemod\def\weapons\rocketlauncher.def in Notepad, and find the section for the entity 'projectile_law_arcing'. It'll look like this:
entityDef projectile_law_arcing { "inherit" "projectile_rocket_base" "dmg_damage" "damage_law" "dmg_splash_damage" "damage_law_splash" "launchFromBarrel" "1" "health" "0" "velocity" "2000 0 0" "face_velocity" "1" "gravity" "120" "fuse" "4" "snd_fly" "sounds/weapons/law/fly" "fx_trail" "effects/base/missile_trail" "fx_explode" "effects/impacts/rocket/explosion_default" "fx_explode_sand" "effects/impacts/rocket/explosion_sand" "fx_explode_metal" "effects/impacts/rocket/explosion_metal" "fx_explode_snow" "effects/impacts/rocket/explosion_snow" "use_air_burst" "1" "fx_airburst" "effects/impacts/rocket/explosion_air" }
We're going to change the rocket so it travels really slowly in a straight line.
First to make it slower, change the velocity setting from 2000 0 0 to 100 0 0, so it only travels 100 units a second.
Next, change gravity from 120 to 0, so isn't pulled down by gravity while in the air.
Lastly, change fuse from 4 to 30, so it'll last 30 seconds before it explodes (unless it hits something first)
This is the result:
entityDef projectile_law_arcing { "inherit" "projectile_rocket_base" "dmg_damage" "damage_law" "dmg_splash_damage" "damage_law_splash" "launchFromBarrel" "1" "health" "0" "velocity" "100 0 0" "face_velocity" "1" "gravity" "0" "fuse" "30" "snd_fly" "sounds/weapons/law/fly" "fx_trail" "effects/base/missile_trail" "fx_explode" "effects/impacts/rocket/explosion_default" "fx_explode_sand" "effects/impacts/rocket/explosion_sand" "fx_explode_metal" "effects/impacts/rocket/explosion_metal" "fx_explode_snow" "effects/impacts/rocket/explosion_snow" "use_air_burst" "1" "fx_airburst" "effects/impacts/rocket/explosion_air" }
Testing
We can test this change by loading the mod via the SDK Launcher (ensuring 'simplemod' is selected) and then loading any map via devmap, for example devmap island.
Once the map is loaded, join the GDF team as a Soldier with the rocket launcher (as that's the only weapon changed by the above file.) If you now fire a non-seeking rocket, you should find it travels very slowly, in a straight line, and lasts 30 seconds before it explodes (unless it hits something first), allowing you to run around and inspect it while it's still in the air.
If you edit a .def file while the game is running, use reloadDecls to force the game to reload all definition files. This allows you to see what effect your changes had on the game, without needing to restart it.
Be aware that for edited declarations to work, you should ensure the following cvar is set com_useBinaryDecls 2, which forces to engine to load your .def files rather then the binary ones shipped with the game.
Script Files (.script)
Although definition files contain settings and values of entities, they can't change the behaviour of entities. For this, you need to edit script files; all weapons, vehicles, items and projectiles are defined with script files. Script files present a 'high-level' way to access the mechanics of the game, and can be modified while the game is running.
Script files are not be be confused with game code, which is programmed in C++ and contains all the low-level game behaviour. Many mods can be created entirely through script files. Note however that script files may be converted to C++ and compiled into a DLL for performance, but is not covered in this tutorial.
ETQW's scripts can be found in \SDK 1.2 Beta\base\script\, and since they are normal text documents, can be opened in Notepad or any other text editor.
The most important files here are events.script (which defines game code methods that are callable from script files), and the base.script files in each directory.
For this bit of scripting, we're going to change the weapon script so weapons don't use up any ammo when they're fired.
Copying
First, we need to know which file to modify - in this case, it's \SDK 1.2 Beta\base\script\weapons\base.script, which contains the basic behaviours shared by all weapons used in the game. However, just like .def files, we shouldn't modify this file, as it's the one from the SDK. Instead, it should be copied to simplemod\script\weapons\base.script, so it's specific to our mod.
Examining
A cursory glance at this script shows that there are two methods related to ammo use - 'UseAmmo' and 'UseAmmo_Stroyent' - which are both called with a modIndex parameter indicating what sort of ammo to be consumed.
void weapon_base::UseAmmo( float modIndex ) { if ( sys.isClient() ) { return; } float amount = ammoRequired( modIndex ); useAmmo( ammoType( modIndex ), amount ); addToClip( modIndex, -amount ); } void weapon_base::UseAmmo_Stroyent( float modIndex ) { if ( sys.isClient() ) { return; } float amount = ammoRequired( modIndex ); useAmmo( ammoType( modIndex ), amount ); }
Both these methods call a few functions defined by the (C++) game code, specifically 'sys.isClient', 'ammoRequired', 'useAmmo' and 'addToClip'. We know this because these functions aren't defined in this .script file, but are present in the events.script file, defined as 'scriptEvent' functions.
Editing
For infinite ammo, the .script simply needs to be edited so the 'useAmmo' and 'addToClip' functions never get called. This can be done a number of ways, but the simplest is for these two 'UseAmmo' methods to simply do nothing:
void weapon_base::UseAmmo( float modIndex ) { } void weapon_base::UseAmmo_Stroyent( float modIndex ) { }
This could be achieved in a large number of different ways, from simply commenting out the code using standard C/C++ comment syntax, or just adding a return at the top of the method.
Testing
To test the script we first need to make ETQW reload the script files. This is done with reloadScript, which usually takes a few seconds, and means we can continue editing .script files in the background without having to quit and reload the game each time. If there are any errors or problems with the script, the ETQW console will list these problems for debugging/fixing.
If the script is compiled successfully, a message such as 'Compiled 'script/main.script': 13141.5 ms' will be displayed.
Note that for scripts to work, the following cvar must be set: g_useCompiledScript 1
Compiling
Thanks to ETQW's built-in interpreter, scripts can be changed and tested very rapidly. However, for the final release of a mod, is is much preferable to compile the scripts into a compiledscriptx86.dll, which will run much faster.
Compiling scripts requires the additional setup of a compiler, and so is not covered in this tutorial.
- See Generating Compiled Scripts for further information.
Packaging your mod
Mods can be packaged in a number of ways, but the simplest is to simply send your mod folder (in this case 'simplemod') to other people who want to run your mod, so they have the same folders and files as you.
Alternatively, all the files inside 'simplemod' can be zipped up and renamed to a PK4 file (e.g. 'simplemod001.pk4'). This is neater and tidier.
TODO