Referencing Multiple Scripts in Skyrim Papyrus

Share

WL

jow do you define a Property in skyrim script so you can reference more than one script

Edit

In Skyrim's Papyrus scripting language, you can define Properties to reference other scripts in several ways:

Basic Property Declaration

papyrus

ScriptName MyScript extends ObjectReference ; Single script reference MyOtherScript Property OtherScriptRef Auto ; Multiple script references using arrays MyOtherScript[] Property MultipleScripts Auto ; Or individual properties for different scripts FirstScript Property Script1 Auto SecondScript Property Script2 Auto ThirdScript Property Script3 Auto

Property Types for Script References

For referencing script instances attached to objects:

papyrus

; Reference a specific object with a script ObjectReference Property MyObject Auto ; Then access its script: (MyObject as MyScriptType) ; Or directly reference the script if attached to a known object MyCustomScript Property AttachedScript Auto

For referencing Quest scripts:

papyrus

Quest Property MyQuest Auto ; Access quest script: (MyQuest as MyQuestScript) ; Or directly reference the quest script MyQuestScript Property QuestScriptRef Auto

Example Usage

papyrus

ScriptName PlayerHouseScript extends ObjectReference ; Properties to reference multiple other scripts DoorScript Property FrontDoor Auto LightingScript Property HouseLights Auto SecurityScript Property SecuritySystem Auto StorageScript[] Property StorageContainers Auto Event OnActivate(ObjectReference akActionRef) If akActionRef == Game.GetPlayer() ; Call functions on referenced scripts FrontDoor.UnlockDoor() HouseLights.TurnOnLights() SecuritySystem.DisableAlarms() ; Loop through array of scripts Int i = 0 While i < StorageContainers.Length StorageContainers[i].RefreshInventory() i += 1 EndWhile EndIf EndEvent

Filling Properties in Creation Kit

After defining Properties with the Auto keyword, you'll need to fill them in the Creation Kit by:

  1. Selecting the object with your script
  2. Going to the script's Properties tab
  3. Assigning the appropriate objects/scripts to each Property

The Auto keyword tells the Creation Kit to automatically create the property interface so you can assign values to these references.

Retry

WL

In one of may scripts I say: Printscreen_Shared Property Data Auto but when I go to fill it in in the CK I only have two choices NONE and Printscreen_MainQuest. I need Printscreen_SharedData but onlt Printscreen_MainQuest is listed any Idea whats up?

Edit

This is a common issue in the Creation Kit when working with script properties. Here are the most likely causes and solutions:

1. Script Not Compiled or Compilation Error

The most common reason is that Printscreen_SharedData script hasn't been successfully compiled:

  • Open the Creation Kit's Papyrus Script Manager (Gameplay → Papyrus Script Manager)
  • Look for Printscreen_SharedData in the script list
  • If it's not there or shows errors, you need to compile it
  • Check for compilation errors in the Papyrus logs

2. Script Name Mismatch

Verify the exact script name in your .psc file:

papyrus

ScriptName Printscreen_SharedData extends [BaseType]

The ScriptName declaration must exactly match what you're referencing in the property. Case sensitivity matters.

3. Wrong Base Class/Extension

Make sure Printscreen_SharedData extends the correct base class that matches your property declaration:

papyrus

; If your property is: Printscreen_Shared Property Data Auto ; Then Printscreen_SharedData should extend Printscreen_Shared: ScriptName Printscreen_SharedData extends Printscreen_Shared

4. Script Attached to Wrong Object Type

The Creation Kit only shows scripts that can be attached to the current object type. If Printscreen_SharedData extends Quest but you're trying to assign it to an ObjectReference property, it won't appear.

5. Script Location Issues

Ensure the script file is in the correct location:

  • .psc files go in Data\Scripts\Source\
  • Compiled .pex files go in Data\Scripts\

Quick Fix Steps:

  1. Double-check the ScriptName in your .psc file
  2. Recompile Printscreen_SharedData in the Script Manager
  3. Verify it extends the same base class as your property type
  4. Close and reopen the Properties window in CK

If Printscreen_MainQuest appears but Printscreen_SharedData doesn't, they likely extend different base classes or there's a compilation issue with the SharedData script.

Retry

WL

All my scripts extend QUEST Printscreen_Shared is not a type of sctipt

Edit

Ah, I see the issue now! If all your scripts extend Quest and Printscreen_Shared is not a script type, then your property declaration is incorrect.

The Problem

You have:

papyrus

Printscreen_Shared Property Data Auto

But Printscreen_Shared isn't a valid script type - it should be the actual script name that extends Quest.

The Solution

Change your property declaration to reference the actual script name:

papyrus

Printscreen_SharedData Property Data Auto

Or if you want a more generic approach and multiple scripts might fill this role:

papyrus

Quest Property Data Auto

Then cast it when you need to access specific functions:

papyrus

; Access functions from the shared data script (Data as Printscreen_SharedData).SomeFunction()

Why Printscreen_MainQuest Shows Up

The Creation Kit shows Printscreen_MainQuest because:

  1. It's a compiled script that extends Quest
  2. Your property is looking for Quest-based scripts
  3. But it's filtering out Printscreen_SharedData because your property type doesn't match

Quick Fix

Change your property declaration from:

papyrus

Printscreen_Shared Property Data Auto

To:

papyrus

Printscreen_SharedData Property Data Auto

Then recompile your script, and Printscreen_SharedData should appear in the dropdown when you try to fill the property in the Creation Kit.

Retry

WL

I am not being clear. I have the PrintScreen_mainquest, printscreena_Folmula and printscreen_Shared all these scripts extend the quest type. I need to set a referebce in Printscreen_main quest and in Printscreen_formla to Printscreen_Shared. I use Printscreen_shared Property Data auto to do this. It wil compile but when I go to fill inthe appropriate script valus I only get one choice Printscreen_mainquest. So why?

Edit

Ah, now I understand! This is a specific Creation Kit behavior issue. Here's what's happening:

The Problem

The Creation Kit is only showing quest scripts that are actually attached to quest objects in your mod. If Printscreen_Shared script exists but isn't attached to an actual Quest record in the CK, it won't appear in the property dropdown.

The Solution

You need to create a Quest record and attach the Printscreen_Shared script to it:

  1. Create a new Quest:
    • Go to Character → Quest
    • Right-click and create a New quest
    • Give it an ID like PrintscreenSharedQuest
  2. Attach the script:
    • In the Quest window, go to the Scripts tab
    • Click Add and select Printscreen_Shared
    • Save the quest
  3. Fill the property:
    • Now when you go back to fill your property in the other scripts
    • You should see PrintscreenSharedQuest in the dropdown
    • Select it, and it will reference the quest with your Printscreen_Shared script attached

Why This Happens

The Creation Kit property dropdown only shows:

  • Quests that actually exist as records in your mod
  • That have the matching script type attached

Even though your Printscreen_Shared script compiles fine, without a Quest record using it, the CK doesn't know what quest object to reference.

Alternative Approach

If you don't want to create a separate quest, you could also attach the Printscreen_Shared script to your main quest alongside Printscreen_MainQuest, but this is less clean architecturally.

Retry

WL

so currently My procedure is to open the CK and Create the MainQuest. I open the mainquest and edit it so that under the scripts tap I can create the scripts: mainQuest Script, ME-Script , MCM_script , SharedData_scsript, and .. formula_script. Are you saying I need to make a new quest for each of these scripts so they will be availiable for filling properties?

Edit

No, you absolutely do NOT need to create separate quests for each script! You're doing it correctly by attaching multiple scripts to one quest.

The Real Issue

If you have all these scripts attached to your MainQuest:

  • MainQuest Script
  • ME-Script
  • MCM_script
  • SharedData_script
  • Formula_script

Then when filling properties, you should see the quest name (like "PrintscreenMainQuest") in the dropdown, not individual script names.

How Properties Work with Multiple Scripts on One Quest

When you reference a quest that has multiple scripts attached:

papyrus

; In your MainQuest script Printscreen_SharedData Property SharedRef Auto

You'd fill this property with your MainQuest, then cast it to access the specific script:

papyrus

; Access the SharedData script functions (SharedRef as Printscreen_SharedData).SomeFunction()

Why You're Only Seeing MainQuest

You're probably only seeing "PrintscreenMainQuest" because:

  1. That's the only quest you've created
  2. All your scripts are attached to that one quest
  3. This is actually correct!

The Solution

Instead of trying to reference individual scripts, reference the quest and cast to the script you need:

papyrus

Quest Property MainQuestRef Auto ; Fill this with your MainQuest ; Then access any script attached to that quest: (MainQuestRef as Printscreen_SharedData).SharedFunction() (MainQuestRef as Printscreen_Formula).FormulaFunction()

Your current setup is actually the standard approach - one quest with multiple scripts attached to it.

Retry

WL

OK. My proble is referencing the shared data. For instance if I have a variable Menu that I define as a property with: bool Property Menu Auto in the shareddata script and I need to referen ce it in mainQuest I have been trying to use: Printscreen_shareddata Property Data with the access being data.Menu. But this gives me the dropdown problem . You are saying to use:

Edit

Yes, exactly! You're on the right track. Here's the correct approach:

Use Quest Property Instead

papyrus

; In your MainQuest script Quest Property MainQuestRef Auto ; Fill this with your actual MainQuest ; Then access the shared data like this: bool currentMenuState = (MainQuestRef as Printscreen_SharedData).Menu

OR Even Simpler

Since you're already IN the MainQuest script, you can reference the other scripts attached to the same quest directly:

papyrus

; In your MainQuest script - no property needed! bool currentMenuState = (Self as Printscreen_SharedData).Menu ; Or if you want to be more explicit: Printscreen_SharedData sharedScript = Self as Printscreen_SharedData bool currentMenuState = sharedScript.Menu

The Key Point

Since all your scripts are attached to the same quest object, Self refers to that quest, and you can cast it to any of the script types attached to it.

Complete Example

papyrus

; In your MainQuest script Event SomeEvent() ; Access shared data directly bool menuOpen = (Self as Printscreen_SharedData).Menu ; Modify shared data (Self as Printscreen_SharedData).Menu = true ; Call functions from other attached scripts (Self as Printscreen_Formula).CalculateSomething() EndEvent

This eliminates the dropdown problem entirely because you're not trying to reference external scripts - you're just casting the same quest object to different script types that are all attached to it.

Retry

WL

What I am trying to do is something like If(Data.Menu) do you thisk I would be rquuired to use somethig like if(self as PrintscreenSharedData)

Edit

No, you can still use the cleaner Data.Menu syntax! You just need to set up the property correctly.

The Solution

papyrus

; In your MainQuest script Quest Property Data Auto ; Fill this with your MainQuest in the CK ; Then you can use the clean syntax you want: If (Data as Printscreen_SharedData).Menu ; do something EndIf

Even Better - Create a Getter Function

For the cleanest syntax, create a getter function in your MainQuest script:

papyrus

; In your MainQuest script Printscreen_SharedData Function GetSharedData() Return (Self as Printscreen_SharedData) EndFunction ; Then use it like this: If GetSharedData().Menu ; do something EndIf

Or Use a Property with Auto-Get

papyrus

; In your MainQuest script Printscreen_SharedData Property SharedData Printscreen_SharedData Function Get() Return (Self as Printscreen_SharedData) EndFunction EndProperty ; Now you can use the syntax you wanted: If SharedData.Menu ; do something EndIf

The property approach gives you exactly the Data.Menu syntax you're looking for, without needing to cast every time you access it.

So to answer your question: No, you don't need if(self as PrintscreenSharedData) every time - you can set it up once and then use the clean syntax you prefer.

Retry

WL

Looking at the set of scripts in my mod i inadvertantly ended ut with a circular reference which may not be required. I have two SKSE plugin functions: checkpath and PrintScreen printscreen is a latent function and so has a somewhat complicated result return proceedure. If I locate the return procedure in the mainQuest script anstead of the Formula script It does not seem to need the circular reference as all its needed paramiters live in the mainquest. So the function is called from the mainquest and returns there. The event that handles the latent function return can simply reference the needed variables directly. is this approach feasible?

Edit

Yes, absolutely! This is actually a much cleaner architectural approach and will solve your circular reference problem.

Why This Makes Sense

Centralized Control: Having the MainQuest handle both the SKSE function call and the return event keeps all the orchestration in one place. This is a common pattern in game scripting.

Direct Variable Access: Since MainQuest can access all the other scripts attached to the same quest via casting (Self as ScriptName), you have direct access to any variables you need without complex property chains.

Eliminates Circular Dependencies: By keeping the latent function lifecycle entirely within MainQuest, you remove the need for scripts to reference each other in circular patterns.

Typical Implementation Pattern

papyrus

; In MainQuest script Event SomeInitEvent() ; Get parameters from other scripts if needed string path = (Self as Printscreen_Formula).GetSomePath() ; Call the latent SKSE function int callbackID = PrintScreen(path) ; or whatever parameters EndEvent Event OnPrintScreenComplete(int callbackID, bool success, string result) ; Handle the return directly If success ; Access any variables you need from other scripts (Self as Printscreen_SharedData).LastResult = result (Self as Printscreen_Formula).ProcessResult(result) EndIf EndEvent

Benefits of This Approach

  • Single Responsibility: MainQuest becomes the coordinator
  • No Circular References: Other scripts don't need to know about each other
  • Easier Debugging: All async flow is in one script
  • Better Performance: Fewer property lookups and casts

This is definitely feasible and actually represents better software architecture than the circular reference approach.