Difficulty Levels

From The DarkMod Wiki
Revision as of 22:31, 8 January 2021 by Geep (talk | contribs) (Add small section "Determining the Current Level From a Script")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

General information

You can change what is in your FM and the way it plays on the different difficulty levels.

It is highly recommended that you do not use these methods to exclude entire sections or interesting features unless you declare this somewhere in the objectives text or in the readme. It's also a good idea to declare if the player will not miss anything whichever difficulty setting he/she chooses.

Excluding & Restricting Entities from/to Difficulty Levels

To restrict an entity to a particular difficulty setting you exclude it from the others, as follows...

To exclude an entity from a particular difficulty level you set it to not spawn as follows:

  • Select the entity
  • Add the following property and value:
  • diff_N_nospawn 1 ... replace N with...
    • 0 = 'Easy'
    • 1 = 'Hard'
    • 2 = 'Expert'
  • The '1' enables it to not spawn and 0 would allow it to spawn (the default)

Placing Entities at Different Locations on Different Difficulty Settings

There is a special spawnarg to change the location and rotation of an entity on different difficulty levels:


"diff_N_change_0" "origin"
"diff_N_arg_0" "-2530 795 -5"

"diff_N_change_1" "rotation"
"diff_N_arg_1" "315"

... where N is the difficulty 0, 1, or 2

(note that the number "x" in "change_x" must correspond to the "arg_x" value in the example above)

This is another method but not needed if you use the above...

You can position an entity in different locations on different difficulty levels. To do this...

  • Clone the entity so you have one copy for each location you want.
  • Optionally rename the entities, eg, sceptor_easy, sceptor_hard, sceptor_expert
  • Add the properties and values, eg, for the one to be used on Easy you would exclude Hard(1) and Expert(2)...
    • diff_1_nospawn 1
    • diff_2_nospawn 1
  • Move the entities to the locations you want.

Objectives: If the entity is an objective then you will need three objectives each having their own difficulty setting (see Objectives)

Inventory Name Clash: If testing with no difficulty settings set then all three copies of the entity will appear the in the mission. In that case if the entity can go in the player inventory, each must have an exclusive inventory name or only the first one can be frobbed (if already in inventory at start not sure - maybe error or only one show.) You can get round that by varying the inv_name property on each, eg, 'A sceptor', 'The sceptor', 'Sceptor', 'Lord's sceptor' but you might want to change those back to one name after testing.

Changing Properties on Entity Instances based on Difficulty Settings

As an example, say you wanted a statue on medium difficulty to face 90 degrees instead where it faces on easy difficulty, 0 degrees. On that instance of the statue, you could add the properties:

"diff_1_change_0" "angle"
"diff_1_arg_0" "90"

Translated: At difficulty 1 (medium), the first (0) of a possible list of changes, is applied to the property called "angle". The value of the corresponding change is then passed by the arg(ument) keypair, and is "90".

The properties of individual entities can be controlled with difficulty level in this manner, in contrast to the Difficulty Editor, which changes classes instead of instances.

Relative Changes

You can either assign new values to spawnargs (like the "angle" "90" example above) or change spawnargs relatively to the existing values. Both additive and multiplicative changes are possible:

Add 45 degrees to the "angle" property like this:

"diff_1_change_0" "angle"
"diff_1_arg_0" "+45"

Double the "health" property with this:

"diff_1_change_0" "health"
"diff_1_arg_0" "*2"

The important part is to use the asterisk *, plus + or minus - sign to indicate relative changes.

Changing CVARs

You can affect CVARs by placing spawnargs like these on the entities:

"diff_1_cvar_0" "tdm_player_default_health"
"diff_1_arg_0"  "40"
"diff_1_cvar_1" "tdm_player_default_height"
"diff_1_arg_1"  "+8"

The above two spawnargs will be activated on difficulty level 1 (Hard) and will set the CVARs tdm_player_default_health to 40 and increase tdm_player_default_height by 8.

Changing Global Variables

You can change cvars across the entire map (for example, all AI HP, rather than just one) easily. See Difficulty Editor for more info.

Changing the Difficulty Level Names

Mappers can change the default names of the difficulty levels, eg, for style, story, or type. For example, suppose in your mission you want one level to include no kills or KOs and add other obstacles so the player has a richer experience playing more stealthily you might want to call it say "Stealthy". Then another difficulty level in your same mission where you put extra enemies in brightly lit areas that the player can only get past by fighting them then you might want to call it say, "Warrior". Another idea you might have would be "Extra Clues". To do this...

  • Select any worldspawn brush or patch
  • Add the following properties and values:
    • difficulty0Name Extra Clues
    • difficulty1Name Warrior
    • difficulty2Name Stealthy

Other suggested styles :"Assassin", "Ninja", "Key Hunt" and so on.

Testing Different Difficulty Settings

To test an uninstalled map on different difficulty levels

  • Select any worldspawn brush or patch
  • Add the following property and value:
  • difficulty N ... replace N with...
    • 0 = 'Easy'
    • 1 = 'Hard'
    • 2 = 'Expert'

There is also a CVAR tdm_difficulty which can be used to override any map-specific or menu-chosen setting. Set the CVAR

tdm_difficulty 2

in the console before starting the map and it will always be using this level. Set the CVAR back to -1 (default) to disable the override. This setting is not saved between sessions to prevent it from unintentionally overriding your settings.

Determining the Current Level From a Script

Function getDifficultyLevel returns a float of 0, 1, or 2, e.g.:

 if(sys.getDifficultyLevel() == 2)

An Example

A number of these techniques are shown in Springheel's Speed Build Challenge - Part 8, starting in the video's second half, around 14:25. This includes the difficulty-dependent variation of:

  • AI paths
  • radius of a torch, and range and angles of lights
  • whether AI will relight an extinguished flame
  • overall lightgem level (using the Difficulty Editor), to affect the ability of AI to see the player throughout the game.