Stim/Response: Difference between revisions

From The DarkMod Wiki
Jump to navigationJump to search
m Categorized
Datiswous (talk | contribs)
 
(13 intermediate revisions by 5 users not shown)
Line 1: Line 1:
'''Stim/Response system for The Dark Mod'''
This article describes how the stim/response system works for '''The Dark Mod'''. The name is taken from the Dromed Stim/Response system. However this does '''not''' mean that you should assume any other similarities. The system was described to me (sparhawk) and I coded it accordingly, but I have no Dromed experience, beyond some '''very''' simple maps, without any special features. I never got beyond the "Create a room and texture it" stage. :)
This article describes how the stim/response system works for '''The Dark Mod'''. The name is taken from the Dromed Stim/Response system. However this does '''not''' mean that you should assume any other similarities. The system was described to me (sparhawk) and I coded it accordingly, but I have no Dromed experience, beyond some '''very''' simple maps, without any special features. I never got beyond the "Create a room and texture it" stage. :)
So while this system may be similar on how it works as seen by the users, you can't assume that this is is more then a fleeting similarity as defined by it's common requirements.
So while this system may be similar on how it works as seen by the users, you can't assume that this is is more then a fleeting similarity as defined by it's common requirements.


== How does it work? ==


The general concept is pretty easy to understand. The mapper populates his map with entities. Each of these entities can be either a kind of actor (a stim) or an actee (the response). Any entity can be both at the same time, however stims don't affect the owner itself. So if the entity carries a stim and it triggers, it will not act on himself, even if the entity has a response for that stim.
Stims and responses are defined by numbers. '''The Dark Mod''' already defines some very common stims (like water) and reserves numbers for them. For a complete list you should take a look at tdm_stim_response.script in the script folder. You will notice that there is one stim named USER. This stim has no special meaning. Instead it defines the lowest number that users can use for themselves. So if you define new stims to be used in your maps, you should use USER+N for your individual stims. All numbers below USER are assumed to be known stims and may trigger specific actions if needed, which possibly includes specific SDK support code.


'''How does it work?'''
As explained above, stims and responses are identified by their id's (the numbers). Whenever a stim is active, the system evaluates all stims and checks if appropriate responses are within its reach. A response is identified by having the same id as the stim. When such a response is found, the response is triggered and a script action is executed for it. If the response doesn't have a script action associated, nothing will happen, but this is usually a waste of CPU, unless the response is coded in C++ directly in the SDK.
 
One major difference between stims and responses is that responses have an action associated with them, while stims don't.
The general concept is pretty easy to understand. The mapper populates his map with entities. Each of this entities, can be either a kind of actor (a stim) or an actee (the response). Any entity can be both at the same time, however stims don't affect the owner itself. So if the entity carries a stim and it triggers, it will not be act on himself, even if the entity has a response for that stim.
Stims and responses are defined by numbers. '''The Dark Mod''' already defines some very common stims (like water) and reserves numbers for them. For a complete list you should take a look at thje darkmod_stim_response.script in the script folder. You will notice that there is one stim named USER. This stim has no special meaning. Instead it defines the lowest number that users can use for themself. So if you define new stims to be used in your maps, you should use USER+N for your individual stims. All numbers below USER are assumed to be known stims and may trigger specific actions if needed, which possibly includes specific SDK support code.
 
As explained above, stims and responses are identified by their id's (the numbers). Whenever a stim is active, the system evaluates all stims and checks if appropriate responses are within it's reach. A response is identified by having teh same id as the stim. When such a response is found, the response is triggered and a script action is executed for it. If the response doesn't have a scriptaction associated, nothing will happen, but this is usually a waste of CPU, unless the response is coded in C++ directly in the SDK.
One major difference between stims and responses is, that responses have an action associated with it, while stims don't.
 
Stims and responses can be enabled and disabled at runtime. This is not only a feature, it is very important for the health of the system. If stims are not destroyed after they are used up, they will take up memory and hog your machine down after time. Also accumulating stims will cause the system to respond slower after time, as more and more stims have to be tested. For example: The arrows (like the water arrow) will spawn an entity that carries the water stim, when the arrow explodes. If that stim is not destroyed, it will continue to fire. Once a water arrow is exploded it doesn't makes sense though to keep it running, so it has to be destroyed. However, there is no definite rule when a stim has to be destroyed because it depends on their actual usage. Some stims may run throughout the game and others should be destroyed after they are used up.
 
 
'''How to set it up?'''
 
Bascially there are several methods to create a stim/response. The most obvious one is to add it in the SDK code, but this is probably the least prefered. For all practical purposes, stims and responses should be added either via scripting or the map editor, without the need of coding in the SDK environment.
 
'''Setting it up in the map editor'''
 
For this I use as an example a candle that should be stimmed by water and fire. The water stim will turn it off, while the fire stim will turn it back on. The actual water and fire stims don't need to be created here, because they are created through the water, resp. fire arrow.
 
The first thing you do is to create brush and assign a candle model to it.
Then create one or more lights, that will carry the light of your candle, as the candle itself doesn't have lighting properties. Note down the names of the lights or change them to something you might recognize.
 
Add the following keys:
  "sr_class_1" "R"
  "sr_type_1" "STIM_WATER"
  "sr_state_1" "1"
  "sr_script_STIM_WATER" "response_water_action"
  "sr_argc" "2"
  "sr_argv_1" "ligth1_name"
  "sr_argv_2" "light2_name"
  "sr_model_1" "candle_turned_off"


  "sr_class_2" "R"
Stims and responses can be enabled and disabled at runtime. This is not only a feature, it is very important for the health of the system. If stims are not destroyed after they are used up, they will take up memory and hog your machine down over time. Also accumulating stims will cause the system to respond slower over time as more and more stims have to be tested. For example: The arrows (like the water arrow) will spawn an entity that carries the water stim when the arrow explodes. If that stim is not destroyed, it will continue to fire. Once a water arrow is exploded it doesn't makes sense though to keep it running, so it has to be destroyed. However, there is no definite rule when a stim has to be destroyed because it depends on its actual usage. Some stims may run throughout the game and others should be destroyed after they are used up.
  "sr_type_2" "STIM_FIRE"
  "sr_state_2" "1"
  "sr_script_STIM_FIRE" "response_fire_action"
  "sr_model_2" "candle_turned_on"


Depending on type (Stim or response) some keys are only valid for stims and others only for responses while some others are shared. Since an entity can have multiple different stims and responses, each type has a number in the keyname. However some keys don't need the number. Since each stimtype can exist only once per entity, the script for a given stim can only exist once, even though the scriptname can be reused multiple times (which is not recommended though) or for different stimtypes.
== How to set it up? ==


If you want to have multiple stims/responses for the same entity just increase the number on the class.The numbers may have no gaps.
Bascially there are several methods to create a stim/response. The most obvious one is to add it in the SDK code, but this is probably the least preferred. For all practical purposes, stims and responses should be added either via scripting or the map editor, without the need of coding in the SDK environment.


The following keys are mandatory and must be set for every stim/responsetype.
== Configuring Stims/Responses in DarkRadiant ==
Since release 0.9.0 [[DarkRadiant]] is capable of setting up stims and responses via a graphical interface. To open the Stim/Response Editor, select your entity and choose the command from the menu.


  "sr_class_1" "R"
--> Screenshot goes here
This key defines wether the entity gets a stim (S) or a response (R). Other values will be ignored and nothing is created. The stim/response is attached to your entity when it spawns.


  "sr_type_1" "STIM_WATER"
The [[Stim/Response Editor]] will pop up and allow you to define stims and responses for your entity. I'll go briefly over the properties of stims and responses in the following sections.
This defines the id of the stim or response and must be defined for both classes. You can either use a name, which must be the same as provided by the darkmod_stim_response.script or a number. For user defined stimtypes only numbers are recognized. In case of predefined stmitypes you can also use the number, but using the name is more rcognizable. So in this case you could also write "sr_type_1" "2", which is the id for the water stim. Howevery, if you do this, you must keep in mind that the script key must use the same syntax. In this case instead of writing "sr_script_STIM_WATER" it would also need to be "sr_script_2".


  "sr_state_1" "1"
=== Stims ===
This key determines wether the stim or response is enabled (1) or disabled (0). If the stim/response is disabled it will not fire (or get triggered).
A Stim is the equivalent to DromEd's Source and can be of various types (Frob, Heal, Damage, Trigger, Sound, Visual, Communication, whatever). Each stim can be either active or inactive, which can be controlled via ticking the checkbox "Active" accordingly.


  "sr_script_STIM_WATER" "response_water_action"
Most stims need to have a '''radius''' defined, that specifies their action area. The radius is measured in Doom Units and its value depends on the purpose of your stim. A torchflame for example has a Fire Stim with a radius of 10, which is fairly small (~25 cm, ~10 inches). One can also set up a stim whose radius is growing during the stim's lifetime, by setting '''radius_final''' (this requires a non-zero '''duration''' being set on the stim).
This key defines the response action script that should handle the response when it is triggered. Note that the name must match the stim id. So if you have a numbered id, then you must name the key accordingly (i.e. "sr_type_1" "100" -> "sr_script_100"). For how to apply the ids, also look at the sr_type description above.


The second important parameter is the '''magnitude''' of the stim. For instance, the fire stim of a torch is supposed to have a smaller magnitude than a lava stream.


The now following keys are scripted and may be changed for different actions. This is for the default implementation though on the water stim. So if you want to do something different you can ignore these keys entirely and write your own script to handle the response.
The magnitude can be either constant over the whole stim range or follow a certain falloff function as defined by the '''falloff exponent'''. A falloffexponent of 0 means that the magnitude is constant over the whole range, which is the default:


  "sr_model_1" "candle_turned_off"
* 0 = no falloff (magnitude is constantly at maximum value over the whole radius)
This key defines a model that should be swapped in for the existing model, when this response is triggered. In our case we want to replace it with a turned off candle (and possibly add a smoke particle trail for a few seconds).
* 1 = linear falloff
* 2 = quadratic falloff
* 3 = etc.


  "sr_argc" "2"
The higher the number, the faster the magnitude is decreasing with the distance. The magnitude is reaching zero as soon as the distance of the responding object is greater than or equal to the stim radius, except for falloffexponent = 0 (no falloff). Negative values are allowed as well, making it possible to actually increase the magnitude of a stim with larger distance < radius. Don't know if that makes sense, though, and I haven't tested it either.
This key defines how many lights you created for the given entity. In my case I used two. These lights are switched off.


  "sr_argv_1" "ligth1_name"
== Stim/Response Key/Value Definitions ==
  "sr_argv_2" "light2_name"
These can be found here: [[Stim/Response Key/Values]] (with examples also)
These keys determine the names of the light entites, that need to be switched off when the candle is extuinguished. Consequently when the fire arrow is shot at them, these are the lights that should be relighted.


[[Category:Tutorial]]
[[Category:Tutorial]]
[[Category:Editing]]

Latest revision as of 12:50, 14 November 2022

This article describes how the stim/response system works for The Dark Mod. The name is taken from the Dromed Stim/Response system. However this does not mean that you should assume any other similarities. The system was described to me (sparhawk) and I coded it accordingly, but I have no Dromed experience, beyond some very simple maps, without any special features. I never got beyond the "Create a room and texture it" stage. :) So while this system may be similar on how it works as seen by the users, you can't assume that this is is more then a fleeting similarity as defined by it's common requirements.

How does it work?

The general concept is pretty easy to understand. The mapper populates his map with entities. Each of these entities can be either a kind of actor (a stim) or an actee (the response). Any entity can be both at the same time, however stims don't affect the owner itself. So if the entity carries a stim and it triggers, it will not act on himself, even if the entity has a response for that stim. Stims and responses are defined by numbers. The Dark Mod already defines some very common stims (like water) and reserves numbers for them. For a complete list you should take a look at tdm_stim_response.script in the script folder. You will notice that there is one stim named USER. This stim has no special meaning. Instead it defines the lowest number that users can use for themselves. So if you define new stims to be used in your maps, you should use USER+N for your individual stims. All numbers below USER are assumed to be known stims and may trigger specific actions if needed, which possibly includes specific SDK support code.

As explained above, stims and responses are identified by their id's (the numbers). Whenever a stim is active, the system evaluates all stims and checks if appropriate responses are within its reach. A response is identified by having the same id as the stim. When such a response is found, the response is triggered and a script action is executed for it. If the response doesn't have a script action associated, nothing will happen, but this is usually a waste of CPU, unless the response is coded in C++ directly in the SDK. One major difference between stims and responses is that responses have an action associated with them, while stims don't.

Stims and responses can be enabled and disabled at runtime. This is not only a feature, it is very important for the health of the system. If stims are not destroyed after they are used up, they will take up memory and hog your machine down over time. Also accumulating stims will cause the system to respond slower over time as more and more stims have to be tested. For example: The arrows (like the water arrow) will spawn an entity that carries the water stim when the arrow explodes. If that stim is not destroyed, it will continue to fire. Once a water arrow is exploded it doesn't makes sense though to keep it running, so it has to be destroyed. However, there is no definite rule when a stim has to be destroyed because it depends on its actual usage. Some stims may run throughout the game and others should be destroyed after they are used up.

How to set it up?

Bascially there are several methods to create a stim/response. The most obvious one is to add it in the SDK code, but this is probably the least preferred. For all practical purposes, stims and responses should be added either via scripting or the map editor, without the need of coding in the SDK environment.

Configuring Stims/Responses in DarkRadiant

Since release 0.9.0 DarkRadiant is capable of setting up stims and responses via a graphical interface. To open the Stim/Response Editor, select your entity and choose the command from the menu.

--> Screenshot goes here

The Stim/Response Editor will pop up and allow you to define stims and responses for your entity. I'll go briefly over the properties of stims and responses in the following sections.

Stims

A Stim is the equivalent to DromEd's Source and can be of various types (Frob, Heal, Damage, Trigger, Sound, Visual, Communication, whatever). Each stim can be either active or inactive, which can be controlled via ticking the checkbox "Active" accordingly.

Most stims need to have a radius defined, that specifies their action area. The radius is measured in Doom Units and its value depends on the purpose of your stim. A torchflame for example has a Fire Stim with a radius of 10, which is fairly small (~25 cm, ~10 inches). One can also set up a stim whose radius is growing during the stim's lifetime, by setting radius_final (this requires a non-zero duration being set on the stim).

The second important parameter is the magnitude of the stim. For instance, the fire stim of a torch is supposed to have a smaller magnitude than a lava stream.

The magnitude can be either constant over the whole stim range or follow a certain falloff function as defined by the falloff exponent. A falloffexponent of 0 means that the magnitude is constant over the whole range, which is the default:

  • 0 = no falloff (magnitude is constantly at maximum value over the whole radius)
  • 1 = linear falloff
  • 2 = quadratic falloff
  • 3 = etc.

The higher the number, the faster the magnitude is decreasing with the distance. The magnitude is reaching zero as soon as the distance of the responding object is greater than or equal to the stim radius, except for falloffexponent = 0 (no falloff). Negative values are allowed as well, making it possible to actually increase the magnitude of a stim with larger distance < radius. Don't know if that makes sense, though, and I haven't tested it either.

Stim/Response Key/Value Definitions

These can be found here: Stim/Response Key/Values (with examples also)