Skip to content

Map Settings

#xoxor4d edited this page Aug 13, 2025 · 4 revisions

Note

I'll try to keep this wiki updated. This wiki does not cover each and every subsetting.
Please always refer to the comments in the map_settings.toml file. It will always reflect the latest functionality.



Tweakable Fog

To change or configure fog for a specific map, open the in-game gui by pressing F5 and go to the MapSettings tab or open the map_settings.toml file in root/l4d2-rtx and add or edit an existing entry under [FOG]

Legacy Fog settings.
Slightly deprecated - Use Map Configs with remix volumetric-system settings when possible.


[FOG]
    c1m1_hotel = { distance = 15000, color = [100, 100, 100] }
    c1m2_streets = { density = 0.000210, color = [120, 107, 79] }

Parameters

Parameter Only One Description Type / Range Default
distance x use linear fog; larger -> less fog float (priority over density if both are defined)
density x use exponential fog; larger -> more fog float [0-1]
color R G B transmission 3D Vector [0-255]

You can further tweak fog visuals by modifying remix runtime settings. This can also be done per map under the [CONFIGVARS] section.




Tweakable Water Settings

To change or configure water settings for a specific map, open the in-game gui by pressing F5 and go to the MapSettings tab or open themap_settings.toml file in root/l4d2-rtx and add or edit an existing entry under [WATER]

Adjust various water related settings per map.
The compatibility mod always spawns a secondary surface with the same size as the original water surface.


[WATER]
    c3m2_swamp = { scale = 10.0, top_layer_offset = 0.0, bottom_layer_offset = -0.25 }
    c3m3_shantytown = { scale = 20.0 }

Parameters

Parameter Description Type / Range Default
scale uv scale - small values reduce repetition while larger values will increase tiling float 1.0
top_layer_offset can offset the dual rendered water mesh along the Z-Axis (usually the animated surface) float 0.5
bottom_layer_offset can offset the original water mesh along the Z-Axis (usually the surface defining water color) float 0.0



Tweakable Culling

To make culling related changes for a specific map, open the in-game gui by pressing F5 and go to the MapSettings tab or open the map_settings.toml file in root/l4d2-rtx and add or edit an existing entry under [CULL]

We need some form of culling in this game to improve the performance. The current system (default setting) forces visibility for everything inside a specified range around the player. Everything outside that area can get culled by frustum culling (and other game mechanics). This will lead so some issues in a fully pathtraced game.

There will be:

  • light bleed
  • lights turning off due to culling
  • entire areas getting culled on larger outdoor maps (which the og. game hides using very dense fog)

Fix light bleed / culled lights

tba .. add images

[CULL]
    c1m1_hotel = [
        { area = 4, leafs = [55, 712] },
    ]

Force Area Visibility

[CULL]
    c1m1_hotel = [
        { area = 1, areas = [6], cull = 0 },
        { area = 2, hide_leafs = [89, 99], hide_areas = [
            { areas = [3], N_leafs = [55, 100] }
        ]},

Parameters

Parameter Sub-parameters Description Type / Range Default
in_area (req.) the area the player has to be in int
areas area/s with forced visibility int array
leafs leaf/s with forced visibility int array
cull [0] disable frustum culling
[1] disable frustum culling in current area
[2] stock
[3] frustum culling (outside current area) + force all nodes/leafs in current area
[4] ^ + outside of current area within certain dist to player (param: nocull_dist)
[5] force all leafs/nodes within certain dist to player (param: nocull_dist)
int [0-5] 5
nocull_dist Distance around the player where objects wont get culled - only used on certain cull modes float 600.0
leaf_tweak = [ ] Can be used to disable frustum culling for specified areas when the player is in specified leafs
Useful at area crossings when used in conjunction with nocull - area-specific markers that block visibility
array of structure below
> in_leafs the leaf/s the player has to be in int array
> areas area/s with forced visibility int array
> leafs leaf/s with forced visibility int array
> nocull_dist uses per leaf value instead of area value if defined int array
hide_areas = [ ] This can be used to forcefully cull parts of the map array of structure below
> areas area/s to hide int array
> N_leafs only hide area/s when NOT in leaf/s int array
hide_leafs force hide leaf/s int array

Useful console commands:

- 'xo_debug_toggle_node_vis'     :: to visualize current node/leaf and area



Hide Models

To change or configure model hiding for a specific map, open the map_settings.toml file in root/l4d2-rtx and add or edit an existing entry under [HIDEMODEL]

This can be used to hide models. Eg. when a certain model is used a lot, it can make sense to hide them and manually re-add the models by adding them as references to Map Markers via the remix toolkit. This will help with CPU Bottlenecks on larger maps.


[HIDEMODEL]
    c1m1_hotel = { radius = [
            6.1857576, #models/props_junk/garbage_sodacan01a_fullscheet.mdl
    ]}

Parameters

Parameter Description Type / Range
name force hide models containing the specified substring string array
radius force hide models with this radius (checking for radii is generally faster and the preferred way to filter models) float array

Useful console commands:

- 'xo_debug_toggle_model_info'    :: to show required prop info (name, radius)



Unbake Models

To change or configure model unbaking, open the map_settings.toml file in root/l4d2-rtx and add or edit an existing entry under [UNBAKE]

If a prop has many unique or unstable hashes (remix) then it's likely that it's vertices contain world position data. Unbaking allows you to prevent the game engine from baking position/rotation/normal information into the model vertices, thus resulting in stable hashes and replaceable props.

Important

This should only be used on props that have a single bone and only if you actually intend to replace the mesh or attach something to it.
Using this on anything else will break animations that are played on the model.


[UNBAKE]
    # use ALL to unbake prop on all maps
    ALL = { checksum = [
        0x6f769ab6, # chair_cafeteria.smd
    ]}

    # only unbake specified props on this level
    c8m4_interior = { checksum = [
        0xc18d886e, # styrofoam_cups.smd
        0x26fa7caa, # styrofoam_cups_p1.smd
        0x6fe3a6a6, # styrofoam_cups_p2.smd
        0xa6a03504, # styrofoam_cups_p3.smd
        0xfa58eac3, # styrofoam_cups_p4.smd
    ]}

Parameters

Parameter Description Type / Range
checksum force hide models containing the specified substring int array - hex format

Useful console commands:

- 'xo_mapsettings_get_unbake_info'        :: to log all currently visible model names to '/logs/mapsettings_unbake_info.log' 
- 'xo_debug_toggle_unbake_model_info'     :: for visualizations



Map Marker Spawning

To change or configure map marker spawning for a specific map, open the in-game GUI by pressing F5 and go to the MapSettings tab or open the map_settings.toml file in root/l4d2-rtx and add or edit an existing entry under [MARKER]. If you are using the GUI, make sure to export the markers to your clipboard when you are done and then manually overwrite the marker section for your map in the map_settings.toml file.

This can be used to spawn unique marker meshes which can be used to attach unique meshes or lights to.

  • This is useful if you want to add additional meshes or lights to a certain spot that has no unique anchors
  • Another idea: Attach a quad mesh to a marker, make it look like water and then spawn that marker wherever you need a puddle
  • You can also hide and show markers on certain events like playing choreographies or sounds.
[MARKER]
    c1m1_hotel = [

        # blocker on connecting hallway
        { nocull = 0, areas = [13], N_leafs = [2366, 2334, 2359, 2371, 2331, 2421, 2328, 2324, 1939, 1930], position = [1728.52, 5714.00, 2721.53], rotation = [90.00, 0.00, 0.00], scale = [2.08, 2.12, 1.00] },

        # sun
        { nocull = 1, position = [278.09, 5762.70, 2992.07], rotation = [0.00, 0.00, 0.00], scale = [1.00, 1.00, 1.00] },

        # culled marker
        { marker = 5, position = [500.0, 5000.0, 2500.0], rotation = [0.00, 0.00, 0.00], scale = [1.00, 1.00, 1.00] },

        # hide marker by default, show when any pistol sound is playing, hide every time a certain choreo is playing on actor
        { nocull = 0, trigger = { show = { sound = "weapons/pistol/", delay = 1.0 }, hide = { choreo = "choreo_name.vcd", actor = "actor_name" }, always = true }, position = [537.72, 5652.03, 2909.78], rotation = [1.50, -66.60, 0.00], scale = [1.00, 1.00, 1.00] },
    ]

Parameters

Parameter Only One Sub-parameters Description Type / Range Default
marker x number of marker mesh - can get culled BUT that can be controlled via leaf/area forcing (initial spawning can't be forced) int [0-99]
nocull x number of marker mesh - never getting culled and spawned on map load (eg: useful for distant light) int [0-inf]
trigger show = { } (opt.) show markers via choreography (.vcd) or sound (spawns marker on map load if not defined - hides it by default if defined) { struct } of parms below
> x choreo = name of choreography (.vcd) (can be a substr) string
> > actor = (opt.) name of actor the event is played on string
> > event = (opt.) name of the event within the .vcd (can be a substr) string
> > param1 = (opt.) name of the event within the .vcd (can be a substr) string
> x sound = EITHER substring of sound name = "sound_substring"
OR hash = 0x133337 (cmd: see desc.)
string OR integer in hex format
> delay = delay after trigger (in seconds) float
> hide = { } (opt.) hide markers via choreography (.vcd) or sound { struct } of same parms as show
> -- ^ -- same parameters as show
areas (opt.) only show nocull marker when player is in specified area/s int array
N_leafs (opt.) only show nocull marker when player is in ^ and NOT in specified leaf/s int array
position position of the marker mesh 3D Vector
rotation rotation of the marker mesh 3D Vector
scale scale of the marker mesh 3D Vector

Useful console commands:

- 'xo_debug_scene_print'        :: (choreo trigger/kill)  prints info about ongoing choreographies to the in-game console) 
- 'xo_debug_sound_print'        :: (sound trigger/kill)   prints info about ongoing sounds to the in-game console)



Remix Config Loading / Transitions

This system can be used to adjust remix config options per map or set certain settings on certain game events such as playing sounds or choreographies.
It supports various options and can smoothly transition between remix option values.


Load configs on map start

  • Create a mapname.conf in l4d2-rtx/map_configs/ and include all the remix variables you want to change when the map with that name loads. This file will be loaded automatically if it exists. Eg. xyz.conf will be loaded if map xyz.bsp loads.
  • You can load additional config files by adding the map name under [CONFIGVARS]
[CONFIGVARS]
    c1m1_hotel = { startup = ["chromatic.conf", "asd.conf"] }
  • This will first load c1m1_hotel.conf (if it exists) followed by chromatic.conf & asd.conf

Transitions / Events

  • You can also load config's on certain events like:
    • Player enters a specified leaf (area of the map)
    • A specified choreography (.vcd) starts to play
    • A specified sound starts to play
[CONFIGVARS]

    c1m1_hotel = { transitions = [
        { conf = "example1.conf", trigger = { sound = 0x31c790a5 }, mode = 0, duration = 16.0, delay_in = 18.0 },
        { conf = "chromatic_explosion.conf", trigger = { choreo = "scenes/", actor = "", event = "angry - dialogue" }, mode = 2, ease = 8, duration = 0.5, delay_in = 0.0, delay_out = 0.15 },
        { conf = "fire_smokey_screen.conf", trigger = { leafs = [4364] }, mode = 2, ease = 8, duration = 5.0, delay_in = 0.5 },
  1. example1.conf will be triggered when a sound with hash 0x31c790a5 starts playing. It will only trigger once and takes 16s to transition to example1.conf values after an initial delay of 18s.

  2. chromatic_explosion.conf will be triggered whenever a choreo containing the substr scenes/ and an event substr containing angry - dialogue starts playing.

  3. fire_smokey_screen.conf will be triggered with a 0.5s delay (delay_in) when the player enters leaf number 4364.
    Setting mode = 2 will always re-trigger this upon re-entering the leaf. Using ease = 8 sets the easing mode to EXPO_OUT.

Parameters

Parameter Sub-parameters Sub-parameters 2 Only One Sub-parameters 3 Description Type / Range
startup configs that will be loaded on map-load, conf matching the map name will be loaded automatically and does not need to be specified array of strings
transitions = [ ] load / transition to config values on specified events array of structure below
> conf name of config containing remix (goal) variables string
> trigger = { } trigger config loading / transition via choreography (.vcd), sound or leaf
> choreo = { } x name of choreography (.vcd) that will trigger the transition (can be a substring) string
> actor (opt.) name of actor the event is played on string
> event (opt.) name of the event within the .vcd (can be a substr) string
> param1 (opt.) name of param1 within the .vcd (can be a substr) string
> sound x hash made up of name, index and position (cmd: see desc.) OR substring of soundname integer [hex] OR string
> leafs x leaf's that will trigger the transition
[!] moving from one leaf to another connected & defined leaf will not trigger the transition
int array
> mode [0] ONCE: On Enter/Start
[1] ONCE: On Leave/End (will only be activated once - until map or map_settings reload)
[2] ALWAYS: On Enter/Start
[3] ALWAYS: On Leave/End (sounds only use ONCE or ALWAYS 0-1 or 2-3)
int [0-3]
> ease [0] LINEAR
[1] SIN_IN
[2] SIN_OUT
[3] SIN_INOUT
[4] CUBIC_IN
[5] CUBIC_OUT
[6] CUBIC_INOUT
[7] EXPO_IN
[8] EXPO_OUT
[9] EXPO_INOUT
int [0-9]
> duration transition time (in seconds) float
> delay_in delay start of transition (in seconds) float
> delay_out delay between end of transition and transition back to the initial starting value (in seconds) - only active if value > 0 float

Useful console commands:

- 'xo_debug_scene_print'           :: (choreo trigger/kill)  prints info about ongoing choreographies to the in-game console) 
- 'xo_debug_toggle_node_vis'       :: (leaf trigger/kill)    draws info about current leaf the player is in (2D and 3D))
- 'xo_debug_sound_print'           :: (sound trigger/kill)   prints info about ongoing sounds to the in-game console)



Spawning / Animating of Lights

Introduction

Creating lights using the remix toolset is not always trivial.

  1. Requires stable hashes
  2. Requires stable & unique meshes if you want to do per map lighting (if you want to create lights in a specific area that should not replicate to other maps).
  3. Animating lights is not yet possible

To create lights via the compatibility mod, open the in-game gui by pressing F5 and go to the MapSettings tab and enable Light Edit Mode or open the map_settings.toml file in root/l4d2-rtx and add or edit an existing entry under [LIGHTS]


Lights can loop endlessly until they are removed by events (choreo / sound) or only run until they reach their animation endpoint.

1. Creating the most basic light (static and alive until a new map gets loaded):

    # red light at map center
    { points = [
        { position = [0.0, 0.0, 0.0], radiance = [10.0, 0.0, 0.0], scalar = 4.0, radius = 3.0 },
    ]},

2. Animated light (alive until a new map gets loaded):

    # red light at map center smooth on to off with hard cut to OFF
    { points = [
        { position = [0.0, 0.0, 0.0], radiance = [10.0, 0.0, 0.0], scalar = 4.0, radius = 3.0 },
        { position = [0.0, 0.0, 0.0], radiance = [10.0, 0.0, 0.0], scalar = 0.0, radius = 3.0, timepoint = 1.0 }, # 2nd point with timepoint
    ], loop = true }, # loop var
  • Addition of a second point to the points array
  • Second point (the last point) has a timepoint variable -> the light will reach the "goal" of the second point after 1 second
  • Added the loop variable which will immediately restart the animation after reaching the "goal" of the very last point
    (not adding the loop variable here would result in the light doing the animation once and staying at the goal of the very last point)

The above has a very hard cut from the last to the first point (it goes from being OFF to immediately ON on loop restart). If this is not desired, you could either:

  1. loop_smoothing

    Add the loop_smoothing var like so:

    ], loop = true, loop_smoothing = true },

    Doing this will automatically create a third point to smoothly transition back to the first point. The total light duration will stay at 1 second.
    In order to meet the 1 second total, every prior timepoint gets automatically adjusted.
    This means that the light will fade from ON to OFF in 0.5s and back to ON in another 0.5s, thus completing the loop in a total of 1s.


  1. first as last point

    Another way would be to copy the very first point and use it as the very last point giving you more overall control.

    { points = [
        { position = [0.0, 0.0, 0.0], radiance = [10.0, 0.0, 0.0], scalar = 4.0, radius = 3.0 },
        { position = [0.0, 0.0, 0.0], radiance = [10.0, 0.0, 0.0], scalar = 0.0, radius = 3.0 }, # 2nd point WITHOUT timepoint
        { position = [0.0, 0.0, 0.0], radiance = [10.0, 0.0, 0.0], scalar = 4.0, radius = 3.0, timepoint = 1.0 }, # last == very first point
    ], loop = true }, # loop var

    I've removed the timepoint of the second point in this example. Only the very last point requires a timepoint. Segment time will be calculated and smoothly distributed between all points between the last and next point defining a timepoint. As in #1, the light will smoothly transition to OFF (2nd point) in 0.5s and back to ON (3rd) in another 0.5s


3. Animated spotlight with choreo trigger:

    # rotating spotlight when actor X does Y
    { trigger = { choreo = "scenes/c1m1_", event = "angry - dialogue", delay = 0.1, always = true }, points = [
        { position = [100.0, 50.0, 300.0], radiance = [10.0, 0.0, 0.0], radius = 0.0, smoothness = 1.0, direction = [0.0,  0.0,  1.0], degrees = 30.0 },
        { position = [100.0, 50.0, 300.0], radiance = [0.0, 10.0, 0.0], radius = 5.0, smoothness = 1.0, direction = [0.0,  0.7,  0.7], degrees = 30.0 },
        { position = [100.0, 50.0, 300.0], radiance = [0.0, 0.0, 10.0], radius = 5.0, smoothness = 1.0, direction = [0.0,  0.0, -1.0], degrees = 30.0 },
        { position = [100.0, 50.0, 300.0], radiance = [0.0, 0.0, 10.0], radius = 5.0, smoothness = 1.0, direction = [0.0, -0.7, -0.7], degrees = 30.0 },
        { position = [100.0, 50.0, 300.0], radiance = [10.0, 0.0, 0.0], radius = 0.0, smoothness = 1.0, direction = [0.0,  0.0,  1.0], degrees = 30.0, timepoint = 4 },
    ], run_once = true }, # remove the light once the animation is finished

Trigger:

  • choreo: (always required) choreographies that contain scenes/c1m1_ in their name will trigger light creation (if that is the only requirement)
  • event: (optional) event strings containing angry - dialogue will trigger light creation (choreo and event need to be fullfilled to trigger light creation)
  • delay: (optional) delay light creation after trigger (in seconds)
  • always: (optional) having this enabled will constantly re-trigger light creation every time a matching choreography starts to play

To summarize: Whenever a choreo with a name that contains scenes/c1m1_ + a choreo-event containing angry - dialogue starts to play, light creation will be triggered.
Using the always var will constantly re-trigger the creation of the light. Defining run_once = true will remove the light after reaching the very last point.

Spotlight:

  • direction: defines the direction of the light. The vector will be normalized in-code. The example above will rotate (roll) the light 360° over a timespan of 4 seconds.
  • degrees: cone angle in degree (anything below 180° enables light-shaping)

Other;


4. Animated lights with sound trigger and choreo kill trigger

    # rotating spotlight when actor X does Y
    { trigger = { sound = 0xe826cc9a, delay = 1.0 }, kill = { choreo = "scene/xyz.vcd" }, points = [
        { position = [0, 0, 0], radiance = [1, 0, 0], radius = 10.0, scalar = 50.0 },
    ]},

This will trigger light creation when a sound with hash 0xe826cc9a starts playing. To get sound hashes for playing sounds, use console command xo_debug_toggle_sound_print. The light will stay on until it gets destroyed when a choreo named scene/xyz.vcd starts playing. To get information about playing choreo's, use console command xo_debug_scene_print.

Parameters

Parameter Only One Sub-parameters Description Type / Range Default
trigger (opt.) = { } x sound (required or below) hash made up of name, position etc. that will trigger light spawning Int (hex format)
x choreo (required or above) name of choreography (.vcd) that will trigger light spawning String (substring)
-> actor (opt.) name of actor the event is played on (to further filter the above) String (substring)
-> event (opt.) name of the event within the .vcd (to further filter the above) String (substring)
-> param1 (opt.) first param of the event (to further filter the above) String (substring)
delay delay spawn after trigger (in seconds) Float [0-Inf] 0s
always can be retriggered, spawns a new light instance everytime Bool False
kill (opt.) = { } x sound hash made up of name, position etc. that will kill the light UInt (hex format)
x choreo name of choreography (.vcd) that will kill the light String (substring)
points (req.) = [ ] position (req.) X Y Z coordinates of light
[!] first point needs to define a position
[!] following ones will use the last defined position if position is not defined
3D Float Vector
radiance R G B radiance of light 3D Vector [0-Inf] 10 10 10
scalar Radiance scalar Float [0-Inf] 1
volumetric_scale volumetric scale of the light Float [0-10] 1
radius Radius of light Float [0-Inf] 1
smoothness Segment smoothness (values above 1 might produce odd results) Float [0-Inf] 0.5
timepoint (*req.) Time in seconds at which the light arrives at the point. (evenly distributed if not specified)
[!] first timepoint is always 0
[!] timepoints can not be out of order
[!] last point requires a timepoint and defines the total duration
Float (0-Inf)
direction Light shaping - light direction (will be normalized in code) 3D Vector [0-Inf] 0 0 1
degrees Light shaping - cone angle - > / < 180° turns ON light shaping Float [0-360] 180
softness Light shaping - cone softness Float [0-PI] 0
exponent Light shaping - focus expo Float [0-1] 0
run_once (opt.) x Destroy light after reaching the last point (goal) Bool False
loop (opt.) x Create a looping light, restart after reaching the last point (goal) Bool False
loop_smoothing (opt.) Automatically connect and smooth the start and end point
[!] requires 'loop' to be true
[!] only position + timepoint is used from the last point
Bool False

Useful console commands:

- 'xo_debug_scene_print'           :: (choreo trigger/kill)  prints info about ongoing choreographies to the in-game console) 
- 'xo_debug_toggle_sound_print'    :: (sound trigger/kill)   prints info about ongoing sounds to the in-game console)