Fallout 2 mod FO2 Engine Tweaks (Sfall)

Discussion in 'Fallout General Modding' started by Dude101, Jul 30, 2007.

  1. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    Again, amazing work phobos, have had one question on my mind for a long while tho:

    Why is it seemingly possible to trigger movement from a global or hookscript? If you put this in a regular script's critter_p_proc:


    Code:
          foreach critter in list_as_array(LIST_CRITTERS) begin
                tile:=tile_num_in_direction(tile_num(dude_obj),random(0,5),random(1,3));
                animate_move_obj_to_tile(critter, tile, 1);
                display_msg("working");
          end
    
    then everybody starts running around like crazy. However, put the exact same thing in a global script and all you get is the message repeated constantly and nobody moves. Any idea why that is and whether there's a way around it?
     
  2. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    There is some additional check in some of the opcodes which fails on global scripts. Many functions don't work because of it, like roll_vs_skill, etc. I'm trying to fix it.

    Edit: Fixed in latest revision. Finally some roll_vs_skill checks!
     
    Last edited: Jan 9, 2015
    • [Like] [Like] x 1
  3. myocytebd

    myocytebd First time out of the vault

    13
    Dec 14, 2014
    How to get it work?

    I tested: (used a recent release; not latest svn)
    Code:
    global script:
    export procedure foo;
    procedure foo begin
        display_msg("foo");
    end
    
    obj_dude:
    import procedure foo;
    procedure map_enter_p_proc begin
        display_msg("dude map_enter");
        call foo();
    end
    
    It does't work, plus random crash at load.


    BTW:
    When I wrote:
    Code:
    export procedure foo;
    procedure foo(variable bar) begin
    end
    
    compiler crashes. Export function cannot have arguments?
     
  4. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    There was a crash bug related to exported procedures in 3.4, it was fixed in 3.5.

    That's a compiler bug, thanks for the report, I've fixed it for the next release. Exported procs can have any number of arguments.

    Just tested it again myself and here's the deal:
    • you can use exported procedures between normal scripts (objects and maps), but you must respect scripts loading order. In other words, scripts with "export" should be the one's that loaded first. Typically export everything in map script and import in object script
    • however, there is obviously something wrong with them when using from sfall scripts, when I call imported procedure, it works, but the script stops working after that call, and nothing is printed in debug.log (no crash)
    • they were even more broken before sfall, some TeamX guy made patches very long time ago, which Timeslip incorporated - it fixed several crashes. Though, looks like more fixing is required for full usage.

    Script load order is:
    1. Map script
    2. Map objects scripts
    3. Sfall Hook scripts
    4. Sfall global scripts
     
    Last edited: Jan 11, 2015
    • [Like] [Like] x 1
  5. myocytebd

    myocytebd First time out of the vault

    13
    Dec 14, 2014
    Another question about the engine: how to properly implement a (short-term) timed behavior?
    For example, a timed explosion to fire 10-seconds later.

    I tried to poll game_time for +100 in a repeated global script.
    But the condition always seem to fire early at 1s-8s. (huge drift)
    (The global script repeating interval varies badly between maps, but sort of consistent in the same map.)

    So it seems that export/import is not yet ready to use for better modularization.

    BTW maybe sfall hooks should cover all normal map/object events?
    For example, it seems that proto data is reloaded between each map load, while global/hook scripts don't have map-enter hook.
     
  6. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    That's strange, since game_time should return number of tics of game time, where one second is 10 tics. There is an sfall function which returns current system time or something like that, you could try to use it.

    That's because when you specify set_global_script_repeat it actually means how many frames to skip before executing "start" proc, so the frequency is closely tied to current frame rate.

    Seems so. However, try out export variables. They should be reliable now (and if not, easily fixable since all related engine hooks are already in place).

    That's a good question. I already started to move in direction of making sfall scripts more flexible and event-oriented rather than abusing set_global_script_repeat:
    • no more need to place "start" proc in the beginning
    • map_enter_p_proc, map_exit_p_proc, map_update_p_proc is already executed for all sfall scripts since 3.4
    • register_hook_proc function (make specific proc to be called instead of "start")
    • many functions which relied on current script having a SID (reference in scripts.lst) now work with sfall scripts
    • there is also set_self function from earlier sfall versions (see question below)

    Now the question is - what to do next? You obviously can't hook object events (like use_p_proc) on global scripts, so they are like map script in this regard. I might implement add_timer_event alternative for global scripts. Also there is a timed and event procedures, though I'm not entirely sure how they work, since no one ever used them in fallout scripting.
    My long term plans in this regards is to find out how to pass argument values to and get return value from procedures. This will not only allow to take sfall hook arguments directly without calling get_sfall_arg (and same for return value), but also to completely replace vanilla opcodes related to exported procedures (may easier than fixing existing code). Interpreter code is very hard to understand from the asm...

    Since there is one interested person, I have another question regarding set_self function. Currently it allows to use functions like pickup_obj(item) from sfall scripts, but only if you call set_self right before the relevant function call (original "self" is reverted automatically after next function call). While this is safer (in case you forget to "set_self" back), it is also not very user-friendly when you need to make chains of such calls. I can leave it as it is, since there are not many functions which actually use self_obj, what do you think?
    (other options include reverting it back automatically after each event is fired for a given script, or at the end of the frame, etc.)
     
    • [Like] [Like] x 2
  7. NovaRain

    NovaRain Casual Modder Modder

    Mar 10, 2007
    sfall 3.5 is released on SourceForge, along with the modders pack and win2k version.

     
    • [Like] [Like] x 2
  8. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013


    Holy crap, on top of all those awesome additions something that let's you use flares when overwriting hs_tohit :salute:. Amazing work, dude.
     
  9. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    I actually added it to use lighting as a factor when sneaking, after disabling light around player with obj_set_light_level. I'm playing a lot of Thief lately and it gives me ideas.. :D
     
    • [Like] [Like] x 1
  10. myocytebd

    myocytebd First time out of the vault

    13
    Dec 14, 2014
    sfall gets AllowUnsafeScripting from wrong section. It should be Debugging according to shipped .ini
    Code:
    sfall\ScriptExtender.cpp(828):    bool AllowUnsafeScripting=GetPrivateProfileIntA("Debug", "AllowUnsafeScripting", 0, ini)!=0;
    BTW to build sfall, which D3D9 SDK release should I get?
     
  11. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    I use June 2010 SDK. Thanks for the report.
     
  12. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    Hey, just a couple of ideas you might consider if they're easy enough and might be of use for your own mod:

    - Carrying over variables in dialogue. I have absolutely no idea how viable this is, but it has always bugged me how you can only do:

    Code:
    NOption("herp",NodeHerp,001);
    and not

    Code:
    NOption("herp",NodeHerp(herp),001);
    forcing you to make a large amount of additional nodes even if all you want to do is offer different prices for an item through dialogue.

    - something like hs_criticalfail. It would be neat to change up the way critical failures work, making the effect not depend on luck alone:

    e.g. the gun crits could be the result of a combination of luck and:

    0 miss (I'd eliminate this one, not very interesting crit fail)
    1 lost rest of ammo (traps/explosives skill; I imagine this means the ammo was poorly maintained and faulty)
    2 weapon dropped (agility)
    3 hit randomly (perception)
    4 weapon destroyed (repair skill)
     
  13. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    Not possible with how procedures are passed as arguments. This particular problem is solved by anonymous functions in other languages and since we don't have such luxury here, you will have to find other options.
    • When one node is referenced once from each of the other nodes - just use normal variable in global scope.
    • In other case (several references from one node) - you have to make several procedures, but try using preprocessor in it's full (I recommend this resource), for example you can make one macro that defines procedure with postfixed name, using ##:

    Code:
    #define NodeFork(x)  \
    procedure NodeFork##x begin \
       ... \
    end
    
    NodeFork(1)
    NodeFork(2)
    NodeFork(3)
    // etc.
    
    
    Isn't there already a CriticalOverrides.ini which allows to customize critical table? This stuff seem very complex to me and I was never interested enough to study how it works :)
     
    • [Like] [Like] x 1
  14. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    That's just for critical hits, and I override those in hs_combatdamage already; plus I like the versatility of hookscripts way more than static configuration files anyway ;)
     
  15. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    Which reminds me of something else you might possibly find interesting for your mod as well.

    It's always bothered me how little attributes meaningfully figure into character creation. If you want to play a character who speaks with a velvet tongue and can barter with the best of them, should you invest in Charisma? Not at all. If you want to be a master lockpicker should you invest in Agility or Perception? Not at all. Attributes other than Intelligence really don't figure into anything other than combat and attribute checks in dialogue (except for the pretty silly npc cap of Charisma).

    The reason for this isn't hard to see: combat has plenty of variables involved (range, damage, thc, etc.), while skill checks usually just have one, namely difficulty. This way, combat can involve not just skills but also different attributes, while skill checks can only involve skills.

    While you could address this by introducing additional variables to skill checks, there's only so much you can do this way (introducing noise generation based on player Agility during lockpicking which alerts those closeby would be one example). So what I was thinking is how interesting it would be if the skill cost increments, which Timeslip already made adjustable on a per skill basis in the skills.ini configuration file, could be changed through a script function as well.

    This way, you could make skill costs depend not just on how high your investment already is, but also how high your attributes are. E.g., a low charisma character would have to spend more skill points to increase his speech or barter skill than a high charisma character, thus making attribute selection a more important part of character creation.
     
    • [Like] [Like] x 1
  16. myocytebd

    myocytebd First time out of the vault

    13
    Dec 14, 2014
    It seems that variables can be called, like opcode? Without a warning or error.
    Like:
    Code:
    variable xxx;
    xxx := ...
    if (cond and xxx()) ...
    And debug.log gets "Error during execution: Wrong type given to lookup_string_proc", plus random crash. (xxx should have int 0 or 1)

    For some reason, this coding error lurks for weeks and doesn't bit me until today. (recompiled a dozen or more times in the meanwhile)
    Though it is in hs_calcapcost, apparently a hot call place.
     
  17. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    This is a feature of original SSL. You can assign string to a variable and call it. String contains the name of some procedure in the script.
     
  18. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    Preview of new feature in script editor:

    This will include argument and result types for every sfall and vanilla scripting function. Descriptions are currently available for a subset of sfall functions (taken from sfall function notes.txt) and for all vanilla functions (from falloutmods.wikia.com)

    New scripting functions:
    • checking if a straight line between two tiles is blocked and by which object (can check for walk blocking, shoot blocking, AI blocking)
    • similar as above, but checks given tile
    • get a list of all objects at given tile
    • get a list of all party members

    Hook script change:
    • ability to override blocking check after "within perception", so you can allow critters to see you through windows, barrels, other critters, etc.
     
    Last edited: Jan 24, 2015
    • [Like] [Like] x 1
  19. JimTheDinosaur

    JimTheDinosaur Vault Dweller
    Modder

    736
    Mar 17, 2013
    Awesome dude :salute:

    I was wondering two things:

    - is it perhaps possible to allow for bigger integers and/or longer floats? Maybe I'm just working stupidly, but I've already encountered a situation where I multiplied a number by 100 a couple of times in a row (to allow for high card tiebreakers in my poker game) resulting in a bad number coming out (it wasn't even that ridiculously long iirc maybe 10^12 or something), and a situation where the five allowed digits weren't enough for me (I wanted a value of 0.000009 or something). It's of course possible to find workarounds, but it feels fairly limited on both "sides". Especially with the bigger integers I'd like to at least see an error message instead of it spouting out a random number.

    - maybe a simple check for whether a value is in an array? It could be that I've just missed it, and I've been using the workaround of "if scan_array(array, value) > 0 then...", but just in case it's been looked over by you as well I thought I might as well mention it.

    edit: btw, I'm still using the previous version, so might be that some of these have been changed in the meanwhile, sorry.
     
  20. phobos2077

    phobos2077 Mildly Dipped
    Modder

    596
    Apr 24, 2010
    Well, all integers and floats are 4 bytes, so there is not much you can do about number of possible values for each variable (though If you really want it, I know there are workarounds...). However, try putting your large integer number into a float variable, because of how floats work, you can have extremely large number (only the precision may be lost).

    As for the 5 digits after problem, I've added sprintf function just for that (your float can actually store the 0.000009 value, it's just when you add it to a string, vanilla stringification function is called, which always uses format %.5f).

    There is a macro in the latest sfall.h:
    Code:
    #define is_in_array(item, array)    (scan_array(array, item) != -1)
    
    If you need to check if some key in associative array exists, just: if (array[key] != 0)

    Check out the latest sfall and SSL libraries in my signature, I've written a lot of SSL helper procedures to work with arrays.

    sprintf was added in 3.4, scan_array was always there :)
     
    • [Like] [Like] x 1