Getting started with TSFC
Tools used in this tutorial
Required |
You should already know[edit | edit source]
- Commands and variables in Oblivion scripts
- Oblivion Script Extender
Background[edit | edit source]
Tibixe's String Function Collection (TSFC) is an OBSE plugin which extends Oblivion scripting with string variables. Strings are sequences of characters, like "apple". There are a few existing commands that accept strings as arguments, such as
SetActorFullName "Player's Horse"
But you can't do this
set pcname to GetName PC set horsename to pcname + "'s Horse" SetActorFullName horsename
This tutorial shows you how to do something similar with TSFC.
Get OBSE and TSFC[edit | edit source]
First, you need the latest version of OBSE and TSFC. Install both.
A mod requires TSFC if and only if it calls commands added by TSFC. TSFC versions are backwards compatible.
Write a simple script[edit | edit source]
Let's write a scripted spell which renames something as a possession of the player.
It's going to be a spell which activates when it hits something.
;variables begin ScriptEffectStart end
It will use five string variables (it's more than required, but keeps things simple)
short playername short itemname short newname short glue short temp begin ScriptEffectStart ;code end
First, we have to set glue to "'s ". You may try set infix to "'s ", but it won't work, because glue stores integer values. Here, you have to use
short playername short itemname short newname short glue short temp begin ScriptEffectStart set glue to StrNew "'s" ;more code end
StrNew tells TSFC that we want a new string with the initial content 's . It returns something that fits into a short value. Next, we want to assign itemname and playername. TSFC provides a function, StrGetName, to do this.
short playername short itemname short newname short glue short temp begin ScriptEffectStart set glue to StrNew "'s" set itemname to StrGetName set playername to player.StrGetName ;more code end
StrGetName is very similar to StrNew, but the initial value of the string will be the name. Now we have to join these strings. This is done with StrCat.
short playername short itemname short newname short glue short temp begin ScriptEffectStart set glue to StrNew "'s" set itemname to StrGetName ; "Item" set playername to player.StrGetName ; "Player" set temp to StrCat playername glue ; "Player's" set newname to StrCat temp itemname ; "Player's Item" ;more code end
Newname is a string which contains the final form of the name. It just has to be copied with the StrSetName command.
short playername short itemname short newname short glue short temp begin ScriptEffectStart set glue to StrNew "'s" set itemname to StrGetName ; "Item" set playername to player.StrGetName ; "Player" set temp to StrCat playername glue ; "Player's" set newname to StrCat temp itemname ; "Player's Item" StrSetName newname end
We're almost finished by now. We just have to tell TSFC that we don't use the strings any more.
short playername short itemname short newname short glue short temp begin ScriptEffectStart set glue to StrNew "'s" set itemname to StrGetName ; "Item" set playername to player.StrGetName ; "Player" set temp to StrCat playername glue ; "Player's" set newname to StrCat temp itemname ; "Player's Item" StrSetName newname StrDel playername StrDel itemname StrDel newname StrDel glue StrDel temp end
The script is ready to be used. Assign it to a spell and try it yourself.
A new function[edit | edit source]
This method is quite complicated. The next release of TSFC (0.5) will introduce a new function, StrExpr. It evaluates an expression and writes its result to the string given as argument.
The above script could be rewritten using it as:
short playername short itemname begin ScriptEffectStart set itemname to StrGetName set playername to player.StrGetName StrExpr itemname "${playername}'s ${itemname}" StrSetName itemname StrDel playername StrDel itemnamename end
Behind the scenes[edit | edit source]
The example above didn't explain how can an arbitrary length string fit in a 32 bit variable. Well, it can't fit there.
The strings are stored elsewhere and are not saved by Oblivion. (The string saving is implemented, but not released as of early September) Functions which create a new string (e.g. StrNew) put the new strings in a global list (the wise call it std::Vector :) ) and return a number.
When a function which uses a string (e.g. StrSetName) gets that number, it looks for the string marked by that number, then uses that to do whatever it is supposed to do.
You don't even need variables. Start Oblivion and type this in the console:
StrNew "Hello World" StrPrint 1
This will print "Hello World", because the first call to StrNew/StrGetSomething will always return 1 (the next call will return 2, after that 3 and so on). StrPrint finds the first string and can print it. If you want to save memory (which is not worth the effort in most cases), you can rewrite the above example with only one variable.
How to continue[edit | edit source]
Browse the TSFC documentation here at the Wiki for detailed descriptions of TSFC commands. If you know C++, you can browse the current TSFC source code [here].
If you have questions, feel free to contact Tibixe here or at the Bethesda Softworks Forums.