Fix underpowered starter torque: mutation bug, hesitation tuning, engagement & compression#13
Conversation
Co-Authored-By: BtaWlf <nharvey53@hotmail.com>
…agement & compression - Fix starterTorque mutation bug: use local variable instead of mutating device.starterTorque each frame during misfires (was causing progressive weakening during cranking) - Reduce struggle phase from 14s fixed to 3-7s scaled with temperature (colder = longer, warmer = shorter) - Raise hesitation factor floor from 50-90% to 70-95% torque range - Raise engagement factor start from 60% to 80% for stronger initial crank - Reduce compression stroke resistance multiplier when cold (2.0 - tempEffect -> 1.5 - tempEffect*0.5) Co-Authored-By: BtaWlf <nharvey53@hotmail.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
This definitely feels better, but still undergoing testing. |
|
Glad to hear it's an improvement! Let me know if any of the values need further tuning after more testing — happy to adjust the struggle duration, hesitation floor, engagement ramp, or compression resistance as needed. |
There was a problem hiding this comment.
Devin Review found 5 potential issues.
🐛 5 issues in files not directly in the diff
🐛 Case mismatch device:lockup() calls undefined method; should be device:lockUp() (combustionEngine.lua:610)
In checkHydroLocking at line 610, device:lockup() is called with a lowercase 'u'. The actual function is defined as lockUp (capital 'U') at combustionEngine.lua:524 and assigned to the device as device.lockUp = lockUp at combustionEngine.lua:4409. There is no device.lockup defined anywhere. When the engine hydrolocks (flood level exceeds threshold), this will cause a nil function call runtime error, preventing the hydrolock from being properly applied and crashing the update loop.
🐛 local dt = 1/60 shadows the function parameter dt, breaking all subsequent time-dependent calculations (combustionEngine.lua:907)
At line 907, local dt = 1 / 60 redeclares dt as a local variable inside updateGFX(device, dt), shadowing the actual frame delta time passed as a parameter. All code after this line within updateGFX — including ignition error timers (combustionEngine.lua:1086-1105), stall timer (combustionEngine.lua:1133), rev limiter timer (combustionEngine.lua:1142), over-rev/over-torque damage accumulation (combustionEngine.lua:1148,1218), afterfire fuel delay pushes (combustionEngine.lua:1364-1367), thermal updates (combustionEngine.lua:1385), and idle AV smoothers (combustionEngine.lua:1391-1396) — all use a hardcoded 1/60s timestep regardless of the actual frame rate. This causes incorrect timing behavior at any frame rate other than 60fps.
🐛 Impossible condition prevents engine shut-off sound from ever playing (combustionEngine.lua:1116-1117)
At lines 1116-1117, the condition requires device.outputAV1 < device.idleAV * 1.1 AND device.outputAV1 > device.idleAV * 1.1 simultaneously. A value cannot be both strictly less than and strictly greater than the same number, so this condition is always false. The shut-off sound will never play. The original code used < device.idleAV * 0.95 and > device.idleAV * 0.5, which defined a valid RPM window.
🐛 Undefined variable misfireAmount causes runtime crash during flood misfires (combustionEngine.lua:3098)
The variable misfireAmount is referenced at lines 3098, 3105, and 3122 but is never defined in the enclosing scope. When a misfire occurs during engine flooding (flood level > 0.1), the code reaches string.format("Misfire! Amount: %.2f, ...", misfireAmount, ...) at line 3098, which will error because misfireAmount is nil and %.2f requires a number. Even if the log were skipped, line 3105 (if misfireAmount < 0.85) would also error comparing nil with a number. This crashes the torque update loop whenever the engine is flooded.
🐛 Operator precedence bug makes coast-down initialization dead code (combustionEngine.lua:3020)
At line 3020, the condition device.starterEngagedCoef == 0 and not device.starterEngagedCoef == 1 is parsed by Lua as (device.starterEngagedCoef == 0) and ((not device.starterEngagedCoef) == 1). Since device.starterEngagedCoef is a number (always truthy in Lua), not device.starterEngagedCoef evaluates to false, and false == 1 is always false. The entire condition is therefore always false, so coastDownRPM and coastDownTime are never initialized.
View 7 additional findings in Devin Review.
Summary
Fixes 5 issues causing the starter motor to feel underpowered during cranking. The root cause was a combination of a progressive torque mutation bug and overly aggressive reduction factors that compounded to deliver as little as ~15% of base torque in cold-start scenarios.
Changes:
Fix
starterTorquemutation bug (line 2645-2646):device.starterTorquewas being mutated every frame during misfires (device.starterTorque = device.starterTorque + misfireTorque + oscillation), causing progressive weakening throughout cranking. Now uses a local variableeffectiveMisfireTorqueto preserve the original device property.Reduce struggle phase duration (line 2354): Was a fixed 14-14.8s at reduced torque. Now scales with engine temperature: 3-4s when warm, up to 7s when very cold (-20°C). Uses
coldFactorderived fromengineTempC.Raise hesitation factor floor (line 2362): Changed from
0.5 + pulse * 0.4(50-90% torque) to0.7 + pulse * 0.25(70-95% torque). The starter no longer drops to half-power during the struggle phase.Raise engagement factor start (line 1679): Changed from
0.6 + 1.7 * curveto0.8 + 1.2 * curve. Initial crank now starts at 80% torque instead of 60%, giving a stronger first turn.Reduce compression stroke resistance when cold (line 2966): Changed from
(2.0 - tempEffect)to(1.5 - tempEffect * 0.5). Cold compression resistance was stacking too aggressively with the other reduction factors.Note: The first commit updates
combustionEngine.luato the current working version (v1.6) which includes glow plugs, carburetor integration, engine failure system, and expanded fuel database. The second commit contains the actual starter torque fixes.Review & Testing Checklist for Human
0.6 + normalizedTemp * 0.6), verify they still feel appropriately harder to start when cold.Notes
starterMaxAVdefault multiplier (idleRPM * 0.5on line 4510) was left unchanged since the user noted this was set for testing purposes. This can be tuned independently.starterTorque,starterMaxRPM, etc.) for per-vehicle adjustments.Link to Devin session: https://app.devin.ai/sessions/bc7edecbb1a84a2a82236338bb6a8c45
Requested by: @lonewolf0708