PerfKit
Settings-only performance tweaks: log stack traces, shadow distance, texture mip level, thread/async upload. No frame cap by default, every option toggleable.
By alp
| Date uploaded | 2 weeks ago |
| Version | 1.1.2 |
| Download link | alp-PerfKit-1.1.2.zip |
| Downloads | 105 |
| Dependency string | alp-PerfKit-1.1.2 |
This mod requires the following mods to function
BepInEx-BepInExPack_GTFO
BepInEx pack for GTFO. Preconfigured and includes Unity Base DLLs.
Preferred version: 3.2.2README
PerfKit
Settings-only performance tweaks for GTFO. It does not modify game data, does not use Harmony patches, and never touches your save. It only adjusts global Unity quality/logging values, and every option can be switched off independently in the config file.
Config file: BepInEx\config\local.perfkit.cfg (generated on first launch)
Defaults
[1-Log]
StripLogStackTrace = true # drop stack traces for Log/Warning/Assert
StripExceptionStackTrace = false # keep them for exceptions
[2-Shadows]
Enabled = true
DistancePercent = 65 # shadow distance = 65% of the original
[3-Textures]
Enabled = true
MipOffset = 1 # one step below what the game itself set
[4-Threads] # absorbed from GTFOThreadRelief
JobWorkerCount = 0 # 0 = leave alone
AsyncUploadBufferMB = 0 # 0 = leave alone
AsyncUploadTimeSliceMs = 0 # 0 = leave alone
AsyncUploadPersistentBuffer = false
[5-Misc]
TargetFrameRate = 0 # 0 = no frame cap
VSyncCount = -1 # -1 = follow the in-game setting
DisableVSyncWhenCapping = false
ReapplySeconds = 0 # 0 = apply once at startup
What each option actually does
| Option | What it changes | Visual impact | Gain |
|---|---|---|---|
StripLogStackTrace |
Application.SetStackTraceLogType → None |
none | small (CPU only) |
StripExceptionStackTrace |
same, for exceptions | none | small, but harder to debug |
DistancePercent |
QualitySettings.shadowDistance scaled |
distant shadows vanish | large (GPU) |
MipOffset |
QualitySettings.masterTextureLimit, relative to the game's own value |
textures/UI get softer | medium |
JobWorkerCount |
JobsUtility.JobWorkerCount |
none | usually zero — Unity defaults to the maximum and only allows lowering |
AsyncUploadBufferMB |
texture upload ring buffer | none | small, costs memory |
AsyncUploadTimeSliceMs |
per-frame upload time slice | none | small |
TargetFrameRate |
Application.targetFrameRate |
none | smoother frame times |
VSyncCount |
QualitySettings.vSyncCount |
possible tearing | lower latency |
Presets
- Conservative —
DistancePercent=85,MipOffset=0, everything else default. - Balanced (default) —
DistancePercent=65,MipOffset=1. - Aggressive —
DistancePercent=40,MipOffset=2.
No frame cap by default.
TargetFrameRate = 0means PerfKit never interferes with frame rate; the game's own VSync decides. Only change it if you want a cap — and then read the next section.
Why a frame cap may appear to do nothing
Unity has a hard rule: while vSyncCount > 0, Application.targetFrameRate is ignored.
GTFO runs with VSync on by default, so setting only TargetFrameRate has no effect.
Two ways to make it work:
TargetFrameRate = 60
DisableVSyncWhenCapping = true # PerfKit disables VSync for you
…or turn VSync off in the game settings yourself. Also note that a cap only matters when your frame rate is above the cap; capping at 60 on a machine that runs at 50 changes nothing. For frame-time stability, cap slightly below your average (e.g. 45 for an average of 50).
If the cap cannot take effect, PerfKit logs a warning instead of failing silently.
Does the periodic re-check cause stutters?
No. When ReapplySeconds > 0, the re-check only touches the cheap values (shadow
distance, log stack traces, frame cap). It never re-applies the texture limit, because
changing masterTextureLimit at runtime re-uploads every texture — that is what causes a
hitch. It also only writes when a value actually deviates, so normally it does nothing.
ReapplySeconds = 0 (default) applies everything once at startup with zero overhead. Raise
it only if another mod keeps resetting these values.
Compatibility
- Only global
Application/QualitySettingsvalues are modified — no GameData blocks, so it does not conflict with mods that change weapons, enemies, maps or UI. - Modded maps are unaffected: these are global rendering settings and do not change map logic, lighting data or generation.
- If you use another graphics mod (e.g. LowSpecGaming), set
ReapplySeconds = 0, otherwise the two will keep overwriting each other. - Performance Traffic Control (PTC) is fully compatible: PTC handles per-object enemy shadows, corpses/ragdolls and fog/vegetation, while PerfKit handles global quality values.
- The former
GTFOThreadRelief.dllfeatures are included under[4-Threads]— do not run both.
A note about Shadow (invisible) enemies
MipOffset lowers texture resolution globally. Shadow-type enemies are only visible through
very subtle shading/distortion, so heavy texture reduction may make them slightly harder to
spot. If that matters to you, set [3-Textures] Enabled = false — the shadow-distance option
provides most of the gain anyway.
Verifying
BepInEx\LogOutput.log prints a before/after snapshot (the human-readable part of these
messages is in Chinese in this build):
[PerfKit] before: VSync=1 targetFrameRate=-1 shadowDistance=200 masterTextureLimit=2
[PerfKit] shadow distance 200 -> 130 m
[PerfKit] texture baseline = 2
[PerfKit] texture mip limit 2 -> 3
[PerfKit] after: VSync=1 targetFrameRate=-1 shadowDistance=130 masterTextureLimit=3
[PerfKit] done.
Comparing the two snapshot lines tells you exactly which values were applied.
Uninstall
Delete PerfKit.dll. The settings return to the game defaults on the next launch; nothing is
written to your save.
CHANGELOG
1.1.2
- Packaging only: English readme and description. No code change.
1.1.1
- The mod no longer caps the frame rate by default (
TargetFrameRate = 0). - Documentation no longer implies a default frame cap. The cap is still available, but has to be enabled explicitly.
1.1.0
- Added
DisableVSyncWhenCapping: whenTargetFrameRate > 0, VSync is disabled so the cap actually takes effect (Unity ignorestargetFrameRatewhilevSyncCount > 0). - A clear warning is printed when a frame cap cannot take effect, instead of failing silently.
- Fixed: the periodic re-check no longer touches
masterTextureLimit— changing it at runtime re-uploads every texture, which is what caused a short hitch. ReapplySecondsnow defaults to0(apply once at startup, zero overhead).- Config descriptions are bilingual (Chinese + English).
- Added before/after value snapshots to the log so you can verify what was actually applied.
1.0.1
- Texture option fixed:
MipOffsetis now an offset relative to the value the game sets at startup, instead of an absolute value (the old behaviour could raise quality instead of lowering it when the game had already reduced texture quality).
1.0.0
- First release.
- Log: disables stack traces for
Log/Warning/Assert(optionally forExceptiontoo). - Shadows: scales the global shadow distance by a percentage.
- Textures: lowers the global mip limit by an offset.
- Threads: absorbs the former
GTFOThreadReliefoptions (JobWorkerCount and async upload settings), disabled by default. - Misc: optional frame cap and VSync (default
-1, follow the in-game setting). - Every option can be toggled independently in
BepInEx\config\local.perfkit.cfg.