Talk:RegisterForModEvent - Form

Active discussions

On Game Load RequirementEdit

  • "Registrations have to be refreshed after each game load."
  • "You must register for ModEvents after every game load!"

My experience suggests that these statements are no longer true. Additionally, if you change a script after registering, the game will actually prefer the version already in the save over the hard copy.

  • warning: Function dcc_ut_QuestController..OnEncounterEnd in stack frame 0 in stack 629647 differs from the in-game resource files - using version from save

--Darkconsole (talk) 2015-01-23T12:42:27 (EST)

Dynamically Creating ModEvents?Edit

Since you gotta specify both the handle and the event name when you register a form for a modEvent, but you only need to specify the event name when you write its code, is it possible to trigger modEvents with the same name using different handles?

For example, let's say that I got a modEvent called "OnSomething" in two different actors:

    event OnSomething()
        ;does things
    endEvent

then I use:

    actor_1.registerForModEvent("something_1", "OnSomething")
    actor_2.registerForModEvent("something_2", "OnSomething")

So, when I call this:

    int handle = ModEvent.Create("something_1")
    if (handle)
        ModEvent.Send(handle)
    endIf

I assume that only the first actor would get the modEvent, even though both have the same valid code. This means I can control whether they get the modEvent triggered, isn't it?


yes. --Darkconsole (talk) 2015-05-05T19:45:11 (EDT)



A script is unregistered for a ModEvent after that event occurs.Edit

@XJDHDR, Undo revision 52358


Notes | A script is deregistered for a ModEvent after that event occurs.


This is very not true. Please present your case in the talk section and we'll work through it. Darkconsole

I agree that this seems inaccurate. Some events have do-once behavior but not this one as far as I know. I would like XJDHDR to present how this was determined. We might be able to explain a misconception. Its even possible you misidentify a nuanced behavior for this event. @XJDHDR, share some more on your notes if possible. Scrivener07 (talk) 2019-01-26T11:50:26 (EST)
I determined this after following the multi-threaded skyrim mods tutorial here. In the 10 thread scripts I created, I send an event once the script has finished it's work (10 calls in total). I found that only the first thread script that finished it's work would trigger the event in the main script. XJDHDR (talk) 2019-01-26T12:52:40 (EST)
Thanks for the detailed reply. How are your threads (scripts) initially registering for the mod event? I have a suspicion that your results are due to how your thread scripts are initially registering for the event. Possibly in your "thread manager" script. Scrivener07 (talk) 2019-01-26T15:58:55 (EST)
To answer your question, my thread scripts are not registering for the mod event. They are sending the mod event and my FuncScript is the one receiving those events. This was with Skyrim Special Edition 1.5.62 and SKSE64 2.0.12, see Example Below. -XJDHDR (talk) 2019-01-26T21:29:34 (EST)
Excellent, thanks for sharing complete source code. Its much easier to clone a local copy for browsing. I dont have Skyrim installed these days to peek at the plugin so please bare with me while I take an educated guess. Did you know that when a script is attached to a Form, and it makes an event registration, the event is registered with the FORM itself. When multiple scripts are attached to the same Form (Quest), the event registration will apply to ALL the Form's scripts. So for example, if your scripts XjMBARFuncScript & XjMbarFirstInstallThreadScript (1-10) are attached to the same Quest then when Thread01.ClearThreadVariables() is called it will also unregister the XjMBARFuncScript script from its result event. In Fallout 4 (Papyrus 2.0), event registrations are per Script rather than per Form. Scrivener07 (talk) 2019-01-27T02:33:42 (EST)
No, I didn't know that. I thought registration was per script. And your guess was correct, the three scripts I mentioned are all attached to the same quest. Well that solves that mystery, I guess I need to make some changes. Thank you! -XJDHDR (talk) 2019-01-27T02:55:51 (EST)
Your scripts look nice. Besides maybe some form IDs you shouldnt have to change anything in code. A work around is to attach one script per Form. I used to make a player ReferenceAlias on my quest for each "thread" in situations like this so everything would be grouped together on the same form. Multiple Quests or some other form type should work perfectly fine to. ReferenceAlias is what I have found to be the most convenient though. Thanks for being so cool about the undo revision and glad to have helped. Also I made some edits to the actual conversation here to make it easier to follow. I hope thats a "proper" wiki thing to do. Scrivener07 (talk) 2019-01-27T04:22:12 (EST)
Thanks again for the help. I decided in the end to keep all the scripts attached to the same quest as they were. This also had a few benefits, such as that I only needed to register for the threads' OnRunThreadedPreInstallCode once in the master script rather than in each thread, as well as replacing a few GetFormFromFile calls with ((Self As Quest) As <script name>). It's a pleasure, when my edit was reverted, I agreed that I might have misunderstood something. Finally, I for one approve of the edits you made and think the conversation does look better now. -XJDHDR (talk) 2019-02-05T18:04:21 (EST)

Example - Mark Books As ReadEdit

In the 10 thread scripts I created, I send an event once the script has finished it's work (10 calls in total).

I can link to copies of my scripts as they are currently written if that helps. This is my thread script that contains all the code that the 10 threads run and which send the event I mentioned above: XjMbarFirstInstallThreadScript.psc. This is the thread master script that prepares and starts the 10 thread scripts: XjMbarFirstInstallThreadMasterScript.psc And this is my function script that, amongst other things, starts up the thread master script and receives the event sent by the 10 thread scripts (lines 196 - 251 are the relevant lines): XjMbarFuncScript.psc


I used the "Send" function in this case but "SendModEvent" had the same behaviour: XjMbarFirstInstallThreadScript.psc

	; OK, we're done - raise event to return results
	Debug.Trace("Mbar: Thread complete " + iThreadNumber)
	Int iModEventHandle = ModEvent.Create("XjMbarSendThreadResults")
	ModEvent.Send(iModEventHandle)


I then have the following in my script that receives the 10 events: XjMbarFuncScript.psc

Event OnSendThreadResults()
	iThreadsProcessed += 1
	Debug.Trace("Mbar: iThreadsProcessed = " + iThreadsProcessed)
EndEvent


I found that only the first thread script that finished it's work would trigger the event in the main script. Here is my Papyrus log to illustrate:

[01/27/2019 - 06:26:37AM] Mbar: Thread complete 10
[01/27/2019 - 06:26:37AM] Mbar: iThreadsProcessed = 1
[01/27/2019 - 06:26:38AM] Mbar: Thread complete 8
[01/27/2019 - 06:26:38AM] Mbar: Thread complete 7
[01/27/2019 - 06:26:38AM] Mbar: Thread complete 6
[01/27/2019 - 06:26:39AM] Mbar: Thread complete 9
[01/27/2019 - 06:26:39AM] Mbar: Thread complete 3
[01/27/2019 - 06:26:39AM] Mbar: Thread complete 4
[01/27/2019 - 06:26:39AM] Mbar: Thread complete 2
[01/27/2019 - 06:26:39AM] Mbar: Thread complete 1
[01/27/2019 - 06:26:39AM] Mbar: Thread complete 5


If I edit my event to say the following: XjMbarFuncScript.psc

Event OnSendThreadResults()
	RegisterForModEvent("XjMbarSendThreadResults", "OnSendThreadResults")
	iThreadsProcessed += 1
	Debug.Trace("Mbar: iThreadsProcessed = " + iThreadsProcessed)
EndEvent


This one does receive all 10 events:

[01/27/2019 - 06:39:59AM] Mbar: Thread complete 10
[01/27/2019 - 06:39:59AM] Mbar: iThreadsProcessed = 1
[01/27/2019 - 06:40:00AM] Mbar: Thread complete 8
[01/27/2019 - 06:40:00AM] Mbar: iThreadsProcessed = 2
[01/27/2019 - 06:40:00AM] Mbar: Thread complete 7
[01/27/2019 - 06:40:00AM] Mbar: iThreadsProcessed = 3
[01/27/2019 - 06:40:00AM] Mbar: Thread complete 6
[01/27/2019 - 06:40:01AM] Mbar: iThreadsProcessed = 4
[01/27/2019 - 06:40:01AM] Mbar: Thread complete 3
[01/27/2019 - 06:40:01AM] Mbar: iThreadsProcessed = 5
[01/27/2019 - 06:40:01AM] Mbar: Thread complete 9
[01/27/2019 - 06:40:01AM] Mbar: iThreadsProcessed = 6
[01/27/2019 - 06:40:01AM] Mbar: Thread complete 4
[01/27/2019 - 06:40:01AM] Mbar: iThreadsProcessed = 7
[01/27/2019 - 06:40:01AM] Mbar: Thread complete 5
[01/27/2019 - 06:40:01AM] Mbar: Thread complete 2
[01/27/2019 - 06:40:01AM] Mbar: iThreadsProcessed = 8
[01/27/2019 - 06:40:01AM] Mbar: iThreadsProcessed = 9
[01/27/2019 - 06:40:01AM] Mbar: Thread complete 1
[01/27/2019 - 06:40:01AM] Mbar: iThreadsProcessed = 10
Return to "RegisterForModEvent - Form" page.