To elaborate on the workaround I suggested in the end, I have now implemented it like this:
Right below my main scene root, I have added a Node2D and attached InputControl.cs to it. On that node, I have added a metadata value named PlayerNode of type NodePath and assigned my Spaceship node from the same scene to it.
Node2D
|- Spaceship + (whatever script is attached in the scene)
|- RemoteTransform2D
|- Node2D + InputControl.cs
The InputControl class now inherits from Node2D and has a Player property of type RigidBody2D that is used as the target of my calls to ship movement methods. I initialize the object as follows:
public override void _Ready()
{
var player = GetNode(GetMeta("PlayerNode").AsNodePath()) as RigidBody2D;
if (player == null)
{
throw new InvalidOperationException("Player object not found.");
}
Player = player;
}
This works, is easy to implement (once you know what API methods to use) and it's easy to understand, still - being a total beginner in Godot - I wonder whether this is the way we're supposed to use Godot?