Skyrim Platform
Skyrim Platform is a modding tool for Skyrim allowing writing scripts with JavaScript/TypeScript. One of the mods built on Skyrim Platform is skymp client. Yes, client of Skyrim Multiplayer is technically a mod for Skyrim Special Edition implemented using Skyrim Platform.
Papyrus types from the original game
All types in SkyrimPlatform have the same name as in Papyrus, for example:
Game
,Actor
,Form
,Spell
,Perk
, etc.To use types from Papyrus, including calling methods and static functions that they have, they need to be imported:
Native functions
Most types have a list of native functions, they are divided into static functions (
Native Global
in Papyrus) and methods (Native
).Static functions are called on the type:
Methods are called on the object:
A list of original game types with documentation can be found here: https://www.creationkit.com/index.php?title=Category:Script_Objects
Calling functions from the original game is only available inside the
update
event handler (see below). If you try to do this in a different context, an exception will be thrown.
Form
Form (
Form
) is inherited by most game types, which have methods such asActor
,Weapon
, etc.Each form has an ID, which is a 32-bit unsigned number (
uint32_t
). In SkyrimPlatform, represented by the typenumber
.If you need to find a form by its ID, use
Game.getFormEx
. Note that it isGame.getFormEx
, notGame.getForm
. The latter always returnsnull
for IDs above 0x80000000 (the behavior of the original game).You can get the form ID using the
getFormID
method. It is guaranteed thatGame.getFormEx
will find the form by the ID returned by this method if the form was not destroyed by the game.
Safe use of objects
After you get the object, you need to make sure that it is not
null
:Or
It is guaranteed that
Game.getPlayer
never returnsnull
.
Unhandled exceptions
Unhandled JS exceptions will be logged to the console along with the call stack.
Raw Promise rejections are also output to the console.
Do not release plugins that have known bugs that are not handled. SkyrimPlatform performance is not guaranteed with unhandled exceptions.
Object comparison
To compare objects in SkyrimPlatform, you need to compare their IDs:
Casting objects to string
Types ported from Papyrus have limited support for a number of operations normal for regular JS objects such as
toString
,toJSON
.
Cast
If you have a
Form
object that is a weapon, and you need aWeapon
object, you can use casting:If you specify an ID for a form that is not actually a weapon, the
weapon
variable will benull
.Passing
null
to the function for casting types as an argument will not throw an exception, but will returnnull
:An attempt to cast to a type that has no instances or is incompatible in the inheritance hierarchy will also return
null
:You can also use typecasting to get an object of the base type, including
Form
:Casting an object to its own type will return the original object:
Papyrus types added by SkyrimPlatform
SkyrimPlatform currently only adds one type:
TESModPlatform
. Instances of this type do not exist by analogy withGame
. Its static functions are listed below.moveRefrToPosition
- teleports the object to the specified location and position.setWeaponDrawnMode
- forces the actor to always keep the weapon drawn / removed.getNthVtableElement
- gets the offset of the function from the virtual table (for reverse engineering).getSkinColor
- gets the skin color of the ActorBase.createNpc
- creates a new form of type ActorBase.setNpcSex
- changes the gender of the ActorBase.setNpcRace
- changes the race of the ActorBase.setNpcSkinColor
- changes the skin color of the ActorBase.setNpcHairColor
- changes the hair color of the ActorBase.resizeHeadpartsArray
- resizes the array of head parts ActorBase.resizeTintsArray
- resizes the main character's TintMasks array.setFormIdUnsafe
- changes the form ID. Unsafe, use at your own risk.clearTintMasks
- remove TintMasks for the given Actor or the Player Character if the Actor is not passed.pushTintMask
- add TintMask with def. parameters for the given Actor or the Player Character, if Actor is not passed.pushWornState
,addItemEx
- add / remove items from def. ExtraData.updateEquipment
- update equipment (unstable).resetContainer
- clear the base container.
Asynchronous
Some game functions take time and happen in the background. Such functions in SkyrimPlatform return
Promise
:When called asynchronously, execution continues immediately:
You can use
async
/await
to make the code look synchronous:
Events
At the moment, SkyrimPlatform has the ability to subscribe to your own events:
update
andtick
.update
is an event that is called once for every frame in the game (60 times per second at 60 FPS) after you've loaded a save or started a new game.tick
is an event that is called once for every frame in the game immediately after the game starts.And also for game events such as
effectStart
,effectFinish
,magicEffectApply
,equip
,unequip
,hit
,containerChanged
,deathStart
,deathEnd
,loadGame
,combatState
,reset
,scriptInit
,trackedStats
,uniqueIdChange
,switchRaceComplete
,cellFullyLoaded
,grabRelease
,lockChanged
,moveAttachDetach
,objectLoaded
,waitStop
,activate
...With
on
, you can subscribe to the event forever.Using
once
, you can add a handler that will be called once the next time the event is fired.The variable
even
always contains variables related to the event to which you are subscribed.
Hooks
Hooks allow you to intercept the start and end of some functions of the game engine.
Currently supported hooks:
sendAnimationEvent
enter
is called before starting the function.ctx
contains the arguments passed to the function and alsostorage
(see below).leave
is called before the function ends.ctx
contains the return value of the function, in addition to what was after the completion ofenter
.ctx
is the same object for calls toenter
andleave
.ctx.storage
is used to store data between calls toenter
andleave
.Script functions are not available inside the
enter
andleave
handlers.
Custom SkyrimPlatform Methods and Properties
There are methods such as
printConsole ()
that can be called immediately after import. They do not belong to any of the game types.printConsole (... arguments: any []): void
- output to the game console, opened by the~
key.worldPointToScreenPoint
- convert an array of points in the game world to an array of points on the user's screen. The dot on the screen is indicated by 3 numbers from -1 to 1.on (eventName: string, callback: any): void
- subscribe to an event namedeventName
.callNative (className: string, functionName: string, self ?: object, ... args: any): any
- call a function from the original game by name.getJsMemoryUsage (): number
- get the amount of RAM used by the embedded JS engine, in bytes.storage
- an object used to save data between reloading scripts.browser
is an object providing access to the Chromium Embedded Framework.getExtraContainerChanges
- get ExtraContainerChanges of the given ObjectReference...getContainer
- get all the items of the base container.settings
- an object that provides access to plugin settings:The plugin settings file is named
plugin-settings.txt
and should be located in theData / Platform / Plugins
folder. File format - JSON, extension.txt
- for the convenience of users.
Changing game console commands
SkyrimPlatform allows you to change the implementation of any game console command, for such a modification you need to get the console command object by passing the command name to the
findConsoleCommand (commandName)
method, short or long.Having received such an object, you can change the short (
shortName
) or long (longName
) command name, as well as the number of accepted arguments (numArgs
) and the function (execute
) that will be executed when this console command is called via game console.The return value of your new implementation indicates whether the original function of this command will be executed.
The first argument is the FormId of the object on which the console command is called, or 0 if it is absent.
The rest of the parameters will be the arguments with which the console command was called, of type
string
ornumber
.Since game functions are not available in this context, you must register an
update
event handler withonce
if you want to call a game function when you invoke a console command:
HTTP requests (experimental)
SkyrimPlatform provides limited support for HTTP requests. At the moment only get
is available.
In case the request fails,
response.body
will be empty.
Hot Reload
Hot Reload for SkyrimPlatform plugins is supported. Changing the contents of
Data / Platform / Plugins
will reload all plugins without restarting the game.For full use, these are features, i.e. reload your plugin with Ctrl + S, take the example plugin as a basis https://github.com/skyrim-multiplayer/skyrimplatform-plugin-example
When reloading plugins, the added event and hook handlers are removed, asynchronous operations are interrupted and all variables are reset, except for
storage
and its properties.
DumpFunctions
SkyrimPlatform has built-in functionality that allows you to output information about game functions to the file
Data / Platform / Output / DumpFunctions.txt
(key combination 9 + O + L). The game pauses for a few seconds while DumpFunctions is running.
Last updated
Was this helpful?