Arma 3 Time Trials

From Bohemia Interactive Community
Jump to navigation Jump to search

This guide will describe how to design and implement a custom Time Trial Challenge as available in the vanilla game.

See also:


Terminology

  • Time Trial (TT) - a simple vehicle race against the clock
  • Competitor - the actor running the trial
  • Marshal - the actor observing the trial and providing feedback / guidance
  • Checkpoint (CP) - a navigation point within a course which a competitor must follow in a fixed sequence (1 consecutive CP may be skipped for a time penalty)
    • The first CP is the start.
    • The last CP is the finish.
  • Time - the time from the start it takes to complete a trial (raw)
    • Time penalties are added to arrive at the final time.
    • The fastest / lowest time is the best and wins.
    • There are bronze, silver and gold medal times to beat.
    • There may be one special time to beat (must be faster than gold).


Setup

At time of writing it is not possible to add new Time Trials as independent (Workshop) scenarios; they need to be added as 'mods' with configuration. This will be possible in update 2.02 however.
  1. Open Eden Editor with the terrain of your choice loaded.
  2. Insert a player character named BIS_TT_Competitor // Fixed system name
  3. Now is a good time to save your scenario a first time. Use a name that is safe to reference as config class, so no spaces - f.e. MyFirstTimeTrial // Referenced later
  4. Insert an empty vehicle named BIS_TT_Vehicle // Fixed system name / not all types of vehicles have been tested, but cars, helicopters and tanks should work
  5. When not already placing the competitor inside the vehicle, ensure this happens on trial start, f.e. via competitor init: this moveInDriver BIS_TT_Vehicle;
  6. Insert a NPC Marshal character of type C_Marshal_F named BIS_rangeOfficer // Fixed system name / place in a separate group and at a reasonable distance in order to see the starter pistol firing
    1. In the marshal's init field enter: this disableAI "ANIM"; BIS_TT_handle = this spawn {waitUntil {time > 0}; _this switchMove "Acts_starterPistol_loop";};
Start CP setup
  1. Insert a Time Trial module
    1. It's not exposed in Eden Editor, so place any other module. We may change this after this documentation is completed.
    2. Save the scenario (be sure binarization is disabled via the checkbox or preferences).
    3. Close Eden Editor to avoid auto-saves.
    4. Open the scenario SQM file in a text editor.
    5. Replace the module's class by ModuleTimeTrial_F.
    6. Save the SQM.
    7. Re-open the scenario in Eden Editor.
  2. Insert an ellipse trigger with default properties named f.e. BIS_TT // Referenced later
    1. Re-size the trigger to encompass your entire trial and a little extra buffer area (you'll likely re-size it later as you progress).
CP setup
  1. Insert a Target - Oval (Ground) prop
    1. Using a similar workflow as above, manually change its class name to Land_Target_Oval_NoPop_F (all targets need their hidden NoPop variant).
    2. Position this target near the finish CP (so that it's visible and accessible to drive to after finishing).
    3. In the target's Texture #0 field, enter: A3\modules_f_beta\data\FiringDrills\restart_orange_ca // Other colors have corresponding textures - see below
  2. Insert a trigger with default properties named BIS_FD_restartSelector1 // Referenced later
    1. Re-size and orient the trigger so that it encompasses the target above and forms a suitable 'parking' spot for the chosen vehicle.
  3. Copy and paste the restart target.
    1. Position it near the first target, typically right from it (but spaced to comfortably allow your chosen vehicle type to access both).
    2. In the target's Texture #0 field, enter: A3\modules_f_beta\data\FiringDrills\quit_ca // Fixed texture no matter the drill color
  4. Insert a trigger with default properties named BIS_FD_quitSelector1 // Referenced later
    1. Re-size and orient the trigger so that it encompasses the target above and forms a suitable 'parking' spot for the chosen vehicle.
Finish CP setup
  1. For each CP (including start and finish), insert a trigger with default properties named f.e. BIS_TT_CP1 // Referenced later
    1. Re-sizing the trigger does not influence actual CP detection (unlike in Firing Drills), but you can still re-size as visual aid (see radius configuration below - default 5 meters)
    2. It is important to orient most CPs well to determine the valid entry angles (for example by left mouse button + left Shift rotating and dragging the arrow in the direction of the next CP).
    3. Alternatively, use 3D helpers directly as CP objects (circles are commonly used for aerial trials).
  2. Set up trial properties via description.ext (see below).
  3. Configure your drill via CfgTimeTrials and CfgMissions (see below).

Drones

  • To make a drone trial, insert a non-empty (i.e. AI crewed) drone and name it BIS_TT_Vehicle as above.
  • Also add a 'fake' player competitor character who is supposedly controlling the drone (do not name this character or any other BIS_TT_Competitor).
  • In the trial's init script, execute:
enableTeamSwitch false;
BIS_TT_Competitor = driver BIS_TT_Vehicle;
selectPlayer BIS_TT_Competitor;

Common Additions

  • CP marking objects
    • Recolored objects (road cones and small flags for ground vehicles / 3D helpers for aerial vehicles)
    • Direction indicators (arrow signs)
  • Decorative props
    • Sponsoring (signs and flags)
    • Marshal stations (desks, chairs, computers, pen and paper, etc.)
    • Spectator areas (barricades, chairs, drinks, etc.)


Configuration

description.ext

#include "\A3\Missions_F_Kart\Challenges\description.hpp" // This will set up various system default settings, such as custom debriefings

onLoadName = "TT: My First Trial"; // Name of your trial (normally the same as defined in CfgMissions)
onLoadMission = "Can you beat my splendid trial?!"; // Overview text of your trial (normally the same as defined in CfgMissions)
loadScreen = "myfirsttimetrial_overview_CO.paa"; // Overview picture of your trial (normally the same as defined in CfgMissions)
briefingName = "TT: My First Trial"; // Same name as above
overviewPicture = "myfirsttimetrial_overview_CO.paa"; // Same picture as above
overviewText = "Can you beat my splendid trial?!"; // Same text as above
//author = "Marshal Henk"; // You! < this cannot work in the current version due to duplicate definition; fix coming in 2.02

doneKeys[] = {"MyFirstTimeTrial_done"}; // Registers having completed (achieved gold or special) your trial

CfgTimeTrials

Trial

This primary trial configuration is now only possible in a mod config, but from 2.02 can be used in a trial's own description.ext
class CfgTimeTrials
{
	class MyFirstTimeTrial // This class name must correspond to the missionName(Source) (also CfgMissions class)
	{
		displayName = "TT: My First Trial"; // Vanilla trials use a format like this, but it's not enforced
		// This color is used in many places
		// It can be any color, but for best results pick a fully supported color (see section below)
		color[] = {__EVAL(240/255), __EVAL(130/255), __EVAL(49/255), 1};
		colorName = "orange"; // This version of the color is more restrictive and can only use specific supported colors (see section below)
		objectTT = "BIS_TT"; // The trial area trigger referenced in the setup guide
		looped = 1; // Whether the trial will loop when crossing the finish CP (undefined uses 0 - point-to-point race)
		noDefaultGPS = 1; // Disables showing of the mini-map GPS (undefined uses 0 - showing)
		//statistic = ""; // Steam stats are not supported for user-generated trials (used for Achievements)
		//leaderboard = ""; // Steam Leaderboards are not supported for user-generated trials
		onReset = "reset.sqf"; // This script is executed each time the trial resets (restarts)
	
		// List any number of objects that you want to be re-colored to the trial color above (f.e. road cones, small flags, etc.)
		recolor[] = 
		{
			"BIS_TT_recolor1", 
			"BIS_TT_recolor2"	
		};

		// Set up objects that should have special decal textures applied (this was more useful before Eden Editor - see vanilla decals below)
		// This is not used a lot in vanilla trials
		decals[] =
		{
			{ "BIS_TT_decal1", "A3\Missions_F_Beta\data\img\decals\decal_watch_out2_ca", 5 } // Object reference, texture path, hidden selection index
		};

		// Object references to the 2 special targets for drill mechanics, as defined in the setup guide
		restartSelectors[] = {"BIS_TT_restartSelector1"};
		quitSelectors[] = {"BIS_TT_quitSelector1"};
		
		timesMedals[] = { 60, 45, 30 }; // Bronze, silver, gold medal times (be sure to follow this order or results may glitch)
		
		timeSpecial = 15; // Optional special time that is faster than gold (when defining this, you do need to also provide the data below)
		nameSpecial = "Nemesis"; // Optional special time label for the HUD
		colorSpecial = "#ffa500"; // Optional special time color for the HUD
		iconSpecial = "\A3\Ui_f\data\GUI\Cfg\Ranks\colonel_gs"; // Optional special time icon for the HUD
		
		// Legacy class used before Eden Editor to load precise object compositions (should not be needed anymore)
		// class DynOs 
		// {
		//		script = "dyno_myfirsttimetrial.sqf"; // Valid DynO mapper output script
		//		positionAnchor[] = {500, 500}; // DynO mapper anchor position in the world
		// }; 
	
		// All of the trials's CPs
		class CheckPoints 
		{
			class CP1 // Start
			{
				// The CP trigger referenced in the setup guide
				// Note that TT CPs don't use these actual triggers for CP detection; they are only used as reference (unlike in Firing Drills)
				object = "BIS_TT_CP1";
			};
			class CP2 // CP #1
			{
				object = "BIS_TT_CP2";
				penaltyMissed = 200; // Increasing the default penalty for skipping this CP to 20 seconds
			};
			class CP3 // CP #2
			{
				object = "BIS_TT_CP3";
				radius = 20; // Forces a non-default CP radius in meters (undefined uses 5)
				height = 300.5; // Only use this ASL forced height for CPs above ground, such as for aerial vehicles
				onActivate = "CP3_onActivate.sqf"; // Script executed when this CP is activated (passed [CP object])
				onDeactivate = "CP3_onDeactivate.sqf"; // Script executed when this CP is deactivated (passed [CP object])
				onClear = "CP3_onClear.sqf"; // Script executed when this CP is cleared (passed [CP object])
				// Especially aerial trials sometimes need artificial helper objects to visualize a CP in the world
				// These object references are shown / hidden when the CP is active
				// Typically use 3D helper objects, such as spheres
				helpers[] = {"BIS_TT_CP3_Helper1", "BIS_TT_CP3_Helper2", "BIS_TT_CP3_Helper3", "BIS_TT_CP3_Helper4"};
			};
			class CP4 // CP #3
			{
				object = "BIS_TT_CP4";
				omnidirectional = 1; // This CP may be entered from any angle (undefined uses 0 - only allowing entry from the correct side)
				onGround = 1; // This CP requires the vehicle to be on the ground / landed (undefined uses 0 - no ground contact needed)
				timeout = 3; // This CP requires the vehicle to meet the CP conditions for 3 seconds
			};
			class CP5 // CP #4
			{
				object = "BIS_TT_CP5";
				slingLoadLoad = 1; // This CP requires the vehicle to have an externally slung load attached
				slingLoadObject = "BIS_TT_SL1"; // Object reference for the specific object that must be slung
			};
			// Finish
			// Even for a looped trial, the Start and Finish are separate CPs!
			class CP6
			{
				object = "BIS_TT_CP6";
			};
		};
	};
};

System

The system-level configuration could be adjusted by a mod, but consider if that is not going to confuse players who may be trained on vanilla trials.
class CfgTimeTrials
{
	// Below point bonuses and penalties are multiplied by this factor to determine time bonuses and penalties
	pointTimeMultiplier = 0.1;

	penaltyMissed = 100; // Pentalty for missing / skipping a CP (so this is 10 seconds)

	// HUD icons for the medal times
	iconsMedals[] =
	{
		"A3\modules_f_beta\data\FiringDrills\medal_bronze_ca", // Bronze
		"A3\modules_f_beta\data\FiringDrills\medal_silver_ca", // Silver
		"A3\modules_f_beta\data\FiringDrills\medal_gold_ca" // Gold
	};
	// HUD colors for the medal times
	colorsMedals[] =
	{
		"#A0522D", // Bronze
		"#C0C0C0", // Silver
		"#FFD700" // Gold
	};

	// Music tracks used in the TT 'jukebox'
	music[] =
	{
		"BackgroundTrack01_F",
		"BackgroundTrack01_F_EPB",
		"BackgroundTrack01_F_EPC",
		"BackgroundTrack02_F_EPC",
		"BackgroundTrack03_F",
		"BackgroundTrack04_F_EPC"
	};
};

CfgMissions

class CfgMissions
{
	// This will expose the trial in the SINGLEPLAYER > CHALLENGES > Time Trials menu
	class Challenges
	{
		class Time_Trials
		{
			class MyFirstFiringDrill // This class should correspond to the class in CfgTimeTrials above
			{
				directory = "myfirsttimetrial.stratis"; // Full path to your trial's scenario folder
				briefingName = "TT: My First Trial"; // Name of your trial (normally the same as defined in CfgTimeTrials)
				overviewText = "Can you beat my splendid trial?!"; // Overview text of your trial (idem)
				overviewPicture = "myfirsttimetrial_overview_CO.paa"; // Overview picture of your trial (idem)
				overviewScript = "\A3\Modules_F_Beta\FiringDrills\scripts\overviewScript.sqf"; // Standard system script to handle the pause menu properly - don't change
				author = "Marshal Henk"; // You!
			};

			// Alternatively you can list your trial in one of the vanilla theme categories: Karts, Helicopters, IDAP, Tanks
			// class Karts 
			// {
			// 		Define your trial here instead for example
			// };
	};
};


Run-Time Tools

Some things are exposed and possible to change or use run-time, f.e. to make special unlocks or events happen.
  • BIS_TT_hasReset: code which returns true when the trial has reset, ended, or is ending
  • BIS_TT_phase: 0 - trial pre-init / 1 - trial pre-start / 2 - trial started / 3 - trial terminated / -1 - trial restarting


Colors

Please see the Firing Drills documentation for this information.

  • Vanilla tanks trials use a different shade of green color: __EVAL(173/255), __EVAL(191/255), __EVAL(131/255), 1
  • Vanilla IDAP trials use a different shade of orange color: __EVAL(229/255), __EVAL(103/255), __EVAL(34/255), 1


Decals

Please see the Firing Drills documentation for this information.


Tips

  • Vanilla trials are designed to be somewhat realistic and safe as a competitive racing sport. Try to imagine and implement safety concerns in your prop placement. For example, protect spectator viewing areas using barriers.
  • Consider making route navigation easier for competitors by physically blocking off incorrect routes (unless you want to offer multiple routes of course). Use props like arrow signs to hint at upcoming turns.
  • Since trials allow skipping a CP with a time penalty, make sure this cannot be easily exploited in a way that makes skipping a CP always faster (i.e. tweak CP penalties appropriately).
    • A common situation may be a swerving road down a hill, which may cause the direct route down to be much faster (this may be intentional of course, rewarding creative competitors).
  • While this is subjective, shorter trials are usually more popular. They allow quick repeats to break the best times, especially when also looped.
  • There are several useful variables stored in the scenario and CP objects (but in most cases manipulating them directly will break the system; read them only):
    • BIS_TT_CPs: array of CP object references
    • CP (most configuration parameters are also stored as similarly named variables, f.e. "onGround")
      • "CP": CP index number
      • "active": true when activated
      • "clear": true when cleared
  • Balancing a trial can be quite hard, since there is a broad range of skills in the playerbase.
    • You should set appropriate medal times.
    • It's recommended to start harder / more difficult, rather than too easy. It's better to nerf later than to go the other way (since you cannot easily undo recorded times).
    • Start by simply playtesting the trial a lot and determining your own best medal times (or invite other playtesters and record their runs / times - video recordings can also be helpful for spotting issues).
      • Real balancing typically starts towards the end of development, because even slight changes can affect times a lot, let alone adding / removing CPs.
    • Vanilla trials apply the following abstract goals per medal:
      • Bronze: achievable by doing a clean race (perhaps 1 small collision) but not taking many risks. For a typical user it should take 1-3 attempts.
      • Silver: achievable by doing a clean race and taking some risks (using maximum acceleration and cutting some corners). Might take 2-5 attempts for example.
      • Gold: meant to be hard. This needs to be a perfectly clean race, at full speed and taking risks. It may take more than 5 attempts.
      • Special: designed to be extremely hard. Some may never beat this.