Jump to content

DOWNLOAD MODS

Are you looking for something shiny for your load order? We have many exclusive mods and resources you won't find anywhere else. Start your search now...

LEARN MODDING

Ready to try your hand at making your own mod creations? Visit the Enclave, the original ES/FO modding school, and learn the tricks of the trade from veteran modders...

JOIN THE ALLIANCE

Membership is free and registering unlocks image galleries, project hosting, live chat, unlimited downloads, & more...

Class #1 - Start here for Basics


WillieSea
 Share

Recommended Posts

Programming Class #1

This is the first draft of the class. It should get you going with scripts in Skyrim.

Post your questions and I will try to answer them. Feel free to answer others questions if you think you know the answer.

Your first script that does something interesting with the player.

I will be going over a lot of stuff not related directly with scripting in this first lesson. But this lesson will show you how to get references attached to scripts and return button presses.

Cipscis has also made a beginners tutorial that you might find some useful information in.

Link to Cipscis tutorial: http://www.cipscis.com/skyrim/tutorials/beginners.aspx

Lets jump right in and create a script that asks the player a question, and then does something based on the players response.

The scripting as it was called in previous construction sets has advanced to a full programming language using Papyrus. This has caused the scripting to now be done outside the construction kit (CK) so there are extra steps you will need to take to get your 'code' attached to objects in the game.

1. First, lets open the CK and load up 'Skyrim.esm'.

gallery_85_79_35468.jpg

2. After its done loading, which can take 3 or 4 minutes, you will be able to find the object we will attach the script to.

gallery_85_79_70488.jpg

You will need to locate the 'Activators' folder. Using a filter is not necessary but it can help you find things your looking for. We will be making a copy of "ImpButton01"

Simply double-click it and its base properties window will open. Give it a new 'Editor ID' name and click the OK button. When it asks if you want to "Create a new Form", click the Yes button.

Congratulations, you just made your first unique object.

gallery_85_79_71735.jpg

This is the "activator" object properties window. Each object type has its own properties you can set. As you can see, Activators allow scripts to be attached to them.

3. Okay, we now have the object we will place the code on, lets write the code now.

Lets open the Papyrus Script Manager so we can create a new code object.

gallery_85_79_41768.jpg

Select from the toolbar, >Gameplay >Papyrus Script Manager

gallery_85_79_12438.jpg

You may notice you have a 'filter' box here too. You can use it if you like.

Right-click in the script window and select 'New'

gallery_85_79_12438.jpg

You will now need to give your script a name, and what type of script it will be. In our case, we will create an "ObjectReference" script.

gallery_85_79_964.jpg

You can find out what to put here by referring to this page, since we want to do an 'OnActivate' script, you see its an ObjectReference type of event.

Index page: http://www.creationkit.com/Category:Events

OnActivate page: http://www.creationkit.com/OnActivate_-_ObjectReference

If you like, you can type something into the 'Documentation String' box to help you remember what the script is supposed to do.

Click the OK button to create the code base object.

:smarty: Smarty Says: Your new code will NOT show up in the box. You need to close the Papyrus Script Manager window and reopen it again to see your new code object.

4. Lets write some code!

Select your script from the list and then double-click it. You may notice that the text you typed into the Documentation String shows up in a balloon window when you hover over your script.

gallery_85_79_42867.jpg

It should open up in Notepad, or if you installed it, Notepad ++. If you get an error, you need to associate the code files with one of these two programs.

Link to setting up Notepad ++: http://www.creationkit.com/Notepad%2B%2B_Setup

You will then be presented with your default code.

gallery_85_79_37468.jpg

Instead of trying to write everything you need by hand, lets make the CK do it for us. Close the code text box for now and go back to your button properties window.

gallery_85_79_71735.jpg

On the right is the 'Papyrus Scripts' window with one script attached, 'TrapLever'. Select it and click the Remove button.

Then click on the Add button and click on your code and click the 'OK' button. Your code is now attached to this button.

gallery_85_79_12579.jpg

5. Attaching message properties to our script/code

Back on the button's properties window, now select the script you just added and click on the 'Properties' button. You will be presenting with the script properties window.

gallery_85_79_41339.jpg

We know we need at least 3 message box properties added, so lets do that now.

gallery_85_79_31222.jpg

For the 'Type' drop down list, choose 'Message'.

The 'Name' allows you to give the property a 'name' that you will use in the script to point to this message.

And as before, the Documentation String allows you to say what this is with balloon windows.

Do this again for your 'Yes' response, and again for your 'No' response messages.

gallery_85_79_18091.jpg

6. Making the messages

gallery_85_79_21758.jpg

Select the message folder and right-click in the right messages area and select 'New' to create a new message.

This is an empty message box which you will fill out with the messages you will use in the script.

Give your new message a new ID and make sure the 'Message Box' is checked.

If you enter text into the 'title' box, it will display on the top of the message box.

In the Message Text section, the text you enter here will display in the main body of the message window.

gallery_85_79_8006.jpg

Since our first message will be the "Question" messagebox, you will also need to add 'Menu buttons'. You can add them by right-clicking in that box.

You then enter the 'Item Text' for the message button. Do this twice, one for the yes and one for the no.

gallery_85_79_44028.jpg

The Yes and No message box will not contain the Menu buttons, so leave them empty.

gallery_85_79_40625.jpg

You should now have your three messages for the script.

gallery_85_79_15885.jpg

7. Attaching the messages

Your probably thinking, this is sure a lot to go through for a message box? I would agree but its worth it.

Go back to the properties of your activator button, select your script and click on the 'Properties' button. Click on one of the button properties and then click the 'Edit Value' button.

gallery_85_79_34841.jpg

Then from the drop down list, select the correct message for each Property.

gallery_85_79_16450.jpg

You have now attached your messages to the script! :thumbsup: Good work!

8. Finishing the script

Now to finalize the script with the 'action' of what we want to do. We will be pulling the messageboxes in and using them along with getting which button the player selected and acting on it.

Pull up your script and lets edit it. >Gameplay >Papyrun Manager and double-click your script in the list.

It should look similar to this:

Scriptname Class01Script extends ObjectReference  
{Script for TESA Class 01}

Message Property Question Auto
{Ask the player a question}

Message Property Yes Auto
{Player answered Yes}

Message Property No Auto
{Player answered No}[/code] Since we are activating a button, we need to use the 'onActivate' event type. So, lets add that line to the bottom of your script.
[code]EVENT onActivate(objectReference akActionRef)
Reference Link to OnActivate: http://www.creationkit.com/OnActivate_-_ObjectReference "akActionRef" is a variable name you will be using in the script below. It holds the reference of the actor that activated the object this script is attached to. For clarity, you should leave it named as is. Now we want to make sure the actor that is activating this button is the player. You do that with an 'IF' condition check.
	If akActionRef == Game.GetPlayer()
Note here that we are checking if the variable 'akActionRef ' is the player. :smarty: Smarty says, if you use a double equals between two variables, you are checking for a condition, like do they equal. If you use a single equal between two variable, you are making the variable on the left equal the variable on the right.
		Button = question.show()
Now we will display the message we created that is the 'question' and has the button index on it. Also note that we have 'button =' in front of this message box. This will automatically return the index number of the button that the player clicked. This is MUCH easier than it was in Oblivion. Since you are using a variable called Button, you also have to define that variable. Above the OnActivate event line, lets define it as such:
int Button

EVENT onActivate(objectReference akActionRef)[/code] Now to figure out what the player wants to do.
[code] if Button == 0
Yes.show()
Game.GetPlayer().AddItem(Gold001, 1000, true)
Next, we will check the value in the variable 'Button'. If the value is 0 (remember when we made the question messagebox above, each button we created had an index number to the left of the text) then we know the player selected 'Yes'. Reference Link to AddItem: http://www.creationkit.com/AddItem_-_ObjectReference Now lets finish it up.
		elseif Button == 1
No.show()
endif
EndIf

endEVENT[/code] You would use the 'elseif' or just an 'else' since there are no other conditions we are checking for. But for clarity I use the index number for all my Button checks. I display the 'No' message and nothing else. I then finish the script up closing all the IF conditions with the 'endif' command. And to close my OnActivate event, I use the 'endEVENT' command. Now, this will not work since the script is saved outside of the CK. It does not know what the object 'Gold001' is. So we have to attach another property to the script (as explained above when you added messagebox properties to the >Activator Button object). I could not find anything related to how to get this to work, but in playing around with it, I found this seemed to work: This time we will add a 'MiscObject' property and give it the name, 'Gold001'.
[code]MiscObject Property Gold001 Auto
Save this and go back to your script. You will notice the property you just added was placed at the bottom of the script. I moved it above my OnActivate event. Now all you have to do is place your >Activator >Class01Button01 into the world somewhere where you can find it. Do that and test it in-game. You should find that when you answer yes, you get 1000 gold and nothing when you answer no.
Scriptname Class01Script extends ObjectReference  
{Script for TESA Class 01}

Message Property Question Auto
{Ask the player a question}

Message Property Yes Auto
{Player answered Yes}

Message Property No Auto
{Player answered No}

MiscObject Property Gold001 Auto

int Button

EVENT onActivate(objectReference akActionRef)

If akActionRef == Game.GetPlayer()
Button = question.show()
if Button == 0
Yes.show()
Game.GetPlayer().AddItem(Gold001, 1000, true)
elseif Button == 1
No.show()
endif
EndIf

endEVENT
[/code]

  • Upvote 2
Link to comment
Share on other sites

This looks really useful. However, I have a newbie-style question.

How would you attach this sort of event (Game.GetPlayer().AddItem(Letter, 1) to a dialogue topic in a quest object? Assuming that this is not part of an actual quest, it's just a script that runs when a player selects a certain dialogue option and it places an item such as a note in their inventory.

Link to comment
Share on other sites

Well, I have not looked much into quest scripting yet. But taking a quick look, there appear to be a few sections you can check.

Look at quest BQ01.

On the 'Quest Stages' tab, index 10, you have an AddItem of a letter in the script box.

If you click the properties button, you will see the letter defined as a property.

On the 'Scripts' tab, you have the 'properties' that were added to the scripts. If you look at the quest script properties, 'QF_BQ01_00095125, you will find the Letter Alias defined as a property. This is probably another way to look at all of the scripts attached to the quest. Dunno.

What you want to do may have something to do with these tabs.

Link to comment
Share on other sites

This looks really useful. However, I have a newbie-style question.

How would you attach this sort of event (Game.GetPlayer().AddItem(Letter, 1) to a dialogue topic in a quest object? Assuming that this is not part of an actual quest, it's just a script that runs when a player selects a certain dialogue option and it places an item such as a note in their inventory.

The "Topic Info" has a slot for Papyrus fragments that are executed either at the beginning or end of the dialogue line. You can insert that code snippet there. Defining properties in fragments is a bit more annoying than in normal scripts though. I still haven't fully figured out that part. Only got it working once.

Link to comment
Share on other sites

  • 2 weeks later...

Well It's not working out for me. Tried the "hello world" one first for a primer and Skyrim just CTD at menu screen, same with this script. Any suggestions?

K got the script to work, seems there's something amiss when I compile from note++. I used the CK to compile and no CTD.

Edited by daverboon
Link to comment
Share on other sites

  • 2 months later...

Very well writen tutorial, I am a complete noob to scripting and had no trouble, many thanks.

In fact it was so well writen I felt comfortable modifying it to better soot my needs, however i do have 1 noobish question.

If I add to the number of possible choices (more then yes/no), eventually there are too many to display "side by side"

and only the middle choices fit on screen.

so my question is, how would i get my choices listed "as a list"

example

from:

yes no maybe sometimes allways Let me think about it

to:

yes

no

maybe

sometimes

allways

let me think about it

Link to comment
Share on other sites

You will need to make a second message, putting half the questions on each.

The first message will also have a 'Next' option.

Message 1: "question"

Give 100 gold

Give 200 gold

Give 300 gold

Give 400 gold

Next Menu

Message 2: "question2"

Give 500 gold

Give 600 gold

Give 700 gold

Give 800 gold

Cancel

EVENT onActivate(objectReference akActionRef)
If akActionRef == Game.GetPlayer()
Button = question.show()
if Button == 0
Game.GetPlayer().AddItem(Gold001, 100, true)
elseif Button == 1
Game.GetPlayer().AddItem(Gold001, 200, true)
elseif Button == 2
Game.GetPlayer().AddItem(Gold001, 300, true)
elseif Button == 3
Game.GetPlayer().AddItem(Gold001, 400, true)
elseif Button == 4
Button2 = question2.Show()
if Button == 0
Game.GetPlayer().AddItem(Gold001, 500, true)
elseif Button == 1
Game.GetPlayer().AddItem(Gold001, 600, true)
elseif Button == 2
Game.GetPlayer().AddItem(Gold001, 700, true)
elseif Button == 3
Game.GetPlayer().AddItem(Gold001, 800, true)
elseif Button == 4
;Cancel so do nothing
endif
endif
EndIf
endEVENT[/CODE]

Edited by WillieSea
Link to comment
Share on other sites

Thanks WillieSea,

Wow what a fast response.

I already have my first Sub Button fully operational, just a matter of rinse and repeat from here.

When finished I'll have a button I can place anywhere I want,

that will allow me to change into whatever clothing I load it with (whether it is in my inventory or not), nice

I'll never have to Bring a party dress to a party again, so to speak.

(this version will have about 12 options, but with what you showed me its possible to go to infinity I guess)

Link to comment
Share on other sites

  • 2 months later...

Just finished up and tested it in game, the button won't activate. It just sits there....menacing... as i mash the "E" key.

Y U NO ACTIVATE BUTTON *me gusta face*

Here is a copy of my script, almost identical:


Scriptname Class01Script extends ObjectReference  

{Script for TESA Class 01}


Message Property Question  Auto  

{Ask the player a question}


Message Property Yes  Auto  

{Player answered Yes}


Message Property No  Auto  

{Player answered No}


MiscObject Property Gold001  Auto  


int Button


EVENT onActivate(objectReference akActionRef)


If akActionRed == Game.GetPlayer()


Button = question.show()

if Button == 0

Yes.show()

Game.GetPlayer() .Add Item (Gold001, 1000, true)

elseif Button == 1

No.show()

endif

EndIf


endEVENT


If it helps, when i tried to add the miscobject gold001, it failed to add it, but it was in my script afterwards regardless.

EDIT: Just compiled using CK, and it failed to compile Class01Script.psc

Edited by TripleSixes
Link to comment
Share on other sites

It should give you an error message, with line and column number of the error.

One error I see right away is you have a space before the period. And a space in the command. And a space after the command...

Programming languages do not like spaces where there should not be one.

Game.GetPlayer() .Add Item (Gold001, 1000, true)

should be

Game.GetPlayer().AddItem(Gold001, 1000, true)

And if your not getting the 'activate' option, you need to use an object that 'can' be activated.

Link to comment
Share on other sites

  • 2 months later...

I am not a 'dialog or quest' user or maker, but I know a little.

From what I understand, you have a 'talk box' which is usually an invisible or hidden npc which you make talk, how I am not sure. You might look into the SAY command.

You start an AI package in many ways, usually by putting a condition on the package, then making the condition true. Then you can force a re-evaluation of the NPC's AI packages using EvaluatePackage.

Link to comment
Share on other sites

  • 3 weeks later...

Thank You WillieSea!!!!! Had one problem, I didn't edit property to fill value on gold, but once I did that it worked like a charm... Yay ME, I'm Edjumacated now.

Seriously though, it's funny how accomplished I felt after following your hand holding tutorial on this basic script, thank you!!! :bowdown: One Noob question though.. ummm how would I add sound via this script so that when the gold is given I hear the coin sound?

Oh and 7-Eleven thanks you also, since I had to buy a 2-litre of Diet Coke and some Chocolate Donuts to stay up all night learning this... lol

Link to comment
Share on other sites

Sounds are objects, just like anything else in the game.

You add it just like you did the >Activator >Button.

Except its a >Sound Marker (found in the Audio folder). You can use the filter to find 'gold' and there you have it.


Sound Property ITMGoldUp Auto
[/CODE] Now you can use the Play command to make the sound play in-game.
[CODE]
ITMGoldUp.Play(Self)

Edited by WillieSea
Link to comment
Share on other sites

Sounds are objects, just like anything else in the game.

You add it just like you did the >Activator >Button.

Except its a >Sound Marker (found in the Audio folder). You can use the filter to find 'gold' and there you have it.


Sound Property ITMGoldUp Auto

Now you can use the Play command to make the sound play in-game.

ITMGoldUp.Play(Self)

You are the man WillieSea! Had some problems getting it to work, but it was not your instructions it was my lack of experience and overthinking it.... lol Thank You, works perfect now!

Link to comment
Share on other sites

Dont worry, you will get the hang of it the more you use scripts.

Should you be interested, the mod 'Levelers Tower' is full of scripts that you can look over and if you see something you like, your welcome to them.

My mods are all free to copy and use.

Edited by WillieSea
  • Upvote 1
Link to comment
Share on other sites

Quote:

"Select from the toolbar, >Gameplay >Papyrus Script Manager"

When I click on Papyrus Script Manager, my CK crashes. Always. :shrug:

I have updated the CK to 1.8.151.0

Edit:

Uninstalling and re-installing the CK fixed this. Using Google I found out that I was not alone with this bug.

Edited by Tamira
Link to comment
Share on other sites

Dont worry, you will get the hang of it the more you use scripts.

Should you be interested, the mod 'Levelers Tower' is full of scripts that you can look over and if you see something you like, your welcome to them.

My mods are all free to copy and use.

Thank You WillieSea, I will tear into them with glee... ;)

I am trying to write a script to make a book that when read lets you trade a dragon soul for 1 level in each skill of a path of your chosing... YES I know this has been done already in other mods, but I love the idea and want to incorporate it into mine too.

And YES I asked permission to use the script but was turned down, and since I am respecting the persons wishes as should be, I am not even looking at the script he wrote. So I am using the denial to motivate myself to learn more about scripting so in the future I can freely share my work as you do. :) So again, Thank You for letting me go thru and use your scripts! I will use what I can and learn from all of them. I know what I want the script to do, I know it can be done because it has been done, so now it's all about learning how to write it to work right.... :)

Link to comment
Share on other sites

  • 1 month later...

Thanks for this, WillieSea, and also for your generous attitude to sharing your work.

The first time I compiled it I did the same as another commenter and didn't edit the Gold001 property, so nothing happened when I pressed the button. The second time, after I filled the property and reloaded, still nothing happened. Is this an example of updated scripts not overwriting their older versions in your savegame that I've heard of, or is it more likely that I did something wrong?

It finally worked when I created a new script with the same code and add that one to the button, but when I use it in-game I have to press my replies twice - I press the physical button and then I have to press each answer buttons twice. What would cause that?

Link to comment
Share on other sites

Sometimes your save game can retain information from old scripts which can mess up changes to the script. Its called a 'dirty save game'. You should ALWAYS use a save game that has NEVER had the mod your working on activated when the game was saved. This is whats called a 'clean save game'.

If your getting the 'question button' twice, your probably calling it twice. Can you post the script your using?

Link to comment
Share on other sites

Here's the code:


Scriptname Class01Script3 extends ObjectReference


Message Property Question Auto

{Ask the player a question}


Message Property Yes Auto

{Player answered Yes}


Message Property No Auto

{Player answered No}


MiscObject Property Gold001 Auto


int Button


EVENT onactivate(ObjectReference akActionRef)

If akActionRef == Game.GetPlayer()

Button = Question.Show()

If Button == 0

Yes.Show()

Game.GetPlayer().AddItem(Gold001, 10000, false)

ElseIf Button == 1

No.Show()

EndIf

EndIf

endEVENT


Link to comment
Share on other sites

Are you even getting the yes or no message displayed?

When you setup your 'yes' and 'no' message, are you pointing to the correct message on the scripts 'properties'?

If you point to the question message again for them, you will see the message the second time, but nothing would happen on a selection.

Also, make sure you only attached the script to the button once. You can place more than one script on an object and they will all run. So if you placed this script on the object twice, it will 'appear' to run twice.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...