Jump to content
Mattiewagg

[Student Thread] Treeaza - Matthiaswagg

Recommended Posts

Alright. Let's get this started. I believe you have but if you haven't please install the Creation Kit (found under Library>Tools in Steam).

Now, please read thesetwo tutorials on scripting I linked, if you haven't already. It should help you understand the basics, so what I say should be a little bit comprehensible. :P

Part 1

Part 2

For scripting, I don't recommend using the built in Creation Kit script editor. It's not all that fun to work with. Especially because if the CK crashes during your writing of a 500 line script, you'll lose all that. If the CK built in editor even lets you write that much. Often it won't. The majority of scripting is done in an exterior program from the CK, except for hooking up your scripts to the game.

Also, syntax highlighting (pretty colors for your code) and auto complete (as you start to write a function or something it'll allow you to autocomplete it, including parameters) and quick compiling will save your life.

So I'm going to highly recommend you install a good text editor for this. Notepad++ and SublimeText 2 are the most well supported editors for Papyrus (Skyrim's scripting language). They're both absolutely free. Sublime Text will ask for you to verify and pay after a free trial, every month or so, but it's not needed to actually pay ever. It's not at all annoying and just a quick Ok every month. I'll briefly outline the pros and cons for you. I'm currently using ST2 though I used NP++ in the past:

Notepad++:

Pros:

- Good support for Skyrim scripting, as well as SKSE functions and SkyUI

- Easy to use

- Nice interface, clean look and good syntax highlighting

- Auto complete is great. Also includes definitions of functions - so it will autocomplete, tell you which mod/script the function is from, what it does (not all definitions are complete but many), and possibly how it's used. This feature is mainly what I miss for NP.

Cons:

- Sort of a pain to set up the quick compiler, which allows you to compile directly from NP++ rather than writing there and then pasting in CK and then compiling there. Note it may just be because I suck really really bad at using the command line/stuff you need to set it up. Some people find it very was, I didnt.

- Can't change color scheme - a few syntax colors to choose from but none radically different

- No extra plugins

Set it up for the CK here: Linky

SublimeText 2:

Pros:

- Super easy to set up

- Support for SKSE, SkyUI, and almost all other SKSE plugins (syntax and autocomplete)

- Changeable color themes

- Autocomplete

- Syntax

- Plugins and more color themes are downloadable with the (free) Package Control. Plugins can be helpful for greater editing of scripts, and color themes are fun to play around with.

Cons:

- Autocomplete doesn't support definitions.

Setup for Sublime Text 2: Linky

I also highly recommend SSE (Skyrim Script Editor). It's newer than the others, but it's got way more features and is easier to set up. It's got all the same features as ST except plugins, and many more:

Note it's still being worked on and sometimes there will be bugs, like an autocomplete not fully autocompleting, that will cause your script not to compile properly. Thus I will recommend ST for now.

- Edit existing script

- Create new script from within the editor

- Quick compile with Ctrl+S

- Compilation error/success window

- Filter for opening script with options of "Starts with" and "Contains"

- Auto complete (SKSE support as well)

- Syntax highlighting

- Customization of highlighting colors from within the editor

- Clean, professional look

- Extreme customization of all features

- Easy to use

- Resizable/minimizable code and compilation result windows

- Highlighting of words that are the same as selected

- FileDiff tool to show differences between two scripts

- Bookmarking line feature

- Mark line as green/yellow/red

- Multilanguage support (currently English/French)

- Comment out current line feature

- Line cloning

- Column selecting

- Custom autocompletes

- "Draft" save (save without compiling)

- Code folding

- Macro recording

- Line numbers (toggleable)

- Export to "rtf" or "html"

- Various hotkeys for functions, like Go To Line, Replace, and many more

- Auto update feature or update from within editor (Help>About)

- Online help and support

- Tab functionality, including tab all selected lines

- Copy and paste functionality

- Spellcheck on commented out areas and strings in progress

- Etc.

Whenever you've got that set up, tell me (along with which text editor you've decided to use). Be sure to associate .psc files, which can be found in Data/Scripts/Source with your text editor of choice and when we do begin be sure to create your scripts and then edit by right clicking and selecting Open in External Editor.

Then tell me anything you were confused about on the tutorials and we'll begin from there. I'll explain what was confusing and we'll begin on a task of sorts - your first script. If you have any preference on what you want the script to do (unrelated to quests for now), please tell me. I'll take it into account as a first or later script to do, depending on complexity. Examples are a series of messageboxes w/ choices, a script on an activator to spawn a creature, a trigger box that when entered will disable a wall (or move the wall if we use a hidden door, but it has to contain the animations for this). There are many more, just tell me what comes to mind.

Edited by Mattiewagg

Share this post


Link to post
Share on other sites

I finished reading through those tutorials.  I already had Notepad++ set up, so I will stick with it for now to edit scripts.  I was confused by the word "auto" always being placed in property declarations.  Also I saw the word "Hidden" once.  Are they required for no reason, or do they cause something about that property to change?

As for what I would like to try to do, I would like to try making a spell that pulls the enemy or object that you cast it on towards you, so you can hit them with melee weapons.  I don't know if this is easy enough to start with, but it would be cool.

Share this post


Link to post
Share on other sites

I'll be explaining the auto thing quite soon, as well as hidden. Auto is basically a "default property" - one that can be read and written (got and set). There's a way to make it different than that, or do different things when written or read, and I'll be explaining that in one of the much later lessons, as it's rarely necessary. Hidden means that you can't set the value of the property externally (in the CK) like most properties, only within the script. You can't see it. It has its uses but is also uncommon and will be explained in detail later on.

I'm not very good at spells, since there's other set up required (other than just the script) - but I should be able to help you out on this one.

I'll write a tutorial for the script when I get a chance. Will probably be in a day-two days. The first tutorial of it will just be showing you how to do it and explaining the script. Then, I'll start teaching you the different parts of scripting and you will begin to write your own.

Edited by Matthiaswagg

Share this post


Link to post
Share on other sites

"Pull to me" spell script tutorial

Okay. We'll begin this by creating the effect for your spell (MGEF/Magic Effect), and the spell itself. Every spell is a combination of one or more effects, and it applies the effects appropriately when the spell is cast. I'm not going to give you a full tutorial on how spells work, because I'm not an expert on spells in the slightest. I've dabbled with them some - they're really not my thing. I do scripts and quests.

That said, let's begin. Load up the Creation Kit, and immediately save to make your own plugin. I assume you know your way around the CK a little - so you should be saving a lot. Go to Magic>Magic Effect. Create a new entry, and style it like so (with your own ID for the MGEF):

http://i.imgur.com/DLCJKlr.png

I'm not sure whether you'd rather have a projectile for the effect, and only make it work if the projectile hits, or just apply the effect to the actor being targeted. Choose whichever you'd prefer for Delivery, and if you choose Target Actor don't pay attention to the projectile part.
Aimed: Effect is attached to a Projectile which is then fired at the crosshairs. If it makes contact with a valid target, the effect is applied.
Target Actor: Effect is immediately applied to an Actor in the crosshairs. No projectile is fired. 

Check out Darkfox127's tutorial on Magic Effects for more info.

From there, you want to close the MGEF and then reopen it with OK. This will allow that Script area to be editable, so you can add your script. To make a new script, click the Add button in the scripts area, and choose [New Script], rather than adding a script from the game. Give your script a name - I gave mine myMGEFEditorIDMGEFScript as the name, which is decent naming conventions but you should figure out what is best for you. In BS provinces, we always use a prefix before any names (CYR:Cyrodiil, ELS:Elswyr I think, HF:Hammerfell, MOR:Morrowind, etc. You'll be informed of the one for the province you join). 

Then right click your script, and select Open in External Editor. This should open your script in NP++ with the appropriate syntax highlighting and such. If not, go to Skyrim/Data/Scripts/Source and be sure you associate NP++ with .psc files.

Paste this into your script, excluding the Scriptname part - that part should have the same scriptname as your script. Scripts must have the same Scriptname as the file name of their script, or it won't compile right. Always remember this.

Scriptname PullSpellEffectMGEFScript extends activemagiceffect  

Event OnEffectStart(Actor akTarget, Actor akCaster); names of parameters can be as you see fit, as long as you use the name you declared
	Float casterX = akCaster.GetPositionX() + 10.0; so they don't come TOO close to the PC, you may have to adjust the 10 part so they come at your preferred distance
	Float casterY = akCaster.GetPositionY() + 10.0; don't actually need to put these in variables, could be directly in the input parameters for TranslateTo but it's cleaner this way
	Float casterZ = akCaster.GetPositionZ(); don't want them to be up in the air
	akTarget.TranslateTo(casterX, casterY, casterZ, akCaster.GetAngleX(), akCaster.GetAngleY(), akCaster.GetAngleZ(), 100.0, 75.0)
	; From CK Wiki page: 
	; A movement speed parameter (afSpeed) of 1 is extremely slow - nearly imperceptible to the human eye. Starting at a an afSpeed of 100 and working up or down towards the desired speed is recommended.
EndEvent

As you can see, we have Events (effectively something sent when that thing happens in game, which the script can then "catch" and use) and Functions inside that event - things like GetPositionY(), which do something. We'll cover Events and Functions in the very first lesson. We see that we have two types of variables here - things like casterX, which are normal variables and can only hold a value of that type (Float is decimal, there's also Bool, Int, ObjectReference, etc.). Then we have parameters, which is data sent with the event - and inside those parentheses of the event. Regardless of whether or not you use the parameters, you MUST declare them. Parameters can only be used within that event. If a variable is declared within an event or function, it can only be used within that event or function.

So we're setting our variables to the position of the caster (person casting the spell) + 10, so the target NPC isn't moved literally to the position of the caster (inside them). You may need to adjust this offset until it looks alright. We then move the target to the caster's position that we just found, as well as their angle, at the inputted speed. Those, inside the parentheses of TranslateTo, are also parameters. You must input them in order for the function to take that information and use it correctly. The . in between akTarget and TranslateTo shows that TranslateTo is being called ON akTarget.

As I mentioned, I took some of the information from the TranslateTo page on the CK Wiki, which is an incredibly valuable source of information. You can find the page here: http://www.creationkit.com/TranslateTo_-_ObjectReference.  There is a page like that for almost every function and event, and a bunch of other information.

And then we end the event, so the script knows anything past that is not to be executed when that event is called.

We don't have any properties here, so I'll cover the Properties and Variables lesson right after Functions and Events, since they're used in most scripts.

So, you compile that script (NP++ should let you do it, not sure what key you set  quick compile to but use that one). Then go back to the CK, and we'll attach this MGEF to a spell. Go to Magic>Spells and make a new spell. Give it an ID, a name, and set the Type/Delivery to the same type as your MGEF. Then add your MGEF in the table of the spell area, by adding a new one there and selecting your MGEF's ID from the drop down.

Save that, and go in game. You'll need to use the console (Help "your spell name") to add the spell to yourself, then doing player.addspell xxxxx, replacing xxxxx with the number/letter combination ID that the help command gave you for your spell. Try it out, and report back if it works. It should, provided it's hitting the appropriate NPC.

(This tutorial for this spell didn't really teach you that much about scripting, unfortunately, so I might have you do another or just go on with the lessons - which would you prefer?)

Share this post


Link to post
Share on other sites

That works fairly well.  The speed was too low, so I cranked it up to 500.0, and then ran around pulling in spiders.  So far most of this is fairly close to other languages that I know, so we can probably continue with the lessons.

Edited by Treeaza
  • reaction_title_1 1

Share this post


Link to post
Share on other sites

Related Resources:

Variables and Properties

Properties and variables are things that are able to point to or “hold” values. Variables are only changeable and accessible within the script that declared them, whereas properties are available from any script ADD HYPERLINK, not just the one that declared them. Variables/properties can contain numbers, or things like Objects or Actors. You’re then able to modify the variable/property, directly modifying that value. You can also access the variable/property and rather than getting a constant value, get the current value of that variable or property.

Declaring Variables

Before you can use a variable or property in the script, you have to declare it. Declarations can go just about anywhere after the scriptname declaration.

Int myInt

That’s a declaration of a variable. As you can see, you have to give it a type and a name. You can also do:

Int myInt = 87

Which gives it a starting value of 87. Otherwise, it would be 0/false/0.0/NONE for other variables.

Declaring Properties

Property declarations are somewhat similar to variable declarations, though you can only declare properties outside of events and functions.

Int Property myIntProp Auto

That’s a declaration of a property. It needs that Property part. The Auto will be what you use ALMOST all the time. You can have different flags at the end, which I go over in Advanced Properties 2 ADD HYPERLINK.

Float Property myFloatProp = 20.0 Auto

That’s a declaration of a property as well, but with a default value. Properties are usually set outside of the script, however, by filling the property. That sets a default value, and is important because it allows you to set other default values – like making an Actor property equivalent to a specific actor, which you can’t do with variables. However, you can also make an Integer property have a default value of 16 just like a variable.

Declaration Location

If you declare your variable outside of any events or functions, it can be used anywhere in the script. If you declare it within a function or event, then it will ONLY be accessible within that function or event.

Setting Variables or Properties

To set a variable or property, you simply use the = sign:

Int thisInt

thisInt = 20

;for properties

Int Property thisInt Auto

thisInt = 20

Getting Variables or Properties

To get the value of a variable or property, you’ll have to use it in conditions or assign another variable to that variable:

thisInt = otherInt

myFloatProperty = myOtherFloatProperty

If x == y; to set, you use =. To compare, you use ==

That concludes this lesson.

Edited by Mattiewagg

Share this post


Link to post
Share on other sites

Lesson on Functions and Events

Resources:

All About Functions (highly recommend you read, as I'm going to have the functions part of this shorter since this is very extensive + examples and written by myself before)

Events Reference

Functions

As you probably know by now, functions make up a lot of your scripts. They make stuff happen, for the most part. Moving things, changing things, getting values, etc. Those are ALL functions. 

A function consists of 5 parts:

Type Function FunctionName(Parameters)
EndFunction 

The function type is used for functions that return values, not functions that only DO things and don't return values (if you have one that returns values and does stuff, it should have a function type). As you know, Show is a returning function. It returns an integer - the button chosen. Thus, it is an Int function.  If it weren't a native function (to be explained later), then it's function declaration would have looked like this:

Int Function Show(float afArg1 = 0, float afArg2 = 0, float afArg3 = 0, float afArg4 = 0, float afArg5 = 0, float afArg6 = 0, float afArg7 = 0, float afArg8 = 0, float afArg9 = 0)
     ;what the function does and returns
EndFunction 

 

The function part is just a function declaration, telling the code that THIS is a function. It's just like the "Property" part of property declarations. The FunctionName part is just like the PropertyName. The Parameters are variables that are passed into the function - so you can have an Actor parameter, Int parameter, etc. This parameter can be used within the code of the function, no matter WHERE you call it from, unlike with global functions (discussed later); which can only use the parameters and nothing from within the script they were declared in. So if I have the function HealthierActor, and it compares the healths of two actors, then I'd have to pass in the two actors as parameters:

Function HealthierActor(Actor actorA, Actor actorB); parameters can be named whatever you like
     If actorA.GetActorValue("Health") > actorB.GetActorValue("Health")
         ;whatever code you want here
     ElseIf actorA.GetActorValue("Health") < actorB.GetActorValue("Health")
         ;whatever code you want here
     Else; is equal
         ;whatever code you want here
     EndIf
EndFunction 

And then, you must close it off with an EndFunction, just like you would close off an event with EndEvent.

Now let's talk about Return values. You can have your function Return a value, which you can then use. You could assign an integer to the return value of a function that returns an int (or float, or bool, for that matter - see Casting though we'll talk more about it later if you want). Examples of Returning functions are functions like Game.GetPlayer(), which returns the Actor of the player so you can easily use the player in a script. You must have a function type if you want your function to return a value. So, while this will NOT work:

Function ThisIsAFunction()
     Return 10 + 10
EndFunction 

 

But this WILL:

Int Function ThisIsAFunction()
     Return 10 + 10
EndFunction 

 

You can also return the value of a parameter, global, variable declared within a function, or a property within a script (IF it is not a global function).

Read the Resource All About Functions for more examples, and info on Native and Global functions. 

Note that if you have a convenience function which is just there so you don't have to retype code a lot, it doesn't mean the code isn't still happening. If you call a function with 30 lines of code in it 100 times in a script, that's still 3000 lines of code being called (not necessarily a bad thing). It's just you typing out only 30ish lines. So it's not more performance friendly, but it's also not less so. It's the same as if you had typed out all the lines, except the file size is smaller and you don't have to type as much.

Events

Events are a bit simpler than functions. As I've said before, they're called when an event in the game happens. They often, but not always, include parameters. Parameters are variables sent along with the event, which you can manipulate within that event. (If you want to use a parameter throughout a script and not just in the event, then you can assign the value of one variable to the value of a parameter.) They look like this (events):

Event EventName(Parameters)
EndEvent

There's not a much that you don't already know about events, to be honest. If you have any questions about them, feel free to ask. There are a few exceptions/things to note, however:

- Don't pile up too much in an OnInit event. It can overload it. It's a rather fragile event, though I know of no others like it. If there's more than a few function/code being called in there, use a RegisterForSingleUpdate(0.1) and then put all that code in the OnUpdate event.

- You can call an event directly. So, you could just call OnUpdate() like it were a function, rather than RegisterForSingleUpdate, if you wanted. Or, you could call any other event and pass in it's parameters. Etc. I've not experimented with this much but I've heard from others more experienced than I, that it is possible.

That's all I can think of for now. If you have any questions whatsoever, want me to clarify on anything, etc. don't hesitate to ask. :D 

You'll be making your own script next.

Share this post


Link to post
Share on other sites

Great.

Hello guys, I need a scipt if it's possible !
 
I need a script for magical effect in ck for a custom spell.
 
Script : 
 
1. When release casted spell, script check if target if human and dead
 
2.1 if 1 is true targeted corpse disepear (or teleport un a custom cell) then add item1 in inventory
2.2 else show a notification in top left corner : 'Target Invalid'
 
Thx for help !

You should know all the events. Use the CK wiki (creationkit.com) to find the other functions. The List of Papyrus Functions should be good for CTRL+Fing through to find a keyword (i.e. searching dead to find the function to check if something is dead). 

Share this post


Link to post
Share on other sites

I can't figure out how to tell if the actor is human.  I've checked the CK wiki, but its information on Races is very limited.  Should I just have a bunch of properties of type Race so that the person using the script can set them themselves or is there a better way to tell what they are?

Share this post


Link to post
Share on other sites

I can't figure out how to tell if the actor is human.  I've checked the CK wiki, but its information on Races is very limited.  Should I just have a bunch of properties of type Race so that the person using the script can set them themselves or is there a better way to tell what they are?

​By human, just go with "is it an actor?". So, you can do this to check that:

If (target as actor)

This is technically casting, which we'll go over next. However, in this case - you could just make the spell target actor, but assuming it's not, you'd need that check. The variable is already technically actor, but it's just a good check in case. So you're basically checking - can this be cast to type actor? If yes, it'll be something. If no, it'll be NONE. If (target as actor) is just checking if it can be cast, not comparing it to something else. Alternatively, you could make Race properties for every human race (if we were going just humans allowed, not mer or beast), then do:

If (target == humanrace1) || (target == humanrace2) || (target == humanrace3);etc
;|| is logical OR, && is logical AND

 

Share this post


Link to post
Share on other sites

Here is my finished script:

 
Scriptname DestroyBodyTakeItemScript extends activemagiceffect

{Races of humans:}
Race Property nordRace Auto;
Race Property imperialRace Auto;
Race Property bretonRace Auto;

MiscObject Property Item1 Auto ;Item to add

Event OnEffectStart(Actor akTarget, Actor akCaster)
	if akTarget.IsDead() && (akTarget as Actor) ;Are they dead yet?
		Race targetRace = akTarget.GetRace();
		if targetRace == nordRace || targetRace == imperialRace || targetRace == bretonRace ;Are they human?
			akTarget.Delete();
			akCaster.AddItem(item1, 1, true)
		else
			Debug.Notification("Target Invalid")
		endIf
	else
		Debug.Notification("Target Invalid")
	endIf
EndEvent

 

 DestroyBodyTakeItemScript.psc

 

I haven't gotten to test it yet, because every time I go into the game and try to give myself the spell that I made with it, it says 'Compiled Script not saved'.  I went into the script in the Creation Kit, compiled it, and re-saved it, and it still won't work.  Any ideas?

Edited by Treeaza

Share this post


Link to post
Share on other sites

Have you attached the script correctly and new game? Also, make sure Scripts.rar in your Data folder is extracted (to your data folder). And ensure all the properties are filled:

http://skyrimmw.weebly.com/skyrim-modding/how-to-fill-properties-skyrim-modding-tutorial

The script is correct. ;) Two notes:

If you're not actually going to use a comment after a script line, you don't need the ;. It's not a full stop or anything in Papyrus - those don't exist. It's just for comments.

Also, you didn't need to store the target's race in a variable to compare it. It's actually better that you did (for threading purposes), since otherwise you'd be calling a function 3 times. Just want to make sure you know something can be compared directly to a returning function w/out being in a var. But if you are calling the function more than once to compare, as you are, storing in a variable is better.

Nice job. Gonna post a quick Script Habits lesson before we move on.

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

×