Add speed-based throttle, surface brake, and turbo lag effects#64
Open
O0rphan wants to merge 5 commits into
Open
Add speed-based throttle, surface brake, and turbo lag effects#64O0rphan wants to merge 5 commits into
O0rphan wants to merge 5 commits into
Conversation
At low speed (parking, hairpins) the throttle trigger feels heavier for more precise inputs; at high speed (highway cruising) it goes lighter so sustained WOT is comfortable without finger fatigue. New settings (Settings > Right trigger section): - enable_speed_throttle: toggle (default on) - speed_throttle_boost: extra force at 0 km/h (0 = off, default 0) - speed_throttle_fade_km: speed where boost fully fades (default 80) When boost > 0, the effective max_force scales from (throttle_max_force + boost) at 0 km/h down to throttle_max_force at fade_km. The existing throttle ramp curve is preserved throughout. Translations added: ru, tr, zh, ja.
Modulates brake trigger stiffness based on the driving surface. On tarmac the brake feels firm and progressive; on dirt it goes softer (spongy feel); on gravel/water even softer - matching how real brakes feel less effective on loose surfaces. New settings (Settings > Left trigger section): - enable_surface_brake: toggle (default off) - surface_brake_tarmac: multiplier on tarmac (1.0 = unchanged) - surface_brake_dirt: multiplier on dirt (default 0.7) - surface_brake_gravel: multiplier on gravel/water (default 0.5) Reuses the same surface classification from wheelspin_buzz (surface_rumble + wheel_in_puddle). Both baseline and max force are scaled by the multiplier before the ramp is computed. Only active while braking. Translations added: ru, tr, zh, ja.
Brief deep vibration on R2 when boost pressure is actively climbing, simulating the moment of lag before full turbo power kicks in. Silent at steady-state boost or zero boost. Uses the existing boost field (0.0-1.0) from Forza telemetry. Delta detection: only fires when (current_boost - previous_boost) exceeds a configurable threshold. Amplitude scales with the rate of boost increase. New settings (Settings > Turbo lag section): - enable_turbo_lag: toggle (default on) - turbo_lag_freq: vibration frequency in Hz (default 8, deep rumble) - turbo_lag_amp: max amplitude (default 40) - turbo_lag_threshold: min boost delta per tick (default 0.05) R2 priority chain updated: gear shift > idle > rev limiter > wheelspin > turbo lag > end wall > throttle ramp. Translations added: ru, tr, zh, ja.
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds new Forza Horizon trigger effects and exposes them in both GUI/TUI settings, including localized strings.
Changes:
- Added surface-aware brake resistance multipliers (tarmac/dirt/gravel).
- Added speed-based throttle resistance (extra force at low speed that fades with speed).
- Added turbo-lag R2 rumble based on rising boost pressure + cooldown, plus new i18n strings.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/modules/tui/settings_tab.py | Adds new settings sections/options for surface brake, speed throttle, and turbo lag. |
| src/modules/gui/settings_tab.py | Mirrors the new settings sections/options in the GUI. |
| src/modules/forzahorizon/effects.py | Implements turbo lag rumble, surface-based brake scaling, and speed-based throttle scaling. |
| src/modules/config/settings.py | Introduces new Settings fields and defaults for the added effects. |
| src/lang/zh.py | Adds translations for new settings strings. |
| src/lang/tr.py | Adds translations for new settings strings (contains a unit issue noted below). |
| src/lang/ru.py | Adds translations for new settings strings. |
| src/lang/ja.py | Adds translations for new settings strings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+144
to
+157
| def turbo_lag(self, t, s, now): | ||
| if not s.enable_turbo_lag: | ||
| self._prev_boost = t["boost"] | ||
| return None | ||
| boost = t["boost"] | ||
| delta = boost - self._prev_boost | ||
| self._prev_boost = boost | ||
| if delta < s.turbo_lag_threshold or boost < 0.1: | ||
| return None | ||
| if now - self._turbo_last_fire < s.turbo_lag_cooldown_ms / 1000.0: | ||
| return None | ||
| self._turbo_last_fire = now | ||
| amp = min(255, int(s.turbo_lag_amp * min(delta / 0.2, 1.0))) | ||
| return vibrate(s.turbo_lag_freq, amp) |
Comment on lines
170
to
190
| handbrake = s.enable_handbrake_bonus and t["handbrake"] | ||
| if not s.enable_brake_resistance: | ||
| return rigid(s.handbrake_bonus) if handbrake else off() | ||
| force = _ramp(t["brake"], s.brake_deadzone, s.brake_baseline_force, | ||
| s.brake_max_force, s.brake_curve, s.brake_wall_engage_at) | ||
| if s.enable_surface_brake and t["brake"] > 0: | ||
| wheels = DRIVEN_WHEELS.get(t["drive_train"], ("fl", "fr", "rl", "rr")) | ||
| if any(t[f"wheel_in_puddle_{w}"] > 0 for w in wheels): | ||
| mult = s.surface_brake_gravel | ||
| else: | ||
| rumble = max(abs(t[f"surface_rumble_{w}"]) for w in wheels) | ||
| if rumble > 0.30: | ||
| mult = s.surface_brake_gravel | ||
| elif rumble > 0.10: | ||
| mult = s.surface_brake_dirt | ||
| else: | ||
| mult = s.surface_brake_tarmac | ||
| force = max(0, int(force * mult)) | ||
| if handbrake: | ||
| force += s.handbrake_bonus | ||
| return rigid(force) |
Comment on lines
+64
to
+69
| # MARK: R2 speed-based throttle | ||
| # Extra throttle resistance at low speed; fades as speed rises. | ||
| # boost=0 means off (no extra force). Flat additive at 0 km/h, fading to normal by fade_km. | ||
| enable_speed_throttle: bool = True | ||
| speed_throttle_boost: int = 30 # extra force added at standstill (0 = off) | ||
| speed_throttle_fade_km: float = 80.0 # speed where boost fully fades |
| "Yeni dili uygulamak için uygulamayı yeniden başlatın.", | ||
| "Speed-based throttle": "Hıza dayalı gaz", | ||
| "Extra force at standstill": "Dururken ekstra kuvvet", | ||
| "Fade-out speed (km/h)": "Sönme hızı (km/s)", |
Comment on lines
+133
to
+134
| "0 = off. Flat resistance added at 0 km/h, fading to normal.": | ||
| "0 = kapalı. 0 km/s'de düz direnç eklenir, normale kadar sönür.", |
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.
Three new adaptive trigger effects for Forza Horizon telemetry.
1. Speed-based throttle resistance (R2)
Extra R2 resistance at low speed that fades as the car accelerates.
A flat additive force (default 30) is applied on top of the normal
throttle ramp at standstill, making the trigger heavier for precise
low-speed control. Fades linearly to zero by the configured speed
(default 80 km/h).
Settings:
enable_speed_throttle(on),speed_throttle_boost(30, 0=off),speed_throttle_fade_km(80)2. Surface-type brake resistance (L2)
Modulates L2 brake force based on surface under the wheels. On tarmac
the multiplier is 1.0 (unchanged). On dirt and gravel the final brake
force is scaled down, making the trigger softer to signal reduced grip.
Uses the same surface_rumble / wheel_in_puddle classification as
wheelspin buzz.
Settings:
enable_surface_brake(off),surface_brake_tarmac(1.0),surface_brake_dirt(0.5),surface_brake_gravel(0.25)3. Turbo lag effect (R2)
Brief deep rumble on R2 when boost pressure is climbing. Detects
per-tick boost delta; fires a low-frequency vibrate (8 Hz) whose
amplitude scales with the rate of boost change. A cooldown timer
(300 ms) and threshold (0.15) prevent steady-state telemetry jitter
from triggering false rumbles at constant RPM. Only fires on cars with
a turbo/supercharger (boost > 0).
Settings:
enable_turbo_lag(on),turbo_lag_freq(8 Hz),turbo_lag_amp(40),turbo_lag_threshold(0.15),turbo_lag_cooldown_ms(300)All three are independent — each can be toggled on/off separately.
Translations: ru, tr, zh, ja.