Time Trials – Arma 3

From Bohemia Interactive Community
Jump to navigation Jump to search
m (Added Steam Workshop info)
mNo edit summary
Line 93: Line 93:
overviewPicture = "myfirsttimetrial_overview_CO.paa"; // Same picture as above
overviewPicture = "myfirsttimetrial_overview_CO.paa"; // Same picture as above
overviewText = "Can you beat my splendid trial?!"; // Same text 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
author = "Marshal Henk"; // You!


doneKeys[] = {"MyFirstTimeTrial_done"}; // Registers having completed (achieved gold or special) your trial
doneKeys[] = {"MyFirstTimeTrial_done"}; // Registers having completed (achieved gold or special) your trial
Line 100: Line 100:
{{Feature|Informative|Not all properties in this sample config are needed for every trial; they are included to showcase all options.}}
{{Feature|Informative|Not all properties in this sample config are needed for every trial; they are included to showcase all options.}}
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
//This primary trial configuration can also be implemented via a mod config, but doing so via description.ext is simplest in most cases.}}
// This primary trial configuration can also be implemented via a mod config, but doing so via description.ext is simplest in most cases.}}
class CfgTimeTrials
class CfgTimeTrials
{
{
Line 204: Line 204:
== CfgMissions ==
== CfgMissions ==


{{Feature|Informative|This is only needed for trials configured via mod config (not via description.ext).}}
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
class CfgMissions
class CfgMissions
Line 273: Line 274:
= Steam Workshop =
= Steam Workshop =


When a trial is self-contained (i.e. configured via description.ext), it can be published to [https://steamcommunity.com/workshop/browse/?appid=107410 Steam Workshop] as ''Scenario''. When players subscribe to such trial, it will be listed in their ''CHALLENGES'' menu.
When a trial is self-contained (i.e. configured via [[description.ext]]), it can be published to [https://steamcommunity.com/workshop/browse/?appid=107410 Steam Workshop] as ''Scenario''. When players subscribe to such trial, it will be listed in their ''CHALLENGES'' menu.


* You need to manually add the ''TimeTrial'' tag while publishing to Workshop!
* You need to manually add the ''TimeTrial'' tag while publishing to Workshop!

Revision as of 17:08, 25 February 2021

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

  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. Ideally 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";};
  7. Insert a Time Trial module (ModuleTimeTrial_F).
    Start CP setup
  8. 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
  9. Insert a Target - Oval (Ground) prop.
    1. Save the scenario (be sure binarization is disabled via the checkbox or preferences).
    2. Close Eden Editor to avoid auto-saves.
    3. Open the scenario SQM file in a text editor.
    4. Replace the target's class by Land_Target_Oval_NoPop_F (all targets need to use their hidden NoPop variant!).
    5. Save the SQM.
    6. Re-open the scenario in Eden Editor.
    7. Position this target near the finish CP (so that it is visible and accessible to drive to after finishing).
    8. In the target's Texture #0 field, enter: A3\modules_f_beta\data\FiringDrills\restart_orange_ca // Other colors have corresponding textures - see below
  10. 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.
  11. 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
  12. 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
  13. 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).
  14. Set up trial properties via description.ext (see below).
  15. Configure your drill via description.ext or 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_custom.inc" // 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!

doneKeys[] = {"MyFirstTimeTrial_done"}; // Registers having completed (achieved gold or special) your trial
Not all properties in this sample config are needed for every trial; they are included to showcase all options.
// This primary trial configuration can also be implemented via a mod config, but doing so via description.ext is simplest in most cases.}}
class CfgTimeTrials
{
	// When using description.ext, the name of this class does not matter much (the system selects the first class)	
	// When using a mod config, this class name must correspond to the missionName(Source) (also CfgMissions class)
	class MyFirstTimeTrial 
	{
		displayName = "TT: My First Trial"; // Vanilla trials use a format like this, but it is 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";
			};
		};
	};
};

CfgMissions

This is only needed for trials configured via mod config (not via description.ext).
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
			// };
	};
};

CfgTimeTrials

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


Steam Workshop

When a trial is self-contained (i.e. configured via description.ext), it can be published to Steam Workshop as Scenario. When players subscribe to such trial, it will be listed in their CHALLENGES menu.

  • You need to manually add the TimeTrial tag while publishing to Workshop!
  • Renaming a trial after publication may invalidate stored record times for subscribed players!
  • Your stored record times from Eden Editor testing (during development), will likely differ to those after publication / subscription.
  • Steam Leaderboards are not supported for Workshop trials.
  • A subscribed trial's medal times will not show in the overview until it has been completed at least once.


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.