String Variables
A variable type added by Oblivion Script Extender (OBSE).
OBSE v0016 introduces the string_var datatype for representing strings of characters.
String variables can be declared and used like normal variables and can hold the return values from OBSE commands defined as returning a string_var. Their contents are preserved with the savegame.
String-related commands include commands to modify a string variable and commands to retrieve a game string and store it in a string variable. Additionally, many existing commands like SetName now have EX counterparts (i.e. SetNameEX) which can accept a format string and a variable number of arguments, including string variables.
A string variable should not be used until it has been initialized with a value, by using it on the left hand side of a call to sv_Construct or a command that returns a string.
An uninitialized string variable has a value of zero, which can be tested for in scripts. The value of an initialized string, on the other hand, is undefined and should never be modified directly by statements such as set someStringVar to 6 or using arithmetic operators.
Similarly, string variables should only be used to store strings, and the result of a string-returning variable should only (and always) be assigned to a string variable.
Creating and using string variablesEdit
Strings are created when you assign a string to a variable of type 'string_var'.
string_var string1 Let string1 = "Hello World"
String variables, actually, hold an internal ID of the string. The string itself is stored somewhere else in memory and is internally connected to the ID stored in the string_var. Understanding this structure may help in some situations.
Using LET to assign a string to a non-initialized string_var creates a new string in memory
Let string1 := “Hello” • string1 points to a newly created “Hello” string
Using LET to assign a string to an initialized string_var replaces the original string with the new string
Let string1 := “World” • Destroys the original “Hello” string • Creates a “World” string • string1 points to the “World” string
Using LET to assign a String_var to another string_var creates a new copy of the string
Let string2 := string1 • Creates a new “World” string • string2 points to the newly created “World” string • string1 still points to the same “World” string as before • string1 and string2 may be changed without affecting each other (as they are different strings)
Concatenating stringsEdit
Strings may be concatenated using the '+' operator.
You may use any combination of string_vars and literals
Let string1 = "Hello" Let string2 = "World" let string3 = string1 + " Wide " + string2
Using string vars in place of literalsEdit
String variables can be passed to any command expecting a string literal as an argument by prefacing the name of the variable with a dollar sign.
The variable can be a quest variable, specified as $quest.varname, or local to the calling script specified as $varname. Example:
string_var msg let msg := "Greetings from Stonekeep, " + player.GetName + "!!!" MessageBox $msg
This deprecates many of the Set...EX commands.
Additionally in v0017, support for string operations has been integrated into the language via OBSE expressions, which leaves functions such as sv_Construct, sv_Substring, etc. mostly deprecated.
Warning: using SET with string_varsEdit
Using SET to assign a String_var to another string_var copies the ID from one var to the other causing both variables to refer to the same string. For instance, in the following code:
string_var string1 string_var string2 set string1 to sv_Construct "First string" set string2 to string1 set string1 to sv_Construct "Second string" ; modifies both string1 and string2
both string1 and string2 end up containing "Second string." If this is not desired behavior, use LET to copy the contents of one string to another.
The problem is that SET was developed before strings were implemented, so it does not handle them well, so it is not prepared to destroy the previous string pointed by the string2.
Like in this example:
Let string1 := “Hello” Let string2 := “World” Set string2 to string1 • DOES NOT destroy the original “World” string originally pointed by string2 >> BLOAT
That “World” will stay in the savegame, unused and unreachable, until the mod is removed.
So, if you need to have two variables pointing to the same string, make sure you explicitly destroy the original string before assigning a new string with LET, like this:
Let string1 := “Hello” Let string2 := “World”
sv_destruct string2 Set string2 to string1
Destroying string variablesEdit
String variables persist in the savegame until they are explicitly destroyed or until the mod from which they originate is removed from the user's mod list.
In general, string variables should be destroyed after use unless it is necessary to save their values permanently.
In the following example, the string variable is used each time the scripted object is activated:
string_var refName ref activatingRef begin onActivate set activatingRef to GetActionRef set refName to activatingRef.GetName if (sv_Count "e" refName > 0) Message "Your name contains the letter e" endif set refName to sv_Destruct end
Because the value of the string variable is only needed temporarily, sv_Destruct is used to prevent it from being saved.
A string stored in a string_var will be destroyed when another string is assigned to that string_var.
Int n String_var MyString . . . Let n += 1 If n == 1 Let MyString := “This is a very very very very very very very very very very long string” Elseif n = 1000 Let MyString := “This is a short string” Elseif n = 2000 Sv_destruct MyString endif
In the above example the long string will exist for 1000 frames (or 1000 runs of the script) and will be in the savegame if the game is saved during this period, but will be destroyed when the short string replaces it in the string var.
The short string will exist for another 1000 frames (and will be in the savegame if the game is saved during this period) and will, then, be destroyed by the sv_Destruct.
So, to prevent those strings taking space in savegames it is good practice to destroy them as soon as possible.
Strings stored in arraysEdit
A string stored in an array (which is not a string_var) will always be destroyed when there are no references remaining to that array.
Array_var MyArray . . . Let MyArray := ar_construct array Ar_append MyArray “This is a string” Let MyArray := GetUserTime
In this example, the string “This is a string” will be destroyed when the original array is replaced by the array returned by GetUserTime.
Strings in user functionsEdit
A string stored in a string_var declared in a User Defined Function:
- Will be automatically destroyed if it is used to store an argument
- Otherwise it will not be automatically destroyed
Scn MyFunction String_var s1 String_var s2 String_var s3 Begin Function {s1} Let s2 := “aaaaa” Let s3 := “bbbbb” Sv_destruct s2 End
In this example:
- S1 will be automatically destroyed at the end of the function
- S2 will be explicitly destroyed by sv_destruct
- S3 will not be destroyed and will bloat the savegame with “bbbbb”s every time the function is called