[Tutorial] Fixing laggy movers

 Forum Forum rules Search FAQ
Maps & Mapping
[Tutorial] Fixing laggy movers
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
RoelerCoaster
USER: MMI

i4Games Trusteei4Games Trustee
PostPosted: Thu Jan 19, 2017 22:37    Post subject: [Tutorial] Fixing laggy movers
Reply with quote

In this tutorial we will cover different ways with which we can try to fix laggy movers. The laggy movers we mean here are movers that visually appear on a different location than that they really are in online games. This is often the case for movers with a long move time, or rotating movers that always rotate in one direction.

Method 1: Simple but not very smooth
In this method we manipulate the RemoteRole of the mover. The downside of this is that it makes the mover very stuttery.

Steps

  1. Select the laggy mover and right click -> Mover Properties


  2. Go to the Networking section and set RemoteRole from ROLE_SimulatedProxy to ROLE_DumbProxy



That's it already.
This works for both "normal" moving movers and for rotating/spinning movers.
Maps that use this method (if you need an example) are for example BT-Lampv4_fix or BT-(D4nK)ForBarcode_v2

Note: I am not 100% sure, but I believe you have to be a bit careful with this method, as it may add some additional load to the server, so do not overdo it.

Method 2: Still quite simple, but for rotating movers only
A well-known trick for fixing laggy rotating movers is using an AssertMover. Although this may already be known by many I'll explain it for completeness.

Steps

  1. Add an AssertMover to your map.
  2. For Key 1, rotate the mover once for 360 degrees in the direction you would like it to rotate.
    Here we rotate clockwise.


  3. Go to the AssertMover section in the AssertMover properties

  4. Set CloseTimes[0] to 0
  5. Set OpenTimes[0] to the desired time for one rotation.
    If you want to match the RotationRate of the original mover, you can use the following calculation
    Code:
     Time = 65536 / RotationRate



  6. In the Mover section, set StayOpenTime to 0, and MoverGlideType to MV_MoveByTime


  7. Trigger the mover using a repeating timed trigger.


You will see a small hiccup after each full rotation of the mover, but it is usually not a problem. One of the reasons for this is that a close time of 0 seconds does not really exists, UT has a built-in lower bound of I believe 0.005 seconds.


Method 3: More complex, but smoother
In this method we split up the long trajectory of the mover into smaller sections and add additional keyframes to the mover. It appears that the position of the mover is synchronized with the server on each keyframe, so we exploit this to add "sync-points" on the mover trajectory. You will notice very small hiccups in the mover at these points, but if you make sure they are on non-crucial positions, or at positions where the player is not on the mover, this shouldn't be a problem.

Note: this method will make the mover move at a constant speed instead of accelerating and decelerating.

We can apply this method for both "normal" moving movers and for rotating/spinning movers, but because of a few details with the rotating mover we will treat it separately.

=== "Normal" moving movers ===
We first consider the situation where we have a mover moving in a straight line.

Steps

  1. Determine the distance between the start and the end of the mover. The distance must be measured to the same relative position of the mover. Usually the pivot is ok, but sometimes a corner may be easier.

    In this example the distance is 1024uu, which should normally not cause issues, but it is just for illustration purposes.


  2. Determine the "sync-points" by splitting the mover trajectory in equal section. Remember that a mover can have at most 8 keyframes, including the start and end, so we can have at most 6 intermediate "sync-points". The number of points you need depends on the total distance of the trajectory. Generally, the shorter the distance between the points the better, but no need to overdo this.

    In our example we will segment the trajectory in 4 sections of 256uu, so we need 3 intermediate "sync-points". Also, This example is just for illustration, normally you would make the distance bigger.


  3. Add a keyframe to each intermediate location.
    On our example we now have 5 keyframes in total.


  4. Finally we have to change some mover settings:

    • Set the MoverGlideType to MV_MoveByTime. This will make the mover move at constant speed. Otherwise it would accelerate and decelerate between each "sync-point".
    • Set NumKeys to the number of used keyframes. In our example this is 5.
    • Calculate the new move time. Say that our original move time was 20 seconds. We have split the trajectory in 4 sections, so each section should take 5 seconds, which we enter.




A downside of this method is that when you add sound to the mover, you will hear the close and open sounds on every intermediate keyframe. You could consider only using the move sound, but keep in mind that UT has a bug where the move sound keeps looping if there is no closed sound.

But I would like a mover that has a quicker return time, otherwise people have to wait very long

Normally one would use an AssertMover in this situation. But I have personally never managed to make an AssertMover work with multiple keyframes. But we can solve this problem by using a FurryMover4.

  1. Replace the mover by a FurryMover4, and setup the (intermediate) keyframes as before.
  2. Also here set the MoverGlideType to MV_MoveByTime, and set NumKeys to the number of used keyframes.
  3. Go in the FurryMover properties to the FurryMover section
  4. Make sure all OpenTimes are set to 0.


  5. Add for each section of the new trajectory a value in MoveTimes. In our running example, we have split the trajectory in 4 sections of 5 seconds each, so we add 4 times the value 5.


  6. The time the mover stays open can be set using FinalOpenTime
  7. Set bAutomate and bImmedateReturn to True, and set the desired return time for ReturnTime


  8. Give the mover a tag by entering a value for Tags[0]. Note that this is also the tag if you want to activate the mover using a button or a trigger, as Events -> Tag is ignored.


  9. If you want to activate the mover by touching it, add the tag to the Mover -> BumpEvent



This also partially solves the sound issue, as you can now use the Closed and Closing sounds without hearing them at the intermediate locations, as the mover returns immediately.

Example maps that use this technique:
BT-TheConquest_dbl
BT-SuperMario-OrigV3
BT-Rating1-v2

Note: A FurryMover4 gives you a lot more flexibility, as you can assign a different move times to each intermediate section.

For example, when we refer back to our running example, we could split the 1024uu trajectory in a section of 256uu, one of 512uu and then again one of 256uu, with move times 5, 10, 5 seconds respectively.
(See for example BT-SuperMario-OrigV3)

=== Rotating movers ===
Usually, method 2 is fine for rotating movers. However, if the mover rotates very slow it can still be a problem. We can use a similar segmentation technique here, but instead of segmenting by distance, we segment by angle. Also here we will use a FurryMover4.

Steps

  1. A full rotation is 360 degrees. We will segment these 360 degrees in equal sections. Also here we have to remember that a mover can have at most 8 keyframes.
    The easiest method is simply taking 4 sections of 90 degrees, which we will do here.


  2. We add a keyframe for the start and end position and each intermediate position.
    Note that the first and the last key look the same, but differ 360 degrees in rotation.


  3. From here simply follow the steps of the FurryMover version of the "Normal" moving movers part, with the following modifications

    • Make the FinalWaitTime 0
    • Make the ReturnTime 0
    • To calculate the time for each section you may want to use the formula of Method 2 to compute the total time and then divide by the total number of sections (4 in this example) to match a certain RotationRate.


  4. Simply trigger the mover using a repeating TimedTrigger (Remember to use the tag in Tags[0]).
  5. Alternatively, to reduce the hiccups even further, you could set bLoop to true in the FurryMover settings,
    and trigger the mover just once with a TimedTrigger.

---

I hope you enjoyed reading and learned some new techniques to deal with laggy movers!


Last edited by RoelerCoaster on Fri Jan 20, 2017 18:10; edited 2 times in total


lvkkie
USER: LVKKIE

DominatingDominating
PostPosted: Fri Jan 20, 2017 06:15    Post subject: Reply with quote

Wow, very handy! Thanks Roel Smile.

SAFeSTeR
USER: SAFECRACKER

Godlike!Godlike!
PostPosted: Fri Jan 20, 2017 17:26    Post subject: Reply with quote

Nice tut for those that don't know of any of these methods.

drunklove
USER: EVOL_KNURD

PlayerPlayer
PostPosted: Fri Jan 20, 2017 20:24    Post subject: Reply with quote

Another option for rotating movers is to use the custom script PropertyChanger.u to toggle SimulatedProxy to DumbProxy then back to SimulatedProxy in a fraction of a second. There's a small jitter every minute or so but the mover doesn't stop rotating, it just updates it online.

https://www.mediafire.com/?j8u6ryscnca8kij

Notes:
-Still needs tested with multiple people, not sure what happens if a player joins a server half way through.
-The higher the TimedTrigger is set the bigger the jitter, the lower it's set the more jitters you see but not as noticeable.
-Only works for movers that rotate, AFAIK.


RoelerCoaster
USER: MMI

i4Games Trusteei4Games Trustee
PostPosted: Fri Jan 20, 2017 20:46    Post subject: Reply with quote

That is actually pretty clever, didn't know about PropertyChanger.u. I didn't expect it to be possible to dynamically change the (Remote)Role.

Display posts from previous:   
Post new topic   Reply to topic All times are GMT
Page 1 of 1

 


Powered by phpBB © phpBB Group