Jump to content
Sign in to follow this  

[REL] Pyro - Papyrus Project Compiler for FO4, SSE, and TESV

Recommended Posts


Pyro is a Python wrapper for the Papyrus Compiler that assists with quickly compiling scripts and placing them where they need to be.

Pyro also supports the use of Papyrus Project files, introduced with FO4, for compiling FO4, SSE, and TESV projects.


  • Tested and working on Python 2.7.13 and Python 3.6.3
  • Downloads and installs lxml via pip on first run



usage: pyro.py [-g {sse,fo4,tesv}] [-i INPUT] [-o OUTPUT] [-q] [-s] [-t]
               [--help] [--version]

required arguments:
  -g {sse,fo4,tesv}  set compiler version
  -i INPUT           set absolute path to input file or folder

optional arguments:
  -o OUTPUT          set absolute path to output folder (default: ..)
  -q                 report only compiler failures
  -s                 skip output validation
  -t                 show time elapsed during compilation

program arguments:
  --help             show help and exit
  --version          show program's version number and exit


> python pyro.py -g sse -i "[...]\Scripts\Source\ExampleScript.psc" -o "[...]\Scripts"

> python pyro.py -g fo4 -i "[...]\Scripts\Source\User\Projects\ExampleProject.ppj"


When the game is switched, all paths are generated using the "Installed Path" key in the Windows Registry for the respective games.

File/Folder Support

The wrapper can compile single .psc files and folders recursively. Scripts are compiled with either -op[timize] (SSE/TESV) or -op[timize], -release, and -final (FO4).

If you want to use different flags for compiling individual files and folders, you might as well just use the compiler directly.

PPJ Support

  • Compiles each script individually in parallel (at least as fast as FO4's multithreaded PPJ compiler)
  • Generates imports from both the input path and <Scripts>
  • No changes to script names in scripts or plugins are needed

The <Imports> and <Scripts> tags are required; however, you need only add the User and Base/Scripts folders as imports. In a future update, the <Imports> tag will be required only for third-party libraries, like SKSE, etc.

The <Folders> tag is not supported.

PPJ Support: Release/Final/Optimize

Release and Final are supported only by the FO4 compiler, but Optimize is supported for all games. The PPJ parser will ignore unsupported attributes.


UltraEdit Tool Configuration



Go to Advanced > Tool Configuration and click the Insert button.

  • [Command Tab] Menu item name = Compile Papyrus (FO4)
  • [Command Tab] Command line = python pyro.py -g fo4 -i "%p%n%e" -p
  • [Options Tab] Program type: DOS program = True
  • [Options Tab] Save active file = True
  • [Output Tab] Command output: Output to list box = True
  • [Output Tab] Command output: Capture output = True
  • [Output Tab] Command output: Handle output as Unicode = True
  • [Output Tab] Replace selected text with: No replace = True

Do not set a working directory. Click OK.

Open a script or project file, and press Ctrl+Shift+# to compile that script or project file. (Go to Advanced to see your custom menu items and their hotkeys.)

For the command line, you may need to use absolute paths to python.exe and pyro.py depending on your development environment.


Share this post

Link to post
Share on other sites

1.1 Update: Optimizations, fixups, and enhancements

  • Improved SSE/TESV PPJ processing speed (i.e., the speed at which data gets to the compiler, not the compiler itself)
  • Added quiet mode (-q to enable; passes -q argument to compiler which reports only failures)
  • Added file validation (-s to skip; validation takes between 0.01 and 0.1 seconds; skip only if you want zero message output)
  • Added time elapsed output (-t to show; for profiling and curiosity)
  • Removed <Imports> requirement in SSE/TESV PPJ XML files
  • Removed path hack (-p no longer needed; if "Source\User" is detected in path, Pyro will auto set default (..) output to the Scripts\*.pex folder)
  • Fixed project output path resolution (same as above)
  • Refactored redundant code

Also did some profiling and found that the SSE/TESV PPJ processor is around 4 seconds slower on average than the FO4 PPJ processor. I toyed with multithreading and asynchronous approaches, which were even slower, but what's implemented now is pretty much as fast as what's possible. Performance might benefit from compiling to a binary, but I doubt the gains would be significant.


  • Add support for using a third-party compiler (i.e., Caprica for FO4)
  • Add support for custom imports in shell (PPJ already supports custom imports)
  • Add support for importing DLC scripts explicitly
  • Add support for importing SKSE and F4SE scripts explicitly
  • Add support for third-party PEX decompilers
  • Add support for packaging compiled and/or source scripts into BA2 archives (FO4 only)
  • Add support for reporting physical lines of code
  • Add support for writing timestamped log files
  • Add support for parsing INI and JSON files instead of PPJ XML files
  • Add support for parsing custom XML tags in all PPJ files to tell Pyro how to BURN BABY BURN

Share this post

Link to post
Share on other sites

I assume this scripting tool aren't meant for new beginners about using a script or two in a mod, so any modder needs to have some basic knowledge about scripting.

Share this post

Link to post
Share on other sites

1.2 Update: Fixes and minor refactoring

  • Fixed an issue where the compiler would throw an exception when the quiet argument was not passed
  • Fixed an issue where only the first duplicate imports were removed during script import generation

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

Support us on Patreon!

  • Create New...