Skip to content

Remove TESObjectREFR::IsInSpaceship, which held GetSpaceship's id (119881) - #55

Open
kiffpuppygames wants to merge 1 commit into
libxse:mainfrom
kiffpuppygames:fix/isinspaceship-id
Open

kiffpuppygames wants to merge 1 commit into
libxse:mainfrom
kiffpuppygames:fix/isinspaceship-id

Conversation

@kiffpuppygames

@kiffpuppygames kiffpuppygames commented Nov 2, 2026 •

Copy link
Copy Markdown

include/RE/IDs.h lists two different functions under the same Address Library id: TESObjectREFR::GetSpaceship (line 2563) and TESObjectREFR::IsInSpaceship (line 2570) both hold 119881. GetSpaceship got 119881 in a617f1f (2025-05-28); IsInSpaceship was added with the same id a day later, in 78b7623 (2025-05-29).

In Starfield 1.16.244, 119881 (0x142116840) is GetSpaceship, and it was the same function in 1.15.222. It takes a bool and returns the reference to the ship whose interior cell the reference is in, or null: it reads the reference's parent cell, checks that the cell is a ship cell (the bool also accepts a second cell type), and looks the ship up by that cell's form id. The game's own GetSpaceship script function (id 67036) prints the returned reference's name and form id.

I found no separate IsInSpaceship function in the executable. The only IsInSpaceship string is the script function's name, used once, by the code that registers the script and condition functions. That script function (66667) and the condition function (65625) both call 119881 with true and test the result for null, and none of the 673 calls and jumps to 119881 is in a one-argument function that returns a bool.

Code that uses the id as an IsInSpaceship check, for example through REL::Relocation<bool(*)(TESObjectREFR*)>, calls GetSpaceship with whatever happens to be in the bool argument's register and reads the low byte of the returned ship pointer as its answer. For a reference that is not in a ship that gives false, which is right; for one that is in a ship it gives true or false depending on the last byte of the ship's address.

SFSE 0.2.21 has the same mistake: sfse/GameReferences.h:248 declares IsInSpaceship as a bool member at 0x02116840, which is GetSpaceship's address.

This PR removes IsInSpaceship, so code that names it fails to compile with a message naming it, instead of calling GetSpaceship as if it returned a bool. Nothing in CommonLibSF uses it; a caller can use GetSpaceship() != nullptr, since the bool defaults to true.

IsInSpaceship{ 119881 } duplicated GetSpaceship{ 119881 }. In Starfield
1.16.244 (and 1.15.222) 119881 is GetSpaceship, which returns the ship
reference or null; no separate IsInSpaceship function was found in the
executable. The game's IsInSpaceship script function (66667) and condition
function (65625) call 119881 with true and test the result for null, so a
caller can use GetSpaceship() != nullptr. Nothing in CommonLibSF uses the id.
@kiffpuppygames kiffpuppygames changed the title fix: remove TESObjectREFR::IsInSpaceship, which held GetSpaceship's id Remove TESObjectREFR::IsInSpaceship, which held GetSpaceship's id (119881) Nov 2, 2026
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.

1 participant