How to Read a Papyrus Log Skyrim

27th February 2012

Papyrus for Beginners

Introduction

When modding Skyrim, y'all volition likely find yourself needing to ascertain behaviour that cannot be set up upwardly with the Creation Kit, similar removing a key from the player when they open a door, or killing a grapheme when a lever is pulled. In society to define this behaviour, you lot volition need to use Skyrim's scripting language, Papyrus.

This tutorial is aimed at people with lilliputian or no prior programming feel, and is an introduction to Papyrus that shows you how to use its simpler features without going also in-depth or getting also technical.

The first section of this tutorial is a "My First Script" tutorial, in which y'all will write a simple script in order to familiarise yourself with the process. After that, I volition talk well-nigh some of Papyrus' more than useful features.

Not every aspect of Papyrus is covered in this tutorial, but if yous wait only to take to write elementary scripts and you aren't interested in the technical side of things, then it should be enough to become y'all going. The topics covered in this tutorial are:

  1. Variables
  2. Backdrop
  3. Conditional Statements
  4. Functions

More complex features, such as states and loops, will exist discussed in a later tutorial, in which I will go into more technical item. If you look to exercise more than very simple scripting, or if you lot're interested in the technical details of papyrus, then keep a wait out for this upcoming tutorial.

In the meantime, if you run into "function not divers" errors and don't know why, take a expect at my "Accessing External Functions and Properties in Papyrus" tutorial, which was written to help with exactly that.

It's also worth mentioning that, while they are used commonly in the creation of quests and such, Papyrus fragments are not covered in this tutorial. Almost everything you lot learn hither should be applicable inside them, though.

My First Script

In this section of the tutorial, we are going to create a plugin file that uses a Papyrus script to print the text "Hello, World!" to the screen. It will briefly go over a few important aspects of Papyrus, and setting upwards a script to be used by a data file in the Creation Kit.

Getting Prepare

Before you write whatever code, you'll want to become a development environs set up upwards. While the Creation Kit does have an internal text editor that you lot can utilise, information technology's defective in a lot of good features.

Take a look at the Creation Kit wiki's list of text editors for instructions on how to set up them up every bit a Papyrus development environment. Personally, I use Notepad++. My setup highlights my scripts similar on the wiki, has function autocompletion, and allows me to compile my scripts with a simple keyboard shortcut.

Script Header

The first part of the first line of any Papyrus script is a ScriptName declaration, which specifies the name that the Cosmos Kit uses to recognise the script. This name volition have to exist the aforementioned as the filename, when the script is saved. Typically, a ScriptName declaration looks something like this:

          ScriptName          MyFirstScript

At a minimum, that starting time line ever starts with "ScriptName", followed by the name of the script you're writing. After that, you'll well-nigh always take an extra bit that says "extends <Type>". The type you use here should exist the blazon of object on which this script should run.

          ScriptName          MyFirstScript          extends          Quest        

This script is going to run on a quest, so later its ScriptName declaration comes "extends Quest". Most commonly, your scripts volition extend one of these object types:

  • ObjectReference
  • Actor
  • ActiveMagicEffect
  • Quest
  • ReferenceAlias

After this first line, it's often a skillful idea to add a documentation comment. Documentation comments are surrounded by curly braces - {} - and are used past the Creation Kit as tooltips for scripts and functions:

          ScriptName          MyFirstScript          extends          Quest          {This is my offset script. It prints the message "Howdy, World!" to the screen once.}        

Events

In guild to accept code that runs, you need to put it inside a native issue. Native events are a special kind of part that the game calls in reaction to certain events. In your script, yous tin define the code that will run when the game calls these events. I draw events and how they work in more detail later in this tutorial.

The outcome we're going to use here is called OnInit. OnInit specifically is an event that is called automatically when the object on which a script runs has the script attached to it, and again whenever that object is reset. At that place are other events that are chosen by the game in unlike situations, just for this script we want to utilise OnInit:

          ScriptName          MyFirstScript          extends          Quest          {This is my commencement script. It prints the bulletin "Howdy, World!" to the screen in one case.}          Event          OnInit          (          )          EndEvent        

Equally you tin see, events start with the keyword "Effect", followed past the proper name of the event. Later on the name comes a pair of brackets. Inside these brackets will go any parameters of this event. Since the OnInit outcome in particular doesn't have any parameters, these brackets are empty. After all of the code that makes up the body of your consequence, the "EndEvent" keyword designates the finish of the event.

Printing The Message

When writing any script, there are two large questions you need to enquire yourself:

  1. When do I want to do something?
  2. What do I want to do?

By using the OnInit upshot, we've set up our script to run some code as soon as the game is loaded (or, at least, that's how it will work once nosotros've also set information technology up in the Cosmos Kit). What'south left now is "What do I want to practice?".

In this script, we desire to print a bulletin saying "Hello, Earth!" to the screen. In that location are a few ways to do this, simply we're going to use the Notification function in this case. This function is a global function (you don't need to worry most what that means for at present) that is defined inside the "Debug" script, and so information technology needs to be called similar this:

          ScriptName          MyFirstScript          extends          Quest          {This is my first script. Information technology prints the message "Hello, World!" to the screen once.}          Issue          OnInit          (          )          Debug          .          Notification          (          "Hello, World!"          )          EndEvent        

Compiling The Script

At present that our script is ready, salvage information technology in the Data/Scripts/Source binder in your Skyrim installation directory as MyFirstScript.psc. Papyrus source files should ever be saved with their filename the same every bit their ScriptName, and the file extension .psc.

Once your script has been saved, it also needs to be compiled. How you practise this will depend on how you've set up your environment, but if you've used Notepad++ like I have, and you followed the setup instructions on the Creation Kit Wiki, y'all should need simply to use a keyboard shortcut similar Ctrl+F5 to compile your script.

In The Creation Kit

At present that yous script is saved, compiled, and ready to run, you need to create a new plugin file to make it run in the game. This script volition demand to be fastened to a new "Quest" object, which we'll create in our plugin.

To create this plugin, starting time open upwardly the Cosmos Kit and load both Skyrim.esm and Update.esm files.

Load both Skyrim.esm and Update.esm

Once everything's loaded, navigate to the Quest area in the Object Window (under the Character department), right-click on the correct hand console of the object window and select "New Quest".

Create a new Quest

When creating this quest, I recommend ticking the "Showtime Game Enabled" and "Run Once" flags on this quest.

Tick "Start Game Enabled" and "Run Once"

The "Outset Game Enabled" flag volition mean that your script volition start correct away, and then yous don't need to worry well-nigh making sure it's running if you need it to handle stuff for which it needs to be running.

The "Run Once" flag prevents your quest from running more than than once, which also prevents it from being reset when it's started. If this flag weren't checked, the OnInit outcome would be chosen twice in a row instead of just once, every bit the script is attached to the quest so the quest is reset when it is told to commencement.

Once the quest has been created, go to its "Script" tab and click the "Add together" push. Here, you should be able to find and select the script you just saved.

Add script to MyFirstScriptQuest <02000D62>

Testing Your Script

After y'all've fastened your script to your quest, save your plugin, then activate it using your favourite mod manager and load upwardly Skyrim. If everything goes co-ordinate to plan, the message "Hullo, Globe!" should appear when y'all load your saved game.

Congratulations, you've now written and gear up a working script!

Having a quest with a script that runs as before long every bit your mod is installed is a useful way to command the setup of your modern. You lot may discover yourself creating a plugin very similar to this ane that gives the player a certain perk or item once your modernistic is installed.


Now that you've worked through the "My Beginning Script" section of this tutorial, the rest of this tutorial will talk about some of Papyrus' simplest and most useful features. You lot'll have seen a couple of these already, now, merely some may still be new to you lot.

You tin expect to use all of the features discussed hither a lot, so information technology's of import that you understand them and that you feel comfortable using them. One time you've completed this tutorial, you lot should try to change the plugin you created in the "My First Script" department so that it makes employ of all the features talked most in the rest of this tutorial.

Variables

Often, you'll find that y'all need to somehow store information for later use. For this purpose, you will normally use a variable. Variables tin can be categorised into two types, value variables and object variables.

Value Variables

These variables directly shop a value. The but possible types of value variables are:

  • int

    Representing "integer", these variables tin shop whole numbers, both positive and negative.

  • float

    Representing "floating signal number", these variables can store non-whole numbers, both positive and negative.

  • bool

    Representing "boolean", these variables tin can only store ii values: true or false. If y'all need to shop a variable that acts somewhat like an on/off switch, you'll desire to use this type.

  • string

    These variables shop strings of characters. These values are always surrounded by double quotes on either side. For case: "This is an example of a string"

Object Variables

Instead of storing values like value variables, these variables bespeak at an object. There are two differences here - the blazon of data involved, and the style in which it is stored.

Instead of using values like 2, or -four.53, or true, these variables permit you access objects. Objects are things like quests, actors, and spells.

Instead of storing something, object variables point at something. To illustrate the divergence, magine you have 2 people, each of them having been told to call up something, and you are allowed to ask them to tell you what they've remembered or tell them to call up something else.

If you ask Person ane to tell you what she'south remembered, she might tell you "v". She'south a value variable of type "int" - she'southward remembering an integer value. If yous tell her that, instead of "five", she should remember "6", then what she remembered before is gone forever and if you ask her over again what she'due south remembering, she'll tell you lot "6".

If you ask Person two to tell y'all what she'south remembered, she might tell you "Go to 221B Baker Street". If you lot follow her directions to 221B Baker Street, you lot'll observe a person, which in Papyrus would be said to exist of blazon "Actor", called Sherlock Holmes. Using these directions, yous could find Sherlock and give him an apple, merely Person two wouldn't know about that. She is an object variable of type "Player" - she's remembering where an histrion is.

If yous tell her that, instead of "Become to 221B Baker Street", she should remember "Go to four Privet Drive, and look in the cupboard under the stairs", then her directions now point to Harry Potter instead of Sherlock Holmes. Even so, unlike before, Sherlock Holmes still exists, and probably still has the apple tree yous gave him. This is what it ways to point to data, as opposed to storing it.

As I mentioned before, the default value of all object variables is a special value called "None". If an object variable contains this value, so it not pointing at any object. Information technology's important to exist aware of this value, as it tin be very useful to check whether or non an object variable is ready to None.

Creating Variables

In social club to create a variable, yous need to declare information technology. The syntax for declaring a variable looks like this:

          int          foo

That line creates a variable of type "int", which is called "foo". Considering we haven't specified a value to give information technology, it volition instead use the appropriate default value for its type.

Variables can be alleged anywhere in your script, so long as it's after your ScriptName declaration. If they are declared outside of a function definition, then you lot tin can only initialise them (assign a value as they're created) to what is known as a literal.

For value variables, a literal is a value in its simplest form - it cannot be an expression. For instance, 2 is a literal, but ane+1 is not. For object variables, the only literal bachelor is None, which is also the default value for object variables, so in that location'southward never whatsoever need to give them an initial value.

The OnInit event, which we used in the "My First Script" section, is an excellent place to initialise variables that require an initial value that has to be calculated or retrieved somehow.

If a variable is alleged within a office, then that variable is just bachelor within that part. The same goes for blocks of other types too, some of which are described afterward in this tutorial. If a variable is declared within a block, that variable is only available within that block.

Irresolute A Variable'south Value

Once yous have alleged your variable, it's possible to change its value with an consignment functioning. To assign a new value to a variable, yous demand to use the assignment operator, which is the equals sign: =

Dissimilar in mathematics, in Papyrus (and other scripting and programming languages) information technology matters what is on each side of the equals sign. On the left, there must exist something in which a value tin be stored, i.e. a variable or a property (more than on properties subsequently). On the right, there must be a value that can be stored there. This value can take the class of an expression, in which instance the expression will be evaluated before the assignment occurs. For example:

foo          =          1          +          1        

When the line above is executed, the expression is evaluated first. You can visualise this as "1 + 1" existence replaced with its result, then now our line of code looks like this in our minds:

foo          =          2        

Now that the right hand side of our assignment is a literal (remember them?), the assignment itself takes place, and our "foo" variable is at present storing the value "2".

Retrieve, when we alleged this variable, we specified that the type of data it is able to store is "int". Now, what would happen if we tried to assign a value to it that is of a different type? The answer depends on the type of the data and the type of the variable.

Casting is the procedure of changing information of i type to information of another type. For some type conversions, the compiler is able to convert the information automatically. For example, if I try to assign the information two, which is of type "int", to a variable of type "bool", the compiler will automatically catechumen that information to the boolean value "true".

Non every type conversion tin can be done automatically, though. Some type conversions, such as converting "float" to "int", cannot be done automatically but can be done manually. This is done through the utilize of the keyword as, in the form "<information> as <type>". For example:

foo          =          3.41          as          int        

If you lot attempt to cast information into an incompatible type, your script will not compile. The Creation Kit Wiki has a page documenting how various type conversions piece of work, including automobile-casting done by the compiler in the absence of the every bit keyword - Cast Reference

Using A Variable's Value

Using the value of a variable is easy. You tin can utilise the value of whatever value variable in an expression in the exact same way equally you could apply a literal of the aforementioned type. For example, imagine we accept two value variables of blazon "int" declared with different initial values:

int foo          =          2          int bar          =          -3        

In an expression, such as one you would employ when assigning a new value to a variable, value variables can be used just like literals of the same type. For example:

foo          =          bar

Just similar earlier, you can visualise this as the variable being replaced with the value that it is storing. In our heads, the above line of code at present looks like this:

foo          =          -iii        

Using object variables in scripts is also like shooting fish in a barrel, although it is not the same as using value variables. Object variables are typically used in function calls, which are described in another section of this tutorial.

Outside of function calls, the simply places you're probable to use object variables are in provisional statements, likewise described in another section of this tutorial, when comparing two object variables with one some other or checking that an object variable is not fix to None.


Backdrop

Because scripts are not internal parts of information files, and the compiler is non an integral part of the Creation Kit, y'all cannot directly refer to data from a data file in a script. If you want to refer to something in your data file, such equally a particular actor, and then you need to employ something else as an intermediate. This "something else" is called a property.

A property allows your script to use information in a data file by providing a special interface that they can both access. From your script's indicate of view, a property is an capricious piece of information of a certain specified type, similar "Actor" or "Quest". From the Cosmos Kit's point of view, it is a signal at which data of that type can be inserted into the instance of your script attached to the object you're editing.

Declaring properties is very similar to declaring variables, except at that place are a couple of extra things you demand to do, and properties cannot be declared inside functions. Hither'due south an case of a typical belongings declaration:

          ObjectReference          Property          foobar          automobile        

As yous tin see, this is like to a variable declaration, starting with the type and besides specifying the name of the belongings, simply there are a couple of extra keywords hither. "Property", as I'm sure you lot've guessed, specifies that "foobar" is a holding, not a variable.

The keyword "auto" basically just ways that setting the value of the property, and asking for it, works only like it would for a variable. There'south a fiddling more to it than that, but I won't get further into it in this tutorial. Only know that yous volition practically ever desire to declare properties in this way, and once you exercise so you'll exist able to treat them as though they were variables.

Once you've defined your property, you can use it in your script as though it points to the object that you want to employ. One time you've attached your script to the right object in the Creation Kit, you will then need to use it to associate your property with the right object via a drop-down list of all objects of your property'south type.

While this ways that you must declare a holding for every specific object that you desire to employ in your script, and set it up in the Cosmos Kit, it also gives yous the great power to build scripts that can exist used in multiple like situations.

Property Auto-Fill

If yous desire to apply specific objects in your script, then by naming your properties the same as the editorIDs of the objects at which you lot want them to bespeak, the Cosmos Kit volition be able to fill up them automatically at the press of a push, so it'southward not quite the hassle it sounds like.

A proficient example of a script that has been written in such a way that information technology can be reused in like situations is the script for the "Transmute" spell, which is chosen transmuteMineralScript.

This script uses iii properties of blazon MiscObject to identify the iii objects altered by the spell. Information technology would be entirely possible to create a re-create of the existing "Transmute" spell and, just by changing the values of these 3 backdrop, enable it to transmute an entirely unlike fix of 3 MiscObjects.

One other of import divergence between variables and properties, into which I won't go into much particular in this tutorial, is that variables are individual, whereas properties are public. What this ways is that any variables y'all declare are accessible only within the script in which they were declared, whereas backdrop are accessible from any script, so long as you lot tin can go a handle on the object on which they be.

It's also worth noting that it's completely possible to declare properties of value types, but they're only useful if yous want to access its value from another script or if y'all desire to tweak the initial value of a not-object type from the Creation Kit, which isn't something you'll need to do frequently. Using object types to insert data available just to the Creation Kit is a much more than common and useful way to use a property.


Conditional Statements

You don't always want your events and other functions to do the same thing every fourth dimension. Sometimes, you want it to do something dissimilar depending on the state of something, like the thespian'south current wellness, or how strongly a container is locked. In lodge to do this, you need to use a provisional statement.

A set of conditional statements tin consists of iv different keywords and at to the lowest degree one expression. Simple sets conditional statements may merely use ii of these keywords, although more than complex ones may use all 4 - some more than once. These four keywords are:

  • If

    This keyword is used to signify the outset of a set of conditional statements. It is followed by a literal or an expression, but similar when assigning a value to a variable, which tin consist of a combination of variables, properties, operators, and calls to functions with return values.

    If and only if the result of an expression is true, a non-zero number, a non-empty string, an object that is not None, or an array with at least 1 element (arrays aren't covered in this tutorial) and so the code inside its conditional statement will be executed.

    More than specifically, this will happen if the result of the expression tin automatically be cast to the boolean value "truthful", only you don't need to worry too much nigh that for now, and I won't be going more in-depth into it in this tutorial. For now, though, I volition refer to such expressions as "evaluating to truthful" for this reason.

  • EndIf

    This keyword is used to signify the end of a set of conditional statements.

  • ElseIf

    Betwixt If and an EndIf, an ElseIf argument statement can exist used with an expression of its own to hateful "if none of the preceding weather condition in this prepare of conditional statements evaluated to truthful, and this expression does evaluate to true, run this code".

  • Else

    After all If and ElseIf statements in a prepare of conditional statements, just before the EndIf, an Else statement can be used, without an expression, to mean "if none of the preceding conditions in this ready of conditional statements evaluated to truthful, run this code". Considering of this, if a set of conditional statements includes an Else statement, some code volition always run.

Hither's an example of a set of conditional statements from a script attached to an actor that demonstrates how you can use them to find various states in the game:

          If          (          IsDead          (          )          )          ; This actor is dead          ElseIf          (          GetActorValuePercentage          (          "health"          )          <          0.5          )          ; This role player is alive and at less than l% health          Else          ; This thespian is alive and at greater than or equal to 50% health          EndIf        

Note that the brackets that I've put effectually the expressions in that case aren't necessary, just I adopt to apply them.


Functions

A function is essentially a wrapper for a section of lawmaking. When a function is called, the code inside it is executed. There are various means in which functions tin be categorised, but for the purposes of this caption I'thousand going to carve up them into three groups:

Native Functions

These functions are what allows Papyrus scripts to collaborate with the game engine. They do not contain Papyrus code, and are alleged along with the keyword native. You lot volition never ever need to declare or ascertain native functions, but you lot should be enlightened of their existence, as they will be the building blocks of your scripts.

Both IsDead and GetActorValuePercentage, which I used in the case of a set of conditional statements above, are native functions.

Non-Native Functions

These functions comprise segments of Papyrus code that can be run past calling the function. They are usually used to make boring, common things very piece of cake to do. For example, if I often discover that I need to discover the largest number out of two integers, I could create a custom function to do this:

          int          Function          Max(          int          a,          int          b)          global          {Returns the largest value out of ii integers}          if          (a          >          b)          Return          a          else          Return          b          endif          EndFunction        

You can ignore the global keyword for now. Only know that it ways my function doesn't demand to do anything with the object to which its script is attached. It's not necessary, but it is a proficient idea to use it when appropriate for reasons I won't get into in this tutorial. About of your functions probably won't be global functions.

As y'all can encounter, in some ways the first line of a role definition is similar to the declaration of a property. Information technology starts with a type - "int" in this case - and so the keyword Function, then the role's name.

After the function's proper name is a set of brackets, which oft has what looks similar a bunch of variable declarations within them, separated by commas. These are the part'south parameters, which are used to pass information into the part when it is called. Not all functions have parameters, simply the brackets are always required, fifty-fifty if they're empty.

NOTE TO Cocky: Default values for parameters (not covered in this tutorial)

In this instance, after the first line is a documentation comment. These are not necessary, merely they are useful to document what the function does, particularly what its parameters are for and what its render value represents.

A render value is a value that is the result of a function. The type of a function'southward return value is specified in the showtime line of its definition - "int" in this case. If a function has a render value, then the lawmaking within it must finish with returning a value. Non all functions take a return value - those that don't only lack a type identifier in their definition.

To render a value, the Return keyword is used, followed by a literal or an expression. In this example, the return value is 1 of the 2 values passed into the office as a parameter, depending on which one is the largest.

After the body of the function, the definition is finished with the use of the EndFunction keyword.

There are other, more avant-garde uses for functions (Notation TO Cocky: providing an externally accessible interface while manipulating privately attainable variables), just I won't go into them in this tutorial.

Events

Events are functions that are pretty much exactly the same as regular non-native functions, except they cannot have render values, there's a slight semantic departure, and for some types of object at that place are some special events.

Most native object types, such as ObjectReference and Quest, have a list of native events that will be called automatically by the game engine in response to certain things in the game. This is what'due south special most events - whereas other functions must always be called by Papyrus lawmaking, some events are called by the game.

Events are very important. Because other functions must be called by Papyrus code, and Papyrus code that actually runs can simply exist inside function definitions, y'all will need to use native events as the points of entry for your code. Without the game calling these events in response to things happening in the game, none of the code you write could always run.

Events are defined in pretty much the same way as non-native functions, except they can't have return values and then they don't utilize a blazon identifier, and instead of the Function and EndFunction keywords they use the Issue and EndEvent keywords.

When the game calls a native event, it passes certain information to that event in the form of parameters. Considering the game needs to be able to pass this information in a item format, your definitions for native events must use the same parameters as the game. This information can be plant on the Creation Kit Wiki, which contains documentation for each native event. For example, here is its documentation for the OnHit result, which is called by the game for objects of type ObjectReference.

Information technology is possible to define custom events, which utilise the same syntax equally native events and piece of work in exactly the aforementioned style as not-native functions without render values. The only potential benefit to this would be that there is a slight semantic difference between functions and events, just in that location is no functional divergence. Information technology will never be necessary for y'all to create custom events, but it's worth knowing that it is possible as y'all may see them in others' code.

Calling Functions

In lodge to run the code within a part definition, the part needs to be called somehow. Calling functions consists of three parts:

FunctionLocation.FunctionName(Parameters)
  1. Function Location

    The vast majority of functions must be called on an object of a certain blazon. For example, the native function IsDead must ever be chosen on an Actor. The calling object for these functions is specified before the proper name of a function, separated by a dot. If it's enclosed in brackets, you can use a complex expression, and so long as its end product is of an appropriate blazon.

    If you are calling this function on the object to which the current script is attached, so you do non need to specify a location.

    Some functions, known as global functions (remember the "Max" part I divers earlier was a global function), are chosen on types instead of objects. I won't get into detail on these in this tutorial, but I will say that a very common and useful example of a global part is the GetPlayer function, which returns the histrion character's Actor object and is called similar this:

                  Game              .              GetPlayer              (              )            

    Basically, global functions ordinarily don't require whatever information about a specific object as input, whereas non-global functions practise.

  2. Role Name

    The name of a function is the simplest function of a part call. It's simply the name of the office as was specified when the function was defined - nil more to information technology.

  3. Parameters

    Subsequently the function'due south proper name, whatever parameters from the function's definition need to be passed into the part call, enclosed by a pair of brackets. Similar in a office definition, the brackets are required fifty-fifty if the funcion has no parameters.

    If the part does have parameters, a value of the correct type (which may be the result of an expression) must be passed into the function call. The order of parameters is the same as in the function definition and, also, they must be separated by commas.

    For case, the "Max" function I divers before could exist called similar this:

    Max(              3              ,              two              +              2              )            

    You may discover that some native functions have parameters that practice not always need to exist specified when they're being called. It is possible for your own custom functions to work this way every bit well, simply that's non covered in this tutorial.


That concludes this tutorial. At the beginning of this tutorial, yous went through the "My Kickoff Script" department to create a plugin that prints out the message "Hello, World!" to the screen. Since and so, you lot've learned about variables, backdrop, provisional statements and functions.

There's yet a lot to learn about Papyrus, but yous know enough now to write relatively simple scripts. In order to solidify what you've learned hither, you lot should return to the script yous created earlier, and edit it to make use of all of these new features that you've learned nearly.

One very useful thing to know when information technology comes to testing scripts is that, because they're not office of whatsoever data files, you don't need to save any plugins that utilize them earlier you can examination changes that you lot've made - all y'all need to exercise is compile them. You volition just demand to use the Creation Kit to attach them to objects and to fix properties.

If yous notice yourself stuck anywhere, the official Cosmos Kit forum is a corking place to ask for help, or y'all can contact me directly.

Expert luck, and have fun scripting for Skyrim!

rodartethinger69.blogspot.com

Source: http://www.cipscis.com/skyrim/tutorials/beginners.aspx

0 Response to "How to Read a Papyrus Log Skyrim"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel