Skip to content

Conversation

@rory-cd
Copy link

@rory-cd rory-cd commented Jan 20, 2026

Description

Problems

  • Below the Surface currently fails to compile using the standard command: skm g++ program.cpp -o game. Error output here.

  • Once the compilation error is amended, the game crashes after the first splash screen with a segmentation fault.

Causes

Compilation errors

The center_point() function is being passed the wrong data type (sprite instead of circle), which causes compilation to fail.

Runtime error

When transitioning between scenes, player states, etc., the state change occurs mid-update. Which means the state is changed (with a direct call to change_state()), then the control flow of the update is passed back to the old (now deleted) state, causing the segmentation fault. State transitions apply to players, screens, and enemies.

Fixes

  • Replaced relevant center_point() calls with sprite_center_point()
  • Updated the state transition logic everywhere states are used, so control flow doesn't attempt to continue on an old state.

Now any class which uses states also includes next_state and next_state_type fields. Rather than calling change_state() mid-update, request_state_change() is called, which queues up the next state (and type) using the new fields. Once the update is finished, apply_next_state() is called, to change the state.

So the control flow has changed from:
Start update() -> change_state() -> finish update()
to:
Start update() -> request_state_change() -> finish update() -> apply_next_state()

Type of change

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

How Has This Been Tested?

On WSL:
Compiled with skm g++ program.cpp -o game
Ran with ./game

Compilation succeeded:
image

Game runs:
image

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have requested a review from ... on the Pull Request

The center_point() function was being called on sprites, rather
than circles as intended. These calls have been updated to
sprite_center_point() instead.
The game was crashing after the title screen and when the player
moved, due to the order of state transitions. When change_state()
was called mid-update loop, control flow continued on the
now-deleted state, causing segmentation faults.

Queued state transitions fix the problem by delaying state changes
until after the current update loop. Rather than calling
change_state() directly, affected classes now call
request_state_change() to queue the next state for later. This
approach has been used everywhere states were utilised:
- Screens
- Player
- Enemies
Copy link

@RealH4D35 RealH4D35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes definitely work

  • Game now compiles
  • Game runs without segmentation fault
  • State transition logic is properly implemented

Note for future work: There are still 109 warnings when trying to compile. Consider addressing these in a future cleanup PR to improve code quality.

Some of the warnings when trying to compile:

image

Tested on Arch Linux using Clang++

Copy link

@Broccoli811 Broccoli811 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The project compiles successfully, indicating correct syntax and linkage, however during the gameplay runtime a segmentation fault occurs. This suggests unsafe memory access. The most likely causes include invalid resource usage (bitmaps, sounds, or animations not properly loaded), out of bounds access to dynamic containers (such as enemies), or the use of freed or null objects during update or draw cycles.

Introducing defensive checks around resource loading, validating container indices, and avoiding mutation of collections during iteration would significantly improve runtime stability.

I ran the game again through gdb to print the backtrace. It appears its giving the bad memory patterns "0xbaadf00d" which means 'new_state' used to exist, but it doesnt anymore. You may need to revise some code to add guards 'Defensive coding' so this never silently crashes.

Image Image

New states for AI (*machine.h) are now initialised as nullptr,
meaning the null check in apply_next_state works as expected,
preventing the segmentation fault.

Player.h has been updated for consistency with the other class
constructors.
@rory-cd
Copy link
Author

rory-cd commented Jan 24, 2026

Thanks @Broccoli811, I appreciate the detailed report.

After playing further in the game I ran into the same issue. The problem was new_state was not initialised as nullptr in the AI classes (*machine.h). So it was passing the null check in request_state_change despite not being a valid state. It is now initialised in the constructor, for consistency with the state initialisation. For example:

FlyMachine(FlyMachineState *state, sprite enemy_sprite) : state(nullptr), next_state(nullptr)

All AI classes have been updated to match, and the Player class has been updated to use this syntax rather than being initialised at field declaration.

I've re-tested on WSL and MSYS2 with no errors.

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.

3 participants