[#bugs] Zones will not suspend while traveling on the world map, due to `TerrainTravel` ...

Issue #6236 new
Freehold Games Bot Account created an issue

Marked for crossposting by: Noelle Lavenza (transgendeer)

Message (jump):

<Noelle Lavenza (transgendeer)> Zones will not suspend while traveling on the world map, due to TerrainTravel reimplementing RunSegment. This prevents XRL.Core.ActionManager.IssueCommand() and XRL.World.ZoneManager.Tick(true) from being called, so if a player enters the world map while zones are waiting to be suspended, they will remain active until the player enters another zone. This can result in a lot of lag; if a player travels between several zones that are too recently active to suspend and then enters the world map while those zones are still active, they will all remain active for potentially hundreds and hundreds of turns until the player enters a new zone.

Comments (2)

  1. Noelle Lavenza
    /// <summary>
    /// Patches ProcessIndependentEndTurn on XRL.Core.ActionManager via Prefix to call Tick(bAllowFreeze: true) on active zones.
    /// </summary>
    [HarmonyPatch]
    public class NoelleTest_TurnPatch
    {
        [HarmonyPatch(typeof(XRL.Core.ActionManager), nameof(XRL.Core.ActionManager.ProcessIndependentEndTurn))]
        static void Prefix()
        {
            XRL.The.ZoneManager.Tick(true);
        }
    }
    
    /// <summary>
    /// Patches XRL.Core.ActionManager.ProcessIndependentEndSegment via Prefix to call IssueCommand.
    /// </summary>
    [HarmonyPatch]
    public class NoelleTest_SegmentPatch
    {
        [HarmonyPatch(typeof(XRL.Core.ActionManager), nameof(XRL.Core.ActionManager.ProcessIndependentEndSegment))]
        static void Prefix(XRL.Core.ActionManager __instance)
        {
            int num29 = 0;
            for (int count8 = __instance.Commands.Count; num29 < count8; num29++)
            {
                __instance.Commands[num29].SegmentDelay--;
                if (__instance.Commands[num29].SegmentDelay <= 0)
                {
                    __instance.IssueCommand(__instance.Commands[num29]);
                }
            }
            for (int num30 = 0; num30 < __instance.Commands.Count; num30++)
            {
                if (__instance.Commands[num30].SegmentDelay <= 0)
                {
                    __instance.Commands.Remove(__instance.Commands[num30]);
                    num30--;
                }
            }
        }
    }
    

    These Harmony patches appear to fix it, albeit at the cost of always freezing any waiting zones the first time the player moves on the world map, since the playertravels for hundreds of turns in one move; this will always lead to the suspension/freezing of any zones with a “SuspendZone” CommandQueueEntry queued, since the maximum time to suspend is 80 turns, while a quickness 100 character with both relevant travel skills will still travel for 100 turns in the flower fields (the terrain tile with the lowest travel segment count).

    One potential solution to this might be to only suspend zones while traveling on the world map, and not freeze them, preventing the momentary freeze while the zone freeze is processed. This would be as simple as changing Tick(true) to Tick(false), but I’m unsure if it would be as dramatic of a performance increase, at least not on its own. From my own testing it appears to be just as effective, though, and without the pause while freezing!

    EDIT: Also, this appears to be the root cause of (almost) all the world map lag observed; while some uses of TurnTick are probably unnecessary, as detailed in #6233, it doesn’t make much of an impact on lag until hundreds of turns are being processed all at once, and they would stop ticking once they’ve been suspended anyway—the only issue is that they were never suspended.

  2. Log in to comment