Jump to content

Some clarification on getformfromfile ?


Recommended Posts

I've been using getformfromfile a fair bit in the mod I created but am aware that having something working well on my system doesn't entail things working well on someone else's system.

In my code, e.g., I have:

If Game.GetFormFromFile(0x0490EC6D, "EasierRidersDungeonPackSSE.esp") != None 
	;create a bunch of string arrays here
Endif

The idea is that I only want to generate the string arrays if I'm using them - and they're only useful if that mod is installed.

0490EC6D happens to be the form id of a map marker originating in that mod.

Is there something more I should be considering here ? Or is this fine ?

 

Link to comment
Share on other sites

This is wrong.   The map marker has FormID 0490EC6D in YOUR game because you have EasierRidersDungeonPackSSE.esp at load index 04.    It will not work for anyone with a different load order.

When using GetFormFromFile:    if this is from a regular type .esp,  you should supply only the 6 last digits of the FormID.    In your case, 0x90EC6D.     If it is from a light .esp  (FormID starting with FE), you should be using only the last 3 digits.    

Link to comment
Share on other sites

Posted (edited)
16 hours ago, scorrp10 said:

This is wrong.   The map marker has FormID 0490EC6D in YOUR game because you have EasierRidersDungeonPackSSE.esp at load index 04.    It will not work for anyone with a different load order.

When using GetFormFromFile:    if this is from a regular type .esp,  you should supply only the 6 last digits of the FormID.    In your case, 0x90EC6D.     If it is from a light .esp  (FormID starting with FE), you should be using only the last 3 digits.    

I thought that might be the case -- thanks for pointing out the distinction between regular and light esp re syntax.

I know that it seems like I'm a moron here, but I struggle for time to learn this stuff and sometimes when I achieve something that works (compiles, functions well in-game) I just move on with other problems. The getformfromfile as I had it worked for me so I marched onward..

That will make about 2 hours of work to resolve, but I'll never make that error again !

12 hours ago, PeterMartyr said:

you should also cast it, no alway cast it

Game.GetFormFromFile(0x0490EC6D, "EasierRidersDungeonPackSSE.esp") as string != None

 

Can you explain why this is ?

Edited by csbx
Link to comment
Share on other sites

I think you are using the cast correctly in this case.

In general, getFormFromFile gives you a Form, but you usually want an Actor, ObjectReference, Spell, Quest, or whatever.  So you'll need to cast it quickly.  Under the principle that it is better to detect errors early, the generally recommended practice is to cast immediately (to a type as specific as possible) and then compare with None (for error detection and recovery).

In this case, you are simply comparing with None, so the cast is not required.  It might still be useful to use a cast if you want the condition to fail in the case you get an unexpected object (perhaps because you are looking at the heavily/unwisely modded version of the referenced esp/esm).

Link to comment
Share on other sites

If you are already using SKSE, use GetModByName to ensure that a mod is present first.  This way, if the user peeks into their papyrus log, they will not see any of the harmless entries created by GetFormFromFile when a mod is not present.  Nothing more annoying than a user reporting that a mod is spitting out errors left and right in the papyrus log.  Especially when those errors are harmless.

If Game.GetModByName("EasierRidersDungeonPackSSE.esp") != 255 ; plugin is present. 255 is returned for inactive or missing plugins
  ; do whatever needed here
EndIf

 

Link to comment
Share on other sites

@csbx you need that maintenance script that I spoke about in an earlier post, using boolean (2 bytes each)

Take Two this time with code, about handling mods in the load order.

Spoiler
ScriptName PlayerAlias extends ReferenceAlias

Property Bool IsModInstalled
    Function Bool Get()
        return IsModInstalled_Var
    endFunction
EndProperty

Property Bool IsThisModInstalled
    Function Bool Get()
        return IsThisModInstalled_Var
    endFunction
EndProperty

; above semi full get only Prop is not necessary but how I would do a Global if you need to check it ¯\_(ツ)_
; you should handle every thing here tho

Bool IsModInstalled_Var = false
Bool IsThisModInstalled_Var = false

Event OnPlayerLoadGame()
    If(SKSE.GetVersion() as Bool)
        If(IsModInstalled_Var)
            IsModInstalled_Var = Game.GetModByName("Mod.esp") != 0xFF
            If(!IsModInstalled_Var)
                debug.Trace("this Mod been uninstalled")
                ; clean up code on removal FYI clean Formlist
                ; or call some code on another script or this
            EndIf
        else
            IsModInstalled_Var = Game.GetModByName("Mod.esp") != 0xFF
            If(IsModInstalled_Var)
                debug.Trace("adding this Mod is installed")
                ; add to formlist
                ; or call some code on another script or this
            EndIf
        EndIf

        ;next mod
        If(IsThisModInstalled_Var)
            IsThisModInstalled_Var = Game.GetModByName("thisMod.esp") != 0xFF
            If(!IsThisModInstalled_Var)
                debug.Trace("this ModName been uninstalled")
                ; clean up code on removal FYI clean Formlist
                ; or call some code on another script or this
            EndIf
        else
            IsThisModInstalled_Var = Game.GetModByName("thisMod.esp") != 0xFF
            If(IsThisModInstalled_Var)
                debug.Trace("adding this ModName is installed")
                ; add to formlist
                ;or call some code on another script or this
            endIf
        EndIf
        ;rinse and repeat till done
    else
       debug.TraceAndBox("SKSE is not running or installed, quit without saving and fix or install :)")
    EndIf
EndEvent

 

BTW I wrote that without having skyrim installed, take it with a grain of salt..  I also made them private because I am protecting them, I trust no one Hee Hee Hee and the Semi Full Prop are  MANUAL READ ONLY, uses no memory and is not baked into the save either so it can't hurt having them has Globals even if you never use them.

I hope you can see the logic? It handles mod install and removal in the middle of a playthru, at a convenient time, at load.. so when your running or searching lists, they are ready to go go go....  

I noticed you needed to work this out weeks ago, why I did a preemptive strike then. Sorry for the tardy reply I have been busy, and did not have time... this time instead of hinting with pseudocode , I am being explicit with papyrus code.  

BTW, you need SKSE to handle things correctly, your mod has needs, just accept it and go with the flow......  if you were hoping for SKSE free?

Edit: remember to comment out trace logs on release or when your happy, I am using them for Info. They are not Warnings or Errors.. But info output to check if the code  is working, or if it need more attention to make it robust.

https://ck.uesp.net/wiki/Trace_-_Debug

spontaneous generated game engine logs warning and errors are not harmless, a null pointer or out of bounds error is a Memory Violation, and certainly not harmless, that why they caught and stopped by the game engine... an out of bounds error has the potential to corrupt the RAM , not F u c k up Skyrim,  F u ck up the PC sideways, it  is more accurate to say that they are caught and stop before they can do damage at massive performance hit. 

JOKE BUT TRUE, that recent windows blue screen in SKYRIM SPEAK: I ran skyrim with empty property and it did not work...,😆🤣😁😂😂😂🤣 that was a NULL POINTER, harmless, S H I T NO, and it was caught too, before it damage the  hardware or data, or system, only data currently in the RAM was LOST, windows is an operating system... , what a save, but yeah what an inconvenience too.

Still think it is harmless? BTW that was not a Microsoft error, blame this company CloudStrike. The fix was easy too, boot in safe mode and delete CloudStrike files...  Things is if your getting warnings or errors in the papyrus log, you need to handle it since your code may/will not run as intended, at a massive performance hit. 🤣 

But yeah people find what do not understand annoying, so comment out info trace logs on release, but use the info warnings and errors during development, to make your code more robust, and performance friendly 

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...