1 SHS Night Vision & Lights
Lucalis edited this page 2026-01-22 20:16:18 -05:00

🔦 SHS Night Vision & Lights - Complete Setup Guide

📑 Table of Contents


Overview

The SHS Night Vision & Lights system provides a complete tactical vision enhancement suite for Arma Reforger, featuring:

  • 🌙 Night Vision Goggles with multiple phosphor colors and gain control
  • 🌡️ Thermal Imaging with multiple palettes
  • 💡 Tactical Lights with flashlight, IR, and strobe modes
  • 🔴 IR Lasers visible only with NVGs active
  • 🔄 Full Multiplayer Sync with server authority

Why use this system? The SHS NV&L system integrates night vision with IR lighting - when NVGs are active, IR lights and lasers become visible. This enables realistic tactical operations where IR devices are invisible to the naked eye but visible through night vision.


Quick Start

Minimum Setup for NVG

  1. Create/open an NVG item prefab
  2. Add SHS_NightVisionComponent
  3. Set m_HDRMaterial to a phosphor color material
  4. Ensure entity has InventoryItemComponent and SignalsManagerComponent

Minimum Setup for Weapon Light

  1. Create/open a weapon attachment prefab
  2. Add SHS_NVL_LightsComponent
  3. Configure light sources in m_aSources
  4. Set a unique m_sLightIdentifier

Installation

Mod Information

Property Value
Mod ID GRSNightVisionandLights
GUID 684D2BF6887913EC
Dependency 58D0FB3206B6F859 (Base Game)

File Structure

SHS_NV_and_Lights/
├── addon.gproj
├── Scripts/
│   └── Game/
│       ├── NightVision/
│       │   ├── SHS_NightVisionComponent.c
│       │   ├── SHS_IRSystem.c
│       │   ├── SHS_IRLaser.c
│       │   └── SHS_IRLightSource.c
│       ├── Lights/
│       │   ├── SHS_NVL_LightsComponent.c
│       │   ├── SHS_NVL_NetworkComponent.c
│       │   └── SHS_NVL_HelmetLightSource.c
│       └── Thermal/
│           ├── SHS_ThermalComponent.c
│           └── SHS_ThermalSystem.c
├── Configs/
│   └── System/
│       └── chimeraInputCommon.conf
└── Prefabs/
    ├── Items/NVG/
    └── Weapons/Attachments/

Night Vision System

NVG Models

The mod includes multiple NVG models:

Model Type Prefab Location
GPNVG-18 Quad-tube panoramic Prefabs/Items/NVG/PGNVG/
PVS-31 Dual-tube binocular Prefabs/Items/NVG/PVS31/
PVS-14 Single-tube monocular Prefabs/Items/NVG/PVS14/
PVS-7 Single-tube goggle Prefabs/Items/NVG/PVS7/

Each model has multiple color variants (Black, FDE, OD, MultiCam).


NVG Component Setup

Add SHS_NightVisionComponent to your NVG item prefab.

Required Components on Entity

Component Purpose
InventoryItemComponent Item handling
SignalsManagerComponent Animation signals
BaseLoadoutClothComponent Equipment slot

Visual Materials

SHS NVG - Visuals
├── m_HDRMaterial      → Phosphor color HDR material (.emat)
├── m_GrainMaterial    → Film grain overlay (.emat)
└── m_BlemishMaterial  → Optional noise/blemish (.emat)

Material Paths:

  • Green Phosphor: Common/Postprocess/HDR_Green.emat
  • White Phosphor: Common/Postprocess/HDR_White.emat
  • Amber Phosphor: Common/Postprocess/HDR_Amber.emat

Phosphor Colors

Configure multiple selectable phosphor colors using m_aPhosphorColors:

m_aPhosphorColors (array)
├── [0] SHS_PhosphorColorOption
│   ├── m_sName: "Green (P43)"
│   └── m_Material: "{path/to/green.emat}"
├── [1] SHS_PhosphorColorOption
│   ├── m_sName: "White (P45)"
│   └── m_Material: "{path/to/white.emat}"
└── [2] SHS_PhosphorColorOption
    ├── m_sName: "Amber"
    └── m_Material: "{path/to/amber.emat}"

Note: Index 0 is the default color (uses m_HDRMaterial). Additional colors are cycled through with the palette keybind.


Brightness/Gain System

SHS NVG - Brightness
├── m_fBaseBrightness         → Starting brightness (default: 1.5)
├── m_bManualBrightnessEnabled → Allow manual adjustment (default: false)
├── m_fBrightnessStep         → Adjustment increment (default: 2.0)
├── m_fMinBrightness          → Minimum value (default: 0.05)
└── m_fMaxBrightness          → Maximum value (default: 20)
Parameter Range Description
m_fBaseBrightness 0.05 - 20.0 Initial gain when NVG activates
m_fBrightnessStep 0.5 - 5.0 How much gain changes per adjustment
m_fMinBrightness 0.01 - 2.0 Prevents completely dark image
m_fMaxBrightness 1.0 - 25.0 Prevents blown-out image

Auto-Gain System

Automatically adjusts NVG state and brightness based on time of day.

SHS NVG - Auto System
├── m_bAutoSystemEnabled      → Enable auto system (default: false)
├── m_fTransitionRate         → Adjustment speed (default: 0.5)
├── m_fAutoBrightnessFloor    → Auto minimum (default: 0.5)
├── m_fAutoBrightnessCeiling  → Auto maximum (default: 15)
├── m_iDawnHour               → Day starts (default: 7)
└── m_iDuskHour               → Night starts (default: 19)

Auto-Gain Behavior

Time Period Default State Manual Override
Daytime (7:00-19:00) NVG OFF Toggle ON → stays on until night
Nighttime (19:00-7:00) NVG ON Toggle OFF → stays off until day

The system tracks two override flags:

  • m_bDayOverride - User forced ON during day
  • m_bNightOverride - User forced OFF during night

Overrides reset on day/night transition.


Thermal Mode

Some NVGs support integrated thermal imaging.

SHS NVG - Thermal
├── m_bThermalEnabled         → Enable thermal mode (default: false)
├── m_ThermalMaterial         → Thermal effect material (.emat)
└── m_sThermalToggleAction    → Input action name

When thermal is toggled:

  1. NVG phosphor effect is replaced with thermal overlay
  2. IR visibility is disabled (thermal doesn't see IR)
  3. Heat sources become visible

Animation Setup

NVGs animate between stowed (flipped up) and deployed (flipped down) positions.

SHS NVG - Animation
└── m_sAnimationSignal        → Signal name in .siga file

Requirements

  1. SignalsManagerComponent on the NVG entity
  2. .siga file with matching signal name
  3. .pap file with procedural animation

Example .siga:

Signals {
    Signal w_nvRotator {
        Type Float
        DefaultValue 1
    }
}

Animation Logic:

  • Signal value 0 = NVG deployed (down)
  • Signal value 1 = NVG stowed (up)

Lights System

Light Component Setup

Add SHS_NVL_LightsComponent to weapon attachments, helmets, or any entity.

Core Configuration

SHS_NVL_LightsComponent
├── m_sLightIdentifier        → Unique ID for network sync
├── m_aSources                → Array of light sources
├── m_sToggleAction           → Flashlight input action
├── m_sToggleIRAction         → IR input action
├── m_sBrightnessUpAction     → Brightness increase action
└── m_sBrightnessDownAction   → Brightness decrease action

Brightness Settings

├── m_fDefaultFlashlightBrightness → Default visible (default: 6.0 LV)
├── m_fDefaultIRBrightness         → Default IR (default: 1.0 LV)
├── m_fMinBrightness               → Minimum (default: 0.1 LV)
├── m_fMaxBrightness               → Maximum (default: 6.0 LV)
└── m_fBrightnessStep              → Step size (default: 0.2)

Light Source Configuration

Each light source is defined using SHS_NVL_HelmetLightSource:

SHS_NVL_HelmetLightSource
├── m_Prefab          → Light entity prefab
├── m_Offset          → PointInfo attachment position
├── m_bIsFlashlight   → Is this a visible flashlight?
├── m_bIsIR           → Is this an IR light?
└── m_sSoundEvent     → Sound on toggle

Light Types

Type m_bIsFlashlight m_bIsIR Visibility
Flashlight true false Always visible
IR Illuminator false true Only with NVG
Dual-Mode true true Depends on mode

Example: M600V Scout Light

m_aSources
├── [0] Flashlight Source
│   ├── m_Prefab: "{...}/FlashlightLight.et"
│   ├── m_Offset: (PointInfo on lens bone)
│   ├── m_bIsFlashlight: true
│   └── m_bIsIR: false
└── [1] IR Source
    ├── m_Prefab: "{...}/IRLight.et"
    ├── m_Offset: (PointInfo on lens bone)
    ├── m_bIsFlashlight: false
    └── m_bIsIR: true

Light Identifier System

The m_sLightIdentifier enables network sync when multiple lights exist on one character.

Why is this needed? In multiplayer, attachment entities (like weapon lights) can have different internal IDs on different machines. The Light Identifier provides a reliable, human-readable way to match lights across the network.

Naming Convention

Entity Type Suggested Identifier
Weapon Light "WeaponPEQ15", "WeaponM600V"
Helmet Light "HelmetLight", "HelmetStrobe"
Chest Light "ChestIR", "ChestStrobe"

Rules:

  • Must be unique per character
  • Use descriptive, consistent names
  • Keep under 32 characters

IR Integration

IR lights integrate with the SHS_IRSystem singleton.

How IR Visibility Works

┌─────────────────────────────────────────────────────┐
│                    SHS_IRSystem                     │
│  ┌───────────────────────────────────────────────┐  │
│  │ Tracks global NVG active state for local player│  │
│  └───────────────────────────────────────────────┘  │
│              ↓ OnNVGStateChanged()                  │
│  ┌───────────────────────────────────────────────┐  │
│  │ Notifies all registered light components       │  │
│  │ - SHS_NVL_LightsComponent                      │  │
│  │ - SHS_IRLaser                                  │  │
│  │ - SHS_IRLightSource                            │  │
│  └───────────────────────────────────────────────┘  │
│              ↓                                      │
│  ┌───────────────────────────────────────────────┐  │
│  │ Each component updates its IR visibility       │  │
│  │ - If NVG ON: Show IR                           │  │
│  │ - If NVG OFF: Hide IR                          │  │
│  └───────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘

IR Filter Toggle

Some devices have removable IR filters - when removed, IR becomes visible without NVG:

// In code:
lightsComponent.SetIRFilterRemoved(true);

// Result: IR light visible to naked eye (appears red/dim)

Light Colors

Flashlights support 8 colors:

Index Color RGB
0 White 1, 1, 1
1 Red 1, 0, 0
2 Green 0, 1, 0
3 Blue 0, 0, 1
4 Yellow 1, 1, 0
5 Orange 1, 0.5, 0
6 Cyan 0, 1, 1
7 Magenta 1, 0, 1

API:

lightsComponent.SetLightColor(2);      // Set to green
lightsComponent.CycleLightColor();     // Next color
string name = lightsComponent.GetCurrentColorName(); // "Green"

Brightness Controls

Brightness can be adjusted while lights are active:

Action Effect
m_sBrightnessUpAction Increase brightness by m_fBrightnessStep
m_sBrightnessDownAction Decrease brightness by m_fBrightnessStep

Adaptive Step Size:

  • Low brightness (< 1.0): Fine control (0.05 step)
  • Medium brightness (1.0 - 3.0): Normal control (0.1 step)
  • High brightness (> 3.0): Standard step

Input Configuration

Default Keybinds

Important: PC keyboard bindings are unbound by default to avoid conflicts. Configure them in Settings → Controls → Keybindings.

Gamepad (Pre-configured)

Action Input
Toggle NVG Double-tap D-Pad Up
NVG Gain Up RB + D-Pad Up
NVG Gain Down RB + D-Pad Down
Reset Gain RB + D-Pad Left
Toggle Auto-Gain RB + D-Pad Right
Cycle Phosphor RB + D-Pad Up (click)
Toggle Flashlight D-Pad Up
Toggle IR LB + D-Pad Up
Strobe D-Pad Down
Radial Menu LB + D-Pad Down

Input Action Reference

NVG Context (SHS_NVContext)

Action Type Description
SHS_NV_Toggle Down Toggle NVG on/off
SHS_NV_Increase AnalogRelative Increase gain
SHS_NV_Decrease AnalogRelative Decrease gain
SHS_NV_Reset Down Reset to default
SHS_NV_AutoGain Down Toggle auto system
SHS_NV_Palette Down Cycle phosphor

Thermal Context (SHS_ThermalContext)

Action Type Description
SHS_Thermal_Toggle Down Toggle thermal
SHS_Thermal_Palette Down Cycle palette
SHS_Thermal_Increase AnalogRelative Increase gain
SHS_Thermal_Decrease AnalogRelative Decrease gain

Light Actions (General Context)

Action Type Description
SHSToggleFlashlight Down Toggle flashlight
SHSToggleIR Down Toggle IR
SHSStrobe Down Activate strobe
SHS_OpenRadialMenu Click Open radial menu
SHS_Light_BrightnessUp Pressed Increase brightness
SHS_Light_BrightnessDown Pressed Decrease brightness

Custom Keybind Setup

To add custom keybinds, modify Configs/System/chimeraInputCommon.conf:

ActionManager : "{...}chimeraInputCommon.conf" {
  Actions {
    Action YourAction {
      DisplayInHint 0
      InputSource InputSourceSum "{GUID}" {
        Sources {
          InputSourceValue "{GUID}" {
            Input "keyboard:KC_X"
            Preset 1
            Filter InputFilterClick "{GUID}" {
            }
          }
        }
      }
    }
  }
  Contexts {
    ActionContext SHS_NVContext {
      ActionRefs +{
        "YourAction"
      }
    }
  }
}

Network Architecture

Replication

Both NVG and Light components replicate their state:

SHS_NightVisionComponent Replication

// Saved to stream:
- m_bActivated (bool)

// On load:
- Calls UpdateAnimation() to sync visual state

SHS_NVL_LightsComponent Replication

// Saved to stream:
- m_bFlashlightOn (bool)
- m_bIROn (bool)
- m_bIRFilterRemoved (bool)
- m_iCurrentColorIndex (int)
- m_fCurrentFlashlightBrightness (float)
- m_fCurrentIRBrightness (float)

// On load:
- Deferred ApplyStateFromReplication()

Network Components

SHS_NVL_NetworkComponent

Handles RPCs for light state changes:

RPC Direction Purpose
AskToggleFlashlight Client → Server Request flashlight toggle
AskToggleIR Client → Server Request IR toggle
AskSetLightColor Client → Server Request color change
AskSetIRFilterRemoved Client → Server Request filter state
AskSetFlashlightBrightness Client → Server Request brightness
AskSetIRBrightness Client → Server Request IR brightness

JIP Handling

Join-In-Progress players receive state via replication:

  1. RplLoad is called with current state
  2. ApplyStateFromReplication() is deferred (500ms)
  3. Lights are spawned if not already
  4. States are applied

Weapon State Monitoring:

For weapon-mounted lights, a periodic check (CheckWeaponState) monitors if the weapon is equipped:

┌─────────────────────────────────────────┐
│         CheckWeaponState (500ms)        │
├─────────────────────────────────────────┤
│ 1. Get character's weapon manager       │
│ 2. Get current equipped weapon          │
│ 3. Check if our weapon is active        │
│ 4. If state changed:                    │
│    - Weapon equipped → OnWeaponEquipped │
│    - Weapon holstered → Clear states    │
└─────────────────────────────────────────┘

Prefab Setup Examples

Example: Basic NVG

Entity: PVS14_NVG.et
├── Components
│   ├── MeshObject (NVG model)
│   ├── InventoryItemComponent
│   ├── BaseLoadoutClothComponent
│   │   └── Area: SHS_NV_ItemSlot
│   ├── SignalsManagerComponent
│   └── SHS_NightVisionComponent
│       ├── m_HDRMaterial: "{...}/HDR_Green.emat"
│       ├── m_GrainMaterial: "{...}/FilmGrain.emat"
│       ├── m_fBaseBrightness: 1.5
│       ├── m_bManualBrightnessEnabled: true
│       └── m_sAnimationSignal: "w_nvRotator"

Example: Weapon Light with IR

Entity: PEQ15_Attachment.et
├── Components
│   ├── MeshObject (PEQ model)
│   ├── InventoryItemComponent
│   ├── SHS_NVL_NetworkComponent
│   └── SHS_NVL_LightsComponent
│       ├── m_sLightIdentifier: "WeaponPEQ15"
│       ├── m_sToggleAction: "SHSToggleFlashlight"
│       ├── m_sToggleIRAction: "SHSToggleIR"
│       ├── m_fDefaultFlashlightBrightness: 6.0
│       ├── m_fDefaultIRBrightness: 1.0
│       └── m_aSources
│           ├── [0] Flashlight
│           │   ├── m_Prefab: "{...}/FlashlightLight.et"
│           │   ├── m_bIsFlashlight: true
│           │   └── m_bIsIR: false
│           └── [1] IR Laser
│               ├── m_Prefab: "{...}/SHS_IRLaser.et"
│               ├── m_bIsFlashlight: false
│               └── m_bIsIR: true

Troubleshooting

NVG Issues

Problem Solution
NVG won't activate Ensure NVG is worn on helmet (not in inventory)
NVG activates from inventory Update to latest version - worn check added
Animation not playing Verify signal name matches .siga file
Brightness not adjusting Set m_bManualBrightnessEnabled: true
Auto-gain not working Set m_bAutoSystemEnabled: true

Light Issues

Problem Solution
Flashlight won't toggle Check keybind is set in options
IR not visible Activate NVGs first
IR visible without NVG m_bIRFilterRemoved is true
Lights not syncing Ensure SHS_NVL_NetworkComponent exists
Lights reset on weapon swap Check CheckWeaponState is running

Common Log Messages

Log Meaning
[SHS_NVG] DeferredKitLoadCheck - Max retries reached NVG in storage, not on character
[SHS_Lights] Entity X needs respawn Light parent relationship broken
[SHS_Lights] RegisterActionListeners - Character mismatch Still initializing, will retry

Reference: Component Fields

SHS_NightVisionComponent

Field Type Default Description
m_HDRMaterial ResourceName - Phosphor HDR material
m_GrainMaterial ResourceName - Film grain overlay
m_BlemishMaterial ResourceName - Optional noise material
m_bThermalEnabled bool false Enable thermal mode
m_ThermalMaterial ResourceName - Thermal effect material
m_sThermalToggleAction string "SHS_NV_ThermalToggle" Thermal keybind
m_fBaseBrightness float 1.5 Starting brightness
m_bManualBrightnessEnabled bool false Allow manual adjustment
m_fBrightnessStep float 2.0 Adjustment increment
m_fMinBrightness float 0.05 Minimum brightness
m_fMaxBrightness float 20.0 Maximum brightness
m_bAutoSystemEnabled bool false Enable auto-gain
m_fTransitionRate float 0.5 Auto-adjust speed
m_fAutoBrightnessFloor float 0.5 Auto minimum
m_fAutoBrightnessCeiling float 15.0 Auto maximum
m_iDawnHour int 7 Day start hour
m_iDuskHour int 19 Night start hour
m_sAnimationSignal string - Animation signal name
m_aPhosphorColors array - Phosphor color options

SHS_NVL_LightsComponent

Field Type Default Description
m_sLightIdentifier string - Unique network ID
m_aSources array - Light source configs
m_sToggleAction string "SHSToggleFlashlight" Flashlight keybind
m_sToggleIRAction string "SHSToggleIR" IR keybind
m_sBrightnessUpAction string "SHS_Light_BrightnessUp" Brightness up keybind
m_sBrightnessDownAction string "SHS_Light_BrightnessDown" Brightness down keybind
m_fDefaultFlashlightBrightness float 6.0 Default visible brightness
m_fDefaultIRBrightness float 1.0 Default IR brightness
m_fMinBrightness float 0.1 Minimum brightness
m_fMaxBrightness float 6.0 Maximum brightness
m_fBrightnessStep float 0.2 Adjustment step

📞 Support


SHS Night Vision & Lights © Shadow Haven Studios