Fallout 2 mod FO2 Engine Tweaks (Sfall)

(sorry for third post in a row, but) I really want to contribute with new features, engine hacks, bug fixes. Can I do that somehow?

Timeslip doesn't seem to show up here. Is she the only project maintainer? Does anyone else has permission to commit something?

My plan:
1) Fix string_split
2) Rewrite arrays like in post above
3) Add several string-related functions (if I can)
4) Add function "set_explosion_radius"
 
Last edited:
(sorry for third post in a row, but) I really want to contribute with new features, engine hacks, bug fixes. Can I do that somehow?
Timeslip doesn't seem to show up here. Is she the only project maintainer? Does anyone else has permission to commit something?
Mash and Haenlomal AFAIK, but Haenlomal has been inactive for quite some time.
I'm curious about the explosion radius, does it really work?
 
I'm curious about the explosion radius, does it really work?

It worked for me, check the other thread. I only found explosion radius for grenades and rockets though.

Another question, what tools people typically use here to map fallout2.exe? Does anyone have some kind of disassembly database for it with different subroutines/variables named?
I started to map out some subroutines using IDA, but there is a lot of code :)
 
Last edited:
I was hoping it is possible for explosions to light up an area for a second - just like real life...it would cool with night encounters.
 
I was hoping it is possible for explosions to light up an area for a second - just like real life...it would cool with night encounters.

Strange thing. Most misc prototypes has proper light intensity/radius defined (if you place rocket or explosion in Mapper at night - you will see it), but when actual explosion happens or rocket fly - no light :(
Need to understand how game creates projectiles and explosion effects. I have a hunch that they are not actual objects, but only graphics is taken from prototype and animated directly on the screen.

Tried to search for many misc prototype IDs (hardcoded in engine) using decompiler, found a couple but changing them had no effect (tried to replace explosion PID with emp explosion).
 
@phobos2077

The skill level of folks here on our forum varies widely, and many readers are beginners at programming. Could you give short description of what an array is and why a person might want to use such a thing, or perhaps a brief example of how it's a time-saver or problem solver?


@ sfall discussion

I can't get play_sfall_sound to work. I use Ruby and the command compiles fine with my script compiler, but during actual game-play any call to play_sfall_sound causes the game to crash (the sound files are in properly named, in .wav format, and in the directory specified in the script).

I read over here:

Timeslip said:
Another quirk of the compiler is that you (normally) can't ignore a functions return value.

Code:
play_sfall_sound("Patch000.dat\\sound\\SFX\\geigerhigh.wav",1);

will not compile, but

Code:
variable tmp;
tmp:=play_sfall_sound("Patch000.dat\\sound\\SFX\\geigerhigh.wav",1);

will

I don't understand that-- what is one supposed to do then with the resulting variable (in this case, "tmp") in order to get the sound to play? Some other step would be necessary.

Thanks
 
Last edited by a moderator:
The skill level of folks here on our forum varies widely, and many readers are beginners at programming. Could you give short description of what an array is and why a person might want to use such a thing, or perhaps a brief example of how it's a time-saver or problem solver?

Well basically an array is a bunch of values stored in single variable (pointer), you can have as many values in one array as you want. In many cases, when you need to work with many of the same (anything), arrays are great.
My English is not very good, so I'll just write some real examples.

1) Let's say we have a mod that delete items from inventory of dying critters (like stimpaks) to make game harder. And you want this configurable, so you add an INI config directive like this:
Code:
...
removePids=40,77,124
And checking if certain item would qualify for removal would be simple:
Code:
// do this once on script init:
// this is just a function that splits string and then converts all values to integers
pidsList := string_split_ints(get_ini_string(....), ","); 

....

// use this in hs_ondeath to check if item qualify:
if (is_in_array(obj_pid(item), pidsList)) then ...
Without arrays we would've needed some dirty solutions like in party orders addon (where NPCs PIDs are defined on different lines, and you have to iterate over INI sections every time - this is a huge disk performance issue), or using some hard-to-understand functions to iterate over string of tokens using "tokenize" function.

2) Let's say we need to implement placable traps. Currently the engine not allows you to add spatial scripts dynamically (only through the mapper), so you need to use "list_begin, list_next" functions to iterate over all critters and check if someone should trigger the trap. How do you store the trap? You can use sfall globals, but since one global is just one value, you will have to limit maximum number of active traps to something like 4 or 5 and your script will have the same code repeated 5 times (repeated code is always HORRIBLE, as it leads to great many bugs and difficult to modify).
Arrays saves the day, as you can place as many of them (information about each trap - tile, elevation, status, trap type, etc.) in the array as you want, and easily save it to the savegame.
When you need to check if trap is triggered, you just iterate over all traps using "foreach" or "while" loop.

Benefits: Unlimited number of traps, less code (easy to modify).

Having arrays that work in expected way and safe to use, you will surely find many applications for them in your daily scripting (store NPCs PIDs to iterate over party members with ease, store object pointers with additional information to implement some new game mechanics, etc.).

What I also want to have is an associative arrays. Normal arrays have specific length (number of values) and to access/change those values you use numeric indexes starting from 0. Those are called "lists" or "vectors". This behavior is good in many applications.
But, let's say you need to make it so some item PIDs may have some information associated with them (like price modifiers). Example:
Code:
; Klamath: Gecko Pelts cost much more, stimpacks less, leather armor less, scorpion tails more (illogical, but balanced)
2=276*2.5|277*2.5|623*2.0|40*0.7|3*0.8|74*0.8|92*2.0|591*2.0
In this case I specify that some items should cost less/more in Klamath. So how do I use this string? Associative arrays come in handy here:
Code:
pidList := some_parse_func(get_ini_string(...)); // this parses the string using string_split and creates array with 8 key => value pairs, where each listed item PID is associated with float price modifier

...

// modify prices like this (simplified pseude-code):
foreach ( pid in all_item_PIDs) begin
   mod := get_assoc_array(pidList, pid);
   if (mod) then
      set_proto_data(pid, PRODATA_IT_COST, cost * mod);
end
I actually have function called "get_assoc_array", but what I want is to be able to use square brackets for this:
Code:
mod := pidList[pid];
Which is currently not possible, because the compiler will simple translate this to:
Code:
mod := get_array(pidList, pid);
And get_array only works with normal arrays (lists), in which we have indexes 0, 1, 2 .... (and not 276, 277, ...).

I hope this is enough to understand that they are must-have in every script language :)
 
Howdy Smoothskins,

Right, I have a problem with recruiting Marcus, the option to tell him ive found the bodies does not show up. after re-loading and trying the quest a couple ways.. no joy. So, i figured why not change the script for marcus to manually add him to my party (without 'completing' this quest) I'm close to trying doing it myself but if I mess up and have to start again.. i just wont.

so if anyone knows how to, or even possibly post a a file replacing Marcus' script with one where he's in my party, that wound be super super cool.

p.s Ive found the bodies, got the note , talked to Zauis, talked to Dan (whom i cant show the note to, tried even placing it on his person..) talked to francis and made him leave (thus making the note disappear,probably not important) but still cant tell Marcus what ive discovered. Running multiple mods this is my own fault.

also apologies if this should be on another board.

thanks.
 
I was hoping it is possible for explosions to light up an area for a second - just like real life...it would cool with night encounters.

After many work, finally managed to implement this. Not perfect though (after explosion light is gone, some of it remains... you can think of this as a grass on fire :D). Will post code later with all other additions.
 
(sorry for third post in a row, but) I really want to contribute with new features, engine hacks, bug fixes. Can I do that somehow?

Timeslip doesn't seem to show up here. Is she the only project maintainer? Does anyone else has permission to commit something?
Sorry, I went and got married, so my time here has dropped from the odd evening down to zero for the foreseeable future. If you want svn access, pm me your sourceforge name and I'll hook you up.

On a completely unrelated note, more weddings should involve ball pits.
 
Congratulation Timeslip, I hope we don't lose you completely...I didn't realise ball pits and weddings were compatible. Thinking about it, why not... :razz:

ball_pit_bacteria_07_13_11.jpg
 
Is there an INI option to change when each dream occurs? I couldn't find it.
Because RP adds a lot of new content to explore, it would be wise to move those dreams a little (suggestion by lujo).
 
Is there an INI option to change when each dream occurs? I couldn't find it.
Because RP adds a lot of new content to explore, it would be wise to move those dreams a little (suggestion by lujo).
No option for it AFAIK. Maybe they're triggered by hitting certain numbers of game ticks that equal to those specific dates?
 
Last edited:
@ arrays

Just curious...

- there's a X amount of "special" doors in a game,

- with default commands/functions/whatever I'd have to create GVAR/MVAR/LVAR per door to make NPC remember that that something happened around the door:

Code:
if (condition) then begin
    // remember that something happend around this particular door
    set_map_var(MVAR_DOOR_X, 1);
    set_local_var(LVAR_TEMP_DOOR_POINTER, 0);
end

and later read those saved variables like this:

Code:
// check is something happened
if (map_var(MVAR_DOOR_X) == 1) or (map_var(MVAR_DOOR_Y) == 1) or (map_var(MVAR_DOOR_Z) == 1) then begin
    do_some_shit;
end

(I'd have to check each door LVAR/MVAR/GVAR! :grin:)

- now, can you make something like this with sfall's array:

Code:
// save object to array
if (condition) then begin
    save_to_array(MY_AWESOME_ARRAY, local_var(LVAR_TEMP_DOOR_POINTER));
    set_local_var(LVAR_TEMP_DOOR_POINTER, 0);
end

// check if object is in array
if (is_object_in(MY_AWESOME_ARRAY)) then begin
    do_some_shit;
end

no pre-defined .inis, and shit - save/read pointers on the fly, just like in case other variables.



---------------------EDIT

Of course, ignore "syntax", or lack of any definition of my array example it just to show what do I mean - I predict I'd have to define max length of array + do some other shits in the first place to make it working. At least this how it was looking with one-dimensional array of objects I've been playing around in some other game. But this was pre-defined, read-only type of thingy.
 
Last edited:
Yeah, this is exactly the thing you can do with arrays. Need to think on how to make them more user-friendly though. This is exactly what I'm going to do: change how arrays work, add some new functions for them, maybe adjust compiler a bit and then do something with backward compatibility...
I would've added INI parameter to switch between new/old arrays behavior but it may be excess. For example I think the second parameter to "create_array" should not exist at all (how many bytes to allocate in memory for each element... not something that regular scripter should worry about).

PS: I don't know if someone already shared something like this or not. While I'm studying both Mapper2.exe and Fallout2.exe in IDA Pro, I'm filling the database with properly named functions, variables, some structures. If anyone wants it, I could share it.
 
Last edited:
Ok, so I've made a few commits. This is a part of the things I want to do apart from array changes. Here's what's been done:

- splitted ScriptExtender.cpp into several .hpp files with all asm/c code related to new operators;
- added several new operators related to strings: 'substr' (get part of string), 'strlen' (length of a string), 'sprintf' (format any variable using format string);
- added 'typeof' operator: returns type of value (1 - integer, 2 - float, 3 - string);
- modified 'atoi' operator: now it will parse hex&octal strings properly into integers;
- Hakunin movie timers are now configurable through INI;
- added INI options to change explosives damage (dynamite and plastic explosive);
- added ComputeSpray mod which allows you to tweak bullet distribution in bursts;
- added ExplosionLighting mod: explosions and projectiles emit light (currently bugged, only enable for testing);

Movie timers and explosive damage are both quick dirty hacks. But it allows to mod those thing for Fallout 2. It may be replaced with separate ini files, etc, in future.

If anyone wants to test new scripting functions, I can post updated compile.exe & ddraw.dll.
In particular, I'm thinking how to better name new utility functions (like strlen). They all named by their C language counterparts (like Timeslip did with atoi, atof, etc.). But maybe they're not very readable for people who aren't familiar with C? They are short and distinctive though.

PS: I hope you guys won't kill me for code refactoring. Several thousand lines of code in single file was too much... It should be a bit more organized now.
 
Last edited:
@ Everyone, NovaRain is now the official sfall file releaser. I won't be doing the sourceforge releases any more.

@ Phobos, might as well move the PM conversation over here. Things like source control and array changes affect everyone, not just me.

phobos2077 said:
That's why I think it's wise to replace old array functions with new ones (slightly different behavior, different number of arguments). It will make scripting safer. Of course, backward compatibility (savegames, old scripts) will be preserved somehow. I know this may sound like a horrible idea (in order to use new arrays behavior, one will have to change all his old scripts that use them), but in reality, only a handful of people actually used arrays in their mods.
The byte parameter was just a quick and dirty hack to let people store strings in the arrays. If you have a better solution for storing strings, go for it. But I think there is a real use case for arrays saved into save games, and that functionality should be preserved, whether as a separate opcode or a parameter to create_array.

I have no particular objection to changing the semantics of create_array, as long as binary script compatibility is preserved. (In sslc, change the create_array token to create_array_depricated or similar, and introduct a new create_array token with a new opcode.) I would prefer source compatibility to be maintained though, unless you have a very good reason not to.

Someone who actually uses arrays in mods should probably weigh in here.

phobos2077 said:
1) can we add sslc and int2ssl sources to sFall repository? (because they are all connected, when you add new operator, it must be added to all 3)
2) do you know who is the original developer of sslc? Do we have permission to post it's source in public repositories?
Short answer is I don't know. I don't believe we have permission to put either in the repository.

phobos2077 said:
3) what do you think if we would hypothetically move sFall repository to git instead of SVN? SVN is outdated and not very friendly. I'm still considering this.
On the personal side, I've never used git before and have none of the tools installed, so I'd rather not have to learn it in order to work on sfall in the future.

On the non-personal side, the differences between source control systems matter very very little for small projects like sfall where there's no contention over files. What concrete advantages would git have over svn assuming no merges, etc are required?

The only reason to switch I can see is if there are other more active contributors in the opposite situation to me. e.g. Glovz sends me patches and I commit them, but if git let him commit himself then that would be a pretty good advantage.

- splitted ScriptExtender.cpp into several .hpp files with all asm/c code related to new operators;
I've thought about doings that a few times. Never quite got around to it though; everything I tried I wasn't quite happy with.

Movie timers and explosive damage are both quick dirty hacks.
All of sfall is one big dirty hack. ;)
 
The byte parameter was just a quick and dirty hack to let people store strings in the arrays. If you have a better solution for storing strings, go for it. But I think there is a real use case for arrays saved into save games, and that functionality should be preserved, whether as a separate opcode or a parameter to create_array.
Of course, possibility to store arrays in savegames will be preserved. However, it shouldn't be default (and forced) behavior. To store array in save, I'm thinking of function like this:
Code:
arr := [1,6,85,"Cool string", 0.3343];
save_array("my_cool_array", arr);
To load it, you will have to call "load_array". This will basically be the same as (and consistent with) "set/get_sfall_global" functions, but for arrays. And it will be safer, since you are using pre-defined array ID.
Other option might be to turn array into "permanent mode" with some function. But that way it won't be clear what arrays are permanent and what are not. So I would stick with "save/load_array".

So here's a sum of what I'm trying to achieve:
1) Arrays won't be saved automatically with auto-generated IDs.
2) You won't have to specify number of bytes for array creation (second argument to create_array will probably be ignored).
3) Easy to use associated arrays with keys of any type.
4) I think set/get_sfall_global should accept any value as key, not just 8-byte string (it will basically be one "main" associated array).

I wonder why we have different functions get_sfall_global_int and get_sfall_global_float ? AFAIK, SSL operator can have returned value of any type.


phobos2077 said:
1) can we add sslc and int2ssl sources to sFall repository? (because they are all connected, when you add new operator, it must be added to all 3)
2) do you know who is the original developer of sslc? Do we have permission to post it's source in public repositories?
Short answer is I don't know. I don't believe we have permission to put either in the repository.
Well I asked Nirran, he's okay with putting int2ssl out (though he's not an original author). As I said before, having all 3 in 1 repo would be of great benefit. I will wait for your permission on this (since there are no license file with sslc and original devs are most likely hard to find/contact with).

On the personal side, I've never used git before and have none of the tools installed, so I'd rather not have to learn it in order to work on sfall in the future.

On the non-personal side, the differences between source control systems matter very very little for small projects like sfall where there's no contention over files. What concrete advantages would git have over svn assuming no merges, etc are required?

The only reason to switch I can see is if there are other more active contributors in the opposite situation to me. e.g. Glovz sends me patches and I commit them, but if git let him commit himself then that would be a pretty good advantage.
Well basically git (or mercurial) are better for projects with several active developers (branching, merging, that sort of stuff is a lot clearer). Also it allows you to commit several times locally before pushing to remote server.

I guess we stick with SVN for now, unless there will be more active developers.

Edit:
Progress on arrays is slow. Would've done by now if not for backward compatibility issues :)
After playing with sslc code, I've come up with a relatively simple solution how to implement array expressions!

So for example, instead of this:
Code:
if (weaponPid == PID_KNIFE or weaponPid== PID_COMBAT_KNIFE or weaponPid== PID_LITTLE_JESUS)
you could do this:
Code:
if (in_array(weaponPid, [PID_KNIFE, PID_COMBAT_KNIFE, PID_LITTLE_JESUS]))
Or if you want to initialize some array:
Code:
myArray := [123, 0.232, "Good stuff"];

"Proper" solution for arrays would be to adjust script interpreter itself to account for array type, create some opcode with variable number of arguments.. But as a quick hack, we can tell compiler to translate our array expression in something like this:
Code:
myArray := (arraystack_new+arraystack(123)+arraystack(0.232)+arraystack("Good stuff"));
This is still valid SSL code. Internally, arraystack_new will create temp array and return it's ID (just like temp_array), and arraystack(x) pushes x to the end of "current" array and returns 0. In the end we get ID of fully prepared array with just one expression :)
 
Last edited:
My unofficial sfall compiles updated to SVN r278 (3.3.1.278): (removed due to newer updates)

Please see phobos2077's post above for newly added features and functions. For more details on ComputeSprayMod, please refer to this post.
3.4 will be released when phobos2077 finishes his current to-do list.

The archive includes four DLLs:
  • the one in the root directory of the archive - normal sfall for WinXP SP3 or later.
  • trace - the debugging version.
  • win2k - for Win2000 and WinXP RTM/SP1/SP2.
  • win2k_trace - the debugging version for modders on older OSes.
The included ddraw_adv.ini has almost all settings recognized by sfall. The only settings not included are debugging settings (they only work with debugging DLLs), main menu offsets (currently only useful for FO1 to FO2 conversion) and NPC combat controls.

And my sslc compiles with the bug fixes by phobos2077: (removed due to newer updates)

There's no change for sslc from the last time. It doesn't support new scripting functions yet. I only separate sslc files from the previous sfall archive, because the total file size was a bit too large.
3.4 modders pack will have the updated sslc, script editor, scripting library and documents.

The archive includes two versions of sslc (compile.exe):
  • sslc_xp - compiled with VS2012-WinXP toolset (v110_xp), supports WinXP SP3 or later.
  • sslc_win2k - compiled with VS2008 toolset (v90), supports Win2000 and WinXP RTM/SP1/SP2.
 
Last edited:
NovaRain - instead of sending your stuff to mediafire or other services i suggest 4shared in my signature's link for you, you can keep your files stored for 90 days just changing one option in the settings and you can decide what you'll share or not.
 
Back
Top