Gun Tactics II

Player's Manual

Version 0.9.3 (2018/08/14)

Copyright © 2018 Leonardo Boselli


The information in this manual and the associated software are provided "as is". There are no guarantees, explicit or implied, that the software and the manual are accurate.


Index


Introduction


0.0   A Bit of History

Gun Tactics II is the successor of GUN-TACTYX - read it like Gun Tactics - that was a "CROBOTS-like game with QuakeIII-style graphics". It belongs to the genre of Programming Games like Tom Poindexter's CROBOTS, an old 1985 DOS game, where some robots fight in an arena, firing missiles and avoiding enemies' projectiles. Such kind of games is involving, but it is not interactive, in fact the player must develop the AI algorithms of his own robot using a programming language and then can follow its fights against other robots, possibly written by other players.
A great deal of these kind of games is available for download, most of them for free. An on-line example was my JROBOTS that dates back to the year 2000. It is a clone of CROBOTS with interesting features. While a player of CROBOTS had to use a subset of C to program his robot (using only integer math because of the limitations of 1985 PCs), a player of JROBOTS uses the Java language and the robot consists of a single Java class. For almost ten years, players could upload the corresponding file to the on-line arena to compete in monthly tournaments against robots developed by other players. One of the most appealing characteristics of JROBOTS was the cooperative play. In fact, while the original CROBOTS had only one-against-all kind of matches, JROBOTS supported matches among team of robots, from doubles to four teams of eight robots each at a time.
During tournaments, since April 2000, a large number of interesting jrobots were uploaded online and featured several different strategies that evolved with time.

Even if JROBOTS was a great game in its genre, it had some limitations and, since the beginning, I wished to develop another game with the strongest points of JROBOTS, but at the same time graphically appealing, with an easy to control execution environment and a more realistic simulator. After a long list of failed attempts, the answer to my wishes appeared in 2003 and its name was GUN-TACTYX.
This game was developed using my proprietary 3D engine (Apocalyx 3D Engine http://apocalyx.sourceforge.net) and the SMALL scripting language. The graphics was more appealing for the time and the bots' code was executed in a controlled environment. There were different kind of play (the traditional gun fight, but also a soccer mode) and for a couple of years a small community of players programmed interesting AI behaviors. A few researchers wrote papers that made use of GUN-TACTYX to develop concepts in particular fields of AI.

After so many years, it's time to revive the concept: it's time for Gun Tactics II. No more based on a proprietary 3D engine (that is difficult for me to upgrade because of so fast paced technological improvements) but based on the freely available up-to-date Unity. No more programming with an almost unknown scripting language (the SMALL language has evolved years ago in PAWN), but programming with the well known and simple to master Lua language.

Index


0.1 Why Lua Language Scripts?

In Gun Tactics II, the player must develop the AI algorithms of his team of bots using the Lua scripting language. This document describes the use of Lua to create scripts that control the bots' behavior. The Lua language is a powerful scripting language easily extendable and embeddable in other applications. It is often a scripting language of choice in the game industry. Here the description of Lua is limited to the features that are useful to create Gun Tactics II scripts, but plenty of other possibilities are available. To know more about Lua visit the site http://www.lua.org.

A Lua interpreter can run instruction by instruction the scripts and provides a fine control of the execution. It is very easy to execute the code for any amount of ticks of (virtual) CPU clock, suspend the execution starting the run of other code and resume it. As a consequence, all the bots of the game use the same amount of time to perform the same actions, saving the reliability of the simulation. The Lua language is very easy to learn for people who already knows a programming language such as Java, C#, Phyton, C++ or others, and may introduce unexperienced people to procedural programming.

Index


0.2 Brief Description of the Game

Keys assignments: A, S, D, W and mouse control the camera movement; U, I, O, P control the simulation speed (U doubles, I normal rate, O halves and P pauses). ESC is used to change from menu to game mode or to quit the application.

The game consists in a fight among 4 teams of 8 warriors. The warriors move in a complex environment with walls. A warrior can walk, run or sprint (run faster), but it suddenly stops when hits a wall or another warrior.
Warriors have a brain that consists in a CPU with a virtual clock frequency of 2500Hz (the simulation runs at a rate of 1/50 of second and 50 instructions are executed at each step). They are equipped with one gun that fires bullets (that run at a speed of 30 m/s). The number of bullets loaded at the beginning is 50. Recharges are provided on the battlefield. A bot can't fire when sprints and the fire rate is 1 shot every 2 seconds.
Every warrior has an initial amount of health, energy and armor. Health starts from the maximum, 100, and decreases when a buttel hits a warrior, 50 units per hit. When a warrior reach zero or less health, it is disabled (and falls to the ground). Energy starts from 100. It decreases 5 units per second when the warrior sprints, 3.5 units per second when it runs, increases 1 unit per second when the warrior is standing and keep its current value when the bot walks. When the energy reaches zero, the warrior can't run or sprint, but can still walk. The Armor value starts from 0, while the maximum is 100. Armor gives protection from hits, but every hit reduces the armor by 50 units. Powerups for health (medikits), energy and armor are available on the battlefield. When a powerup is hit by a bot, it disappears from the battlefield but is respawned after a certain amount of time.

Warriors may rotate their forward direction around their vertical axis and rotate the torso up to specific values. The gun, its aim device and other sensors are linked to the torso and follow its movement.

Among the others described in Part III, some of the main functions (the types 'float', 'int' or 'bool' are just placeholders to make clear arguments and return values of each function: in this version of Lua, variables are declared with 'local' and are numerical in a general way) available to warriors to interact with each other and with the environment are:

A match lasts for a certain duration (the time that a damage circle takes to close around the center of the arena). There is only one condition for victory: to survive the enemies.

This is only a brief overview of the game. Other details appear in the list of the functions that control the bot's behavior available in Part III.

If you have any question, contact me at leonardo.boselli@youdev.it.

Index


0.3 The Story So Far...

Index


Part III - The Gun Tactics II API

The warriors in the Gun Tactics II arena are controlled by Lua scripts. The interface to the surrounding environment is given by the following set of functions. The value assigned to some arguments and returned values are specific to the current implementation of the game and may change in future releases, but the API and its specifications are very likely fixed once for all.
A player writes the source code of his bot in a text file (for example "rookie.lua"). A function called "main()" is called when the script is executed.

Local scripts are stored in the "/_MyBots" folder of the game, while scripts downloaded from the repository are stored in "/_OtherBots".

Here follows the complete list of functions with some explanation that specifies also the parameters of the warriors and some characteristic of the environment in the current implementation.
Note: In the following list, the types "float" or "int" are used to mark numerical arguments and return values, but that types are there only for clarity and it is an error to use them in Lua scripts, in fact Lua is not a typed language. Remember that the simulator of Gun Tactics II uses meters and seconds as units of space and time respectively and radians for angles.

Index


API functions

float getTime()
Returns the elapsed time in seconds since the beginning of the match. The time advances in discrete steps of 1/50 seconds.
int getId()
Returns the identification value of the bot from 0 to the maximum number of mates in the team decreased by one.
int getMates()
Returns the number of active mates not yet disabled.
float getX() / float getY()
Returns the absolute coordinates of the location of the bot. X and Y lay on a horizontal plane.
float getGasRadius()
Returns the radius of the safe area. When the bot is outside of the safe area, it receives 5 units of damage per second. Bullets are stopped by the gas, even if they are shot in the gas.
float getDir()
Returns the absolute forward direction of the bot (the direction towards which the bot walks/runs/sprints). "Absolute" means that different bots face the same direction when getDir() reports the same value or values that differ of 2*k*PI, were k is an integer. Be aware that the angle returned by getDir() is not bounded by any interval of values, so don't expect always a returned value between -PI and PI.
IMPORTANT - Angles are expressed in radians. Zero radians points along the positive direction of the Y axis and angles increase clockwise (so pi/2 points along the positive direction of the X axis, pi along the negative direction of Y and 3/2 pi along the negative of X axis).
float getGunDir()
Returns the angle of rotation of the torso around a vertical axis (relative to the forward orientation of the legs). It gives also the direction of the gun.
float getHeadDir()
Returns the angle of rotation of the head around a vertical axis (relative to the forward orientation of the legs plus the one of the torso). It gives also the direction of the sensors to aim, sight and watch.
float getEnergy()
Returns the current energy of the bot. When the energy reaches zero the bot is stopped and requires an energy of 5 units before it can walk again. The initial and maximum value is 100.
float getHealth()
Returns the current health of the bot. When the health reaches zero, the bot is disabled. The initial and maximum value is 100. Every bullet hit reduces the health or armor by 50 units.
float getArmor()
Returns the current armor of the bot. The armor absorbs the damage preserving health but reducing its value at the same time. The initial value is 0. The maximum value is 100. Every bullet hit reduces the health or armor by 50 units.
int getGunLoad()
Returns the current number of bullets in the barrel of the gun. The initial and maximum value is 50.
int getTouch()
Returns the last object touched by the bot. Only the last one is reported. The returned value are 0 (nothing), 1 (bot), 2 (bullet), 3 (energy powerup), 4 (armor powerup), 5 (health powerup), 6 (bullets powerup), 99 (arena walls). After returning, the value is reset to zero. The size of the bounding box of the bot is 0.4 m.
float getSpeed()
Returns the current speed. The walking speed is 1.7 m/s. The run speed is 3.5 m/s. The sprint speed is 5.0 m/s.
float stop()
Performs the "stop" action. The bot does not stop immediately except when walking, provided that at least 1 second have passed since the last movement action. When standing, a bot can still rotate on its vertical axis. Returns the current speed.
float walk()
Performs the "walk" action. The bot does not walk immediately except when standing or running, provided that 1 second have passed since the last movement action. The walk speed is 1.7 m/s. Returns the current speed.
float run()
Performs the "run" action. The bot does not run immediately except when walking or sprinting, provided that 1 second have passed from the last movement action. The run speed is 3.5 m/s. Returns the current speed.
float sprint()
Performs the "sprint" action. The bot does not sprint immediately except when running, provided that 1 second have passed from the last movement action. The sprint speed is 5.0 m/s. Returns the current speed.
float dir(float direction)
Performs the smallest rotation at the maximum speed around the vertical axis to reach the specified direction. The angle of rotation is absolute (this means that bots facing different directions, given the same argument, face at the end the same direction). Returns the current direction. The angular speed of the rotation is PI/2 radians per second.
IMPORTANT - Angles are expressed in radians. Zero radians points along the positive direction of the Y axis and angles increase clockwise (so pi/2 points along the positive direction of the X axis, pi along the negative direction of Y and 3/2 pi along the negative of X axis).
float gunDir(float angle)
Performs a rotation around the vertical axis of the bot's torso. The angle of rotation is relative to the legs direction (this means that a zero angle points the gun directly forward according to the walk direction). Torso rotations can't exceed PI/4 radians to the left or to the right. The torso turns at an angular speed of PI/2 radians per second. Returns the current direction.
float headDir(float angle)
Performs a rotation around the vertical axis of the bot's head. The angle of rotation is relative to the torso direction (this means that a zero angle points the head in the direction of the gun). Head rotations can't exceed PI/4 radians to the left or to the right. The head turns at an angular speed of PI/2 radians per second. Returns the current direction.
bool shoot()
Shoots a bullet, provided that at least 2 seconds have passed since the last shot. The direction of the bullet is given by the sum of the current angles of the legs and the torso, because they affect the direction of the gun. The speed of the bullet is 30 m/s. Returns true if the bullet is shot, false otherwise.
float sight()
Returns the distance of the nearest wall right in front of the gun.
float aim()
Returns the distance of the nearest bot in front of the gun (positive if the bot is an enemy and negative if it is a friend). If no warrior is in front of the aim device, it returns zero.
float watch(float aperture, int filter)
Returns the distance of the item specified by filter (1 - bot, 2 - bullet, 3 - energy powerup, 4 - armor powerup, 5 - health powerup, 6 - bullets powerup) in the forward direction (legs direction plus gun direction) within the given aperture (maximum value PI/4 to the left and to the right). If the bot is a friend, the distance is given with a negative sign. If no item of that kind is found, the returned value is zero.
float radio(int slot, float value)
Sends a value on specified slot (there are 16 slots, numbered from 0 to 15) of the channel reserved to this bot. Returns the value previously sent on the same slot.
float listen(int channel, int slot)
Returns the value sent to the specified slot of the given channel. The number of the channel is equal to the id number of the bot using that channel.
bool print(string text)
Available for debug purposes. Prints a line of text on the top of the screen. The function succeeds if and only if the script calling is the same loaded in the editor window.
bool write(string text)
Available for debug purposes. Writes a string on the file called "yourbotname.debug.txt". The function succeeds if and only if the script calling is the same loaded in the editor window.
bool print(string text)
Available for debug purposes. Prints a line of text of the top of the screen. The function succeeds if and only if the script calling it is the same loaded in the editor window.

Index


Any question? Contact Leonardo Boselli at leonardo.boselli@youdev.it
Find Gun Tactics II at https://www.youdev.it/gt2