Fallout 1 Scripts

Discussion in 'Fallout General Modding' started by WraithUV, Feb 22, 2005.

  1. WraithUV

    WraithUV It Wandered In From the Wastes

    140
    Feb 22, 2005
    Had a longer, more detailed version of this, but I lost the browser and don't feel like typing it all again...

    Basically, first off I apologize if this is a repeat issue -though I've been using search (both here as well as google etc) for about a week and not found what I'm after yet, and I'm getting really sick of wading through ancient posts that haven't a thing to do with my issues.

    So... Is there anywhere I can lay hands on actual source for the Fallout 1 scripts? If not, could someone suggest what seems to be the best combination of utilities for decompiling, editing, and compiling them?

    I've tried a few things, and none of them seem to *quite* be working for various reasons -which I won't bother with unless there's a need for it based on answers to the above questions since going through the specifics of what's going on with all the various tools and combinations of them is rather lengthy.

    Thanks,

    -Wraith
     
  2. dude_obj

    dude_obj Vault Senior Citizen
    Moderator

    Oct 19, 2004
    I suggest using noid's decompiler to get to source. Then jargo's FSE has a converter to change to interplay format. You can also use that to recompile the scripts. See the tools page for where to get these:

    http://modguide.nma-fallout.com/tools/

    Try this to decompile all of the scripts:

    for %i in (*.int) do ruby decompile %i
     
  3. Shadowbird

    Shadowbird Where'd That 6th Toe Come From?

    442
    Jul 20, 2003
    I'm using customized Noid's decompiler and the official fallout compiler. Works like a charm.
     
  4. WraithUV

    WraithUV It Wandered In From the Wastes

    140
    Feb 22, 2005
    I'm guessing both the above suggestions also make use of the (open) watcom preprocessor, but what do you mean by customized Noid's?

    I ask only because I've only ever found one version of it anywhere, and if there's something special I have to (should) do to it, I'd rather find out sooner than later, since I'll invariably wind up bashing my skull with a shoe repeatedly in the meantime trying to get everything to behave. ;)

    And thank you both for the replies. Also kudos on that tools page and the acompanying FAQ, dude_obj. One of the best finds I managed to come across in my searches, and I'm sure I'll continue to make freequent use of it while I try to learn all this stuff. :)

    -Wraith
     
  5. Shadowbird

    Shadowbird Where'd That 6th Toe Come From?

    442
    Jul 20, 2003
    Well, if the FSE does what dude_obj says, then it's probably OK. I personally just don't enjoy the prospect of using a "translator" for something that can be done straight away. Right now I have one batch file for copying scripts to my development dir and decompiling, and one for compiling them and putting them back. Can't imagine working seriously if I had to go through another program manually to "translate" the script... However, Noid's decompiler comes with a compiler, so if you're not like me who prefers the official compiler just because it's "the official", you can use that. But they require Ruby installed - check the readme file.

    Well, technically you don't *need* the preprocessor to compile and work with scripts, but - as you cleverly put it - we "make use of it". Preprocessor, simply put, allows you to make shortcuts - instead of writing numbers in functions and then trying to remember what is what (WTF is a
    Code:
    if (script_action==11)
    ?), you can make text shortcuts:
    Code:
    if (script_action==SCRIPT_ACTION_TALK)
    looks much better, doesn't it?

    Well, you don't *have* to do anything if you use the same Noid's compiler (unless one of them crashes, as it did for me. I fixed it and forgot which one was it), but if you want to use the official one, "there'll be hell to pay". Took me half a night (probably *because* it was night) to figure out how to make the decompiler remove the "()" from the end of the functions that have no parameters. If you want detailed info on how to set up for Fallout 1 scripting using Noid's decompiler and official compiler, send me a mail and we can discuss in detail.
     
  6. dude_obj

    dude_obj Vault Senior Citizen
    Moderator

    Oct 19, 2004
    Well if you use FSE you don't use another tool, it's your editor, translator, and compiler. It uses the official compiler, so its not unofficial. As to the matter of translation, personal choice I guess, I want my FO1 scripts to be same format as FO2, and I'm not writing code in noid format.

    I don't normally use FSE, I too have some customized batch scripts, but I know it translates noid to interplay and hooks into the official compiler. Jargo is making a command line version of his translator. When that is done I can change my whole set of FO1 script source to interplay format with one command.

    Regarding FO1, what would be really useful is the building of header files over time, like the FO2 headers, where you can specify things by name rather than number (GVARs, PIDs, etc).
     
  7. Shadowbird

    Shadowbird Where'd That 6th Toe Come From?

    442
    Jul 20, 2003
    As I've said - I worked out this prob by modifying the Noid's decompiler, so I get a straight Interplay SSL right away.

    Well, most of the stuff can be used from Fallout 2 - IMO there are more additions than changes, so it shouldn't be too hard to convert them back. And all GVARS are in the vault13.gam file.
     
  8. WraithUV

    WraithUV It Wandered In From the Wastes

    140
    Feb 22, 2005
    Well thanks to Shadowbird and dude_obj, I seem to have FO1 script decompiling and compiling working, which is a good thing.

    Now then... heh. Dear gods what a mess. I'm guessing from what I'm hearing that no one has ever whipped up (or released) some headers for these things anywhere?

    I mean... From looking at these things, I'm guessing that:
    Code:
     
        critter_add_trait(self_obj, 1, 6, 2);
        critter_add_trait(self_obj, 1, 5, 6);
    
    ...set the given critter's Team (to 2) and AI packet (to 6)... Maybe lol.

    This is just a highly speculative guess really, since I'm basing this off disecting the decompiled script and looking things up in the FO2 DEFINE.H file -which of course I can only assume is only semi-compatable in the first place.

    Then you get into things like...
    Code:
        display_msg(message_str(114, 100));
    
    Which aparently displays the message found at index {100} in the left hand display window. Similar procs are used for float text and conversations as well, though the big question is, what does the "114" refer to?

    I mean, I understand that tells us which .msg file to look at, but at this point, I'm a little lost as to exactly what the 114 means -which leaves me completely guessing as to which msg file I need based on filename guessing basically -which is going to slow things down quite a bit.

    Does this somehow tie into PIDs, or is it something else entirely?

    And again, I appreciate the help and patience with my n00b issues. I have some fairly ambitious final goals in mind (though taking it in small steps to get there little by little at first), but diving into this fresh with very little actual doccumentation (especially specifically related to FO1) is a tad bit overwhelming right out of the gate. ;)

    -Wraith
     
  9. dude_obj

    dude_obj Vault Senior Citizen
    Moderator

    Oct 19, 2004
    That's what I was suggesting: as people figure out various parts of decompiled FO1 scripts, it would be good to make headers for what is known. I mean the equivalent of itempid.h, critrpid.h, aipacket.h, global.h, teams.h etc. If they exist I haven't seen them anywhere.

    That looks right to me. I don't think they would have changed something as basic as ID numbers for teams and AI packets (I hope).

    114 is the script ID. So to find the message file, the reference is scripts.lst. The 114th script in scripts.lst will have the same name as the message file. Hence the need for a scripts.h header. If you look at what the FO2 scripts do:

    #define br_mstr(x) message_str(SCRIPT_ZCBRAHMN,x)

    They put the script name (as found in scripts.h) into the define for br_mstr, which is a shortcut way of doing the same thing you are looking at in FO1.

    We all do :) Lots of patience and persistence is required.
     
  10. WraithUV

    WraithUV It Wandered In From the Wastes

    140
    Feb 22, 2005
    Ok... Now I'm getting mad lol

    I'm sure there's a simple answer to this, but it's driving me about crazy.

    From what I've seen, anything that references something by an index (say for example set_global_var(x,y); seems to start at 0 (zero) on the first line of a file, and then increment line by line. So if you mess around with say global_var(4), you're actually modifying whatever variable is named on line 5 of vault13.gam

    Ok, fine. This all makes perfect sense to me so far.

    The problem I seem to be having deals with local_var. First of all, the file scripts.lst also defines a number of local variables for each given script -though unless that number also counts any global_vars used by that script, I've no idea where the get their numbers.

    I'm tinkering slightly with cook.ssl (the cook in the Shady Sands kitchen) to do some simple things and see what's what.

    They had 3 variables:
    variable hostile := 0;
    variable initialized := 0;
    variable round_counter := 0;

    yet the lst file says 7. Furthermore, they've thrown me a total curve here someplace, since after a lot of trial and error, I found out that when they reference local_var(1), it's checking or setting hostile status which frankly doesn't make any sense as I would expect that being the first varible encountered declared in the file to be local_var(0), not 1.

    To frustrate me even more (yes, I'm certain this is the only reason for this) it SEEMS as if the variable following this (initialized) is being referenced as local_var(0) -though most often they seem to refer to this one directly by name instead, though strangely enough they only seem to do it for THIS variable. In any case, if the freaking variable before it (the first one in the file) is 1, how the hell is this one 0? lol

    So my questions are:
    1. Just how the hell are local variables indexed?
    2. What's up with the seemingly non-matching numbers in the scripts.lst file?
    3. Can you refer to a variable completely interchangably within the same file? That is, calling it local_var(x) as well as simply by name?
    4. With that in mind, can you manipulate them directly? I've seen some references like "hostile :=0;" which from anything I ever learned would be setting the local variable "hostile" to "0" -but if that's the case, why the hell use set_local_var(var, value) in the first place instead of just using X :=Y;

    GAH! ...um. Help? LOLl

    -Wraith
     
  11. Corpse

    Corpse Mildly Dipped

    554
    Apr 7, 2003
    I've never had to index them that way, usually when I try to call a local variable I refer to by the name I gave it at the start of the script. eg.

    Only exception is when I want to use variables that are not indexed in the variable list, I just create the variable header under the procedure where I am going to use that variable.

     
  12. jargo

    jargo Where'd That 6th Toe Come From?

    492
    May 25, 2003
    There is a BIG difference between normal SCRIPT variable with is declared at start of script like this:

    Code:
    variable foe_ptr :=0; 
    variable wield_ptr := 0; 
    variable ammo_ptr:= 0; 
    
    And used like this:
    Code:
    foe_ptr := Self_obj;
    
    These variables are not saved in savegame file!!!!

    There is another type of variable called LOCAL SCRIPT variable.
    How many of these variables are being used is set in scripts.lst

    Code:
    # local_vars=7
    
    If local_vars is set to 7 then you can use local variables with numbers from 0 - 6 like this:

    Code:
    set_local_var(5, 1);
    display_msg("Local var 5 has value: " + local_var(5));
    
    These variables are SAVED in the savegame file.
     
  13. WraithUV

    WraithUV It Wandered In From the Wastes

    140
    Feb 22, 2005
    Yeah, while beating on these scripts and docs and FAQs and any of the other 4 million windows I have open at the moment (lol -gotta love coding in a totally new environment) I figured it was along those lines.

    From what I now gather, there are:
    Global variables (vault13.gam) -always in effect everywhere and saved.
    Map variables (MapName.gam) - always in effect so long as the given map is loaded in memory - saved (I think) - need to export these to scripts to manipulate them directly (I think), but are fairly easily available to any script active in the given map.
    Script variables (ones you just declare and use in the script itself) - not saved, available to the script itself only (far as I can tell -besides of course if you passed a script variable's value to a global variable or something, but that's a different matter entirely)
    and finally, these darned local variables.

    From what I now think I understand, these are variables that are given memory allocation when a specific script is called (whether you actually use them or not), and they can be used and manipulated within the script, and their state will be saved in savegames or if you leave the map or whatever else.

    The only thing I can't figure out now is.. how do you know where / what these variables are set to? Does the engine simply set up a block of these things (like an array) based on how many you declare in scripts.lst and initialize them all to 0 (zero) - so you can then just grab one and use it any way you need within the script? Or is there actually an index of these things somewhere obvious I'm missing here? Or.. something entirely different? I've been digging through everything I can find, but other than my "array" idea here, I'm basically at a total loss for how these things would work since I can't find any mention of them other than the proceedures that work with them =/

    Thanks again,

    -Wraith
     
  14. jargo

    jargo Where'd That 6th Toe Come From?

    492
    May 25, 2003
    Small correction:

    Not exactly ;). You put two types of variables to one sack.
    You re right about map vars but there is one more variable type and it is IMPORTED/EXPORTED VARIABLE.
    Map vars don't need to bee imported just use them like local variables, and they are saved.

    Iported variables are not saved and they can bee exported from any script on map and imported by any other on the same map, but normal object(like critter) can be destroyed(killed), the best way to export variable is using map script(it cannot be destroyed).
    They exists untill exporter object exists.
    One exported var can be imported by many scripts.
    Imported variables are used like normal script variables:

    Code:
    import variable some_onj;
    ...
    
    some_obj := Self_obj;
    
    Yes when you set that script acklint.int has 7 local vars then engine will prepare 7 variable from number 0 to 6 for use when this script is run. They have 0 as initial value and are ready to use.
     
  15. Shadowbird

    Shadowbird Where'd That 6th Toe Come From?

    442
    Jul 20, 2003
    EDIT: The below is in Fallout 1.

    I think you're all making one mistake here - as far as I've tested, the
    Code:
    # local_vars=X
    line doesn't affect anything - IMO it's just a comment (unless its 0). For example, in my scripts.lst, I have
    Code:
    Seth.int        ; Seth from Shady Sands to transport to Rad Scorpion Caves.                   # local_vars=1
    , but I still use up to local_var(10) and local_var(11) without problems... The line only has any real effect if you set it to 0 - then none of the lvars seem to be working.

    Oh, and BTW, local vars from 0 to 3 are usually used for reaction settings:
    Code:
    #define LVAR_REACTION                   (0)       // Seth's reaction to player
    #define LVAR_REACTION_LEVEL             (1)       // Seth's reaction level to player (1:bad, 2:normal, 3:good)
    #define LVAR_REACTION_INIT              (2)       // Has initial reaction been applied?
    #define LVAR_REACTION_UNKNOWN           (3)       // Unknown variable, something with reaction. Only get's checked, never set.
     
  16. jargo

    jargo Where'd That 6th Toe Come From?

    492
    May 25, 2003
    Well in FO2 this is not a comment(# is a separator in scripts.lst) and it works just as expected, but never tested it in FO1.
    But i can't imagine this to not work since engine must know how many saved vars(and local_var is saved) it has to prepare(but it can be that FO1 has hard local vars number limit).
     
  17. WraithUV

    WraithUV It Wandered In From the Wastes

    140
    Feb 22, 2005
    OK... new question. It still deals directly with the topic though, and good manners taught me it's always best to try to add to a topic than begin a new one when possible.. so...

    I've been hacking my way through several scripts with slow but steady progress using Noid's decompiler, then FSE for conversion and editing (and recompile with the official and open watcom obviously).

    For the most part, things are going fine. I know my code is a bit ugly since I haven't taken the time to hack out a set of headers so have no macros etc etc, but still, they work so it's all good.

    However, in the script "obj_dude", down near the end one command decompiled to "maybe_8148();" and the converter turns it into "8148;"

    I have absolutely no clue what the hell that is or does, but it seems to compile just fine -though not knowing what it is does make me a little nervous about causing problems I may be unaware of.

    Worse, I wanted to do some work to old buddy Ian, and there's a similar line in there. It decompiles to "maybe_812c();" and converts then to "812c;"

    Besides it making me wonder as above, this one doesn't compile unless I comment the line out. I get an error on that line of "TEMP.SSL(199): Error! expecting ';'."

    So... anyone have any idea what the hell this is, and what I should do about it? I know I can get it to compile by commenting it out, but I'd really rather not do that without knowing what the hell it is first.

    Thanks,
    -Wraith
     
  18. Shadowbird

    Shadowbird Where'd That 6th Toe Come From?

    442
    Jul 20, 2003
    maybe_8148 == endgame_movie
    maybe_812c == inven_unwield
     
  19. WraithUV

    WraithUV It Wandered In From the Wastes

    140
    Feb 22, 2005
    Appreciate it Shadowbird.

    Is there a list of these somewhere so if I run into more of them (which wouldn't shock me) I don't have to keep pestering people?

    I kinda figured they must be things Noids didn't quite know how to decompile right when I looked at 'em, but it was beyond me (besides completely guessing) how to figure out what they'd be lol

    -Wraith
     
  20. jargo

    jargo Where'd That 6th Toe Come From?

    492
    May 25, 2003
    Hey thanks Shadowbird will update converter to handle this opcodes.