Skip to content

Keep the interior camera list at one address - #213

Merged
Adubbz merged 3 commits into
TheMoonPeople:masterfrom
SirFancyBacon:fix-interior-camera
Oct 24, 2026
Merged

Adubbz merged 3 commits into
TheMoonPeople:masterfrom
SirFancyBacon:fix-interior-camera

Conversation

@SirFancyBacon

@SirFancyBacon SirFancyBacon commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Entering some interiors, Carl's house in Norune among them, crashed in CFrame::GetLWMatrix. SetCameraPos kept the active camera as a pointer into a list that is freed every frame. It now keeps the camera by its place in that list, and the list lives on the stack again.
fixes #214
fixes #217

Cause

  • The core dump's backtrace: CFrame::GetLWMatrix ← CFrame::GetWorldPosition ← SetCameraPos ← EditInLoop.
  • SetCameraPos (port/src/edit_in.cpp) rebuilds the interior's camera list every frame from the parts' camera markers, and the file-static active_camera remembers which one the player last stood in, from one frame to the next.
  • In retail the list is a local array, so active_camera points into the stack. That only holds because the list sits at the same address every frame and is refilled before active_camera is read.
  • 98580bd moved the list into a std::make_unique allocation made on each call. The next frame's allocation can land elsewhere, leaving active_camera pointing at freed memory, and GetWorldPosition then follows a garbage parent pointer. Whether it crashes depends on the allocator, which is why only some interiors show it.

Fix

  • active_camera is the camera's index in the list, -1 for none, instead of a pointer. EditInInit resets it to -1, where it reset the pointer before.
  • The list is a std::array<INTERIOR_CAMERA, 8> on the stack again, so there is no allocation each frame. The cap of eight and the early returns from 98580bd are kept.
  • The index is checked against this frame's list before it is used. Retail never needs that, since an interior's camera count doesn't change while the player is in it, but a stale index can then never read a slot that wasn't rebuilt.
  • Two commits: the first restored a fixed address for the list (a static array), the second replaces that with the index. They can be squashed.

Testing

  • In game (Linux, Flatpak): Carl's house, which crashed on entry every time, now loads and plays normally.
  • Builds with no new warnings; all tests pass but the two GfxValidation ones, which need a Vulkan validation layer the SDK lacks.

SetCameraPos's static active_camera points into the frame's camera list
from one frame to the next. Retail's list sat on the stack at the same
address every frame; a fresh allocation per call left the pointer
dangling, so entering some interiors, such as Carl's house, crashed.
SetCameraPos remembered the camera the player stood in as a pointer into
the list it rebuilds every frame. Retail's list sat on the stack at the
same address each frame, so the pointer stayed valid; once the list was
allocated per call it dangled. The camera is now kept by its place in
the list, which lives on the stack again.
SirFancyBacon added a commit to SirFancyBacon/Chronicle that referenced this pull request Oct 23, 2026
@Adubbz
Adubbz merged commit ffee33d into TheMoonPeople:master Oct 24, 2026
7 checks passed
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.

Unplayable on Linux - It seems to fail when mayor gives you the key [BUG] - Crash when entering interiors

2 participants