k4zmu2a / SpaceCadetPinball

Decompilation of 3D Pinball for Windows – Space Cadet
MIT License
3.42k stars 210 forks source link

The game crashes when more than 20 balls exist in the playfield (?) #209

Open cihe13375 opened 5 months ago

cihe13375 commented 5 months ago

How to reproduce: 1) Cheats - enable bmax and hidden test 2) press R repeatedly to be promoted to the highest level 3) select Maelstrom mission and complete it. Now 3 extra balls would appear in the playfield 4) repeat 3). Each time repeating 3) the ball count in the playfield would +3 (1->4->7->...). Repeat until there are 19 balls in the playfield (note that we have enabled bmax so would not lose any balls) 5) now repeat 3) another time. The game will crash after the mission is completed.

v2.1.0 flatpak version. ubuntu 24.04.

Randomno commented 3 months ago

I think this behaviour matches the original. If you enable hidden test and press b, it spawns another ball. Or at least it's supposed to in the original? I don't think 3DPB supports multiple balls on screen at all.

Regardless, if you press b about 20 times the game will crash.

Unhandled exception at 0x010048c5 in PINBALL.EXE: 0xC0000005: Access violation writing location 0x00000000.

And doing the same in the decomp (where it actually spawns more balls on screen):

SpaceCadetPinball: /home/randomno/SpaceCadetPinball/SpaceCadetPinball/TSink.cpp:84: static void TSink::TimerExpired(int, void*): Assertion ((void)"Failure to create ball in sink", ball)' failed.

EDIT: Okay, thanks to another comment in this repo I learned you can enable cheats in Full Tilt with "hidden[tab]test". Spamming B crashes with Assertion Failed: ball != NULL && "Failure to create ball in sink" in file Common\Src\pbctrl.cpp, at line 3717

k4zmu2a commented 3 months ago

V2.1.0 closely follows FT code for the ball, so this behavior is as designed. There is a hard limit of 20 on number of balls in play, mostly imposed by the renderer. New ball fails to spawn when this limit is reached. Game crashes because there is no code for handling failed ball spawns. Weirdly enough, the ‘b’ cheat itself has all the safeguards; crashes happen in the rest of game logic, such as TSink. Ball slot exhaustion can never happen in game; at most three balls can be active at once during multi-ball event.

Now the question is – does altering this behavior makes sense? I theory, crashing the game should be impossible, even with dev tools. However, this bug seems very niche, and fixing it will not improve main game loop (unless we make an alt table with more than 20 active balls)).