Difference between revisions of "Cross Script Variables"

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
imported>Bruneauinfo
m
imported>Bruneauinfo
(Simplified the beginning and took out some unnecessary information.)
 
(20 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{Discussion}}
A time may come when you will wish to have a repository to store variable values that can be read from and written to by any script. This article addresses a basic method for not only storing and retrieving non-float numeric values, but object references as well. This could prove very handy when creating dynamic game scenarios.  
 
If you are looking for a way to get the value of a variable from one script running on one object to a script running on another object I imagine you may have entered the above article name or something similar to it in your search for an answer. As you first begin writing mods you will probably notice that Oblivion assumes the only variables that should be universally accessible are the Global variables. This would not be a terrible thing except that all Global variables are treated as ''floats''. (See [[Floating Point]].)
 
It is possible a time will come in writing a script when you will wish to have a repository to store variable values that can be read from and written to by any script. Fortunately this is possible. This article addresses a method for not only storing and retrieving non-float numeric values, but object references as well. This could prove very handy when creating dynamic game scenarios.  


== The Basics ==
== The Basics ==
Line 9: Line 5:
A scenario for creating and testing this type of functionality includes at least three features:  
A scenario for creating and testing this type of functionality includes at least three features:  


1 - A quest script that acts as the database for storing values. (One might want to read over the article [[Quest scripts]] to get familiar with the source of this idea.)
1 - A script that acts as the database for storing values. In this article a Quest Script will be used to demonstrate this.  


2 - A script that writes a value to one of the variables in the "database" Quest script when it is activated.  
2 - A script that writes a value to one of the variables in the "database" Quest script when it is activated.  
Line 19: Line 15:
=== The Quest Script ===
=== The Quest Script ===


The quest script acts as a database. Unfortunately Oblivion doesn't provide the powerful database features you would find in an SQL database service. Still, it does provide the quest script where the most basic database functionality can be achieved - a command syntax for reading and writing to its variables from external scripts.
The quest script acts sort of like a very basic database. The next two scripts will demonstrate the command syntax for reading and writing to the quest script's variables from other scripts.


The script:
The script:
Line 33: Line 29:
  short ShortVar ; integer values can be stored and retrieved
  short ShortVar ; integer values can be stored and retrieved


  begin GameMode
  begin GameMode ; begin block is not required


  ; you don't have to put anything in here
  ; you don't have to put anything in here
  ; in fact you probably shouldn't. nothing is required here.
   
  ; if you set the value of a variable here it will be locked in
  end ; if begin block is not used the 'end' is not required either.
; instead you will set the values of these variables from outside scripts 
 
end


</pre>
</pre>
Line 46: Line 39:
Make sure you set the Script Type as "Quest" in the script editor window and then save your script.  
Make sure you set the Script Type as "Quest" in the script editor window and then save your script.  


The script is very simple. You just declare all the variables you need for storing values. Too bad there isn't a way to create variables dynamically as with an SQL database. Still, this functionality is much better than nothing at all!
The script is very simple. You just declare all the variables you need for storing values.  


====Notes====
====Notes====


*You should NOT assign starting values to your variables. If you need to do this, do it using some other method. Setting values within this script essentially locks the value in. There may be a workaround for doing this, but more testing will be required.
*If you assign starting values to your variables in the "database" script use a doOnce variable to keep the variables from being reset to their initial values on every frame refresh. Setting values within this script's Begin-End block without a doOnce will essentially "lock in" the values to their initial setting.


*The variable names listed in the script can be named whatever you like - preferably something meaningful to their purpose.  
*The variable names listed in the script can be named whatever you like - preferably something meaningful to their purpose.  


*You must declare a variable in the quest script and compile it BEFORE you can reference them in the read/write scripts described below. If you attempt to code your read/write commands and the variable has not yet been declared in the quest script you will receive a compiling error in your read/write script. (''specifically this error message will state that your variable is an unknown variable or command even though you have declared the variable already within the read/write script.'')


The next part of this step is to create a quest. You can read up on the steps for creating a quest on the wiki. Just keep in mind that the only setting needed for creating this functionality is the "Script" setting under the ''Quest Data'' tab. Once you create and name your quest select your quest script from above under the ''script setting'' for the quest. (''For these examples the quest is named '''MyQuest'''''.)
 
The next part of this step is to create a quest. You can read up on the steps for creating a quest on the wiki. Just keep in mind that the only setting needed for creating this functionality is the "Script" setting under the ''Quest Data'' tab. Once you create and name your quest select your quest script (as seen above) under the ''script setting'' for the quest. (''For these examples the quest is named '''MyQuest'''''.)


==== Notes ====
==== Notes ====


*You do not need to start the quest! The values within the quest can be written to and read from even if it is never started. And anyway it saves on CPU cycles.
*You do not need to start the quest. The values within the quest can be written to and read from even if it is never started. However, if you set initial variable values in your Begin-End block then you will have to start the script at some time to set those values. Once set you can stop the script with StopQuest.
 


=== Storing a Value ===
=== Storing a Value ===
Line 79: Line 73:
  begin onActivate
  begin onActivate
   
   
   set "MyQuest".refVar to "ObjectReference" ; or some reference variable
   set MyQuest.refVar to ObjectReference ; or some reference variable


   set "MyQuest".floatVar to 1234567890 ; or some float variable
   set MyQuest.floatVar to 1234567890 ; or some float variable


   set "MyQuest".ShortVar to 2012 ; or some integer variable
   set MyQuest.ShortVar to 2012 ; or some integer variable


  end
  end
Line 90: Line 84:


That's it! Now associate this script with some object that can be "activated". When the player or an actor activates the object the values listed above will be assigned to the script variables in the quest script.  
That's it! Now associate this script with some object that can be "activated". When the player or an actor activates the object the values listed above will be assigned to the script variables in the quest script.  
It's very important to notice where quotes were used in the example script. These are '''required'''. If the quotes are not used the script will fail to work properly. Yes, the script will compile, but the values will not be written to the quest script. References as well as the reference for the quest require these quotation marks. However, in the case of a reference variable quotes are only required when setting the value of the reference variable.
set "MyQuest".refVar to ThisReferenceVar


=== Reading a Value ===
=== Reading a Value ===
Line 118: Line 108:
begin OnActivate
begin OnActivate


set refVarRetrieved to "MyQuest".refVar
set refVarRetrieved to MyQuest.refVar


set floatVarRetrieved to "MyQuest".floatVar  
set floatVarRetrieved to MyQuest.floatVar  


set ShortVarRetrieved to "MyQuest".ShortVar
set ShortVarRetrieved to MyQuest.ShortVar


MessageBoxEx "See my reference: %n See my float: %g See my integer: %.0f", refVarRetrieved, floatVarRetrieved, ShortVarRetrieved
MessageBoxEx "See my reference: %n See my float: %g See my integer: %.0f", refVarRetrieved, floatVarRetrieved, ShortVarRetrieved
Line 130: Line 120:
</pre>
</pre>


Again the quotes around the name of your quest are critical for this to work. Also, if you use this script exactly as written the message box will show the name of your reference rather than the reference. See [[MessageBoxEx]] for more. But the reference value is there and ready for use.  
If you use this script exactly as written the message box will show the name of your reference rather than the reference. See [[MessageBoxEx]] for more. But the reference value is there and ready to use.


== Practical Applications ==
== Practical Applications ==


So one might be wondering where functionality like this might prove useful. If you're just writing simple mods this type of functionality may seem a bit excessive. But take as an example a mod where the player will only belong to one faction (''other than the player faction of course.'') Oblivion is designed assuming the player might be a member of many factions. But what if your mod required and only allowed the player be a member of one faction? And what if the relationships between factions was critical to the playing out of your mod? In this situation you might find yourself writing scripts where you would have to do a long series of repetitive checks like these:
So one might be wondering where functionality like this might prove useful. If you're just writing simple mods this type of functionality may seem a bit excessive. But take as an example a mod where the player will only belong to one faction (''other than the player faction of course.'') Oblivion is designed assuming the player might be a member of many factions. But what if your mod only allowed the player be a member of one faction? And what if the relationships between factions was absolutely critical to the playing out of the other scripts and behaviors in your mod? In this situation you might find yourself writing scripts where you would do a long series of repetitive checks like these:


  if (player.GetInFaction ''FactionRef'' == 1)
  if (player.GetInFaction ''FactionRef'' == 1)


These checks would go through each possible faction and could start to get a little hard on the eyes and make trouble shooting scripts a bit more difficult.  
These checks would go through each possible faction and could start to get a little hard on the eyes if there were a great many factions. This would make trouble shooting your scripts a bit more difficult too.
 
Using the functionality discussed in this article you could store the player's faction in a quest script and just retrieve it with a few lines of code each time a script needed the information! If the player's faction could switch you would just write code to change the value in the quest script for those situations.


Using the functionality discussed in this article you could store the player's faction in a quest script and just retrieve it with a few lines of code! If the player's faction could switch you would just write code to change the value in the quest script.
==Final Notes==


====Notes====
*All the example scripts above are for basic concept testing. They are simplistic for the sake of study. Actual application would include additional content in each script.


*The example scripts above are for proof-of-concept testing. They are simplistic for the sake of study and application.
*It is also possible to use an object script could be used in place of the quest script for the "database" feature. But the method is slightly different.


*The See Also section refers to conditionals that appear to offer the functionality discussed in this article, but '''do not'''. However, the syntax for reading and writing to a quest script was derived from notes from those articles and are worth mentioning.  
*It is possible for other variable types provided through the OBSE to be stored and retrieved using this system. For example, strings and arrays.


===See Also===
==Additional Reading==


*[[GetScriptVariable]]
*[[GetScriptVariable]]
*[[GetGlobalValue]]
*[[GetGlobalValue]]
*[[GetQuestVariable]]
*[[GetQuestVariable]]
The above articles should be read for reference purposes. Although not directly related it is valuable to note that these are only conditionals that appear to offer the functionality discussed in this article, but '''do not'''. Still, the syntax for reading and writing to a quest script was derived from notes found in these articles and so are worth reviewing.
==See Also==
*[[Quest scripts]]
*[[Global Scripts]]
*[[Global Scripts/Extended]]

Latest revision as of 13:58, 30 December 2010

A time may come when you will wish to have a repository to store variable values that can be read from and written to by any script. This article addresses a basic method for not only storing and retrieving non-float numeric values, but object references as well. This could prove very handy when creating dynamic game scenarios.

The Basics[edit | edit source]

A scenario for creating and testing this type of functionality includes at least three features:

1 - A script that acts as the database for storing values. In this article a Quest Script will be used to demonstrate this.

2 - A script that writes a value to one of the variables in the "database" Quest script when it is activated.

3 - A script that reads a value from one of the variables in the "database" Quest script when it is activated.

Using this basic model you should be able to easily construct a simple scenario to see this functionality in action.

The Quest Script[edit | edit source]

The quest script acts sort of like a very basic database. The next two scripts will demonstrate the command syntax for reading and writing to the quest script's variables from other scripts.

The script:


 Scriptname MyQuestScriptDatabase

 ref refVar ; reference values can be stored and retrieved

 float floatVar ; float values can be stored and retrieved

 short ShortVar ; integer values can be stored and retrieved

 begin GameMode ; begin block is not required

 ; you don't have to put anything in here
 
 end ; if begin block is not used the 'end' is not required either. 

Make sure you set the Script Type as "Quest" in the script editor window and then save your script.

The script is very simple. You just declare all the variables you need for storing values.

Notes[edit | edit source]

  • If you assign starting values to your variables in the "database" script use a doOnce variable to keep the variables from being reset to their initial values on every frame refresh. Setting values within this script's Begin-End block without a doOnce will essentially "lock in" the values to their initial setting.
  • The variable names listed in the script can be named whatever you like - preferably something meaningful to their purpose.
  • You must declare a variable in the quest script and compile it BEFORE you can reference them in the read/write scripts described below. If you attempt to code your read/write commands and the variable has not yet been declared in the quest script you will receive a compiling error in your read/write script. (specifically this error message will state that your variable is an unknown variable or command even though you have declared the variable already within the read/write script.)


The next part of this step is to create a quest. You can read up on the steps for creating a quest on the wiki. Just keep in mind that the only setting needed for creating this functionality is the "Script" setting under the Quest Data tab. Once you create and name your quest select your quest script (as seen above) under the script setting for the quest. (For these examples the quest is named MyQuest.)

Notes[edit | edit source]

  • You do not need to start the quest. The values within the quest can be written to and read from even if it is never started. However, if you set initial variable values in your Begin-End block then you will have to start the script at some time to set those values. Once set you can stop the script with StopQuest.

Storing a Value[edit | edit source]

Okay! Now that you have your quest and a quest script associated with it you need to know how to write values to it.

The script:

 Scriptname MyWritingScript

 ref refVar ; reference values can be stored and retrieved

 float floatVar ; float values can be stored and retrieved

 short ShortVar ; integer values can be stored and retrieved

 begin onActivate
 
   set MyQuest.refVar to ObjectReference ; or some reference variable

   set MyQuest.floatVar to 1234567890 ; or some float variable

   set MyQuest.ShortVar to 2012 ; or some integer variable

 end

That's it! Now associate this script with some object that can be "activated". When the player or an actor activates the object the values listed above will be assigned to the script variables in the quest script.

Reading a Value[edit | edit source]

Now that you know how to write values to your quest script database you just need to know how to read them.

The script :

Scriptname MyReadingScript

 ref refVar ; reference value as stored

 ref refVarRetrieved ; reference value as retrieved

 float floatVar ; float value as stored

 float floatVarRetrieved ; float value as retrieved

 short ShortVar ; integer value as stored

 short ShortVarRetrieved ; integer value as retrieved

begin OnActivate

set refVarRetrieved to MyQuest.refVar

set floatVarRetrieved to MyQuest.floatVar 

set ShortVarRetrieved to MyQuest.ShortVar

MessageBoxEx "See my reference: %n See my float: %g See my integer: %.0f", refVarRetrieved, floatVarRetrieved, ShortVarRetrieved
			
end

If you use this script exactly as written the message box will show the name of your reference rather than the reference. See MessageBoxEx for more. But the reference value is there and ready to use.

Practical Applications[edit | edit source]

So one might be wondering where functionality like this might prove useful. If you're just writing simple mods this type of functionality may seem a bit excessive. But take as an example a mod where the player will only belong to one faction (other than the player faction of course.) Oblivion is designed assuming the player might be a member of many factions. But what if your mod only allowed the player be a member of one faction? And what if the relationships between factions was absolutely critical to the playing out of the other scripts and behaviors in your mod? In this situation you might find yourself writing scripts where you would do a long series of repetitive checks like these:

if (player.GetInFaction FactionRef == 1)

These checks would go through each possible faction and could start to get a little hard on the eyes if there were a great many factions. This would make trouble shooting your scripts a bit more difficult too.

Using the functionality discussed in this article you could store the player's faction in a quest script and just retrieve it with a few lines of code each time a script needed the information! If the player's faction could switch you would just write code to change the value in the quest script for those situations.

Final Notes[edit | edit source]

  • All the example scripts above are for basic concept testing. They are simplistic for the sake of study. Actual application would include additional content in each script.
  • It is also possible to use an object script could be used in place of the quest script for the "database" feature. But the method is slightly different.
  • It is possible for other variable types provided through the OBSE to be stored and retrieved using this system. For example, strings and arrays.

Additional Reading[edit | edit source]

The above articles should be read for reference purposes. Although not directly related it is valuable to note that these are only conditionals that appear to offer the functionality discussed in this article, but do not. Still, the syntax for reading and writing to a quest script was derived from notes found in these articles and so are worth reviewing.

See Also[edit | edit source]