Not Painkiller related, but still a retro experience – have a play with this: https://www.pkeuro.net/spectrum/
Monthly Archives: April 2026
Painkiller (2004) – Major Bugs and Fixes (Original and Expansions)
1. Launch/Compatibility Crashes (PC/OS Issues)
-
Game Won’t Start on Modern Windows (Crash at Launch): On Windows 10/11, Painkiller often crashes immediately on startup (screen flicker then exit). This affects Steam/GOG Black Edition (v1.6x) and older releases. Reproduced by running on Win10 with modern GPUs (e.g. Nvidia RTX) without special measures. The root cause is that Painkiller uses old DirectX9-era rendering and protected DRM (StarForce on retail), which is incompatible with modern drivers/OS. The official game lacks a built-in fix. Community findings show that installing a DirectX wrapper (dgVoodoo2) solves the crash: one user reports “I installed dgVoodoo… it should start to work”. In practice, copying dgVoodoo’s
d3d9.dll(and related 3Dfx DLLs) into the game folder causes the game to run on Win10. Fix: Use dgVoodoo2 or similar (native API translation) and run the game in compatibility mode if needed. This solution is easy to apply (just file copy) and has minimal side-effects, though performance may differ slightly. No source code patch is available; this is the accepted workaround. Difficulty: Low; Feasibility: High; Side effects: negligible (some users tweak settings to remove dgVoodoo watermark). -
StarForce DRM Failure: Early retail editions used StarForce copy-protection, which “does not work on modern versions of Windows”. This causes crashes or bootloops at launch. Officially, the issue is resolved by patched retail or digital re-releases (which remove StarForce). The fix is to apply the 1.64 retail patch or use the Black Edition, which contains no active StarForce. (Steam/GOG versions ship already patched.) No code fix possible without source; community hack: install a patched EXE without StarForce. Difficulty: N/A (handled by applying official patch).
2. Save/Load and Progression Crashes
-
Checkpoint/Save Crashes (Corrupted Saves): Multiple reports (e.g. Steam thread) describe the game “crashes when I save” at specific points, particularly in chapter 4 (“Docks”). Symptoms: reaching a checkpoint or manually saving causes an instant crash; reloading that save also crashes. Investigations show the save file becomes corrupted if captured during a volatile moment (often when many enemies spawn). Affected versions: Black Edition (v1.6x) after patch 1.35. Likelihood: Occasional but critical (blocks progress). Community diagnosis: this is a bug introduced in patch 1.35 or later – earlier (v1.31) reportedly never crashed. A common workaround is to limit the framerate (e.g.
setmaxfps 120) before loading, which stabilizes physics and prevents crash. Also, verify game files (to repair any corrupt exe) and delete the specific corrupted save slots. The final solution: installing the unofficial Painkiller Fix Pack v1.64 or higher fixes this crash. This patch (community mod) corrects the save timing bug at that checkpoint. Fix: Use mod (v1.64) or limit FPS to 120 before saving/loading; if stuck, delete broken saves and replay. Difficulty: Moderate (apply community patch or careful manual steps); Side-effects: FPS capping may slightly alter gameplay feel but stabilizes physics. The underlying cause is a Havok physics timing glitch under high FPS leading to save-state corruption. -
Missing/Glitched Enemy Spawns (Level Blocking): In some levels (e.g. City on Water in chapter 7), certain enemies fail to spawn, leaving the player unable to progress. Example: user IHateStairs reports “halfway through there are supposed to be like 6 enemies… 3 of them aren’t spawning”, freezing the level. Cause: a scripting or AI spawn-trigger bug in that map. Affected versions: Black Edition, likely both retail and patched. Frequency: rare (map-specific). Fix: Community workaround is to skip the glitch via a level-select or use the Powermad cheat mod to noclip past the blockade. A better fix (requires modding) would be to correct the map’s spawn script or add the missing spawn points. Without source, the practical solution is to use community patches that include map fixes (the official 1.64 patch notes mention “fixes on many levels to pass 5 stars”, which likely include spawn issues). Feasibility: High (cheat bypass), but proper fix (editing map scripts) is difficult without tools. Side-effects: Using cheats may disable achievements; map fix mod should have no side effects other than correcting the spawn.
-
AI Pathfinding / Stuck Enemies: Certain enemies occasionally get stuck or ignore the player. For example, Winged Demon in “Dead City” can fail to find the player and roam aimlessly. Cause: level geometry or AI waypoint bug. Also, bosses’ weapons don’t always get removed correctly (GunGhoul bug: axe/hammer left after boss death in patch 1.3 was fixed). Fix: Community patches address specific cases (the “dead city” demon bug is noted in mod comments). Feasibility: Medium (requires modded AI parameters); side-effects: minimal if fixed correctly.
-
Physics / Ragdoll Glitches: At very high framerates (>200 FPS), physics behave erratically (limbs flying unrealistically) – a known Havok bug. Players report “when shooting a stake at an enemy and his body flies up somewhere… result of high FPS”. Unofficial fixes introduce a console command
setmaxfpsto cap FPS for stable physics. The official patch did not include this, but many mods do. Fix: Apply community mod that addssetmaxfpscommand (difficulty low) or use an external frame limiter. Difficulty: Low; Side-effect: smooth gameplay. -
Weapon/Effect Bugs: Various weapon-specific bugs are documented by the community. Examples (from mod comments and changelogs):
- Shuriken Gun Audio: In early patches, shooting the shuriken gun rapidly would cut out its sound. Official patch 1.3 fixes this: “audio effect when shooting shuriken gun repeatedly no longer cuts out”. Modern versions already include this.
- Stake Gun Stats: Thrown stakes/bolts are not counted in kill statistics; mod fix exists.
- Sound/SFX Issues: Some pickups had wrong sound (“RifleFlameThrower wrong sound”). Mods correct sound assignments. Fix: Replace audio tag in config (easy if modded).
- Monster Spells: A rare Evil Monk crash was fixed by community mod. Cause: faulty AI state.
- Tarot & Powerups: Certain tarot card usage left game in a muted state (monster disappearance sound cut; demon morph music not returning). Community mod fixed monster-disappear sound.
- 4GB RAM Limit: On 64-bit systems, the 2GB memory limit can cause CTDs on large levels. Fix: XDavidXtreme’s 4GB patch lifts memory cap and adds windowed mode. Difficulty: Low (drop files), no side-effects known.
3. Gameplay Mechanics & AI
-
Enemy Behaviors: Some enemies had incorrect stats. For instance, SamuraiV2’s melee damage was set to 2 instead of 20, making them weak. Also, Guardian demon’s hammer (Thor) did not get the bonus damage from Fury/Rage tarot. These are data bugs in enemy parameters. Community mods fix these by editing AI config (difficulty: medium). Impact on gameplay: only makes enemies underpowered; fix improves intended challenge.
-
Secret Collection Bugs: Collecting all secrets in Battle out of Hell gave no bonus. A mod “fixes the bonus for completing BooH with all secrets”. Related: gold farming exploit on tarot board was removed (fix for gold gain bug).
-
Level Star Ratings: Some levels could not achieve 5★ rating due to hidden glitches. Community patch “fixes on many levels to pass 5 stars”.
4. Graphics and Video
-
Widescreen / Aspect Ratio: The game was designed for 4:3. On 16:9 or 21:9, several HUD and UI elements misalign. For example, tarot card unlock GUI is “messed up” in ultra-widescreen (need WidescreenHUDFix). Many community mods (e.g. WidescreenHudFix) correct UI scaling. Fix: Use mods like “PK Widescreen HUD Fix” (low difficulty to install) or enable the Advanced Settings menu (added by Randomguy7’s mod) to adjust HUD. Side effects: minor black bars or stretched HUD if not fixed.
-
Menu/Logo Glitches: The Black Edition logo music was silent in Steam version; community patch restored it. Extremely minor now.
-
Rendering Stutters on High-End GPUs: Users report frame stutter when many enemies spawn or die, despite high FPS. Often caused by background tools (e.g. Razer Game Booster) or driver issues. Solutions include updating drivers, disabling overlays, or lowering settings. No code fix; recommendation: disable third-party injectors. Side effect: none.
-
High-Resolution Issues: On 4K or high-res, the in-game menus and cursors may scale incorrectly (e.g. off-screen elements). Mods like HiResMenuFix by Lemmers (also included in some pack) fix this. Difficulty: low (apply mod files).
5. Audio and Music
-
Cut-Out or Missing Audio: Beyond the Shuriken gun fix (officially fixed in 1.3), community reports “no menu music” in some mod builds. That is a mod issue: ensure
music.enable 1in config. One user noted “menu became laggy” after patch (likely due to unresolved assets in mod). Official audio bugs seem rare post-1.3. Minor fix: mod Painkiller Hit Blur Fix handles HUD/shader but not audio; focus on fixes above. -
Voiceover/Localization: No major bugs reported in English VO. Localization patches exist (e.g. Italian conversion on ModDB) but official game has no glaring text bugs. Spanish/German fans may note mistranslations, but no authoritative bug reports were found.
6. Controls and Input
-
No Controller Support: Painkiller lacks native gamepad support. Multiple players advise against using a controller; only keyboard/mouse is supported. Workaround: use generic controller-to-keys tools (e.g. Xpadder). Difficulty: easy; side effect: imprecise strafing. Not a “bug” per se, but a limitation.
-
QuickSave Crash: A few users noted that using quicksaves can crash the game on some Win10 setups (see Steam thread “quick saves in windows 10 crash”). This seems tied to the same save-corruption issue above.
7. Networking/Multiplayer
-
UI Synchronization: Official patch 1.3 fixed some MP bugs: e.g. “scoreboard getting stuck open in rare instances as a spectator”. Also “server passwords now work from command line” was fixed. There are no major unresolved network bugs known for modern play; community mods included OpenSpy integration (enabling modern server browsers).
-
Latency & Ragdolls: Competitive play (CPL) redesigned some weapons and telefrag chance. Modern online play uses fan servers; typical bugs are outside scope of original game code.
8. Prioritized Bug List (Summary)
Below is a concise list of the most critical bugs, with reproduction and fixes:
| Bug / Category | Description & Repro Steps | Affected Versions | Frequency | Likely Cause | Fix / Mitigation (Difficulty / Side-effects) | Sources |
|---|---|---|---|---|---|---|
| Crash on Startup (Win10/11) | Game crashes on launch (black screen) on modern Windows. | All PC versions (esp. Win10) | Common | Incompatible DirectX/DRM (StarForce) | Use dgVoodoo wrapper (install DX9 and 3Dfx DLLs). Difficulty: Low. No loss of features. | [25][14] |
| Save/Load Crash (Corruption) | Game CTD when saving at/checkpoint or loading that save (notably C4L1 “Docks”). | Black Edition (post-1.35) | Occasional | Physics state save glitch under high FPS | Limit FPS to 120 or use community patch 1.64. Delete corrupted saves. Difficulty: Med (requires patch or careful saves). FPS cap may alter feel. | [29][41] |
| Missing Enemy Spawns (Level) | Certain enemies fail to spawn (e.g. “City on Water” skip), blocking progression. | Black Edition | Rare | Scripted spawn event bug | Bypass: noclip or level-select (Powermad mod). Full fix requires editing level scripts (community patches might already fix this). Difficulty: High to implement manually; Low to cheat-bypass. | [34][37] |
| AI Stuck / Pathfinding | Enemies (e.g. Winged Demons) get stuck in geometry or not trigger, sometimes indefinite. | All versions | Occasional | Faulty AI waypoints or level bugs | Community patch fixes known cases. No official fix. Difficulty: Med (mod needed); side-effects minimal. | [40][41] |
| Physics / Ragdoll Issues | Unstable physics at high FPS (e.g. limbs shoot off unrealistically); enemy knockback exaggerated. | All versions | Common if uncapped | Havok engine non-determinism | Cap FPS (command setmaxfps from mod) or use Vsync. Difficulty: Low. Maintains stability; may reduce raw FPS. |
[29][41] |
| Audio Glitches | Repeated shuriken firing could cut out sound (fixed in 1.3 patch); occasional missing menu music in fan patches. | Pre-1.3 / community mods | Rare | Audio engine buffer bug | Ensure latest patch (1.3+) or remove faulty mod files (e.g. alsoft.ini). Difficulty: Low. No side-effects. | [11][55] |
| Localization/Assets | No major bugs in official English; mods required for other languages (Italian, etc. on ModDB). | N/A | – | – | Use language patches (e.g. Italian Conversion mod). | [63] |
| Input/Controller | No built-in gamepad support; impossible to strafejump with controller. | All versions | N/A | Design choice | Use keyboard+mouse (recommended) or third-party mapper. Difficulty: Low. Gameplay designed for mouse. | [52] |
| Graphics/Resolutions | HUD/menu elements misaligned at UHD/widescreen; black bars or stretched UI. | Modern monitors | Common | 4:3-native HUD | Install widescreen HUD fix mods (e.g. by Lemmers) or use Advanced Settings mod. Difficulty: Low. | [41][55] |
| Performance/Stutter | Frame hitches when many enemies spawn or on certain drivers (Catalyst 15.x, overlays). | All versions | Occasional | Driver or tool conflicts | Update GPU drivers; disable background tools (e.g. Razer Game Booster). Difficulty: Low. Side-effects: none (fix removes lag). | [32][55] |
| Networking/MP UI Bugs | Occasional issues (scoreboard stuck pre-1.3). | Pre-1.3 | Rare | UI focus bug | Already fixed in official 1.3 patch. No remaining critical MP bug known. | [11] |
Each fix above should be tested: official fixes (patch 1.3/1.3.5) cover some issues; community patches like Unofficial 1.66 or Painkiller Fixes v1.64 cover the rest. When source code is unavailable (the case here), all root-cause diagnoses come from reverse-engineering and player testing (as cited).
4. Community Patches / Mods Comparison
Many fan-made patches aggregate fixes and quality-of-life improvements. Below is a comparison of notable community patches/mods:
| Mod/Patch | Features / Fixes | Fixed Bugs | Compat. | Install Complexity |
|---|---|---|---|---|
| Unofficial Patch 1.66 (2017) | Combines previous fixes plus 2 new fixes (details on PKZone). Generally updates exe and scripts to v1.66. | Broad bugfixes: save/load crashes, spawn bugs, etc. (see PKZone/changelogs). | Black Edition (PKBE), Overdose | Moderate (replace exe/data) |
| Randomguy7’s Fix Comp. v4 (2015) | Adds numerous fixes: weapon animations/sounds, reload fixes, new console cmds (FPS cap, FOV), advanced menu, hi-res menu, etc.. | Physics instabilities (add fps cap), boss camera, bookeers stats, etc. | PK original & BE (installs in game folder) | Moderate (mix of files) |
| Painkiller 4GB + Windowed (XDavid) | Removes 2GB memory cap, adds forced windowed mode option, integrates OpenSpy server browser. | Out-of-memory CTDs, Alt+Tab crash due to exclusive fullscreen. | All Painkiller games (2016) | Low (drop into Bin) |
| HiRes Menu Fix (Lemmers) | Fixes stretched/offscreen menus at very high resolutions (4K). | Menu/UI misalignment at 4K/UHD. | Any version (just UI files) | Low (instructions in README) |
| Widescreen HUD Fix (Lemmers) | Adjusts HUD/crosshair for 16:9+. | HUD elements stretched or off-center on widescreens. | All versions | Low (just a DLL or INI) |
| Powermad (cheat script) | Cheat console (noclip, godmode, etc.) for debug or bypassing issues. | Bypass for stuck levels/spawns, save issues, etc. (by noclipping out). | Original/BE | Low (run in-game script) |
| PainEditor (by community) | Level editor (not a bugfix). Useful to inspect/fix map scripts (advanced users). | N/A (tool). | All versions | High (technical use) |
(Mods/patches cited from ModDB and community sources.)
Each of the above mods must be compatible with the correct game version (most assume latest official v1.64/1.66). They generally involve copying files into the game directory (some require overwriting data files). Feasibility ranges from trivial (drop-in fixes like 4GB patch) to moderate (integrated fix packs). No major side-effects are reported, though some users noted that combining too many fixes can cause minor instabilities (e.g. menu lag) – usually resolved by using only needed fixes. Always back up original files first.
Sources: Official patch notes and community wikis; discussions on Steam and ModDB by developers and modders. These provide confirmed bug details and fix recommendations.
Painkiller’s Physics Architecture: Why It Breaks at High FPS and How to Fix It
1. Observed Physics Issues in Painkiller
Painkiller’s physics and animations demonstrably break at high frame rates. Community sources repeatedly note that capping to 60 FPS is “necessary” because above that “the physics are broken”. In practice, players see ragdolls “fly” strangely when killed with the Painkiller beam, and some scripted jumps or drops fail (e.g. enemies meant to drop through ceilings get stuck). One mod patch for Painkiller: Overdose explicitly fixes “Meteorite/Grenade rains” and “hanging corpses” that were originally “FPS based” and would “fling [corpses] like a feather”. Similarly, special weapon mechanics can misbehave: for example the HellBlade’s ammo consumption originally depended on the frame rate.
Other symptoms include input and loading glitches tied to vsync (the NVidia forum notes a “60 Hz fullscreen lock” bug when MSAA is enabled) and even system issues on multi-core CPUs. A user on the Widescreen Gaming Forum warned that Painkiller has “serious issues with multicore CPUs” – the only reliable fix was to force the game onto a single core or enable vsync. In short, anything that changes the timing of frame updates (higher FPS, multi-core scheduling, no vsync) can break game logic.
2. Technical Causes
The root cause is that Painkiller’s update loop ties physics/game logic directly to each frame rather than using a fixed time step. In developer interviews, Painkiller is noted to use Havok physics, but there is no evidence the engine implemented a proper fixed-step integrator for Havok. Instead, the game likely uses each frame’s time delta (or even an implicit unit of “one frame”) as the physics step. According to physics programming principles, this approach makes simulation results depend on the frame rate. As Glenn Fiedler’s “Fix Your Timestep!” explains, using a variable delta time each frame can cause physics to speed up, explode, or tunnel inconsistently when the frame rate changes. Painkiller appears to exhibit exactly these symptoms.
Moreover, many in-game systems likely schedule events by frame count or frame-based delays. For example, scripted triggers or enemy AI routines might assume a constant number of frames per second. When actual FPS deviates, those triggers fire too early or too late (or not at all). The mod patch notes suggest things like grenade spawn rates were per frame, hence fixed once they were made “no longer FPS based”. In combination, the engine’s lack of a fixed-tick accumulator, and coupling of physics to rendering, plus possible use of integer timers or frame-based loops, causes the frame-rate-dependent bugs.
3. Consequences for Gameplay and Modding
Frame-tied physics has serious gameplay consequences. Players on modern hardware either must cap FPS to 60 (losing smoothness) or suffer glitches. Critical gameplay elements (jumping puzzles, enemy hits) may fail unpredictably, making some parts of the game unplayable at higher FPS. Multiplayer (and any deterministic mechanics) also suffer: if client and host run at different FPS, their game states diverge, leading to desyncs or incorrect predictions. Modders likewise face challenges: any mod that adds fast-moving physics objects or scripts might work at 60 Hz but break at higher rates. Reproducing bugs is hard when simulation depends on frame timing. Even tool enhancements like the FPS limiter mod had to manually throttle the game (to 120 FPS) to restore “playable” physics.
In summary, the game is essentially non-deterministic across hardware, and any attempt to speed it up causes “broken” physics. This undermines reproducibility (critical for debugging and mods) and spoils the intended gameplay feel.
4. Proposed Solutions (Prioritised)
We recommend these fixes, in order of importance:
-
Implement a Fixed Timestep Loop: Use a constant physics update interval (e.g. 60 Hz or 30 Hz) with an accumulator. Each frame, accumulate real elapsed time, and step the physics simulation in fixed-size chunks. This guarantees consistent simulation regardless of rendering FPS.
-
Clamp or Sub-step Excess Time: To prevent instabilities if a frame takes too long, cap each physics step to the fixed interval. If frameTime > fixedStep, run multiple sub-steps within a loop (a “semi-fixed timestep”). This ensures no single step is too large (avoiding explosions or tunneling).
-
Interpolate for Smooth Rendering: With physics stepping decoupled, use interpolation to smoothly render frames between physics updates. Store the previous and current physics state, compute
alpha = accumulator/fixedStep, and interpolate positions for rendering. This allows rendering at high FPS while physics runs at fixed rate. -
Decouple Networking/Logic Tick: Separate any network or game-logic tick from rendering. For example, keep a game simulation tick (e.g. 60 Hz) that advances game logic, while rendering and input processing can run independently. This prevents network updates from speeding up with graphics.
-
Rework Timing/Event System: Convert any frame-count-based timers to real-time or fixed-step timers. For example, instead of “wait 30 frames” use “wait 0.5 seconds” in scripts. Ensure that triggers and scripts use the fixed timestep rather than raw frame events.
-
Determinism and Compatibility: Make the fixed-step simulation deterministic (given same inputs it produces the same output). For mods, offer a “legacy mode” fallback that emulates the old timing (e.g. by limiting FPS to 60 under the hood) for backwards compatibility.
-
User-Configurable Tick Rate: Expose a configuration for target physics tick rate (like
SetMaxFPSor a newMaxTickRate). The engine already supports a max FPS setting (community mod usesWORLD.SetMaxFPS); we would embed an official config. This allows modders or players to tune if needed.
Each fix should be carefully tested. The highest priority is a correct fixed timestep (guaranteed consistent physics) over e.g. just limiting FPS by other means. The table below summarises key symptoms and solutions:
| Symptom / Issue | Likely Cause | Proposed Fix | Risk/Impact |
|---|---|---|---|
| Ragdolls/enemies misbehave at >60 FPS | Physics and forces updated per render frame | Use fixed-update loop (e.g. 60 Hz tick) with accumulator | Major: Changes pacing of physics. Need tuning, but fixes accuracy. |
| Scripted events fail (e.g. drop triggers) | Frame-based event counters / timers tied to FPS | Use time-based triggers or fixed-tick counters | Medium: Requires rewriting scripts/triggers, thorough testing. |
| Multi-core/unlimited FPS crashes | Engine not thread-safe / no FPS cap | Force single-thread or implement thread safety; set fixed max FPS | Low: Workaround vsvsync may reduce performance. Full thread fix complex. |
| Network inconsistencies (multiplayer) | Server/client tick tied to render loop | Separate network tick, or enforce fixed server tick (e.g. 60 Hz) | Medium: May need new network code; improves sync. |
5. Migration Plan (Legacy Engine)
For the legacy Painkiller engine (no source code currently available publicly), we outline an implementation approach:
- Engine Code Changes: Identify the main game loop (in the engine or DLL). Insert a timing accumulator: measure real time each frame, add to
accumulator. In a loop, whileaccumulator ≥ fixedStep, call the existing physics/logic update function (ideally extracted) with a constantdt = fixedStep, then subtract fromaccumulator. If source code is not available, one could inject code via a DLL patch or use the existing LScripts mechanism to call a new update loop, if feasible. - Config Options: Introduce new settings (e.g. in
Config.ini) forPhysicsTickRateor adapt the existingMaxFPSto mean physics tick. Ensure there’s a default that replicates old behaviour (possibly “60 Hz fixed” or even an “unlimited” legacy mode) for compatibility. Provide a console command (as the mod does) to adjust it. - Script Integration: Review any engine scripts (Lua/LScripts) for frame-based logic. Replace frame-dependent waits (
Wait:N) with time-based or fixed-step waits if possible. If LScript exposes time, use that; otherwise use the new tick rate to calculate frames. - Testing Strategy: Create automated tests or manual checklists (below) running the game at various simulated FPS (30, 60, 120, 240) and verifying identical outcomes. Compare with baseline (unmodded) at 60 FPS to ensure fixes do not break intended gameplay. Focus on boss fights, physics puzzles, and ragdoll interactions.
- Rollback/Compatibility: If some mods expect the old fast-FPS behaviour (unlikely), provide a “legacy mode” toggle. Consider a rollback/resume system only if the engine ever supported save-scumming; more importantly ensure new code does not conflict with saved game states or cheats.
- Performance Trade-offs: A fixed timestep loop may require multiple physics steps per frame on fast machines, costing CPU. However, Painkiller’s physics are relatively simple (2004 era). We recommend targeting 60 Hz; if performance suffers, consider “semi-fixed” where a maximum sub-step count is allowed (as in Gaffer’s article). Use interpolation to allow rendering at higher rates without additional simulation cost.
6. Example Pseudocode and Flowchart
Fixed-timestep loop (pseudocode):
c
const double fixedStep = 1.0 / 60.0; // 60 Hz physics tick
double accumulator = 0.0;
double prevTime = getTime();
GameState prevState, currState;
while (gameRunning) {
double now = getTime();
double frameTime = now - prevTime;
prevTime = now;
accumulator += frameTime;
// Perform fixed-timestep updates
while (accumulator >= fixedStep) {
prevState = currState;
updatePhysics(currState, fixedStep); // advance physics/logic
accumulator -= fixedStep;
}
// Interpolation factor
double alpha = accumulator / fixedStep;
// Interpolate state for smooth render
GameState renderState = interpolateState(prevState, currState, alpha);
render(renderState);
}
This uses the accumulator pattern. It ensures physics runs at a constant rate (60 Hz) no matter how fast getTime() advances. The renderer interpolates between prevState and currState based on alpha for smooth visuals.
mermaid
flowchart TD
A[Start Frame] --> B{Get current time, compute Δt}
B --> C[accumulator += Δt]
C --> D{accumulator >= fixedStep?}
D -- Yes --> E[prevState = currState]
E --> F[updatePhysics(currState, fixedStep)]
F --> G[accumulator -= fixedStep]
G --> D
D -- No --> H[alpha = accumulator / fixedStep]
H --> I[interpolate(prevState, currState, alpha)]
I --> J[Render interpolated state]
J --> A
This flowchart illustrates how physics updates (yellow) run in discrete steps of fixedStep time, while rendering (blue) uses interpolation between physics states.
7. Testing Checklist & Metrics
To verify the fixes, we propose this checklist and metrics:
- Multi-FPS Consistency: Run key gameplay segments (start of Level 1, boss fights, puzzles) at different frame caps (30, 60, 120, 240 FPS) and ensure identical outcomes. No ragdoll anomalies or missed triggers should occur.
- Physics Stability: Dropping or throwing objects should behave the same at all frame rates. Ragdoll trajectories from the Painkiller beam should land consistently (no “flying away”).
- Performance: Measure CPU usage and frame time. Ensure physics steps per second ~= tick rate, and that the simulation “keeps up” without spiral-of-death. If not, consider lowering tick rate or capping steps per frame as per semi-fixed advice.
- Networking: If multiplayer is used, check that lag compensation or prediction is unaffected. Host/client should not desync due to frame differences.
- User Experience: Confirm that input handling (movement, shooting) feels correct with interpolation; no input lag introduced. Check mouse/keyboard responsiveness.
- Regression Tests: For mod compatibility, load popular mods (e.g. co-op, new levels) at uncapped FPS and verify they don’t break scripts. Compare with stock behaviour at 60 Hz.
- Tools/Automation: Use a script or tool to force frame rates and capture logs. A simple metric is to log the number of physics steps per second (should be constant, e.g. 60).
If any test fails, investigate whether physics or logic code still depends on frame counts, and adjust accordingly. For performance, the key metric is that simulation time per real second ≈ physicsTickRate (e.g. 60 updates per second on average), and that rendering can exceed it without issues.
Sources
The above analysis draws on both official and community information about Painkiller’s engine and physics:
- Steam Community Discussion – “What is the optimal framerate for this game?” (Painkiller: Black Edition). Reports from players confirming that physics glitches occur above ~60 FPS.
- Widescreen Gaming Forum – “Painkiller: Detailed Report” (2007). Notes on engine issues with modern multi-core CPUs and the need to cap FPS or use one core.
- ModDB Patch Notes – Painkiller: Overdose 86.2u Patch (community mod). Lists specific fixes of frame-rate-dependent bugs (e.g. Hellblade ammo, meteor rains, ragdoll flinging).
- Steam Community Guide – “Painkiller FPS limiter” by Peppins (2015, updated 2023). Demonstrates that by default the engine had no FPS cap (unlimited mode) and community mods set it to 120 FPS for stability.
- Gaffer on Games – “Fix Your Timestep!” (Glenn Fiedler, 2004). Explains why physics must not be tied to variable frame Δ-time and provides fixed-step and accumulator techniques.
- Jakub’s Tech Blog – “Reliable fixed timestep & inputs” (2024). Describes a fixed-update game loop with interpolation and the pitfalls of separating physics and rendering updates.
Each source is cited with numbered references. Community sources are explicitly flagged and developer guidance on fixed timesteps provides the technical basis for the proposed solution.