Skip to content

fix: correct hand grenade slide friction/deceleration - #91

Open
andrewcaluzzi wants to merge 1 commit into
murkantor:mainfrom
andrewcaluzzi:fix/grenade-slide-upstream
Open

andrewcaluzzi wants to merge 1 commit into
murkantor:mainfrom
andrewcaluzzi:fix/grenade-slide-upstream

Conversation

@andrewcaluzzi

Copy link
Copy Markdown

Goal

The goal of this PR is to resolve an issue with the engine's handling of hand grenade slide/deceleration at higher-than-N64 FPS counts. Issue #90 details the current state.

Description

A landed grenade's brake (unk94) is applied once per 60Hz field in objTick's slide loop, but each pass is also scaled by g_GlobalTimerDelta (the frame's delta). Higher frame rates and tick rates therefore get less braking per field, i.e. frame-dependent physics: grenades slide about 2.5x as far as the N64 at 60Hz and 5x at tickhz 120.

The fix uses a fixed 3.0 instead (matching gunfire.c's PLAYER_LAUNCH_CADENCE), which is approximately what the N64 applied at 20fps. Demo playback keeps the original line so attract demos stay in sync.

Fixes #90

Type of Change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • Test Case A (control on upstream v1.0.2b)
  1. Obtain and setup Project Midas 1.0.2b
  2. Go to any level with hand grenades equipped (cheats) or acquire them in the level
  3. Throw the grenade
  4. See the grenade slide much further than usual
  5. Press Tab (or whatever Classic Mode is bound to) to toggle Classic Mode
  6. Throw the grenade again in the same position
  7. See the grenade slide much less, stopping closer to the player
  • Test Case B (fix on current branch)
  1. Obtain and setup Project Midas on this branch
  2. Go to any level with hand grenades equipped (cheats) or acquire them in the level
  3. Throw the grenade
  4. See the grenade slide a normal amount
  5. Press Tab (or whatever Classic Mode is bound to) to toggle Classic Mode
  6. Throw the grenade again in the same position
  7. See the grenade stop in approximately the same place

Footage of control vs. fix

grenade-vanilla-vs-fix.mp4

Please describe every way you've tried to break the game. How did this not break other features the game has?

Thorough automated testing

Test Result
14 attract demos, before/after Tick logs byte-identical
dam1 / facility1 reference runs Identical (453 / 419 lines)
Demo path exercised Yes: runway1 has a guard grenade that slides
Slide at 60 Hz, 9 throws on Surface 1, Jungle, Cradle Before 1111–1228 units, after 420–504. N64 at 20 fps (calculated): 453
Slide at tickhz 120 Before 1481–1739, explodes while it moves. After ~510, stops
Classic Mode (N64 frame pacing), vanilla vs fix 343 / 343, 504 / 404. Vanilla behaves like the fix
Demo check removed Demos still identical, because the runway1 grenade slides on a 3-field frame. The check stays: 2- or 4-field frames would drift

Notes

  • Settle cannot stop the brake: unk64 is clamped to 0.03–0.15.
  • A bounce changes only vertical speed.
  • A slope has no effect: a landed grenade has no gravity term.
  • The brake per tick is the same on all levels tested.

I also manually tested in various levels (Surface 1, Dam, Cradle) with all weapons/infinite ammo

Checklist

  • My code has been thoroughly tested and is free of bugs
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • The commits I've made a clean, small and easy to understand
  • My changes generate no compiler warnings
  • My Code is AI-Generated or AI-assisted (please specify which AI model you are using): Claude Opus 5.5
  • My PR contains no AI-generated images, textures, models, sound or music (these are never accepted)
  • I am an AI (please specify which AI model you are)
  • I have reviewed my PR to make sure the above is truthful and accurate. I understand my PR can be rejected if it doesn't meet this project's standards.

A landed grenade's brake (unk94) is applied once per 60Hz field in
objTick's slide loop, but each pass is also scaled by g_GlobalTimerDelta
(the frame's delta). Higher frame rates and tick rates therefore get less
braking per field, i.e. frame-dependent physics: grenades slide about
2.5x as far as the N64 at 60Hz and 5x at tickhz 120.

The fix uses a fixed 3.0 instead (matching gunfire.c's
PLAYER_LAUNCH_CADENCE), which is approximately what the N64 applied at
20fps. Demo playback keeps the original line so attract demos stay in sync.

Fixes murkantor#90
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hand grenades have little to no friction/deceleration when thrown

1 participant