This is a great idea - I'd love to see this become the standard as time goes on.
In my tweaks to Aladdin's Castle, I ran into a couple of other items that would be really useful to externalize into an options file. That got me thinking in terms of generalizing the cController.txt idea so that it could handle any set of options.
I came up with a little script that I think accomplishes this. It lets you define an arbitrary set of constant names and their default values. For each name, it looks to see if the name is defined in an external options file. If so, the script defines the constant using the value in the options file. If the constant isn't defined in the options file, we use the default value that you define in the script.
As with cController.txt, the idea is that this option file is a single file shared among all tables. The user only has to define the option settings once, and they'll automatically work for all tables that use the options loader.
Here's what I came up with:
Sub LoadOptions(vars)
Dim fname, FileSys, fp, txt, i, fileVars
set fileVars = CreateObject("Scripting.Dictionary")
fname = UserDirectory & "options.txt"
Set FileSys = CreateObject("Scripting.FileSystemObject")
If FileSys.FileExists(fname) then
Dim re : set re = New RegExp : re.Pattern = "(\w+)\s*=\s*("".*""|\d+)"
Set fp = FileSys.GetFile(fname).OpenAsTextStream(1,0)
While Not fp.AtEndOfStream
txt = trim(fp.ReadLine)
Dim matches : set matches = re.Execute(txt)
if matches.Count then
Dim m : set m = matches.Item(0)
fileVars(m.SubMatches(0)) = m.SubMatches(1)
end if
Wend
fp.Close
End If
for i = 0 to ubound(vars) step 2
dim var : var = vars(i)
dim val : if VarType(fileVars(var)) <> vbEmpty then val = fileVars(var) else val = vars(i+1)
ExecuteGlobal "const " & var & "=" & val
next
End Sub
Put a call to this routine near the top of the script, with an array of constants to be defined and their default values:
LoadOptions Array("XXX", 1, "YYY", 2, "ZZZ", """foo""")
Here's how this works. The LoadOptions first looks for a file called Visual Pinball\User\options.txt. If the file exists, the script reads each line from the file, parses it as a VARNAME = VALUE line, and stashes the resulting VARNAME and VALUE in a hash table. After finishing with the file, the function then goes through the "vars" argument array and defines each variable as a script constant, by executing a CONST VARNAME = VALUE statement in the global scripting context. If the variable was defined in the options file, we define the value from the options file; if not, we define the default value from the "vars" array.
I think this design has all of the properties we'd want from such a mechanism:
- It's zero hassle for users who don't want to know about it. No error messages ever pop up if the file doesn't exist. The script simply uses the default values if no options file exists.
- It's infinitely extensible. Every table can add whatever options it wants. If the option is unique to the table, that's fine, but the main point is to share option settings that apply to many tables.
- There's no problem if a table adds new options that aren't listed in the user's option file. The table simply gets its default values in this case.
- There's no danger of naming conflicts from adding new options. If a user adds a bunch of options to the options file that a table doesn't need, the table ignores them. Each table only gets the option names loaded that it specifically lists in the name/default array when it calls LoadOptions.
- It's efficient for scripting, since the options are all defined as CONST items. (I'm not sure if the VB Script engine used in VP actually makes use of constants for run-time efficiency, but it could in principle, and it could in future versions. At any rate, CONST should be as good as any other way of defining these values, if not better.)
Table builders, let me know what you think! It'd be great to see at least the cController.txt mechanism get widely adopted, but I think it would be a little better still if something truly general could get traction.
Edited by mjr, 10 August 2015 - 09:22 PM.