Skip to content

Instantly share code, notes, and snippets.

@mrowrpurr
Last active May 3, 2025 23:34
Show Gist options
  • Save mrowrpurr/75b0c9cf8ffadf9d38d2d42c4cf2d8f6 to your computer and use it in GitHub Desktop.
Save mrowrpurr/75b0c9cf8ffadf9d38d2d42c4cf2d8f6 to your computer and use it in GitHub Desktop.
Papyrus for Programmers

Papyrus for Programmers

Notes for Skyrim Scripting episode

How does Scripting work in Skyrim and Creation Kit?

Example Scripts:

  • KillerItem (Object Reference)
  • Magic
    • SpellSelf (Lesser Power, Fire & Forget, Self) Optional:
    • SpellTarget (Spell, Fire & Forget, Target Actor)
    • AbilitySneak (Ability) [on ReferenceAlias]
  • No .esp
    • JustAScript
    • HelloOnActivate *Food*
  • Other Examples:
    • Dialogue fragments, Quest stage fragments, etc
extends ActiveMagicEffect, Quest, ReferenceAlias,
        ObjectReference, SKIConfigBase, Dialogue...

Then look at how they are attached in Creation Kit.

Language Syntax

  • Comments (including {docstring} comments)
  • Casing (insensitivity & idioms)

Data Types (and local variables)

  • int, float, bool, string
  • Arrays
    • Utility to create and resize
  • String manipulation
    • StringUtil
    • How does SKSE add scripts and functions?
  • Implicit casting
  • Explicit as casting
  • Type naming collisions of local variables

Control Flow

There is no switch and no for

  • if conditionals
  • while loops
    • no break

States

  • GotoState and organizing with functions
  • GotoState("")
  • GetState
  • OnBeginState and OnEndState

Functions

  • Positional and Keyword Arguments
  • Default argument values
  • Type naming collisions of argument names
  • global
    • Global scripts (with only global functions)
  • native

SKSE

  • What is SKSE?
  • Reverse Engineering, Hooks
  • Comes with functions!
  • Comes with events!
  • Can make your own functions and events in your own SKSE plugins!

Script Variables

  • View in .ess Elder Scrolls Save files
  • Type naming collisions of variable/field names

Script Properties

  • auto
  • autoReadonly
    • Not saved
  • "Full properties"
    • Readonly
    • Writeonly
    • Read and Write
  • conditional (only on auto and on conditional scripts)
  • Filling properties
    • Fill via CK
      • Pick in render window (ObjectReference) or from cell (ObjectReference)
      • Name it the same as the EditorID and auto-fill or create using CK
    • Fill via No .esp
    • Game.GetForm() versus properties (leads into the next section...)

Forms and Script Types

  • Forms and Form IDs and Mod Indexes (FEzz000 zz000000 FF000000)
  • Learn the type functions and properties from CreationKit.com and VS Code and reading source
  • Form < ObjectReference < Actor
  • Form < Book
  • Alias < ReferenceAlias
  • ActiveMagicEffect
  • Fallout 4 has ScriptObject
  • Editor IDs and po3 Tweaks

Scripts as Objects

  • Attached to objects in the VM (Bind())
  • Constructor (OnInit)
  • Casting a Quest to a certain script
    • Casting ReferenceAlias etc to a certain script
    • Cannot upcast a script that wasn't attached as a given type
    • If multiple scripts of the same type are attached, first or random instance returned
      • For these circumstances, can store arrays (and arrays) or attached instances

Events

  • OnInit
  • OnPlayerLoadGame
  • See Events page on CreationKit.com
  • Can call just like functions
  • Events added by SKSE (and when using reloadscript)
    • Finding DXScanCodes
    • Finding UI targets

Waiting

  • RegisterForSingleUpdate
  • Utility.Wait[MenuMode]

SKSE Mod Events

  • Sending
  • Receiving
  • Sending and Receiving with custom arguments

Debugging

  • Debug.MessageBox
  • Debug.Notification
  • Debug.Trace
    • .ini settings

Patterns: "Control Script" (or "Maintenance")

  • Use a Quest and use GetQuest by editor ID to return the singleton

Using Papyrus libraries, e.g. PapyrusUtil or UIExtensions

  • Via Creation Kit and MO2
  • Via Visual Studio Code and <Import> includes
  • Champollion when necessary to get the .psc to compile against / review
    • Anonymization
    • .pas representation

Useful Console Commands

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment