Exposed vehicle commanders or MGers are not displayed as exposed to other players

Issue #332 resolved
Colin Basnett created an issue

Had this happen on Freyneux the other night.

Comments (6)

  1. Colin Basnett reporter

    A bit more information on this. I saw this also happen during our private testing with the StuG machine-gunner. He was clearly shooting the gun, but he wasn't visually popped out of the gun. When i fired at him, he died. So the same issue seems to apply to mounted tank machine-guns as well.

  2. Matt Hands

    Will add some debug logging tomorrow evening. As this happens all the time it will be quick and easy to fix. I think either non-owning net clients somehow aren't triggering NextViewPoint() or going into state ViewTransition. We'll see.

    Vehicle drivers were working correctly, with driver appearing in unbuttoned position to other net players, so issue seems specific to vehicle weapons. Code is basically the same for vehicle driver and other positions, except veh weps rely on the Gun actor/reference.

  3. Matt Hands

    Have made some changes as part of commit 1f20749, which weren't specifically aimed at this bug, which may affect it. Pls let me know if you are on the test server and see a difference. I'll be adding some debug logging [on Sunday 21 June as I ran out of time tonight]. I'm not concerned about this one, as I'm confident it's an easy detect & fix.

  4. Matt Hands

    Fixed in commit b5cd890, including removal of temp debug.

    A strange one ! Or rather, a strange issue/native bug is exposed. There were no bugs in our code. The cannon and MG pawns, which did not work, were following the same code flow as a vehicle driver, which did work. The sequence on a net client is basically: detect changed value of DriverPositionIndex in PostNetReceive(), call NextViewPoint(), go to state 'ViewTransition', state handles animations.

    Works fine on server and owning net client. In vehicle class it also works fine on non-owning net client (other, viewing player). But in VehicleWeaponPawn it doesn't work on non-owning client. Logging shows that non-owning client goes to state ViewTrans, but does not execute ANY state code - including the final GotoState(''), so it never leaves ViewTrans !! And I remember from previous experience that if you try to set a VehicleWeaponPawn timer on a non-owning client, the timer is set (TimerRate is set in native to the timer duration), but the timer doesn't actually count (TimerCounter stays at zero and does not count up as it should). But I also recall that if the non-owning client subsequently took control of the VWPawn, the timer began to count up and then Timer() was called. I logged all this stuff to investigate and confirm.

    I'm sure there is no intended reason why a non-owning net client cannot use state code or timers. A difference is that a non-owning client has Role of simulated proxy, where the controlling client is an autonomous proxy. But that has no effect in UScript, as the all functions/state involved are/were simulated and are called from the local machine, which is a sim proxy, so is able to execute sim functions/states. I believe this is a bug in RO VWPawn native code.

    Compare to ROWheeledVehicle, where NextViewPoint() always sends any net mode into state ViewTrans. And that all works fine and I continue to use that basic method in vehicle classes. But an ROVehicleWeaponPawn has a different NextViewPoint(), which calls AnimateTransition() on a non-owning net client instead of going to ViewTrans. I never understood why ROVehicle and ROVWPawn handled that differently and concluded it wasn't deliberate. Now I believe it is - and that the use of AnimateTransition() is a workaround for the fundamental bug I describe above.

    Because both state code and timers are not working on a non-owning client, my hypothesis is that the bug lies in native Tick() in VWPawn, probably introduced in ROVWPawn. I've seen UT2004 native code snippets that show how native Tick (as opposed to the UScript Tick that we see) is used to control timers, i.e. native Tick() increases TimerCounter and calls Timer() when TimerCounter reaches the set TimerRate (duration). It's logical to assume that native Tick() will also control execution of state code, with its latent functionality, including the timer-like Sleep(), plus calling BeginState() and EndState(). Moving between states is not instant and there is always some timing element, even if it's just making sure EndState() has finished before commencing new state functionality.

    So I think a bugged native Tick(), probably in ROVWPawn(), probably fails to execute at all on a non-owning client, or at least fails to execute the code that handles timers and state code. And regardless of whether my hypothesis is correct, the problem is definitely there, so it's something we need to be aware of and work around.

    My fix is to revert to using AnimateTransition() for non-owning net clients on cannon and MG pawns. It's a little less clean than before and is less perfect functionality, solely because we can no longer disable the player's bullet whip attachment only AFTER a buttoning up transition finishes. Can't use a timer because it fails to work in the same way state code fails to work.

    So now, on a non-owning client, the whip attachment is disabled as soon as the player begins to button up. In theory, this means that hits will no longer be registered on that client while the player is buttoning, although it is only a momentary issue. But the hit will still be registered on the server and the owning client (the shot vehicle occupant), so it's only a question of local effects. And in practice, most hits on exposed commanders will be bullets from fairly close range, where a pre-launch trace will register the hit, play the effects & prevent the bullet from even spawning.

  5. Log in to comment