| Revision as of 23:33, 21 February 2009 Gcamp (Talk | contribs) Scripts Pitfalls ← Previous diff |
Current revision Gcamp (Talk | contribs) LUA |
||
| Line 5: | Line 5: | ||
| Scorched3D supports configurable weapons via its XML accessory definition files, see [[Scorched3D_v42|current scorched3d weapons]]. The XML definitions allow you to make an almost limitless number of complex weapons, and in most cases this is the easiest way to create new weapons. | Scorched3D supports configurable weapons via its XML accessory definition files, see [[Scorched3D_v42|current scorched3d weapons]]. The XML definitions allow you to make an almost limitless number of complex weapons, and in most cases this is the easiest way to create new weapons. | ||
| - | In some cases the XML accessory definition files don't allow you to create the weapons you want, perhaps the weapons are very complex or the XML syntax doesn't exist. For these occasions you can Weapon Scripts. | + | In some cases the XML accessory definition files don't allow you to create the weapons you want, perhaps the weapons are very complex or the XML syntax doesn't exist. For these occasions you can use Weapon Scripts. |
| - | Instead of XML Weapon scripts use the LUA scripting language to define Scorched3D weapons. See [[Scripting|Scorched3D scripting home]] for an introduction to scripting on Scorched3D. | + | Instead of using XML Weapon scripts use the LUA scripting language to define Scorched3D weapons. See [[Scripting|Scorched3D scripting home]] for an introduction to scripting on Scorched3D. |
| - | ==LUA== | ||
| - | Weapon scripts are written as normal text files containing LUA code. See [http://www.lua.org/manual/5.1 LUA Documentation] for documentation on the LUA scripting language. | ||
| - | |||
| - | ;The LUA interpreter imbeded in Scorched3D supports the following standard libraries- | ||
| - | :Basic functions | ||
| - | :String manipulation | ||
| - | :Table manipulation | ||
| - | :Mathematical functions | ||
| - | :Scorched3D specific functions | ||
| - | All of the standard libraries are documented in the [http://www.lua.org/manual/5.1 LUA Documentation], with the exception of the Scorched3D functions. The Scorched3D functions allow scripts to interact with and manipulate the Scorched3D engine. | ||
| ==Weapon Scripts== | ==Weapon Scripts== | ||
| Line 32: | Line 22: | ||
| :position - A table containing the coordinates of the current weapon | :position - A table containing the coordinates of the current weapon | ||
| :velocity - A table containing the velocity factors for the current weapon | :velocity - A table containing the velocity factors for the current weapon | ||
| + | |||
| + | Both position and velocity tables contain three number entries x, y and z. | ||
| ===Simple Example Script=== | ===Simple Example Script=== | ||
| Line 40: | Line 32: | ||
| print(velocity.x, velocity.y, velocity.z); | print(velocity.x, velocity.y, velocity.z); | ||
| end | end | ||
| - | As you can see it implements the runWeapon function. When executed the script will print the playerId, position and velocity to the Scorched3D console. You can access the console by pressing the ` key. | + | As you can see it implements the runWeapon function. When executed the script will print the playerId, position and velocity to the Scorched3D console. You can access the Scorched3D console by pressing the ` key when running the game. |
| ===Using the Scorched3D functions=== | ===Using the Scorched3D functions=== | ||
| Line 50: | Line 42: | ||
| :s3dweapon - The scorched3d weapons library containing functions specific to creating and manipulating weapons. See [[LUA s3dweapon library]] | :s3dweapon - The scorched3d weapons library containing functions specific to creating and manipulating weapons. See [[LUA s3dweapon library]] | ||
| - | For example, the following script prints the size of the current landscape to the console: | + | For example, the following script prints the size of the current landscape to the console. It does this by using the s3d.get_landscapewidth and s3d.get_landscapeheight functions that are defined in the s3d library, and the print function that is defnined in the LUA standard library. |
| function runWeapon(playerId, position, velocity) | function runWeapon(playerId, position, velocity) | ||
| landwidth = s3d.get_landscapewidth(); | landwidth = s3d.get_landscapewidth(); | ||
| Line 56: | Line 48: | ||
| print("Landwidth", landwidth, "Landheight", landheight); | print("Landwidth", landwidth, "Landheight", landheight); | ||
| end | end | ||
| - | This script uses the s3d.get_landscapewidth and s3d.get_landscapeheight functions that are defined in the s3d library. | ||
| ====Example 1==== | ====Example 1==== | ||
| Line 153: | Line 144: | ||
| ===Global variables=== | ===Global variables=== | ||
| - | It's fine to use global variables but don't use them to store data across different runs of the same script. Put another way just asume the script will be started from fresh every time. | + | It's fine to use global variables but don't use them to store data across different runs of the same script. Put another way, always asume the script will be started from fresh every time. |
| '''Storing data for use across different executions of the same script will cause online games to become out of sync and ultimately fail.''' | '''Storing data for use across different executions of the same script will cause online games to become out of sync and ultimately fail.''' | ||
| == WeaponScript AccessoryAction== | == WeaponScript AccessoryAction== | ||
| + | |||
| + | ===Introduction=== | ||
| In fact the configuration for the Weapon Scripts is in the existing XML file (accessories.xml), but this is purely used to tell Scorched where to find the script and when to use it. Weapon scripts are defined in new type of accessoryaction called ''WeaponScript''. This ''WeaponScript'' is just a 'normal' accessoryaction and can be used interchangably with other accessoryactions in the accessories.xml. | In fact the configuration for the Weapon Scripts is in the existing XML file (accessories.xml), but this is purely used to tell Scorched where to find the script and when to use it. Weapon scripts are defined in new type of accessoryaction called ''WeaponScript''. This ''WeaponScript'' is just a 'normal' accessoryaction and can be used interchangably with other accessoryactions in the accessories.xml. | ||
| Line 172: | Line 165: | ||
| </accessoryaction> | </accessoryaction> | ||
| The above accessoryaction has two mandatory parts, the filename and the entrypoint: | The above accessoryaction has two mandatory parts, the filename and the entrypoint: | ||
| - | * filename is the path to the LUA script that you want to run when the accessoryaction is executed. | + | * filename is the path to the LUA script that you want to run when the accessoryaction is executed. This filename is relative to the root of your mod. See [[Modding_Basics|Introduction - Modding Basics]]. |
| - | * entrypoint is the LUA function in the script to execute when the accessoryaction is executed. | + | * entrypoint is the LUA function in the script to execute when the accessoryaction is executed (in this case runWeapon(playerId, position, velocity)). |
| - | * variable is a *optional* list of variables that may be passed into the script. | + | * variable is a *optional* list of variables that may be passed into the script. This will be defined in the script as global variables. |
| + | ===Simple Example=== | ||
| Here is an example use of a WeaponScript: | Here is an example use of a WeaponScript: | ||
| Line 189: | Line 183: | ||
| The above accessory creates a weapon called 'Test Script'. When the tank fires this weapon the ''runWeapon'' function in the ''data/lua/accessories/test.lua'' script will be executed. | The above accessory creates a weapon called 'Test Script'. When the tank fires this weapon the ''runWeapon'' function in the ''data/lua/accessories/test.lua'' script will be executed. | ||
| + | ===More Complex Example=== | ||
| - | Obviously this is a very simple example and as stated earlier you can use WeaponScripts anywhere that you can use an accessoryaction. | + | As stated earlier you can use WeaponScripts anywhere that you can use an accessoryaction. Here is an example of using a weapon script after a projectile. |
| + | |||
| + | <accessory> | ||
| + | <name>Test Missile</name> | ||
| + | <accessoryaction type="WeaponProjectile"> | ||
| + | <projectilescale>0.5</projectilescale> | ||
| + | <spinspeed>1.0</spinspeed> | ||
| + | <collisionaction type="WeaponScript"> | ||
| + | <filename>data/lua/accessories/test.lua</filename> | ||
| + | <entrypoint>runWeapon</entrypoint> | ||
| + | </collisionaction> | ||
| + | </accessoryaction> | ||
| + | </accessory> | ||
| == Weapon Scripts Walkthrough == | == Weapon Scripts Walkthrough == | ||
| + | |||
| + | Here is the basic steps you should use to create a weapon script:- | ||
| + | # Write the weapon script and save it to a text file. | ||
| + | # Put this text file into your mod. Generally under the data/lua directory. | ||
| + | # Edit the accessories.xml file and create/add your new weapon. This weapon should contain a call to a WeaponScript accessorypart somewhere within it. | ||
| + | # Run Scorched3D | ||
| + | # Choose a custom game using your mod and test your new weapon | ||
| + | # Rejoice | ||
| + | |||
| + | == Weapon Scripts Advanced Uses == | ||
| + | |||
| + | Once your weapon is defined you can call it from anywhere that uses weapons, including periodic events and death actions for tanks and buildings. | ||
Contents |
Scorched3D supports configurable weapons via its XML accessory definition files, see current scorched3d weapons. The XML definitions allow you to make an almost limitless number of complex weapons, and in most cases this is the easiest way to create new weapons.
In some cases the XML accessory definition files don't allow you to create the weapons you want, perhaps the weapons are very complex or the XML syntax doesn't exist. For these occasions you can use Weapon Scripts.
Instead of using XML Weapon scripts use the LUA scripting language to define Scorched3D weapons. See Scorched3D scripting home for an introduction to scripting on Scorched3D.
Weapon scripts are just normal LUA scripts. However there must be one function (the entry point) in the LUA script that takes a playerId, a position and a velocity. Simply put, one function in the script must look like this:-
function runWeapon(playerId, position, velocity)
This is the function that will be called when ever this weapon is executed. You can have as many other functions as you need in the file but this one is mandatory.
Both position and velocity tables contain three number entries x, y and z.
Here is a very simple weapon script:
function runWeapon(playerId, position, velocity) print(playerId); print(position.x, position.y, position.z); print(velocity.x, velocity.y, velocity.z); end
As you can see it implements the runWeapon function. When executed the script will print the playerId, position and velocity to the Scorched3D console. You can access the Scorched3D console by pressing the ` key when running the game.
What makes the Scorched3D scripts useful is using them to interact with the Scorched3D engine. To do this Scorched3D provides a set of library functions that be called from within your scripts.
For example, the following script prints the size of the current landscape to the console. It does this by using the s3d.get_landscapewidth and s3d.get_landscapeheight functions that are defined in the s3d library, and the print function that is defnined in the LUA standard library.
function runWeapon(playerId, position, velocity)
landwidth = s3d.get_landscapewidth();
landheight = s3d.get_landscapeheight();
print("Landwidth", landwidth, "Landheight", landheight);
end
You can combine Scorched3D functions with the LUA functions to perform very complicated operations. For example, the following script creates a set of explosions in a diagonal line across the landscape.
function runWeapon(playerId, position, velocity) -- Get the landscape width and height using the s3d library functions landwidth = s3d.get_landscapewidth(); landheight = s3d.get_landscapeheight();
-- Print the width and height to the console
print("Landwidth", landwidth, "Landheight", landheight);
-- Create an explosion line from landscape corner to corner
landstart = 0;
while (landstart < landwidth and landstart < landheight) do
-- Get the current landscape height at the position landstart, landstart
height = s3d.get_height(landstart, landstart);
-- Use the s3dweapon.explosion function to make an explosion
s3dweapon.explosion(
playerId, -- Create an explosion for the same player as fired this weapon
{ -- Create a table that has the position of the explosion
x=landstart,
y=landstart,
z=height
},
{ -- Create a table that describes the explosion parameters
size = 4, -- The size of the explosion
hurtamount = 0,
deform = 2,
animate = false
});
-- Move to the next position
landstart = landstart + 15;
end
end
The following example creates an explosion 10 units to the right of the player that fired the weapon.
function runWeapon(playerId, position, velocity)
s3dweapon.explosion(
playerId, -- Create an explosion for the same player as fired this weapon
{ -- Create a table that has the position of the explosion
x=position.x + 10,
y=position.y,
z=position.z
},
{ -- Create a table that describes the explosion parameters
size = 4, -- The size of the explosion
hurtamount = 0,
deform = 2,
animate = false
});
end
This example finds all tanks that are currently playing and fires a "Nuke" weapon at their positions.
function runWeapon(playerId, position, velocity) -- Get a table containing all of the tanks currently playing, -- the table key is the playerid -- the table value is the tank details tanks = s3d.get_tanks();
-- Iterate over these tanks, k is the playerid, v is the tank details
for k,v in pairs(tanks) do
-- Check the tank is still alive
if (v.alive) then
-- Fire a nuke at this tanks position using the s3d.fireweapon function
s3d.fire_weapon(
"Nuke", -- Fire a "Nuke" weapon
playerId, -- From the same player that executed this script
v.position, -- At the tanks location
{x=0, y=0, z=0} -- With no speed or direction (velocity)
);
end -- End if
end -- End for
end -- End function
Using the print function can be a simple way of debugging scripts, however print statements slow down the game and should not be present in the final version of the script.
Scripts give you much power, but with that comes great responsibility! While the engine is optimized, performing huge amounts of calculations in a script or firing a large number of weapons/explosions will slow the game down. Don't go overboard with the amount of work you try to do in a script.
You can used the ActionProfiling console command to check how many explosions and actions were fired in a turn. After each turn the number of actions should be printed to the console.
ActionProfiling = on
It's fine to use global variables but don't use them to store data across different runs of the same script. Put another way, always asume the script will be started from fresh every time.
Storing data for use across different executions of the same script will cause online games to become out of sync and ultimately fail.
In fact the configuration for the Weapon Scripts is in the existing XML file (accessories.xml), but this is purely used to tell Scorched where to find the script and when to use it. Weapon scripts are defined in new type of accessoryaction called WeaponScript. This WeaponScript is just a 'normal' accessoryaction and can be used interchangably with other accessoryactions in the accessories.xml.
Here is an example WeaponScript accessory action:
<accessoryaction type="WeaponScript">
<filename>data/lua/accessories/test.lua</filename>
<entrypoint>runWeapon</entrypoint>
<variable>
<name>testvar1</name>
<value>10</value>
</variable>
</accessoryaction>
The above accessoryaction has two mandatory parts, the filename and the entrypoint:
Here is an example use of a WeaponScript:
<accessory>
<name>Test Script</name>
<bundlesize>2</bundlesize>
<cost>10</cost>
<accessoryaction type="WeaponScript">
<filename>data/lua/accessories/test.lua</filename>
<entrypoint>runWeapon</entrypoint>
</accessoryaction>
</accessory>
The above accessory creates a weapon called 'Test Script'. When the tank fires this weapon the runWeapon function in the data/lua/accessories/test.lua script will be executed.
As stated earlier you can use WeaponScripts anywhere that you can use an accessoryaction. Here is an example of using a weapon script after a projectile.
<accessory>
<name>Test Missile</name>
<accessoryaction type="WeaponProjectile">
<projectilescale>0.5</projectilescale>
<spinspeed>1.0</spinspeed>
<collisionaction type="WeaponScript">
<filename>data/lua/accessories/test.lua</filename>
<entrypoint>runWeapon</entrypoint>
</collisionaction>
</accessoryaction>
</accessory>
Here is the basic steps you should use to create a weapon script:-
Once your weapon is defined you can call it from anywhere that uses weapons, including periodic events and death actions for tanks and buildings.