The throttle a pod respawns under is nobody's order
Player request from the six-player night: a pod that dies at full throttle reappears under a hand still holding full throttle, and launches on it. The pod should respawn with the throttle at zero and stay there until the player has brought the control back to zero themselves. The arcade never met the problem in this form - its throttle was a physical lever that kept its position regardless - but the same idea protects a real lever too, which matters now that the pods want this code. The latch lives in VTVControlsMapper, the one place every control source - RIO lever, pad trigger, keyboard axis, input script - funnels through, per simulation step, so it is deterministic and local to the owning machine by construction (the mapper only runs on MasterInstance). VTV::Reset arms it through DeathReset, with one wrinkle: the controls mapper is subsystem ZERO, below BasicSubsystemCount, so Reset's subsystem loop has never reached it. It is called explicitly now. Only RegularReset latches - that is the death respawn and the first spawn (so a throttle held through the countdown no longer buys a flying start). Football's repositioning reset does not latch, and mission review has no controls. While latched the mapper computes as though the throttle were zero, but only for the pass: the true lever position is restored at the bottom of the function, so the cockpit gauge and the watchers keep showing the player the hand they need to bring down. The restore also keeps the release test honest - RIO analog events arrive on CHANGE, so a zeroed attribute would otherwise sit at zero, release the latch by itself, and hand back a live throttle the moment the hand twitched. Release is at 5% of travel: wide enough for a resting trigger or a real lever's potentiometer sitting a few counts off its stop, narrow enough that easing off does not satisfy it. Proven with the input-script harness, both directions. Throttle held at 1.0 from the green light: the pod moves 1.3cm in 30 seconds, all of it hover settle. Throttle at zero for two seconds then 1.0: the latch releases in the quiet window and the pod is 665m down the track twenty seconds later. The second run is also the normal-play case - a control already at zero releases the latch on the first step, invisibly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -102,3 +102,6 @@ rpl4.log
|
||||
rpl4-fail.log
|
||||
last.spl
|
||||
SPOOLS/
|
||||
|
||||
# Playtest evidence - dumps, logs, symbol snapshots. Kept on disk, not in history.
|
||||
playtestlogs/
|
||||
|
||||
+18
@@ -1702,6 +1702,24 @@ void
|
||||
subsystem->DeathReset(reset_command);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// The controls mapper too. It is subsystem ZERO, below
|
||||
// BasicSubsystemCount, so the loop above has never reached it - which
|
||||
// was fine while it had nothing to reset. It does now: the respawn
|
||||
// throttle latch, which holds the pod at zero throttle until the
|
||||
// player's control has come back to zero. See
|
||||
// VTVControlsMapper::DeathReset for which resets latch and why.
|
||||
//
|
||||
{
|
||||
Subsystem *mapper = GetSubsystem(ControlsMapperSubsystem);
|
||||
|
||||
if (mapper)
|
||||
{
|
||||
Check(mapper);
|
||||
mapper->DeathReset(reset_command);
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
|
||||
@@ -401,6 +401,28 @@ VTVControlsMapper::AttributeIndexSet& VTVControlsMapper::GetAttributeIndex()
|
||||
// Model Support
|
||||
//
|
||||
|
||||
//
|
||||
// How close to zero the throttle control must come to release the latch,
|
||||
// as a fraction of full travel. Wide enough for a resting pad trigger, a
|
||||
// wound-down keyboard axis, or a real lever's potentiometer sitting a few
|
||||
// counts off its stop - the pod bay hardware is where this will matter -
|
||||
// and narrow enough that it cannot be satisfied by easing off.
|
||||
//
|
||||
static const Scalar kThrottleLatchRelease = 0.05f;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
VTVControlsMapper::DeathReset(int reset_command)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
if (reset_command == VTV::RegularReset)
|
||||
{
|
||||
throttleLatched = True;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
@@ -455,6 +477,43 @@ void
|
||||
Verify(stickPosition.y >= -1.0f && stickPosition.y <= 1.0f);
|
||||
Verify(pedalsPosition >= -1.0f && pedalsPosition <= 1.0f);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------
|
||||
// The respawn throttle latch.
|
||||
//
|
||||
// A pod that dies at full throttle reappears under a hand still
|
||||
// holding full throttle, and used to launch on it. From a respawn
|
||||
// until the control has been seen back at (near) zero, the mapper
|
||||
// computes as though the throttle were zero.
|
||||
//
|
||||
// The zeroing is for this pass only - the true lever position is
|
||||
// put back at the bottom of the function - so the attribute the
|
||||
// cockpit gauge and the watchers read stays the player's actual
|
||||
// hand, which is the thing they need to see to bring it down. It
|
||||
// also means the release test reads the real control each step
|
||||
// rather than last step's overwrite: RIO analog events arrive on
|
||||
// CHANGE, so an overwritten attribute would otherwise sit at zero,
|
||||
// release the latch on its own, and hand back a live throttle the
|
||||
// moment the hand moved.
|
||||
//
|
||||
// Placed after the input script so a scripted run latches the same
|
||||
// way a hand-driven one does, per step, deterministically.
|
||||
//----------------------------------------------------------------
|
||||
//
|
||||
Scalar lever = throttlePosition;
|
||||
|
||||
if (throttleLatched)
|
||||
{
|
||||
if (lever <= kThrottleLatchRelease)
|
||||
{
|
||||
throttleLatched = False;
|
||||
}
|
||||
else
|
||||
{
|
||||
throttlePosition = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------
|
||||
// Figure out the proper control model to use based upon the speed
|
||||
@@ -833,6 +892,12 @@ void
|
||||
intercom->SetPTTStatus((Logical) pttStatus > 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Put the real lever position back - see the latch above. Identity
|
||||
// whenever the latch is idle.
|
||||
//
|
||||
throttlePosition = lever;
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
@@ -949,6 +1014,7 @@ VTVControlsMapper::VTVControlsMapper(
|
||||
stickPosition.y = 0.0f;
|
||||
throttlePosition = 0.0f;
|
||||
pedalsPosition = 0.0f;
|
||||
throttleLatched = False; // the first-spawn Reset sets it
|
||||
|
||||
reverseThrust = 0;
|
||||
liftCut = 0;
|
||||
|
||||
@@ -182,6 +182,16 @@ protected:
|
||||
ControlsButton
|
||||
previousPTTStatus; // used to detect change in PTT status
|
||||
|
||||
//
|
||||
// True from a respawn until the throttle control has been seen at
|
||||
// (near) zero. While set, InterpretControls behaves as though the
|
||||
// throttle were zero, whatever the hand is doing; the attribute
|
||||
// itself keeps the real lever value so the cockpit gauge shows the
|
||||
// player what they must bring down. See DeathReset.
|
||||
//
|
||||
Logical
|
||||
throttleLatched;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Model Support
|
||||
//
|
||||
@@ -206,6 +216,22 @@ public:
|
||||
void
|
||||
SetConfigurationState(Logical enter_config);
|
||||
|
||||
//
|
||||
// Latch the throttle at zero until the player's control comes back to
|
||||
// zero. Called by VTV::Reset on a regular reset - a death respawn, and
|
||||
// the first spawn - because the hand that was holding full throttle
|
||||
// when the pod died is still holding it when the pod reappears, and
|
||||
// the pod used to launch on it. The arcade never had the problem the
|
||||
// same way: its throttle was a physical lever the pilot had to move
|
||||
// regardless.
|
||||
//
|
||||
// Football and mission review resets do not latch: one repositions
|
||||
// every pod mid-game where the friction is unwanted, the other has no
|
||||
// controls at all.
|
||||
//
|
||||
void
|
||||
DeathReset(int reset_command);
|
||||
|
||||
virtual void
|
||||
CreateTemporaryEventMappings(
|
||||
Receiver *receiver,
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
Red Planet 4.12.217 (056ee0b)
|
||||
Environ: 12 setting(s) from environ.ini
|
||||
Environ: environ.ini does not mention 24 option(s) this build knows: RP412INPUTFOCUS, L4MAPPOS, L4MAPSCALE, RP412PODIUMHOLD, RP412PHYSICSHZ, RP412INTERP, RP412NETPREDICT, RP412GAUGESLICE, RP412MAPRATE, RP412GAUGEDIAG, RP412LAMPSWEEP, RP412CONNECTWAIT, RP412RECORDSIZE, RP412GAUGEPROFILE, RP412RENDERDIAG, RP412PHYSTRACE, RP412SPAWNZONE, RP412INPUTSCRIPT, RP412JOYLOG, RP412AUDIOVOLUME, RP412AUDIOBASS, RP412VERTEXPROC, RP412VSYNC, RP412CAMLOG
|
||||
Environ: they are at their built-in defaults - delete environ.ini to get the documented file back
|
||||
L4CONTROLS=PAD;KEYBOARD
|
||||
Video: frame target 60 fps, drawing interpolated across the physics step
|
||||
SteamNetTransport: up as 169.254.8.177 (fake ports 33416 console, 33417 game)
|
||||
L4Application: -fit chose -res 1920 1080 (100% canvas) for the 2560x1080 monitor
|
||||
L4Application: -fit placed the window borderless at 2560x1080 before the first mission
|
||||
FrontEnd: callsign "Pilot" and loadout from pilot.cfg
|
||||
FrontEnd: saved callsign "PoorImpulseControl" and loadout to pilot.cfg
|
||||
Lobby: joined 109775241819393971
|
||||
SteamNetTransport: peer registered: 169.254.88.186 (console 10608, game 10609, id 76561198659597127)
|
||||
SteamNetTransport: peer registered: 169.254.35.214 (console 62256, game 62257, id 76561197995508393)
|
||||
SteamNetTransport: peer registered: 169.254.105.170 (console 4648, game 4649, id 76561197970536135)
|
||||
SteamNetTransport: peer registered: 169.254.240.193 (console 7168, game 7169, id 76561197976435895)
|
||||
SteamNetTransport: peer registered: 169.254.8.177 (console 33416, game 33417, id 76561197969401853)
|
||||
SteamNetTransport: peer registered: 169.254.122.50 (console 41360, game 41361, id 76561198022091594)
|
||||
PadBindings: 59 key buttons, 8 key axes, 10 pad buttons, 5 pad axes
|
||||
PadRIO: virtual RIO active (XInput pad + keyboard)
|
||||
PadRIO: controls answer only while the game window has focus
|
||||
Trying to find the monitor marked as active in Windows...
|
||||
Monitor 0 was set as active in Windows... setting it as the primary monitor.
|
||||
Either MFDs are explicitly disabled, we're running in windowed mode, or we don't have enough monitors attached to this machine. MFD monitors will not be detected.
|
||||
Game is currently running windowed mode- will set all remaining undefined monitors to be the same as the primary monitor.
|
||||
Video: presentation interval vsync
|
||||
Video: vertex processing HARDWARE
|
||||
SVGA16: cockpit canvas at 100% for the 2560x1080 work area
|
||||
SVGA16: secondary displays at UL 100% UC 100% UR 100% LL 100% LR 100% radar 100%
|
||||
SVGA16: radar on the bottom centre (L4RADARPOS)
|
||||
SVGA16: cockpit fitted 1920x1080 at 100% in a 2560x1080 client
|
||||
GaugeInterpreter: undefined label 'Initialization'
|
||||
SteamNetTransport: listening on engine port 1501 (fake port 33416)...
|
||||
PadRIO: controller 0 connected
|
||||
SteamNetTransport: incoming [#4027028733 P2P steamid:76561198659597127@169.254.248.212:15404 fakeport #0] - accepting
|
||||
SteamNetTransport: connected [#4027028733 P2P SDR steamid:76561198659597127@169.254.248.212:15404 fakeport #0]
|
||||
STATUS: socket accepted from 169.254.88.186:1501!
|
||||
Connected to ConsoleHost at 169.254.88.186:1501
|
||||
SteamNetTransport: connecting to 169.254.88.186:1502 (fake port 10609)...
|
||||
SteamNetTransport: connected [#2546421614 P2P SDR steamid:76561198659597127@169.254.88.186:10609]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.35.214:1502 (fake port 62257)...
|
||||
SteamNetTransport: connected [#3892042932 P2P SDR steamid:76561197995508393@169.254.35.214:62257]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.105.170:1502 (fake port 4649)...
|
||||
SteamNetTransport: dropped [#1183141278 P2P ?@169.254.105.170:4649] end reason 5003: Timed out attempting to connect
|
||||
SteamNetTransport: attempt 1 ended in state 5
|
||||
SteamNetTransport: attempt 2 ended in state 1
|
||||
SteamNetTransport: connect timed out after 20s (RP412CONNECTWAIT)
|
||||
Could not open connection to 169.254.105.170:1502.
|
||||
SteamNetTransport: connecting to 169.254.240.193:1502 (fake port 7169)...
|
||||
SteamNetTransport: connected [#555564226 P2P SDR steamid:76561197976435895@169.254.240.193:7169]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: listening on engine port 1502 (fake port 33417)...
|
||||
Connected to GameMachineHost at 169.254.88.186:1502
|
||||
Connected to GameMachineHost at 169.254.35.214:1502
|
||||
Connected to GameMachineHost at 169.254.240.193:1502
|
||||
SteamNetTransport: connecting to 169.254.88.186:1502 (fake port 10609)...
|
||||
SteamNetTransport: incoming [#1946318435 P2P steamid:76561198022091594@169.254.251.68:21949 fakeport #1] - accepting
|
||||
SteamNetTransport: connected [#1380037914 P2P SDR steamid:76561198659597127@169.254.88.186:10609]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.35.214:1502 (fake port 62257)...
|
||||
SteamNetTransport: connected [#1946318435 P2P SDR steamid:76561198022091594@169.254.251.68:21949 fakeport #1]
|
||||
SteamNetTransport: connected [#371675616 P2P SDR steamid:76561197995508393@169.254.35.214:62257]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.105.170:1502 (fake port 4649)...
|
||||
SteamNetTransport: dropped [#1416324186 P2P ?@169.254.105.170:4649] end reason 5003: Timed out attempting to connect
|
||||
SteamNetTransport: attempt 1 ended in state 5
|
||||
SteamNetTransport: connected [#2299564679 P2P SDR steamid:76561197970536135@169.254.105.170:4649]
|
||||
SteamNetTransport: connect succeeded (attempt 2)
|
||||
SteamNetTransport: connecting to 169.254.240.193:1502 (fake port 7169)...
|
||||
SteamNetTransport: connected [#1693276213 P2P SDR steamid:76561197976435895@169.254.240.193:7169]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
Listen requested on port 1502 but gameListenerSocket already existed!
|
||||
STATUS: socket accepted from 169.254.122.50:1502!
|
||||
Connected to GameMachineHost at 169.254.122.50:1502
|
||||
Connected to GameMachineHost at 169.254.88.186:1502
|
||||
Connected to GameMachineHost at 169.254.35.214:1502
|
||||
Connected to GameMachineHost at 169.254.105.170:1502
|
||||
Connected to GameMachineHost at 169.254.240.193:1502
|
||||
All connections completed!
|
||||
SteamNetTransport: connecting to 169.254.88.186:1502 (fake port 10609)...
|
||||
SteamNetTransport: incoming [#418395659 P2P steamid:76561198022091594@169.254.251.68:21949 fakeport #1] - accepting
|
||||
SteamNetTransport: connected [#3771470973 P2P SDR steamid:76561198659597127@169.254.88.186:10609]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.35.214:1502 (fake port 62257)...
|
||||
SteamNetTransport: connected [#418395659 P2P SDR steamid:76561198022091594@169.254.251.68:21949 fakeport #1]
|
||||
SteamNetTransport: connected [#107458131 P2P SDR steamid:76561197995508393@169.254.35.214:62257]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.105.170:1502 (fake port 4649)...
|
||||
SteamNetTransport: connected [#173068106 P2P SDR steamid:76561197970536135@169.254.105.170:4649]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.240.193:1502 (fake port 7169)...
|
||||
SteamNetTransport: connected [#1962487129 P2P SDR steamid:76561197976435895@169.254.240.193:7169]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
Listen requested on port 1502 but gameListenerSocket already existed!
|
||||
STATUS: socket accepted from 169.254.122.50:1502!
|
||||
Connected to GameMachineHost at 169.254.122.50:1502
|
||||
Connected to GameMachineHost at 169.254.88.186:1502
|
||||
Connected to GameMachineHost at 169.254.35.214:1502
|
||||
Connected to GameMachineHost at 169.254.105.170:1502
|
||||
Connected to GameMachineHost at 169.254.240.193:1502
|
||||
All connections completed!
|
||||
SteamNetTransport: connecting to 169.254.88.186:1502 (fake port 10609)...
|
||||
SteamNetTransport: connected [#3345733046 P2P SDR steamid:76561198659597127@169.254.88.186:10609]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.35.214:1502 (fake port 62257)...
|
||||
SteamNetTransport: connected [#488432965 P2P SDR steamid:76561197995508393@169.254.35.214:62257]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.105.170:1502 (fake port 4649)...
|
||||
SteamNetTransport: incoming [#1418378592 P2P steamid:76561198022091594@169.254.251.68:21949 fakeport #1] - accepting
|
||||
SteamNetTransport: connected [#1418378592 P2P SDR steamid:76561198022091594@169.254.251.68:21949 fakeport #1]
|
||||
SteamNetTransport: dropped [#1982903022 P2P steamid:76561197970536135@169.254.105.170:4649] end reason 5003: Timed out attempting to connect
|
||||
SteamNetTransport: attempt 1 ended in state 5
|
||||
SteamNetTransport: attempt 2 ended in state 1
|
||||
SteamNetTransport: connect timed out after 20s (RP412CONNECTWAIT)
|
||||
Could not open connection to 169.254.105.170:1502.
|
||||
SteamNetTransport: connecting to 169.254.240.193:1502 (fake port 7169)...
|
||||
SteamNetTransport: connected [#3943096642 P2P SDR steamid:76561197976435895@169.254.240.193:7169]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
Listen requested on port 1502 but gameListenerSocket already existed!
|
||||
STATUS: socket accepted from 169.254.122.50:1502!
|
||||
Connected to GameMachineHost at 169.254.122.50:1502
|
||||
Connected to GameMachineHost at 169.254.88.186:1502
|
||||
Connected to GameMachineHost at 169.254.35.214:1502
|
||||
Connected to GameMachineHost at 169.254.240.193:1502
|
||||
SteamNetTransport: connecting to 169.254.88.186:1502 (fake port 10609)...
|
||||
SteamNetTransport: connected [#1251939970 P2P SDR steamid:76561198659597127@169.254.88.186:10609]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.35.214:1502 (fake port 62257)...
|
||||
SteamNetTransport: connected [#389222490 P2P SDR steamid:76561197995508393@169.254.35.214:62257]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
SteamNetTransport: connecting to 169.254.105.170:1502 (fake port 4649)...
|
||||
SteamNetTransport: incoming [#2399032524 P2P steamid:76561198022091594@169.254.251.68:21949 fakeport #1] - accepting
|
||||
SteamNetTransport: connected [#2399032524 P2P SDR steamid:76561198022091594@169.254.251.68:21949 fakeport #1]
|
||||
SteamNetTransport: dropped [#3050802723 P2P steamid:76561197970536135@169.254.105.170:4649] end reason 5003: Timed out attempting to connect
|
||||
SteamNetTransport: attempt 1 ended in state 5
|
||||
SteamNetTransport: connected [#4019172527 P2P SDR steamid:76561197970536135@169.254.105.170:4649]
|
||||
SteamNetTransport: connect succeeded (attempt 2)
|
||||
SteamNetTransport: connecting to 169.254.240.193:1502 (fake port 7169)...
|
||||
SteamNetTransport: connected [#2022716960 P2P SDR steamid:76561197976435895@169.254.240.193:7169]
|
||||
SteamNetTransport: connect succeeded (attempt 1)
|
||||
Listen requested on port 1502 but gameListenerSocket already existed!
|
||||
STATUS: socket accepted from 169.254.122.50:1502!
|
||||
Connected to GameMachineHost at 169.254.122.50:1502
|
||||
Connected to GameMachineHost at 169.254.88.186:1502
|
||||
Connected to GameMachineHost at 169.254.35.214:1502
|
||||
Connected to GameMachineHost at 169.254.105.170:1502
|
||||
Connected to GameMachineHost at 169.254.240.193:1502
|
||||
All connections completed!
|
||||
NetClock: host 2 first sample, offset -51745 ms
|
||||
NetClock: host 3 first sample, offset -16521 ms
|
||||
NetClock: host 4 first sample, offset 20923 ms
|
||||
Physics: fixed step, 50 Hz
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user