Jump to content

SFO updates


Recommended Posts

SFO (the 'stratagems functional overlay' function-library in which SCS is written) has undergone some significant changes to take advantage of WEIDU v247, specifically the fun_args MODDER flag. Since I know a few people use SFO for their own projects, I thought I'd describe those changes here. (This will mean little or nothing to anyone who isn't already familiar with SFO syntax.)

The point of the 'fun_args' flag is that with it set, WEIDU will throw a WARNING if you call a function using an argument that isn't defined for the function. This catches a nasty kind of silent bug, where you mistype the name of a function's argument and so the function uses the argument's default value. I've wanted this for ages, and it's in v247 at my request. It does, however, cause two problems for SFO.

The first is that fun_args enforces strong typing: it will complain if you send a value as an INT_VAR to a function that has it defined as a STR_VAR or vice versa. SFO (and SCS code written in SFO) was quite sloppy about this, so I've had to go through quite systematically identifying places where it needed tightening up. (I wrote automated code to find these cases, since fun_args itself doesn't give much telemetry: it's in the function_analysis.tpa library in stratagems/lib if you want it.) In doing so, I caught a number of small bugs in SFO itself.

The second is more complicated. An SFO patch is a set of function=>argument pairs (strictly, it's a set of function=>code pairs, where code evaluates to an argument). But when the patch is executed, not only the argument is sent to the function, but also the variables 'filename', 'file_ext', 'entry_index', 'offset_base', and 'offset_secondary'. A patch command like   do_this=>thing, for instance, ends up generating a WEIDU command like this:

LPF CRE_do_this_thing INT_VAR offset_base=78 offset_secondary=144 entry_index=0 STR_VAR arguments="thing" filename="firkra01" file_ext="cre" END

But very few of the functions used in SFO patches actually need all of this information. Many need only 'arguments'. Plenty don't even need that. And so most of them are only defined with only "arguments" (if that) as a variable. Previously this didn't matter, but under fun_args it throws lots of false-positive warnings.

Since I don't want to have to add a bunch of unused arguments to all SFO's functions, I've changed the conventions. Now, a function used in an SFO patch can have at most one argument, 'arguments' (STR_VAR). It can access filetype, file_ext, entry_index, offset_base, and offset_secondary because they're set in the environment where the function is called; they no longer need to be, and indeed must not be, defined as explicit arguments. (I try not to do this sort of thing more than I can help because it violates function encapsulation, but here I think it's the least worst option.) 

This also means that if you call an SFO function explicitly (and not via the patch framework) you need to make sure any of the relevant variables it needs are set. The officially recommended way to do this is 

LPF apply_patches_inline STR_VAR editstring="<function>=><argument>" filename=<whatever> file_ext=<whatever> END

In addition, if a patch contains 'function=>null' or 'function=>""' it's called without any argument at all. (So the 'null' or "" value won't be seen by the function.)

There is one additional change unrelated to WEIDU v247. The ini handling in SFO has been broken out into a new function library, lib_ini.tph, which lives in stratagems/lib. This needs to be loaded and then set up separately from, and before, SFO itself is loaded. The new ini library works pretty much the same as the old one, except that if you check an ini entry that isn't actually in the ini file, it throws a WARNING. (You can suppress this with INT_VAR silent=1.)

Link to comment
On 10/11/2020 at 5:20 AM, DavidW said:

There is one additional change unrelated to WEIDU v247. The ini handling in SFO has been broken out into a new function library, lib_ini.tph, which lives in stratagems/lib. This needs to be loaded and then set up separately from, and before, SFO itself is loaded. The new ini library works pretty much the same as the old one, except that if you check an ini entry that isn't actually in the ini file, it throws a WARNING. (You can suppress this with INT_VAR silent=1.)

This one caught a subtle bug in one of my mods.  Good things. ^^

Link to comment

I already have some DEFINE_DIMORPHIC_FUNCTIONS (it's in Weidu v247 because I asked for it) and I update double-defined functions when I see them but I don't see a lot of advantages in systematically doing it - more accurately, the advantages are outweighed by the likelihood of accidentally breaking something.

Link to comment

It's a non-backward-compatible new library (about which I'm not likely to answer questions right now, since it's still in development, but you're welcome to look around it!) I'm likely to use it for new content, but not to convert old content (i.e. SCS) into it. The IWDSpells converter is written in 2e; the rest of SCS is in 1e, and will probably stay that way.

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...