Docs: 0.1.3 version refs, check count, what the 0.1.3 recording verified, event-handler patches in the session guide (PL8, PL7) - #4
Merged
Conversation
…date README said 0.1.2 and that nothing after 0.1.0 had been played; it now says 0.1.3, what has been played since, and that the zip is dist\PerformanceLog-<version>.zip (the manifest's version, as build.ps1 names it). CLAUDE.md said "about 70" C# checks; it is 91 at 0.1.3, and it now points at docs/TESTING.md for the current count. Its "what is verified" note mentioned only the 0.1.0 run. docs/TESTING.md said nothing from 0.1.1 onward had run in a game. The 0.1.3 session 2026-09-21_23-13-11 (43.9 minutes, ten mods, defaults) shows item 1 (the 0.1.1 fixes: 3 wrapper swaps, workingMB 5587-7090, game singletons labelled "game", heap growth on 310 loading rows, Draw Calls largest 37554, LoadAll 1) and item 8 (deep installed, 47081184 sampled component calls, 3475 component rows). They move to a new "verified in a real game" section with the lines that show them. Item 1 keeps only zipping a folder while the game runs, which no recording can show. Items 2, 3 and 7 stay open; item 7 now notes that PerformanceSettings.Load() ran against the real Mod Settings services (a load row in profile.csv, and defaults that an unloaded setting would have clamped to 1 or 0). The mod's own cost estimate (0.45% of a frame) is recorded with the caveat that it rests on patchCallNs 0. The CHANGELOG's 0.1.3 heading drops "not yet played", and its note that nobody had played it now says that was at release. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Timing is inclusive per key, and the game runs event handlers at once: EventBus.Post calls every [OnEvent] method synchronously once the bus is ready, and C# events such as Inventory.InventoryChanged (which StockpileVisualizers.OnInventoryChanged listens to, and MixedStorage patches) fire inside the code that changed something. So a mod's patch on a handler has no row of its own: its time lands in the entity, component or singleton that raised the event, or in otherMs. Events posted while the game loads are queued until EventBus.PostLoad and are charged to its post-load row. The session guide (docs/SESSION-README.md, copied into every session folder) now says so in "Which mod is it?", points at the # patch|other| and # patch|shared| lines that name these handlers, and says that a Watch entry with that name times the handler with every patch on it (Watch patches with Priority.First/Last). The # patch| bullet also lists the "other" tag it had left out. Both fixtures' README.md are regenerated from it; their frames.csv is left as it was, because regenerating also rewrites allocKB values that differ from run to run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review of the PL8 docs found three small inaccuracies: - TESTING.md quoted two frame counts for the same session (236917 from summary.md, 236918 from the closing lines, which count the first frame too). The wrapper bullet now says "for the whole recording" instead of a second figure. - README.md and TESTING.md's intro said the 0.1.3 recording shows "the 0.1.1 fixes" working, while TESTING.md keeps one of them (zipping a session folder while the game runs) open because a recording cannot show it. Both now say "every 0.1.1 fix a recording can show". - The rewritten last sentence of the CHANGELOG 0.1.3 entry kept an older false clause: the five-minute check does not start by checking overheadUs; its step 10 measures the cost. It now says that. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 22, 2026
kramsey458
marked this pull request as ready for review
September 22, 2026 19:32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Docs only. The repository docs still described 0.1.2 and said nothing from 0.1.1 onward had been played. Since then 0.1.1 and 0.1.3 have been recorded in the game. This PR updates the version references and the check count, and records what the 44-minute 0.1.3 recording
2026-09-21_23-13-11verified in the game. TESTING items 2, 3 and 7 stay open. It also adds one paragraph to the session guide (docs/SESSION-README.md, embedded in the mod and copied into every session folder) about where a mod's patch on an event handler is charged.No code, settings, file-format, Harmony or version changes.
manifest.jsonand the csproj still say 0.1.3.Items
PL8: versions, check count and verified-in-game notes (87036bd, 1032b3f)
dist\PerformanceLog-<version>.zip(the version inpackaging/manifest.json, which is howbuild.ps1names it) instead of a fixed0.1.2.2026-09-21_23-13-11:singleton wrappers put in place|3(0.1.0: 488601)workingSet|from Windows, andworkingMB5587 to 7090modDraw Calls Count|produced valuesLoadAll|1componentrows over 47 classespatchCallNs|0, so this is not a measurementdeepas the default) and the parts of item 1 that a recording can show moved into that section.PerformanceSettings.Load()did run against the real Mod Settings services. There is aloadrow, the# config:values are the defaults afterApplyTo, and an unloadedModSetting<T>readsdefault(T)(checked by decompiling ModSettings.Core), so it would have been clamped to its minimum. Whether the page renders, and whether a changed value reaches a session, stays open.overheadUs(that is step 10).Documents/Timberborn/PerformanceLog,Player.log, the code, and the decompiled ModSettings.Core. An independent reviewer re-derived all of them with its own scripts over the 26 recordings.PL7: event-handler patches in the session guide (0f59baa)
[OnEvent]methods and C# event handlers such asStockpileVisualizers.OnInventoryChanged, which MixedStorage patches. Its time is charged to whatever raised the event: an entity's tick (entMsand that entity's rows), a singleton's row, orotherMs. Events posted while the game loads wait forEventBus'spost-loadstep and are charged there. The# patch|other|and# patch|shared|lines name these handlers in full, and aWatchentry with that name times the handler together with every patch on it (kindmethod). The# patch|bullet now also lists theothertag, which it had left out.README.mdfiles were regenerated, soWriterTests.FixturesAreCurrentpasses. Only those files are committed. See the second new finding for why the regeneratedframes.csvwas left out.EventBus(PostcallsPostNowat once oncePostLoadhas set_ready; before that, events queue in_earlyEventsandPostLoaddrains them),StockpileVisualizers(_inventory.InventoryChanged += OnInventoryChanged),Watch.cs(aPriority.Firstprefix and aPriority.Lastpostfix; non-public methods are resolved too) andPatchReport.cs. The real session's header has# patch|other|...StockpileVisualizers.OnInventoryChanged|postfix|kyler.mixedstorage, and itsprofile.csvhas apost-loadrow forEventBus.Tests
dotnet run --project tests -c Release -- --managed <Managed>)python -W error::ResourceWarning -m unittest discover -s tools -p test_perflog.py)dotnet build source/PerformanceLog.csproj -c Release)Co-op impact
None. Only Markdown changes, and neither simulation nor the wire format changes. The mod only observes.
Proposed CHANGELOG lines
(CHANGELOG.md itself only changes as described under PL8: the 0.1.3 heading and that entry's last sentence.)
Needs in-game testing
Watch = Timberborn.StockpileVisualization.StockpileVisualizers.OnInventoryChangedtoPerformanceLog.cfgin the mod'sversion-1.1folder, then restart the game. Play 3 minutes while stockpiles fill. Theframes.csvheader should have# watch|Timberborn.StockpileVisualization.StockpileVisualizers.OnInventoryChanged(Object,InventoryChangedEventArgs)|watching, andprofile.csvshould havemethodrows for it. Remove the Watch line afterwards.SlowFrameMsto 77, load a save, play a minute and leave. The new session'sframes.csvshould say# thresholdMs: 77.frames.csv,profile.csv,spikes.csvandevents.csvwith non-zero sizes.Review
One adversarial reviewer (save compatibility and cross-mod interaction) approved. It re-ran both suites (91/91, 44 OK) and re-derived every figure in the new TESTING section from the recordings. It confirmed the item 7 narrowing by decompiling ModSettings.Core, and the SESSION-README claims against the decompiled game. It found three nits, all fixed in 1032b3f:
summary.md, 236918 from the closing lines, which also count the first frame). Now one figure.overheadUs"). Now it points to step 10.Declined: README's "From 0.1.1 you can also copy or zip the folder while the game runs" (under the session-folder description) stays as it is. It describes what the mod does, and
WriterTests.ReadableWhileRunning/RetriesWhenHeldcheck it automatically. TESTING.md tracks the separate question of whether it has been seen in the game.Found along the way, not fixed here:
summary.mdwrongly says "Unity's frame phases: NOT measured" whenever the player leaves to the menu.Session.StopcallsPlayerLoopTiming.Uninstall()(which setsInstalled = 0) beforeRefreshSummary("finished"). All 11 of 26 real sessions that ended with "the game was left" say this, while theirframes.csvsaysplayerLoop|timed 8 phases. Only the summary line is wrong; the data is fine. The reviewer confirmed this. It needs its own fix.--write-samplewrites differentallocKBvalues on every run, becauseProbe.Framereads the test process's real heap viaGC.GetTotalMemory.FixturesAreCurrentcompares only headers and the Markdown files, so it does not notice. Any PR that regenerates fixtures therefore churnsframes.csvwith meaningless diffs.For the maintainer: 0.1.3 has now been played in the game. CLAUDE.md says a release stays a pre-release until it has been played, so whether to change the v0.1.3 GitHub release is your call. This PR does not touch it.
Expect small conflicts in
docs/TESTING.mdwith #1, #2 and #3 (check counts, item 2's wording, #1's new item 9). Whichever lands second should keep both sides.🤖 Generated with Claude Code