#"Collection modified, enumeration operation may not execute" when invoking VivHelper.PerfectTeleport

19 messages · Page 1 of 1 (latest)

torn ruin
#

Full context:
Im writing a mod that adds a trigger that can save/load a player's position at a certain time. Upon loading the state, the mod invokes VivHelper.PerfectTeleport using Reflection like so:

MethodInfo tele = teleportFunctions.GetMethod("PerfectTeleport", BindingFlags.NonPublic | BindingFlags.Static);
                    tele.Invoke(null, new object[] {
                        entityList[i], // the player (this also works with other entites so this is only called if entityList[i] is a Player entity.)
                        RoomStateTrigger.currScene, // The current scene.
                        roomName, // The room that the state was saved in.
                        positionList[i],
                        true, // endCutscene
                        false, // actAsTransition
                        null,
                        null,
                        null,
                        null
                    });

teleportFunctions is initialized like this:

static EverestModuleMetadata vivHelper = new() {
            Name = "VivHelper",
            Version = new Version(1, 13 ,3)
        };
// ...
if (Everest.Loader.TryGetDependency(vivHelper, out EverestModule vivModule)) {
                vivAssembly = vivModule.GetType().Assembly;
                teleportFunctions = vivAssembly.GetType("VivHelper.Module__Extensions__Etc.TeleporterFunctions");
            }

Within the actual map, states are saved in a given room, and the loading is handled using a Frost Helper Activator setup in a bits&bolts globally loaded room.

  • A "recall" flag is controlled by a globally loaded SetFlagOnButtonPressController
  • Upon the flag being set to true, a Frost Helper Activator activates my state loading trigger that will grab the Player entity and run the code above to teleport the player.
    However, when the player is teleported, the game crashes with a System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
#

My understanding of the issue is that something is breaking with the Frost Helper flag listener's foreach loop in the Session_SetFlag() method when the PerfectTeleport() method is called, but I don't know where to go from there

brazen crater
#

this seems like frosthelper's fault

#

yea

torn ruin
#

(ignore the entity being an InputFlagController here, I tried both that and the SetFlagOnInputController and it does the same thing)

brazen crater
#

might be worth ccing @burnt dock

torn ruin
#

currently im getting the LevelData from the next parameter of the onTransitionTo Everest event (temporary solution) and getting the name from that

#

though both my trigger and the activator are globally loaded in a _bb_global room so are they still being removed when the Level changes?

torn ruin
#

alright
though i do have one more question (just clarification things)
so adding a handler to change the level from the old one to the one I'm trying to teleport to at the end of the frame will fix the problem, do i put the entire teleport code from the beginning in there so it waits until the end of the frame to teleport the player? or is it something completely different that i have to add before the teleport code

just trying to understand specifically what you mean by "changing the level"

torn ruin
#

ok cool
thanks!
ill let you know if it works

torn ruin
#

uhh
ok
it's a different error this time

System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at Celeste.Mod.TurnbackHelper.TurnbackHelperRoomState.<>c__DisplayClass11_1.<recallState>b__0() in TurnbackHelper/TurnbackHelperRoomState.cs:line 57

the line 57 in question:

TurnbackHelperModule.currLevel.OnEndOfFrame += () => {tele.Invoke(null, [ // line 57
                        entityList[i],
                        RoomStateTrigger.currScene,
                        roomName,
                        positionList[i],
                        true, // endCutscene
                        false, // actAsTransition
                        null, 
                        null,
                        null,
                        null
                    ]);
                    };

@slender agate sorry for the ping but im at a loss here

torn ruin
#

it has something to do with the lambda expression, because no matter where i put the expression it gives me the same error.
but idk what List object it could be referring to here, or what index parameter it's saying is out of range

candid escarp
#

From the looks of it, entityList and positionList are both List objects, make sure that i is in bounds for each of them

#

i must be less than the Count attribute for each list, and be greater than or equal to 0

#

Yea, it looks like there is another list as well

torn ruin
#

oh
how it works is i have a list of Entity references that are saved in entityList, as well as their positions at the time of the save trigger activating in positionList

this trigger works for all Entities i just need this teleport to work when the item in the list is a Player object

I checked both lists when they crash and neither of them are causing the error

#

I also moved the onEndOfFrame += () => {} line to encompass the entire recall function that the teleport code is in and i get the same error