Skip to content

While a demo loads, the demo player bar shows how far along it is (#465) - #758

Merged
ccoventry merged 23 commits into
devfrom
feat/loading-progress-465
Oct 25, 2026
Merged

ccoventry merged 23 commits into
devfrom
feat/loading-progress-465

Conversation

@ccoventry

@ccoventry ccoventry commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Release note: New: While a demo loads in the game, the demo player bar shows how far along it is.

Closes #465

What it does

While viewdemo is still reading a demo, the stock demo player (VCR) bar shows n% and a thin progress bar where its time label sits. Both hide once the console says "Demo file completely loaded.", and the time label shows again. The number is the same one the DoD Studio window's Playback tab already shows (#565): the span the demo player has buffered so far, divided by the playback length in the demo's own directory.

Studio side: native/src/demo_bar_res.rs (new)

  • with_loading_controls(res) -> Option<String> inserts two blocks before the top-level object's closing brace: a Label named StudioLoadPercent and a ProgressBar named StudioLoadProgress. Both start with visible 0 and are placed from TimeLabel's xpos/ypos/wide/tall, or the stock place if the layout has no TimeLabel. Everything else in the user's file stays byte for byte, including its line endings and the trailing NUL a build-mode save leaves. A file that already has the controls comes back unchanged.
  • install(game_dir, game_folder) reads <folder>\resource\DemoPlayerDialog.res (dod unless the Game folder setting says otherwise, Setting for the game folder name (-game <mod>), default dod #402), or valve\resource\DemoPlayerDialog.res when that has none, and writes <folder>_addon\resource\DemoPlayerDialog.res. Nothing under the game folder or valve is ever written. If the target already holds exactly what would be written, it skips the write.
  • An edit saved to the addon file is kept. Studio's copy starts with a // DoD Studio writes this file ... (marker <hash>) line, the FNV-1a hash of the rest of the file. A file without that line (a build-mode save writes no comments) or whose hash no longer matches (a hand edit) is the user's: the launch builds from it instead, adds the two controls only if they're missing (keeping every other byte, and no marker, so it stays the user's), and otherwise leaves it alone. The activity log says "kept your edited ..." or "added the loading progress controls to your edited ...". Deleting the file goes back to the game folder's layout. A UTF-16 edit is left untouched and logged; an empty addon file is rebuilt.
  • prepare(hl_exe) is called from PatcherConfig::build_hlae_process, so every launch gets it: a batch, Launch Preview and Launch Game. It writes one activity-log line when the file is (re)written, and one when it is skipped (no source file, or one it can't read).

Hook side: goldsrc-hooks/src/demo_bar_progress.rs + studio_panel/hook/demo_bar_progress.rs (new)

  • New cvar ds_demo_show_load_progress, default 1.
  • Every frame, studio_panel::hook::poll runs the update before its "is our window open" early return. It reads demo_seek::buffered_while_loading(), so the cost is one interface lookup and two slot calls while no demo is loading.
  • While loading, it finds the children by name under GameUI's DemoPlayerDialog popup (the feat(goldsrc-hooks): resizable GameUI windows that remember their place (#408) #410 walk), sets the label through Label::SetText and the bar through ProgressBar::SetProgress (vftable-checked against progress_bar_vftable), and shows both. When loading ends it hides them.
  • It only writes when the percent changes. It logs every tenth and the end, plus one line per session if the bar has no such controls (the game was started without -addons or without Studio's layout).
  • No new offsets. The GameUI slots and the progress_bar_vftable already sit in BUILDS for both builds and are checked by tools/verify_studio_panel.py; the demo player slots are the ones demo_seek already verifies on PRE and Anniversary.

Decisions

  • Default 1, not 0. It only shows anything on the layout Studio's own launch writes, so a game started any other way is unchanged. ds_ui_viewdemo_in_panel and ds_ui_console_in_panel are the precedent for default-on window features. Because of the default, Studio's launch does not need to send it.
  • No cfg_scan tier. It's a harmless setting, and ds_ui_viewdemo_in_panel is in no tier list either.
  • Does nothing while ds_ui_viewdemo_in_panel is 1. The bar is parked off screen then, and the Playback tab shows the progress.
  • load_progress::length_of_current_demo is now pub(super), so both progress displays read the demo's length once per demo. demo_list_folders::Setting::new is now pub(crate) so the new cvar reuses that on/off type.
  • PRE's old dod_addon\resource\DemoPlayerDialog.res is replaced at the next launch. That file is the experiment with the -10 s / +10 s / x0.5 / x1 / Decals buttons (their dem_jump/dem_speed commands do nothing in GoldSrc). The issue's 2026-10-12 decision allows overwriting it. The new file is your dod\resource layout plus the two controls. (On this PC it was already replaced on 10-13 by a test build of this PR; PRE's and POST's addon files now are exactly that output, which the new code recognises as Studio's.)
  • Keep build-mode edits (your decision on the review's open question). How Studio tells its own copy from yours: a marker line in the file with a hash of the rest, not a record kept elsewhere and not timestamps. The marker travels with the file, so a reinstalled Studio, a second Studio checkout or a cleared settings folder still tells them apart, and nothing can drift out of step with it; timestamps change on a copy or unzip without the file changing. The game's KeyValues reader skips // lines (the stock ClientScheme.res starts with them), and the in-game runs below load the marked file.
  • A copy written before the marker that is byte for byte what Studio would build now counts as Studio's and gets the marker; anything else unmarked is yours.
  • Once the addon file is yours, it no longer follows dod\resource. A later change to the game folder's layout doesn't reach it until you delete the addon file; the activity log line says so on every launch.
  • The hook's "the demo bar has no StudioLoadPercent" log line now names <folder>_addon for the running Game folder instead of always dod_addon.

Name (after #719)

The cvar is ds_demo_show_load_progress (the #555 table's name for show_load_progress). It never shipped, so it has no old_names.rs entry; it is listed in console_prefix's NEW_SINCE_555 instead. It sits under DEMO PLAYBACK in Commands.txt and docs/dodstudio_commands.md.

Tests (local, at 47bde20, dev 5bc7b6a merged in)

  • rustup run 1.98.1 cargo fmt --all --check: clean
  • rustup run 1.98.1 cargo clippy --workspace --all-targets --locked -- -D warnings: clean
  • rustup run 1.98.1 cargo clippy -p goldsrc-hooks --target i686-pc-windows-msvc --all-targets --locked -- -D warnings: clean
  • cargo test -p goldsrc-hooks --target i686-pc-windows-msvc: 872 pass
  • cargo test --workspace: all pass (native 803; one timing test in shared::paths failed once while two builds ran side by side and passed on the rerun)
  • npm run test:unit: 904 passed (104 files)
  • New: studio_s_copy_carries_a_marker_and_is_rebuilt, a_build_mode_save_with_the_controls_is_left_alone, a_build_mode_save_without_the_controls_gets_them_and_stays_the_user_s, a_hand_edit_that_keeps_the_marker_line_is_still_the_user_s, an_unmarked_copy_studio_would_write_is_studio_s, a_user_s_edit_in_utf16_is_left_as_it_is, a_user_s_edit_that_is_not_utf8_is_kept_byte_for_byte, an_addon_file_with_no_layout_is_rebuilt, the_marker_needs_its_own_hash. The Setting for the game folder name (-game <mod>), default dod #402, non-UTF-8 and UTF-16 tests still pass.
  • Release DLL rebuilt to local\test-465\dodstudio_goldsrc_hooks.dll (the previous one kept beside it as .prev-3118435c.dll).

In game (2026-10-25, game_probe, Brain account, -addons, ds_ui_viewdemo_in_panel 0, viewdemo solifotw-bewton)

The layout step was run as the launch runs it (demo_bar_res::install(<install>, "dod"), from a throwaway example binary), then the game.

  • Edit kept, PRE: a hand edit in dod_addon (PRE's dod\resource layout with Play and Pause swapped, no controls, no marker): step 1 AddedToEdit, step 2 KeptEdit. Hook log 0 … 90%, then "the demo is loaded"; no "has no StudioLoadPercent". After loading, the bar shows ▶ before ⏸ (the edit) and the time.
  • Edit kept, POST: same from valve\resource: AddedToEdit, then KeptEdit; the bar shows 32% and the progress bar while loading, with ▶ before ⏸; after loading 06:09:09 x1 Playing.
  • Studio's marked copy, PRE and POST: the 10-13 unmarked copy was recognised as Studio's (Written, then Unchanged); the file now starts with the // marker line, and the game loads it: 0% and the bar while loading, 0 … 90% in the log on both.
  • Both installs' addon files were put back to how they were before the runs (backups in local\backups\1020\).
    Reports: local\game-probe\758-pre-edit\, 758-post-edit\, 758-pre-marked\, 758-post-marked\.

The PRE bar with no time after loading, seen in the 10-24 smoke test, was not this PR: it was the remembered window size from POST squeezing PRE's taller bar (#1020, fixed in #1046). These runs set ds_ui_remember_layout 0 to keep that out. No other open PR touches native/src/demo_bar_res.rs or the two demo_bar_progress.rs files.

User test steps (run on both PRE and POST)

  1. git checkout feat/loading-progress-465 and run Studio from it as usual.
  2. In Studio, go to Paths → GoldSrc Hooks DLL and pick local\test-465\dodstudio_goldsrc_hooks.dll. Close the game if it's running.
  3. Launch Game. In the activity log, look for Demo bar layout: wrote ...\dod_addon\resource\DemoPlayerDialog.res from ...\dod\resource\DemoPlayerDialog.res (on POST, from ...\valve\resource\...).
  4. In the console: ds_ui_viewdemo_in_panel 0 (so the stock bar is used), then viewdemo <a 100 MB+ demo>, e.g. viewdemo wsod25_grp2_h1_hltv.
  5. Watch the bar. Where the time normally shows, you should see n% and a bar filling up while the title says "Loading ...". Both go away when the console prints "Demo file completely loaded.", and the time shows again.
  6. In the hook log, look for demo_bar_progress: loading the demo, 0% … 90%, then demo_bar_progress: the demo is loaded. If it says the demo bar has no StudioLoadPercent, the layout wasn't picked up (check -addons and step 3).
  7. ds_demo_show_load_progress 0, then viewdemo again: no progress shows.

On PRE, the old experiment dod_addon\resource\DemoPlayerDialog.res (with the -10 s / +10 s / Decals buttons) is replaced by this launch. Your dod\resource layout carries over unchanged.

🤖 Generated with Claude Code

ccoventry and others added 2 commits October 13, 2026 05:29
…d_addon

Studio copies the user's dod/resource DemoPlayerDialog.res (or the stock
valve one) into dod_addon/resource and adds a hidden percent label and
progress bar where TimeLabel sits. The user's files are never written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dodstudio_show_load_progress (on by default) fills the StudioLoadPercent
label and StudioLoadProgress bar on the VCR bar while viewdemo is still
reading, with the Playback tab's percent, and hides them once loaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ccoventry ccoventry linked an issue Oct 13, 2026 that may be closed by this pull request
@ccoventry

Copy link
Copy Markdown
Owner Author

In-game smoke test (game_probe, Brain account), DLL local\test-465\dodstudio_goldsrc_hooks.dll, demo solifotw-bewton (209 MB), dodstudio_viewdemo_in_panel 0, launched with -addons.

game_probe launches the game itself, so the .res was written by this PR's own demo_bar_res::install (the file compiled into a scratch binary) before each launch: POST from valve\resource, PRE from dod\resource. PRE's old experiment file is backed up in local\game-probe\backup-res\PRE\.

POST: pass. n% and the bar sit where the time is while the title says "Loading ...", and are gone afterwards (time, x1 Playing back). expect demo_bar_progress: the demo is loaded passed, and there was no "has no StudioLoadPercent" line.

  • local\review-images\pr758_post_loading.png (47%, bar filling)
  • local\review-images\pr758_post_loaded.png (time back)

PRE: pass, same result, with your dod\resource layout (Master / Events / Save row kept).

  • local\review-images\pr758_pre_loading.png (41%)
  • local\review-images\pr758_pre_loaded.png

Notes:

  • After the map comes up, GameUI hides as it always does, so you only see the bar after pressing ESC. Before that it shows over the main menu at 0% (local\review-images\pr758_post_loading_menu.png).
  • On both installs the number never gets near 100%. The log goes 0, 11, 20 ... 60%, and then "the demo is loaded" arrives at about 60-65% (POST run 2 at 06:00:28 → 60%, loaded 4 s later; PRE the same). So the bar disappears at about two thirds full. The Playback tab (feat(goldsrc-hooks): dodstudio_panel, DoD Studio's own window in the game (Part of #408) #565) uses the same number, so it probably ends early there too. I didn't dig into why (the buffered span against the directory's playback length for this demo); it's worth a look before release, or at least worth knowing that "loaded" can come at ~60%.

Reports: local\game-probe\pr758-post-2\, local\game-probe\pr758-pre\.

# Conflicts:
#	studio/src/console_commands_data.js
@ccoventry

Copy link
Copy Markdown
Owner Author

Merged dev in (7cca6ef); conflicts in studio/src/console_commands_data.js, resolved by regenerating it with goldsrc-hooks/tools/console_names.py (Commands.txt merged cleanly, keeps dodstudio_show_load_progress); local tests/clippy pass, CI green; test DLL rebuilt at local\test-465\

The stock bar's progress now reads load_progress::demo_percent(), the
number #804's loading strip and #816's lead-in fix share, so all three
displays agree. console_commands_data.js regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ccoventry

Copy link
Copy Markdown
Owner Author

Re-check on POST after the dev merge. Setup: bc7b639, DLL local\test-465\, Brain account, game_probe with -addons, dodstudio_viewdemo_in_panel 0, viewdemo solifotw-bewton. Report: local\game-probe\20261019-114006\.

  • Pass: the game's demo bar shows "29%" and then "49%" with the bar filling while the title says "Loading solifotw-bewton.dem …". Once loaded, the time and "x1 Playing" are back. The hook log goes 0, 10, 20 … 50%, then "the demo is loaded", and there's no "has no StudioLoadPercent" line.
  • Faster now: with viewdemo loads demos faster: up to 8 ms of each frame instead of 33 packets (#798) #805's fast load on dev, this 209 MB demo loaded in about 20 s.
  • Still there: the bar goes away at about half full. "Demo file completely loaded." arrives at 50% on this demo (60-65% in the first test). The number is dev's load_progress::demo_percent(), the same one the in-game window's loading strip uses, so the strip ends early on this demo too. The demo's directory gives 2,996 s of playback. If the demo player's buffered span (its GetEndTime − GetStartTime) only reaches about 1,500 s, the demo clock probably restarts partway through, which the directory's wall time doesn't. That's my guess, not checked. Counting bytes read instead of seconds would avoid it. It isn't a While a demo loads, the demo player bar shows how far along it is (#465) #758 problem, and I'd file it on its own if you want it fixed.

ccoventry and others added 2 commits October 21, 2026 03:21
…_progress

Dev's #719 renamed every console name to ds_<area>_...; this PR's
show_load_progress becomes ds_demo_show_load_progress per the #555 table.
Commands.txt and dodstudio_commands.md take dev's side with the row
re-added under DEMO PLAYBACK; console_commands_data.js regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ccoventry

Copy link
Copy Markdown
Owner Author

Merged dev in (after #719) at 70ee9924.

  • Renamed show_load_progress to ds_demo_show_load_progress (the Rename the in-game commands: area as the second word (spec_, hud_, world_...), and a shorter prefix #555 table), and moved it under DEMO PLAYBACK in Commands.txt and docs/dodstudio_commands.md. console_commands_data.js is regenerated. The name never shipped, so it has no old_names.rs entry. It is listed in console_prefix's NEW_SINCE_555, which a dev test needs.
  • Local checks: fmt, clippy 1.98.1 (workspace and i686), hook tests (689), workspace tests, npm run test:unit (602): all pass.
  • Test DLL rebuilt: local\test-465\dodstudio_goldsrc_hooks.dll.
  • game_probe re-run on PRE and POST: viewdemo solifotw-bewton with ds_ui_viewdemo_in_panel 0. The bar showed n% and filled while loading (33% in the PRE grab), and the hook logged the demo is loaded. "ds_demo_show_load_progress" is "1". Both PASS (local\game-probe\758-ds-pre\, 758-ds-post\).

🤖 Generated with Claude Code

ccoventry and others added 2 commits October 22, 2026 03:58
NEW_SINCE_555 keeps dev's three names and this branch's demo_show_load_progress; console_commands_data.js regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ccoventry

Copy link
Copy Markdown
Owner Author

Brought up to date with dev (unattended pass). Head 1f3f306b.

  • Merged dev. The conflicts were NEW_SINCE_555 and console_commands_data.js:
    • NEW_SINCE_555 keeps dev's three names and this PR's demo_show_load_progress.
    • The data file is regenerated with console_names.py.
  • A second gh pr update-branch after that was clean.
  • Local:
    • clippy 1.98.1, hooks both targets and the workspace: clean.
    • goldsrc-hooks i686: 702 pass.
    • workspace: 1191 pass.
    • JS unit: 604 pass.
  • CI green on 1f3f306b.

In game. DLL local\test-465\, rebuilt from 1f3f306b. game_probe, Brain account, viewdemo ktps8w1-m00cat_soul_lenn_h2.

  • PRE, PASS (local\game-probe\uh-758-pre-r2\):
    • Playback tab logged 0, 10 ... 90%, then "the demo is loaded".
    • ds_demo_show_load_progress is registered.
    • ds_debug_status: temp-entity fix 6 of 6, hull-trace guard on (pre-Anniversary on PRE, 25th Anniversary on POST)
  • POST, PASS (uh-758-post-r2\): the same.
  • The stock-bar path (ds_ui_viewdemo_in_panel 0 with Studio's own launch layout) was not run: game_probe doesn't write that layout.
  • Neither hook log shows a hook failing. The only "not installed" lines are modules that are build-specific by design: frame_esc on PRE, lightmap_gamma on POST.

🤖 Generated with Claude Code

ccoventry and others added 6 commits October 23, 2026 03:24
# Conflicts:
#	goldsrc-hooks/src/lib.rs
#	native/src/patch/console_prefix.rs
#	studio/src/console_commands_data.js
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	studio/src/console_commands_data.js
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, refuse UTF-16

With a Game folder other than dod (#402) the game runs with -game <folder>
-addons and searches <folder>_addon, so the layout written to dod_addon from
dod\resource never loaded. It now reads <folder>\resource (else valve) and
writes <folder>_addon. The file's bytes go through unchanged (Latin-1
round trip), so text that isn't UTF-8 no longer becomes U+FFFD, and a UTF-16
file is refused instead of getting ASCII blocks spliced into it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It runs every frame from HUD_Frame (CLAUDE.md: no blocking mutexes there).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ccoventry

Copy link
Copy Markdown
Owner Author

Correctness review (unattended pass, offline only, no game launched). Head 7e22ba0e.

What I checked: the whole diff against origin/dev.

  • Studio side: nothing under the game folder or valve is written; the launch always passes -addons, so the dod\dodstudio_ui fallback doesn't come into it; an unreadable or missing source is logged and skipped; error text uses .display(); tests use fake install paths and the redirected activity log, so cargo test writes nothing into a real install.
  • Hook side: it runs on the engine thread from poll; no new offsets, and the GameUI/ProgressBar slots and vftable are the ones already in BUILDS for both builds; nothing indexes or unwraps; the popup is looked up again on every change, so no stale panel handle is kept (the Anniversary ESC crash); a second demo or a map-change demo shows it again because the percent goes back to Some; ds_ name, Commands.txt, console_commands_data.js and NEW_SINCE_555 agree.

Bugs fixed:

  1. Game folder setting (Setting for the game folder name (-game <mod>), default dod #402) ignored (851d145). With a Game folder such as dod_movies, Studio launches -game dod_movies -addons, and the engine looks in dod_movies_addon. The PR wrote dod_addon from dod\resource, so the bar never showed the progress, and the hook log said the layout was missing. It now reads <folder>\resource (else valve\resource) and writes <folder>_addon\resource, with the same folder the launch line uses. Test: another_game_folder_reads_its_own_layout_and_writes_its_own_addon.
  2. A layout that isn't UTF-8 got mangled (851d145). The file went through from_utf8_lossy, so a Windows-1252 character, such as a label text "Zurück", would show as garbage in the copy. The bytes now go through unchanged. A UTF-16 file is refused with a log line instead of getting ASCII blocks spliced in, which would have broken the whole bar layout. Tests: bytes_that_are_not_utf8_are_kept and a_utf16_layout_is_refused_not_broken. Neither is likely with build-mode saves, which are ASCII.
  3. Per-frame mutex (7e22ba0). The shown percent was a std::sync::Mutex locked every frame from HUD_Frame, against CLAUDE.md's hot-path rule. It's now an AtomicU32. Only one thread ever took it, so you would not have seen anything; behaviour is unchanged.

Local results:

  • cargo test -p native: 783 pass.
  • cargo test -p goldsrc-hooks --target i686-pc-windows-msvc: 751 pass.
  • clippy 1.98.1, workspace and i686: clean.
  • fmt --check: clean.
  • Release hook build: OK, copied to local\test-465\dodstudio_goldsrc_hooks.dll. It's unsigned, so run it through build-and-launch.ps1 if WDAC blocks it.

Open questions for you:

  • Build-mode edits to the bar can be lost. With -addons, the game loads the bar from dod_addon\resource\DemoPlayerDialog.res. If you edit the bar in build mode (Ctrl+Shift+Alt+B) and save, the save most likely goes to that file, which is how PRE's old experiment file ended up there. The next Studio launch rebuilds that file from dod\resource, so the edit is lost. Should Studio warn about this, or start from the dod_addon copy when it is newer? I left it, since the design (regenerate from dod\resource at every launch) was decided on 2026-09-29 and 2026-10-12.
  • A TimeLabel placed with relative positions. If the user's TimeLabel uses build mode's relative forms (xpos "r100", "c-50"), the two controls fall back to the stock spot (284, 64) and not to wherever the time actually is. They still work, but they may sit in the wrong place. Stock and your PRE layout use plain numbers.
  • Not a bug here, just noting it: the hook's "no StudioLoadPercent" log line still names dod_addon for every Game folder.

🤖 Generated with Claude Code

@ccoventry

Copy link
Copy Markdown
Owner Author

Smoke test of the rebuilt DLL: rebuild works on PRE and POST.

DLL local\test-465\dodstudio_goldsrc_hooks.dll (rebuilt this morning on dev 3118435). game_probe, Brain account, -addons, ds_ui_viewdemo_in_panel 0, viewdemo solifotw-bewton (209 MB). Both installs already had the layout with StudioLoadPercent/StudioLoadProgress in dod_addon\resource (game_probe doesn't write it).

PRE: pass.

  • The bar shows 36% and fills while the title says "Loading solifotw-bewton.dem ...". Hook log: 0, 18, 20 ... 90%, then "the demo is loaded". No "has no StudioLoadPercent" line.
  • After loading, the percent and bar are gone.
  • ds_demo_show_load_progress 0 and a second viewdemo: no percent shown.
  • ds_debug_status: temp-entity fix 6 of 6, hull-trace guard on (pre-Anniversary). Only "not installed" line: frame_esc (POST-only by design). No crash.

POST: pass.

  • 40% and the bar while loading; once loaded the time and "x1 Playing" are back (06:05:55 x1 Playing). Log 0 ... 90%, then "the demo is loaded".
  • With the setting at 0, the stock time shows while loading, no percent.
  • ds_debug_status: temp-entity fix 6 of 6, hull-trace guard on (25th Anniversary). No crash.

Not this PR, but worth knowing: on PRE the bar has no time label after loading, and the time slider sits on the button row. It is the same with ds_demo_show_load_progress 0 from launch, so it comes from the PRE layout file or the bar's layout, not from the new controls. The 10-12 PRE grab showed the time, so something changed since then. POST is fine.

Screenshots in local\review-images\758\:

  • pre_loading_36pct.png, pre_loaded_progress_gone.png, pre_setting_off_loading_no_progress.png, pre_setting_off_loaded_no_time_label_either.png
  • post_loading_40pct.png, post_loaded_time_back.png, post_setting_off_loading_no_progress.png

Reports: local\game-probe\probes-758-pre\, probes-758-pre-off\, probes-758-post\.

ccoventry and others added 2 commits October 25, 2026 16:19
# Conflicts:
#	studio/src/console_commands_data.js
Studio rebuilt <game>_addon\resource\DemoPlayerDialog.res at every launch,
so a layout saved there from the game's build mode was lost on the next
launch. Studio's copy now starts with a // line holding a hash of the rest;
a file without it, or whose hash no longer matches, is the user's: the
launch adds the two loading controls only if they are missing and otherwise
leaves it alone. An unmarked copy identical to what Studio writes counts as
Studio's. The hook's missing-controls log line names the addon folder of the
running game folder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ccoventry

Copy link
Copy Markdown
Owner Author

Keep edits (your decision): done in 47bde20. dev merged in first (976b3ab; console_commands_data.js regenerated).

What changed: Studio's dod_addon\resource\DemoPlayerDialog.res now starts with a // line holding a hash of the rest of the file. At launch:

  • that line present and the hash matching: Studio's copy, rebuilt from dod\resource (else valve\resource) as before;
  • no line (a build-mode save writes no comments) or a hash that no longer matches (a hand edit): yours. The launch adds the two loading controls only if they're missing, keeps every other byte, adds no marker (so it stays yours), and otherwise leaves the file alone. The activity log says which. Delete the file to go back to the game folder's layout;
  • an unmarked file that is exactly what Studio would write (this PR's earlier test builds left those in PRE's and POST's dod_addon on 10-13) counts as Studio's.

Why a marker in the file rather than a record Studio keeps elsewhere or timestamps: it travels with the file, so a reinstalled Studio, a second checkout or a cleared settings folder still tells the two apart; timestamps change on a copy without the file changing.

Also: the hook's "the demo bar has no StudioLoadPercent" line now names <folder>_addon for the running Game folder.

Tests: fmt and clippy 1.98.1 (workspace and i686) clean; hooks i686 872 pass; workspace all pass; JS unit 904 pass; 9 new demo_bar_res tests. CI green on 47bde20.

In game (Brain, -addons, ds_ui_viewdemo_in_panel 0, ds_ui_remember_layout 0, viewdemo solifotw-bewton; layout step run as the launch runs it):

  • PRE and POST, a hand edit (Play and Pause swapped, no controls) in dod_addon: AddedToEdit, then KeptEdit on the next run. The bar shows the swapped buttons, the progress while loading (POST grab: 32%), and the time after. Log 0 … 90%, then loaded, on both.
  • PRE and POST, Studio's own copy: the 10-13 copy recognised as Studio's and marked; the game loads the marked file and shows the progress on both.
  • Both addon files put back as they were (backups in local\backups\1020\).

The no-time PRE bar from the 10-24 smoke test was #1020: the remembered size from POST squeezing PRE's taller bar, not this PR. Fix in #1046.

Verdict: ready to merge.

🤖 Generated with Claude Code

@ccoventry
ccoventry merged commit f5f1e7c into dev Oct 25, 2026
5 checks passed
@ccoventry
ccoventry deleted the feat/loading-progress-465 branch October 25, 2026 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show loading progress while a demo loads in the game

1 participant