Category talk:Scripting

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search

Script Limit[edit source]

Defining the Limit[edit source]

Is there a limit to the number of lines a script can contain? I'm currently editing a script with about 52 lines (including debug code to later be stripped), and the CS refuses to save changes beyond a certain point. If I click on the save button, and then try to edit the script editor, I get the "do you want to save this script" message; if I say "yes", it just returns me to the editor. If I say "no", it closes the editor but the changes are not saved.

It _appears_ that if I put any function below line 39, it causes a problem (endifs and ENDS are fine). Perhaps I'm just doing something wrong? Eallman 16:20, 4 April 2006 (EDT)

Dragoon Wraith TALK 21:02, 29 June 2006 (EDT): There is a limit. It's quite large for regular scripts, but result scripts it's only 1024 characters.
Dragoon Wraith TALK 16:44, 4 July 2006 (EDT): I have a script that hit the limit, which appears to be character-based rather than line-based. After hitting the limit, I copied it into Word and ran a Word Count, and here's what I got:
Pages                                 24
Words                              4,521
Characters (no spaces)            25,667
Characters (with spaces)          31,472
Paragraphs                           649
Lines                              1,296
I'm not sure which version of "characters" we should be looking at, but because I wasn't able to complete the line I was on, it definitely is character based.
ShadowDancer 20:57, 4 July 2006 (EDT): I wonder if its Characters (with spaces)? It seems to me that this number is close to 32,767 and might be a memory limit maybe with filesize overhead?
ShadowDancer 09:12, 11 July 2006 (EDT): K, I have the actual answer. The limit is 32,767 and its the number of characters including special characters i.e. the enter key. If you add the number of lines to the number of characters (with spaces), you end up with 32,768 and since there isn't a return after the last line, that is one less return which results in 32,767. It is probably just an artificial limit in the base programming (probably visual basic) creating the scriptedit box.

Extending the Limit[edit source]

Dragoon Wraith TALK 10:13, 11 July 2006 (EDT): I know little about how you would program the script editor, but is it possible to have a limitless box? Because I really would like to write a script about 5x or 6x the size of the limit...
ShadowDancer 12:17, 11 July 2006 (EDT): Umm, in theory? Yes. The trick is that they would need to change the coding of the construction set program (and possibly Oblivion depending on how it deals with the script file). I am going to assume that the construction set was built using visual basic (which may or may not be true). The problem comes from the use of the control (a text box I think) used to create the scriptedit window. This is why there is a limit on the amount of characters that it will hold (32,767). They would essentially need to rewrite the construction set and do something similar to MS Word so that more characters could be held in the scriptedit window. I don't know if that involves multiple "text boxes" or a completely different control, but that is essentially the issue.
After checking around a bit, short of someone writing a program to edit the .esp files and make the scripts in them fully readable and recompiled on save, I dont know how you would write a script longer than the current limit. And even then, Oblivion itself might have problems trying to deal with the script.
Dragoon Wraith TALK 15:28, 11 July 2006 (EDT): I was actually thinking about how plausible it would be for Bethesda to remove the limit, not a modder. Obviously a modder would have significant trouble doing so. Anyway, your answer makes it clear that changing it would be quite a hassle for them, so I can't hope for that.
ShadowDancer 18:00, 11 July 2006 (EDT): Thats not necessarily true. It is possible that only the construction set might need to be changed. The scripts in the mods are all in the .esp files so it all depends on how the game actually functions and uses scripts. And its quite possible that a 2nd party script editor could be written since the .esp file shows pretty much all of the script when opened in MS Word. There are a bunch on other characters that don't show properly or are other symbols maybe, but it looks like it is fairly consistant. It might even be possible to write as much as you can in the construction set and then open the .esp file and paste in the rest. The answer to that would require an experiment on the .esp file and would also test how Oblivion handles longer scripts.
Dragoon Wraith TALK 19:22, 11 July 2006 (EDT): (that was getting confusing, I reorganized things to make both conversations make sense - unfortunately that means being rather far to the right) Hmm... this certainly is interesting. I don't even have the know-how to test that, but I'd definitely be interested in the results.
ShadowDancer 19:48, 11 July 2006 (EDT): Do you still have the script that is at the limit? If so, send me a copy, and the additional that you want to add and I will see if I can load it up and make Oblivion run without crashing. Its just opening the .esp file in MS Word, click OK when it asks about the file, finding the script, and then doing a copy and paste of the additional script into the script in the .esp file. In MS Word most of the script is in plain text.

Dragoon Wraith TALK 11:05, 12 July 2006 (EDT): (can't take right-ness any longer) Why Word? Word's awful for coding, with margins and hidden characters and the like. A good plaintext editor would be better, I just used Word for the wordcount.

At the moment, the script is actually in MS Excel (you would not believe how much tedious typing this program can save a scripter), so I'll have to convert it to plaintext (copy and paste into Notepad, Replace tabs with spaces), but I'm actually pretty busy at the moment. I'll send it to you when I get a chance. Thanks for your help.

ShadowDancer 12:49, 12 July 2006 (EDT): Actually, I can imagine a great deal of typing that would be saved by that. I mentioned MS Word because I was still stuck in the character limit explaination mode as well as that being the first editor I used to open the .esp file and it seemed to work fine. As for using a plaintext editor, you are right about it probably being better. Normally thats what I use for coding HTML. The only issue I have with notepad is that there is a limit on the amount of data that notepad can hold. Wordpad actually works better since it can hold more data.
Dragoon Wraith TALK 13:48, 12 July 2006 (EDT): There are a number of very good programs available for code editting. I use Notepad mostly because I'm too lazy to try out the other ones.
ShadowDancer 14:05, 12 July 2006 (EDT): LOL! Its pretty much the same here. Wordpad is nearly identical to Notepad with the exception that it isn't hindered by the same character limit that Notepad has. There may be a limit to it, but I haven't run into it yet when opening random files.
For long scripts I use emacs, and the CS was made with Visual C++ (see start of RTL at 0x590aac)--JOG 13:00, 12 July 2006 (EDT)
Dragoon Wraith TALK 13:48, 12 July 2006 (EDT): I read Emacs's website, and while it seems a powerful tool, I didn't really see how you used it. Do you have it specially set up to help with TES scripting, or do you just use it as a text editor with extra features?
And what effect, if any, does the fact that C++ was used have on whether or not it would be possible to write longer scripts than usually allowed?
ShadowDancer 14:05, 12 July 2006 (EDT): Using Visual C++ or Visual Basic to build the construction set really doesn't make much of a difference (except for how the programming code is written and operates). For instance, Visual C++ runs faster than Visual Basic for visual display effects. As far as controls go, its pretty much the same in that the controls are usually pre-made and you drag and drop them to create forms and such (in this case, the scriptedit window). The other question to ask would be how much spacing are you putting into the script? Removing excess lines would shorten the number of characters but it is only one character per enter so it wont save much in spacing. Comments, on the other hand, could take up a large amount of usable space in the script due to the character limit.
Dragoon Wraith TALK 17:50, 12 July 2006 (EDT): Already considered that - but I haven't used many comments, and not really that many tabs, either. And even if I were to remove all of them... it's over 10,000 lines long now (this is the naming script).
For the record, though, I've already determined how to break up the script, so I don't need this. This is entirely out of curiousity for me (though it would save some work, I suppose).
ShadowDancer 18:47, 12 July 2006 (EDT): Thats OK, I enjoy trying to figure out stuff like this too. Besides at some point it might be necessary or just plain easier. I had figured that you would have already thought of that but just to be on the safe side I thought I would ask. You mentioned earlier that you had the script in MS Excel and then cut & paste it into Notepad. Out of curiousity, how do you get it from Notepad to the construction set after changing the tabs to spaces?
Dragoon Wraith TALK 10:59, 21 July 2006 (EDT): Uhm... Copy&Paste? I don't remove all the tabs, because I want to keep the indentation, but when you copy something from Excel and paste it into Notepad, it puts tabs in between columns. By removing the tabs, because of the way I have the Excel document set up, it creates properly written code that can be directly pasted into the CS.
By the way, would you still like to see the script?
ShadowDancer 15:34, 21 July 2006 (EDT): LOL! Yeah I was thinking about going in and just cutting out that question since I figured it out since I asked. Originally, I tried to do the fairly standard Alt-E C/Alt-E P which of course didn't work since the controls aren't set up like that in the CS. I grumbled a bit and forgot about it until you mentioned it (yes, I have been typing in scripts by hand for no reason) and then I went back into CS with the sole purpose of figuring it out a couple days ago. Needless to say, I have done more scripts in the last 2 days than I had done before I figured it out.
Sure, I would love to see it.

Ways Around the Limit (that don't involve 3rd party apps)[edit source]

Scruggs 19:30, 10 July 2006 (EDT) I would think it would be a limit of the compiled script, not the actual text, but i can't say that for sure. If you want to reduce the size of a script, though, you can transfer some of your if blocks into quest stages or dialog topics, setting up the conditions to do the work for you. Then just call setStage or Say to run the conditions. Say is useful when you need the results to run on the calling actor, which setStage won't allow.
Dragoon Wraith TALK 19:58, 10 July 2006 (EDT): I actually do have ways around it, but since I'm not sure how that would work... how would you use Say?
Scruggs 21:13, 10 July 2006 (EDT) Each dialog topic can have multiple responses, with each response having a different set of conditions. When you call Say, the calling actor picks the response(s) in that topic for which he passes the conditions, and runs the result script on himself. There is no text and no voice associated with the responses. A simple (and stupid) example: you created a spell that kills the target, if he belongs to any of the five joinable factions. You could either add a separate if-elseif to your script for each faction, or you could set up a topic with 5 responses filtered for each of the guilds. So the first response's condition would be getInFaction magesGuild == 1.00 and it's results would be kill. Calling Say myTopic from your script turns several lines of code into just one line.
Obviously, it's not a huge benefit when you're only testing for five conditions, but if you're approaching the limit for script length it could be very useful. I'm still trying to figure out if NPCs will say all of the responses within that topic for which they pass the conditions, or just the first one that matches. If they only speak one response, you could most likely chain them up by calling Say again in the results field. That would let you check for all conditions (such as checking for all factions to which a NPC might belong, instead of just one).
This, along with quest stage results for conditions/results that don't need to run on a specific target, is making the scripting for Oblivion Unscripted much easier, since I do a lot of randomly-generated stuff. It also makes it easier to add new conditions or change things around, without having to restructure your script. And it makes long scripts more compact and easier to read. I thought it might be useful to you given the size of your scripts.

Dragoon Wraith TALK 11:03, 21 July 2006 (EDT): Another issue here (for me) was transferring variable values from one script to the next when using multiple Magic effect scripts to get around the limitation on any single script - to do this, I used weightless amulets with a script to render them unequippable, with the Unplayable box checked, and then the script adds as many of them as the value of the variable. So like this:

First script:

AddItem "amulet" varName

Second script:

set varName to GetItemCount "amulet"

I just thought that could be helpful to someone else.

Why not using simply global or quest variables ??? Gamall 11:17, 21 July 2006 (EDT)
Dragoon Wraith TALK 12:01, 21 July 2006 (EDT): Because multiple actors would be affected by the spell at the same time, and so I needed them to keep track of these values locally. A global script could only support transfer for a set number of actors - this way can handle as many actors as there are in range, no matter how many that is. It also saves running a separate quest with a whole new script.
Gamall 12:33, 21 July 2006 (EDT) Ok, I get it. Better make sure the amulets weight nothing, though ;)
Dragoon Wraith TALK 12:53, 21 July 2006 (EDT): Oh, but of course! I changed the above to reflect that requirement.

If / Elseif / Else explanation[edit source]

Later: obviously not the case, since I just found a Beth script with about 150 lines.

Well, very strange. Apparently the problem was that I was passing an elseif without a specific parameter:

if var==1
   somecode here

      else if
         someothercode here

This SHOULD be a legal structure, and the compiler didn't seem to dislike it. BUt as soon as I changed it to

if var==1
....
  elseif var!=1


my saveprob disappeared. Now to debug the script itself, instead of the CS <G> Eallman 16:44, 4 April 2006 (EDT)


That's because else if implies some other condition. Try else instead of else if.--Tegid 12:51, 4 April 2006 (EDT)

if and elseif require conditions:
if (condition)
    effect
elseif (condition)
    effect
else
    effect
endif
Note the presence of the condition for both if and elseif; this is mandatory, and if it's omitted and still compiles, that's a compiler bug. (By the way, use four tildes to sign: ~~~~.) —Simetrical (talk • contribs) 21:13, 4 April 2006 (EDT)

DO'H! I'm forgetting by basic programming skills <G> Oddly, though, the compiler doesn't complain about this- the script just won't run <G> Acutally, there are a number of errors the compiler doesn't catch- I just found a typo where I'd substituted "77" for logical "&&", and nary a peep.

EA

ModAV and Negative Values[edit source]

But now I've run into another problem. I'm trying to build a script that will allow an item to give a scalar skill boost while it's in inventory based on the player's base skill (You get less benefit the higher your base skill is). Apparently, you can use PLayer.modav with a POSITIVE variable (player.modav var), but you can't decrement the same way (player.modav -var), at least I've found no syntax that the compiler will accept to do this- (I need to do this to "reset" the skill to its regular level). Am I correct in assuming this is a missing feature in the compiler, or am I doing something stupid again?

EA

Tegid 14:48, 6 April 2006 (EDT): Read the ModAV page again. From my understanding you merely need to set player.modav back to 0 to remove the effect. If that doesn't help, you can always use GetAV and SetAV to do temporary modifications.

Eallman 16:48, 6 April 2006 (EDT)

(thanks for the sig tip) Not according to the page:

"If you use ModActorValue in a script, the Script Modifier is adjusted, and ONLY a script can adjust it back. In other words, if you have a script do

player.modav health 100

you are also responsible for doing

player.modav health -100 ".

So, you need to SPECIFICALLY reduce the mod by an equal amount, BUT the compiler apprently won't accept a negative variable as a parameter, only a positive one.

The problem is constructing the script in sucha way that you gon't get a looped reference from player.getav. Working on it.

Eallman 18:19, 6 April 2006 (EDT)

Found it! To use a negative variable for PLayer.modav, you have to first set ANOTHER variable to the negative value you want to use:

var2= -var1 PLayer.modav var2

very Byzantine, but it does indeed work

Dragoon Wraith TALK 21:02, 29 June 2006 (EDT): You don't need to set a separate variable - you just can't use the negative sign in the function's argument (any more than you can use any other mathematical expression), you have to set it to the negative separately:
modav var
set var to -var
modav var
Would increase and then decrease by the same amount.

A bit off from the original topic: I don't have any problem using player.modav strength -2 eg in a script... a problem occurs in the console window though. Try using ModPCAttribute instead, I don't have any problems with this at all. Or if you want the effect to hit an actor: ModActorValue

Are Script Blocks Atomic[edit source]

--Tegid 15:19, 12 April 2006 (EDT) When I start executing a script on a particular object, is it guaranteed to finish with the block it is in before being interrupted by another script, or is there no such guarantee?

Eallman 18:50, 14 April 2006 (EDT)

Not even sure how you'd test this, without running a lOT of meesgae blocks by <G>. My initial reaction would be that this would be the case UNLESS you called another script from within the block, but that's gut feeling based on nothing in particular. If you called another script, it would surely intercept the rest of the block, and i'm nt _sure_ it would return correctly.


--Tegid 19:21, 14 April 2006 (EDT):How exactly would you call another script? You mean an Activate call? That just sets a flag to let the script parser know that the next time it runs through that objects script, it should run the activate block. See talk:Activate for details.


Editing Scripting Code[edit source]

Is there any possible way to, say, perhaps, edit the scripting code?

scn answerscript

short answer

float timer

Begin Gamemode

set answer to getanswer

if answer == 1

messagebox,"Yay! Where is it?"

elseif answer == 0

messagebox,"Oh no! I think I'll die if somebody (preferably Bethesda) doesn't make a program to do that!"

set timer to getsecondspast

endif

end

Begin gamemode

if timer == 1..............

Can you see why I want to edit it?Axle12693 18:40, 3 January 2007 (EST)

You want Oblivion Script Extender.
And while we're at it, why not check out some tips for wiki format so people can actually read your comments? ;) http://meta.wikimedia.org/wiki/Help:Editing Scruggs 23:35, 3 January 2007 (EST)

when i run the exe it say this:

You are using the original 0.1.0.288 version of oblivion, please upgrade to 1.1.0.511.


how do i upgrade? Axle12693 17:08, 4 January 2007 (EST)

So confused[edit source]

So I try to make my first script and I end up with this my only goal was to make this script kill you if endurance is less then 100 and it won't work I've try tons of stuff can someone tell me what I'm doing wrong, please and thank you--Candc4 19:52, 27 September 2011 (EDT)

Begin Unnamed 
OnPCEquip 
Short OnPCEquip
if ( OnPCEquip == 1 )
set OnPCEquip to 0  
endif  
; Checks for Scripted Item
if ( player->GetEndurance < 100 ) 
Player->Sethealth 0 
messageBox, "You Have been crushed by Scripted Item" 
; Kills player if endurance is less then 100 
End Unnamed
OK, so there are a few problems here. You seem to be assuming that script works like some other scripting languages, perhaps? Because you're not using Begin or End or the OnPCEquip blocktype correctly, which is your problem. You're also using player->, which is how some languages (C++, for one) would handle a similar operation, but script uses player. for that (as would C++ in other situations). Finally, there is no "GetEndurance" function, you have to use GetActorValue. I'd recommend reading My First Script and My Second Script for some useful tutorials in how the language works.
I also recommend that you use indentation to make your code easier to read. Anyway, your script should look something like this:
ScriptName Unnamed

short equipped ; don't use function names for variables

Begin OnPCEquip

  if ( player.GetActorValue Endurance < 100 )

    player.Kill ; Kill will kill the player

    MessageBox "You have been crushed by a Scripted Item."

  endif

End
Hopefully that will give you something to look at for help. However, in the future, this is not really the best place for trouble-shooting; the Forums are best for that. This would be more of a place to ask questions about specific articles, or where to find information. I am curious, however, how you tried to find information before posting; what you looked at and stuff (or where you looked and failed to find things), because your script doesn't look bad, just not written in Oblivion's scripting language. I'm curious where you got those ideas, especially if it was from this site (because I want to fix that).
Dragoon Wraith TALK 11:52, 28 September 2011 (EDT)
Ah yes it is not written for oblivion it was written for morrowind, making "Player->" correct because "Player." is a oblivion command along with "kill" I also believe "Player->Sethealth 0" is equal to the "Kill" command of oblivion, please correct me if I'm wrong, also is this site for elder scrolls games in general or is the site only for oblivion, I also did reasearch scripting I got my info from [1] you also say my script looks like it works with C++ does morrowind scripts run using C++ --Candc4 13:52, 28 September 2011 (EDT)
Five years ago, I would have recognized that instantly, but it's been a long time since I did any Morrowind scripting. Anyway, yes, they've changed the scripting language in quite a few places. The blocktypes, . instead of ->, and the ref variable type are probably the most notable, but there's also things like GetAV where they changed it from being several different functions to just one where you pass what value you're interested in. GetPos and SetPos are a similar story, IIRC (Morrowind had GetPosX, GetPosY, GetPosZ, right?)
As for Kill, you could also use SetAV Health 0, similar to Morrowind, but the kill command is a little more convenient. Some modders like to use both just to be certain everything works correctly.
Anyway, those tutorials should help you out.
Dragoon Wraith TALK 12:50, 29 September 2011 (EDT)