Maxi
Member
- Messages
- 197
- Reaction score
- 146
(post mostly written by claude, verified be me)
Game Version
v2026.11.10.5801 (reproduced with stock parts only); first found on v2026.10.25.5707
Operating System
Windows 11
What Happened
When a vehicle with RCS thrusters is split by a decoupler, the flight computer of the new (separated) vehicle computes its first RCS parameters from the thruster data of the whole vehicle before the split. In that first step the rate bit on the pitch and yaw axes is far too large, and the flight computer raises the Angle Deadband from it. The deadband is only ever raised, so the wrong value stays.
Stock vehicle on v2026.11.10.5801 (details under Reproduction Steps), Balanced profile (1.000 deg) before the split:
On v2026.10.25.5707 I saw larger values on two smaller probes (the carrier had 1.000 deg on Balanced):
What Was Expected
The new vehicle uses the thruster data of its own parts from its first flight computer step. It keeps the attitude profile (Balanced, 1 degree), and the deadband grows only when the thrusters of this vehicle need it.
Reproduction Steps
Always. Every split of a vehicle with RCS thrusters on the separated part.
Additional Info
I found this with mods loaded, while I tested my own part mods with automated flight tests. On v2026.11.10.5801 I reproduced it with stock parts only: the vehicle above is built from Core parts, and the test runs the normal game code headless (no content mods; only my test harness and a small test plugin that spawns the vehicle, presses the staging key and reads the values). The test also read the thruster state of the new vehicle at the end of
Technical analysis (decompiled 2026.11.10.5801)
Where the value is set:
Either of these removes the problem. The first one is the root cause:
Game Version
v2026.11.10.5801 (reproduced with stock parts only); first found on v2026.10.25.5707
Operating System
Windows 11
What Happened
When a vehicle with RCS thrusters is split by a decoupler, the flight computer of the new (separated) vehicle computes its first RCS parameters from the thruster data of the whole vehicle before the split. In that first step the rate bit on the pitch and yaw axes is far too large, and the flight computer raises the Angle Deadband from it. The deadband is only ever raised, so the wrong value stays.
Stock vehicle on v2026.11.10.5801 (details under Reproduction Steps), Balanced profile (1.000 deg) before the split:
- 2 carrier tanks (10.2 t in total, probe 3.3 t): Angle Deadband of the probe 1.463 deg after the split. Pitch and yaw rate bit in its first step 7.317 deg/s, from the second step on 0.738 deg/s.
- 6 carrier tanks (24.1 t in total, the same 3.3 t probe): Angle Deadband of the probe 4.634 deg after the split, Rate Limit 23.17 deg/s. Pitch and yaw rate bit in its first step 23.17 deg/s, from the second step on 0.738 deg/s.
On v2026.10.25.5707 I saw larger values on two smaller probes (the carrier had 1.000 deg on Balanced):
- 21.065 deg for a 129 kg probe with two RCS pods (23 N each)
- 4.891 deg for a 503 kg probe
What Was Expected
The new vehicle uses the thruster data of its own parts from its first flight computer step. It keeps the attitude profile (Balanced, 1 degree), and the deadband grows only when the thrusters of this vehicle need it.
Reproduction Steps
- In the editor, start the vehicle with the tank
CoreFuelTankA_Prefab_MP1W1HA, so that this carrier tank is the root part and the probe is the part that separates. Add five moreCoreFuelTankA_Prefab_MP1W1HAbelow it (with only one more tank the effect is there but small). - On top of the first tank add
CoreCouplingA_Prefab_Decoupler1WA, thenCoreFuelTankA_Prefab_MP1WHalfHA, then the probe coreCoreCommandC_Prefab_ProbeCoreSmallA. - Put four
CorePropulsionB_Prefab_RCSSmallFourHornV1Aon the side of the half-height MP tank, 90 degrees apart. Put the decoupler in a stage of its own. - Launch, and put the vehicle in orbit (for example with Debug > Show Set Orbit Debug). Leave the flight computer on the Balanced profile and RCS on. Nothing else is needed: the attitude mode can stay Manual.
- Open Debug > Show Flight Computer Debug. "Angle Deadband" shows 1 (degrees).
- Press the staging key to fire the decoupler, and switch to the new probe vehicle. "Angle Deadband" shows about 4.63 and "Rate Limit" about 23.2, and the Balanced profile button is not shown as selected.
- Click Balanced. "Angle Deadband" goes to about 1.39 and stays there.
Always. Every split of a vehicle with RCS thrusters on the separated part.
Additional Info
I found this with mods loaded, while I tested my own part mods with automated flight tests. On v2026.11.10.5801 I reproduced it with stock parts only: the vehicle above is built from Core parts, and the test runs the normal game code headless (no content mods; only my test harness and a small test plugin that spawns the vehicle, presses the staging key and reads the values). The test also read the thruster state of the new vehicle at the end of
Vehicle.Split, before its first flight computer step. This confirms the cause below.Technical analysis (decompiled 2026.11.10.5801)
Where the value is set:
FlightComputer.UpdateRcsParamscomputesRateBit = thrusterAuthority.MinRotationalImpulse.Hadamard(inverse inertia)and then raises the deadband withAngleDeadband = MathEx.MaxIfRhsFinite(AngleDeadband, 2 / MaxFlightComputerRate * RateBit)for each axis. It only raises it and never lowers it.RateLimitis raised the same way withRateDeadband.ComputeControlcallsUpdateRcsParamsin every step, also in the Manual attitude mode.- The only code that sets it back is
FlightComputer.SetAttitudeProfile, which is called by the profile buttons.FlightComputer.HasAttitudeProfilecomparesAngleDeadbandandRateLimitwith the profile values for equality, so after the raise no profile looks selected.PhysicsBubble.ResolveRateLimitForCurrentProfilehas the same equality test. - With
MaxFlightComputerRate = 10, a rate bit of 23.17 deg/s gives 2 / 10 * 23.17 = 4.634 deg, which is the measured value.
Vehicle.SplitcallsPartTree.Split, which moves the parts to a newPartTreethroughTransferPartSubtreeToandTransferPartSubtree(part, States), and thenpart.Modules.AddStatesInto(States, prevStates).- That ends in
ModuleStateful<...>.StateList.AddFrom(modules, oldStates). When the new list is empty it does_globalState = oldStates._globalState. For the thrusters the global state isThrusterControllerGlobalState, which holds the cachedAuthority(TotalTorque,MinRotationalImpulse),MaxThrustFromRotationand the cache key (CachedCenterOfMassAsmb,CachedMass,CachedCtrl2Body). So the new vehicle starts with the thruster authority of the whole vehicle, computed about the centre of mass of the whole vehicle. - Measured at the end of
Vehicle.Split(6 carrier tanks): the new 3302.5 kg probe vehicle hadCachedMass24101.1 kg,CachedCenterOfMassAsmbX = -2.04 m andMinRotationalImpulse(100.04, 232.37, 232.37) N m s. These are exactly the values of the whole vehicle before the split. After its first step the cache was rebuilt:CachedMass3302.5 kg, centre of mass X = 0.855 m,MinRotationalImpulse(100.04, 7.398, 7.398) N m s. - The new vehicle gets a new
FlightComputerin theVehicleconstructor (Balanced, 1 deg). Its firstFlightComputer.ComputeControlreadsoutputs.Thrusters.GlobalState.Authority. The inverse inertia is already the one of the probe, butMinRotationalImpulseis still the value of the whole vehicle. It was built from torque arms about the old centre of mass, about 3 m away from the probe thrusters, and withThrusterAuthority.ConservativeWithit is the maximum over both directions. The product is a pitch and yaw rate bit about 31 times too large (23.17 against 0.738 deg/s), andUpdateRcsParamsstores it inAngleDeadbandandRateLimitfor good. - The stale value is used only once.
Rocket.UpdateRocketscallsRocket.UpdateThrusterCacheafter the flight computer step, andThrusterControllerGlobalState.IsCacheValidfails because the centre of mass and the mass differ. From the second step the authority is correct. One step is enough, because of the ratchet. - The roll axis is not affected in this layout, because the torque arm about the stack axis does not change with the centre of mass along the stack. The error grows with the distance from the old centre of mass to the thrusters of the new vehicle, so a long carrier and a light probe give the largest values.
Either of these removes the problem. The first one is the root cause:
- In
StateList.AddFrom(or inVehicle.Split), do not copy the global state ofThrusterControllerGlobalStateto the new tree. Start it fromThrusterControllerGlobalState.Zerowith an invalid cache key, so that the firstUpdateThrusterCachecomputes it before the flight computer reads it. The other global states that are copied this way should be checked too. - Make the rate-bit part of the deadband non-persistent. Keep the profile deadband and rate limit as the stored values, and compute the effective values in each update as
max(profile value, 2 / MaxFlightComputerRate * RateBit). Then one wrong update cannot stay forever, andHasAttitudeProfilekeeps working.
Upvote
0