Configuration reference

Everything VDM knows about a venue lives in one flat text file. This page covers the file format, where the application looks for it, and what each group of keys does — starting with the ones that must be re-established on every new machine.

Settings that must be re-established on a new laptop

This is the single most important thing to understand about VDM's configuration. A settings.txt copied from a working machine will not work as-is on a different one. Some values describe the machine, not the venue — and the application will not tell you they are wrong. It will run, and produce nothing, or produce something subtly incorrect.

Re-establish every one of these on a new machine before a real event.
KeyShips asWhy it is machine-specificHow to re-establish
*camera_device_path[0]
*camera_device_path[1]
*camera_device_path[2]
Empty — by design. The key is absent from both the shipped configuration and the template. These are Windows Media Foundation symbolic links. They encode the specific device instance on the specific machine and are regenerated per machine. An empty value means that feed is skipped entirely. Tools → Select Cameras… in the controller. Assign each detected device to Feed 0 (TOP), Feed 1 (MIDDLE), Feed 2 (BOTTOM). Assigning a device auto-starts capture and motion for it.
*capfile_nvenc_gpu_name NVIDIA GeForce RTX 3070 Ti Laptop GPU A substring matched against the installed adapters. On any other GPU it matches nothing. The companion key capfile_nvenc_gpu_index is -1, meaning resolve the index from this name. Tools → Select GPU. Leaving the name blank lets FFmpeg pick automatically, which is a reasonable fallback.
big_window_width
big_window_height
2880 / 1620 Sized for one particular laptop panel. On a smaller display the window runs off-screen; on a larger one you waste working area. Edit to suit the actual display, via the controller's Settings tab or a text editor.
disable_nvenc_encoding 1 (NVENC disabled) A workaround for the behaviour of one specific GPU — not a general setting. Leaving it at 1 on capable hardware silently gives up hardware encoding. Try 0 on new hardware and verify the encode path. Revert to 1 only if it misbehaves. See the NVENC constraint.

None of these four are optional to review. The first two make the system non-functional if wrong. The third makes it unusable but obviously so. The fourth costs you the hardware encoder without any indication that it has.

What carries over, and what does not

Beyond the four above, a second class of settings is tied to the physical camera rig rather than to the computer. These carry over perfectly — but only if the cameras have not moved.

SettingsCarries over if…Must be redone if…
@far[F][I] / @near[F][I] grid-line anchors, and the meter_line_* geometry The cameras are mounted in exactly the same positions, at the same aim, at the same venue. Any camera has been moved, re-aimed, or remounted — or you are at a different hill. Distances will be confidently wrong otherwise.
motion_start_x/y[N], motion_end_x/y[N] Same camera framing. Framing changed. The region is in frame pixel coordinates.
ignore_start_x/y[N], ignore_end_x/y[N] Same camera framing and the same fixed distraction in shot (a flag, a marshal's post). Framing changed, or the thing being ignored has moved.
feed1_x0_translates_to_feed0_x, feed2_x0_translates_to_feed1_x The relative geometry between the cameras is unchanged. Any camera moved relative to its neighbour.
Motion thresholds — ydiff_min[], min_blob_sizes[], min_motion_count[], min_nomotion_count[] Usually. These are tuning values and travel reasonably well as a starting point. Nothing forces a redo, but expect to re-tune for different light, snow conditions or camera distance.
Movie logic — min_frames, max_frames, min_type2_frames, padding, overlay_frame_offsets[] Generally yes. These describe the shape of a jump, not the hardware. overlay_frame_offsets[] is timing-sensitive and worth re-checking after auto-setup at a new venue.

The practical rule

Same rig, same hill, new laptop → copy settings.txt, then fix the four machine-specific keys above. Different rig or different hill → copy it anyway as a starting point, then recalibrate motion regions and grid lines from scratch.

File format and prefix conventions

settings.txt is flat key=value text, one setting per line, parsed by src/common/settings.c. There is no registry use, no %APPDATA% storage, and no secondary config file — apart from pixel_frames.txt, which is generated alongside it.

The type of a key is encoded in the key name itself, and the marker is part of the literal key — you must type it:

MarkerPositionTypeExample
*PrefixString*font_file=numbers.txt
@PrefixCoordinate pair, written x,y@far[0][ 0]=960,100
%SuffixFloatmax_diff_y%=0.700000
noneIntegermin_frames=60

% is a suffix, not a prefix

Unlike * and @, the float marker goes on the end of the key name: max_diff_y%, not %max_diff_y. Some older notes describe all three as prefixes. They are not.

Not every float key carries the marker — mouse_position_speed and scene_trigger_f0_fraction are floats with no %. The marker is part of the key's spelling, so match the existing file rather than reasoning from the type.

Comments and parsing rules

The shipped settings.txt contains no comment lines at all — it is machine-written. settings_sample.txt is the commented template, and its comments are the best short description of each key it covers.

How many keys are there

FileKeysNotes
settings.txt (live)356176 scalar keys plus 180 @far/@near anchor entries. No comments.
settings_sample.txt141Plus 49 comment lines. Contains no live anchor entries — the @far/@near examples in it are commented out.
Recognised by the parser387207 scalar plus 180 coordinate entries.

The template is not a subset of the live file

Each file contains keys the other lacks. settings_sample.txt has not kept pace with the parser: about two dozen of its keys are no longer recognised, and it omits whole families the live configuration uses (analytics, adaptive auto-setup, capfile encoding, ignore regions). Treat it as documentation of the keys it covers, not as an authoritative inventory. See Stale and ignored keys.

Where VDM looks for settings.txt

Configuration discovery is filesystem-based. In order:

  1. The controller walks up to five parent directories from the executable's own location, looking for settings.txt.
  2. Failing that, the path given as the command-line argument: VDM.exe settings_file.
  3. Failing that, settings.txt in the current working directory.

The settings file is a positional argument

It is VDM.exe settings.txt, not VDM.exe --settings settings.txt. There is no --settings flag; any non-flag token on the command line is taken as the settings path, and a second one is an error.

In a standard C:\VDM\ installation everything is flat, so the first rule finds the file immediately. The parent-directory walk exists so that a developer running out of build\Release\ picks up the repository-root configuration without arguments.

How the file is written back

VDM does not edit settings.txt in place. When settings are saved — from the Settings tab, from Save Regions, from grid-line calibration, or at the end of auto-setup — the application rewrites the entire file from its in-memory state, writing to a temporary file and then renaming it over the original. The rename is atomic, so an interrupted save cannot leave a half-written configuration.

pixel_frames.txt is regenerated at the same time.

Consequences of a wholesale rewrite

Take your own copy of a known-good settings.txt before any calibration session, and keep it somewhere VDM will never write.

Key reference by theme

Values shown are from the shipped live configuration. Where the commented template gives a different default, both are shown. Indexed keys are written [0..2] for per-feed values; some motion keys carry a fourth index [3] used as a global entry.

Window and display geometry

KeyTypeLive valueMeaning
big_window_widthint2880Main window width in pixels. Machine-specific.
big_window_heightint1620Main window height in pixels. Machine-specific.
frame_position_bar_heightint15Height of the frame position bar, in pixels.
mouse_position_speedfloat2.000000Pixels of right-drag per frame when scrubbing. Higher is slower.
cursor_line_widthint2Width of the cursor measurement line.
cursor_line_Y / _U / _Vint180 / 180 / 100Cursor measurement line colour in YUV.
crosshair_widthint12Crosshair width in pixels.
default_view_frame_offset_from_endint0Default view offset from the end of a clip.
*font_filestring48Declared as the path to the bitmap font glyph table, but not read by any code. The font is always loaded from numbers.txt. See the note below.

*font_file is vestigial — leave it alone

In the shipped configuration this key holds the literal value 48 rather than a filename, which looks like a defect. It is not one, because nothing reads the key. All four consumers — the viewer, the fileviewer, videogen and the practice player — pass numbers.txt as a hardcoded literal, so the bitmap font is always loaded from numbers.txt in the working directory regardless of what this key says.

Setting it to a real path, setting it to a wrong path, and leaving it at 48 all behave identically. The 48 is most likely an orphaned font_size value left on the wrong key by the cleanup that removed font_size, font_window_width and font_window_height as never-consumed.

The consequence that matters: if overlays fail to render, the cause is a missing numbers.txt — never a font_file misconfiguration. Editing this key cannot fix it. Because the filename is hardcoded with no setting to override it, numbers.txt must sit in the working directory beside the executables.

Cameras and device selection

KeyTypeLive valueMeaning
*camera_device_path[0..2]stringabsentMedia Foundation symbolic link per feed. Set through Tools → Select Cameras…. Empty means the feed is skipped. Machine-specific — ships empty by design.
feed_countintabsent, defaults to 3Number of active feeds, 1–4. Changing it requires a VDM restart.
feed_motion_on[0..2]int1, 1, 1Enable motion detection per feed. Also toggleable live from the Feeds tab, where the change is memory-only.
*practice_video_path[0..2]stringabsentPer-feed video file for practice mode, set via Tools → Select Practice Files…. Empty falls back to the legacy file-naming convention.
practice_video_sync_offset[0..2]intabsentSeek-to-sync frame offset per feed. A negative value selects the built-in fallback offsets.

Motion detection

Detection regions

KeyFeed 0Feed 1Feed 2Meaning
motion_start_x[N], motion_start_y[N]
motion_end_x[N], motion_end_y[N]
0, 231 → 1919, 671 0, 503 → 1919, 839 0, 406 → 1919, 631 The rectangle in each camera's frame where motion is detected. Narrow it to exclude trees, buildings, flags and spectators. All three span the full frame width; only the vertical band differs, isolating each camera's stretch of hill. An index [3] exists as a global entry.
ignore_start_x[N], ignore_start_y[N]
ignore_end_x[N], ignore_end_y[N]
387, 394 → 603, 520 unset unset A rectangle inside the motion region to exclude — for a fixed distraction such as a flag or a marshal's position. Set with Ign Reg N in the Preview tab. Only feed 0 uses one in the shipped configuration.
*saved_motion_range A 12-integer CSV backup of the motion regions Written before auto-setup runs, so the regions can be restored afterwards.

Difference thresholds

KeyTypeLive valueMeaning
max_diff_y%float0.700000Maximum share of Y-plane pixels allowed to differ before the frame is treated as a scene change rather than a jumper.
max_diff_u% / max_diff_v%float0.350000Same for the chroma planes.
min_diff_y%float0.002000Minimum share of differing pixels for the frame to count as containing motion at all.
min_diff_u% / min_diff_v%float0.000100Same for chroma.
max_diff_y_quick%, max_diff_u_quick%, max_diff_v_quick%float5.0Thresholds for the fast pre-pass.
max_diff_yint19287Absolute pixel-count ceiling for the Y plane.
max_diff_u / max_diff_vint9643Absolute ceilings for chroma.
max_diff_y_quick, max_diff_u_quick, max_diff_v_quickint3000Absolute ceilings for the fast pre-pass.
ydiff_min[0..3]int34, 34, 34, 34Minimum per-pixel Y difference for a pixel to join a blob, per feed. Index 3 is the global entry.
udiff_min[0..3]int7, 9, 9, 9Same on the U plane.
vdiff_min[0..3]int7, 6, 7, 7Same on the V plane.
ydiff_maxint100Upper per-pixel difference bound on Y.
udiff_max / vdiff_maxint64Upper per-pixel bounds on chroma.

Blob detection

KeyTypeLive valueMeaning
min_blob_sizes[0..3]int100, 300, 300, 250Minimum blob size in pixels to count as a jumper, per feed. Raise it to ignore small movement; lower it if distant jumpers are missed.
max_blob_sizeint12858Maximum blob pixel count. Filters out whole-scene changes such as a cloud shadow crossing the hill.
max_blob_countint25Maximum blobs retained per frame.
min_blob_keepint70Minimum size to keep a blob during filtering.
min_blob_neighborsint3Minimum neighbouring pixels required for a pixel to survive into a blob.
min_blob_distance[0..3]int4, 8, 14, 4Minimum inter-frame blob movement, per feed.
max_blob_distance[0..3]int50, 60, 80, 80Maximum inter-frame blob movement — beyond this the blobs are not the same object.
blob_fuzz_x / blob_fuzz_yint60 / 60Merge blobs within this pixel distance of each other.
erase_shadowsint0Enable shadow removal.
shadow_frames_backint8How many frames back the shadow-removal secondary difference reaches.

Motion markers

KeyLive valueMeaning
mark_motion0Draw motion markers into the frames.
mark_motion_Y / _U / _V245 / 245 / 265Motion marker colour in YUV.
making_movie_Y / _U / _V0 / 0 / 0Marker colour used while a movie is being committed.
debug_motion1Verbose motion logging to motion_debug_N.log.

Movie and clip logic

KeyTypeLive valueMeaning
min_framesint60Minimum length of a committed movie clip, in frames. At 60 fps this is one second.
max_framesint518Maximum clip length. Bounded by the 520-frame shared-memory ring.
min_type2_framesint114Minimum frames for a type-2 movie — one whose lower half comes from feed 2 rather than feed 0.
min_frames_between_moviesint2Debounce: minimum frame gap between two triggers.
pre_movie_padding_framesint10Safety padding added before every movie start.
post_movie_padding_framesint10Safety padding added after every movie end.
movie_padint0Additional frames before and after a movie. The template default is 30.
overlay_frame_offsets[0..2]int142, 420, 200Per-feed frame offset applied when rendering overlays. Timing-sensitive; re-check after auto-setup at a new venue.
min_motion_count[0..2]int20, 20, 20Consecutive frames of motion required before a movie triggers. Lower is more responsive but produces more false triggers.
min_nomotion_count[0..2]int95, 30, 10Consecutive frames without motion required to end a movie. Higher gives longer clips that capture more of the landing. Note how different these are per feed — feed 0 waits far longer than feed 2.
scene_trigger_f0_fractionfloat0.900000Fraction of the frame width used for the feed-0 scene trigger.
backward_scan_max_gap_framesint4Maximum consecutive missed frames tolerated during backward scan.
backward_scan_velocity_tolerance_percentint40Velocity match tolerance during backward scan, as a percentage.
viewer_ring_channelsint4Number of channels in the viewer's local movie review ring. Valid range 2–32; raising it costs memory.
cli_wait_for_active_motionint1CLI modes defer shutdown while motion is still active.

Encoding

KeyTypeLive valueMeaning
disable_nvenc_encodingint1Disables NVENC hardware encoding, forcing the software path. Machine-specific workaround — see above.
*capfile_nvenc_gpu_namestringNVIDIA GeForce RTX 3070 Ti Laptop GPUSelects the NVENC GPU by name, matched as a substring. Blank lets FFmpeg pick. Machine-specific.
capfile_nvenc_gpu_indexint-1-1 resolves the index from the name above; 0, 1, 2… select an adapter directly. There is no separate gpu_index key.
capfile_quality_cqintabsent, defaults to 35NVENC constant-quality target for capfile recording. Clamped to 15–40; lower is higher quality and larger files.
capfile_stitch_across_pauseintabsent1 produces a single seamless mp4 across pauses, dropping the pause-gap wall time from the output timeline.
*capfile_output_dirstringabsentAbsolute output directory for capfile recordings. Blank means CapturedVideos under the working directory.

Feed alignment and synchronisation

KeyTypeLive valueMeaning
feed1_x0_translates_to_feed0_xint1880The X coordinate in feed 0's frame that corresponds to X=0 in feed 1's frame. This is how the system stitches the feeds into one continuous view of the hill. Tied to the camera rig.
feed2_x0_translates_to_feed1_xint1720The same relationship between feeds 2 and 1. Tied to the camera rig.
blob_match_tolerance_usint8333Timestamp tolerance in microseconds when matching a blob across feeds. 8333 µs is half a frame at 60 fps.
feed_sync_offset[0..2]intabsentSequence offset relative to feed 1, computed automatically. Feed 1 is always 0.

Grid lines and hill calibration

KeyFeed 0Feed 1Feed 2Meaning
meter_line_count[N]696How many metre lines that feed draws.
meter_line_start[N]354055The metre mark of the first line.
meter_line_increment[N]555Metres between adjacent lines. Feed 0 therefore covers 35–60 m, feed 1 from 40 m, feed 2 from 55 m.
meter_line_radius[N]222Line thickness, in pixels from the centre.

Line colours are given in YUV. meter_line_Y/U/V is 255/265/245, meter1_line_Y/U/V (whole-metre lines) is 245/265/245, and meterD_line_Y/U/V (sub-metre lines) is 245/245/265.

Anchor pairs

Each metre line is defined by two anchor points per feed:

@far[0][ 0]=960,100      far anchor for feed 0, line 0
@near[0][ 0]=960,900     near anchor for feed 0, line 0
@far[0][ 1]=985,100
@near[0][ 1]=990,900

The far anchor is where that metre mark crosses the far edge of the hill — toward the top of the frame and the vanishing point. The near anchor is the near edge, at the bottom, closer to the camera. The viewer draws the line between them and linearly interpolates distance between adjacent lines.

The key space is @far[F][I] and @near[F][I] with F = 0–2 and I = 0–29, giving 180 entries in total. Single-digit inner indices are space-padded to two characters: @far[0][ 0] through @far[0][29]. In the shipped configuration, feed 0 has anchors 0–5 populated, feeds 1 and 2 have 0–6, and the rest are 0,0.

Check the anchor count against the line count

In the shipped configuration meter_line_count[1] is 9, but only seven anchor pairs (indices 0–6) are populated for feed 1. Lines with unset anchors have nothing to draw between. Confirm during calibration that every feed has as many populated anchor pairs as its line count claims. verify on target hardware

Anchors are normally set through the Setup Grid Lines panel rather than by hand — see User guide § grid-line calibration. Each anchor is written to settings.txt immediately as you place it.

Auto-setup and analytics

KeyLive valueMeaning
auto_setup_max_jumpers1Auto-setup stops after this many completed jumpers.
auto_setup_max_frames1500Auto-setup stops after this many feed-1 frames, whichever limit comes first.
practice_max_jumpers1Same limit for practice mode.
practice_max_frames1500Same frame limit for practice mode.
auto_setup_adaptive_width_enable1Enable adaptive narrowing of the analysis width when per-frame processing runs slow.
auto_setup_adaptive_width_threshold_us14000Per-frame motion processing budget ceiling, in microseconds.
auto_setup_adaptive_width_trial_frames300Frames sampled before deciding to narrow.
auto_setup_adaptive_width_slow_pct5Share of frames allowed over budget before narrowing kicks in.
auto_setup_adaptive_width_min_pct33Floor on how far the width may be narrowed.
analytics_min_tracked_frames5Minimum tracked frames before analytics will act.
analytics_adjustment_cooldown30Frames to wait between successive automatic threshold adjustments.
analytics_threshold_step2Step size for each automatic adjustment.
analytics_max_multiplier2Ceiling on cumulative automatic adjustment.
analytics_retry_budget_us10000Time budget in microseconds for analytics retries.

Paths and upload

These appear in settings_sample.txt with the defaults below but are absent from the shipped live configuration, so the compiled-in defaults apply. Add them explicitly if you need different values.

KeyDefaultMeaning
*archive_diroutput_videosWhere videogen writes committed jump_*.mp4 clips. Created at startup if absent.
*upload_hostthehansens.comFTP host. Passed to upload_video.bat as VDM_UPLOAD_HOST.
*upload_pathuploadsRemote directory. Passed as VDM_UPLOAD_PATH. By convention this is a server-side symlink the tournament admin repoints to the current event.
*upload_signal_urlhttp://www.thehansens.com/tournament/signal_next.cgiURL fetched after a successful upload. Passed as VDM_SIGNAL_URL.
upload_enabled1Kill switch. 0 skips the upload spawn entirely; the encode still happens.

Credentials never go in settings.txt

There is no username or password key, by design. FTP credentials live only in %USERPROFILE%\.netrc, which curl --netrc reads. That file is operator-provisioned, is never packaged, and does not exist until you create it. See Installation § upload credentials.

Stale and ignored keys

Because unrecognised keys are silently dropped, both shipped files carry lines that do nothing. Knowing which they are saves you from tuning a value that has no effect.

In the live settings.txt

Two families are present but no longer read by anything — they were removed from the parser in a dead-write audit and are residue in the file:

They will disappear the next time VDM rewrites the file.

In settings_sample.txt

About two dozen keys in the template are no longer recognised. The ones most likely to mislead, because they sound like things you would want to change:

Key in the templateStatus
feed_offset[0..2]Not recognised. The template describes it as delaying a feed by N frames; feed alignment is now handled by feed_sync_offset[] and the feedN_x0_translates_to_* keys.
min_type1_framesNot recognised. Superseded by the per-pixel pixel_frames.txt mechanism.
min_diff_y, min_diff_u, min_diff_v, min_quick_sizeNot recognised. The percentage forms with the % suffix are the live ones.
show_jumper_numbers, show_name, show_speed, font_size, only_one_viewer, show_lines_mode, draw_circle_around_blobs, showing_motionNot recognised. Several of these functions are now controlled from the UI — blob circles by the Circles On/Off button, motion highlighting by Highlight ON/OFF.
debug_distance, play4_show_frame_rate, distance_look_back_n_framesNot recognised.
meters_from_takeoff_to_visible, last_visible_meter_lineNot recognised. Hill geometry is expressed through the grid-line anchors.

How to tell whether a key took effect

Save from the controller and re-open settings.txt. Because saving rewrites the file from the parsed in-memory state, any key that survives the round trip is recognised, and any key that vanishes never was.