User:Ducks/A Simple First Mod

From Mod Wiki
< User:Ducks
Revision as of 10:58, 30 November 2007 by Ducks (talk | contribs)

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.

Introduction

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 a rocket
  • 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, homing rockets, and the amount of damage these rockets do when they explode.

These files are typically split into many sections. In the case of the Rocket Launcher file, the first section with numbers (which starts 'invItemDef inventory/weapons/law') contains basic information such as what model to use, its name, and lots of values about when it can be used and the spread it produces.

Further down, under 'entityDef projectile_law' are all the values for the actual (seeking) rocket (the one that flies through the air and explodes), 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 of not hitting 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 arcing rocket so it travels really slowly, lasts really long, and doesn't arc (i.e. make it fire in a straight line).

Copying the .def file

First, we need to know which file to modify - 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. 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 launched, the game will use the simplemod rocketlauncher.def file, instead of ETQW's. So we can change this file as much as we want.

Editing the .def file

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"
}

Script Files (.script)

Where definition files contain settings and values of entities, script files describe the behaviour of entities. 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.

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 the .script file

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 the .script file

A cursory glance at this script shows that there are two methods related to ammo use - 'UseAmmo' and 'seAmmo_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 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.

Compiling

The script editing in this tutorial is ideal for development purposes, since it is easy to edit scripts and see their effect immediately in-game via ETQW's built-in interpreter. However, for the final release of a mod, is is much preferable to compile the scripts into a .DLL, which will run much faster.

Compiling scripts requires the additional setup of a compiler, and so is not covered in this tutorial, but is covered elsewhere on the Wiki.

Packaging your mod

Mods can be packaged in a number of ways.