Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: HowTo Rubble - The Rubble tutorial thread  (Read 2862 times)

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
HowTo Rubble - The Rubble tutorial thread
« on: November 22, 2013, 10:27:42 am »

This thread is where I will post any and all Rubble tutorials as I wright them. Feel free to ask questions about anything Rubble related.

(Once I get more tutorials a TOC will go here)
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: HowTo Rubble - The Rubble tutorial thread
« Reply #1 on: November 22, 2013, 10:28:20 am »


Tutorial 1: Basics

This tutorial introduces a few of the basic Rubble templates and explains how to create a simple addon.

In this tutorial I will be recreating the Better Dorfs Bonfire addon.

The bonfire is a simple furnace that lets you create two kinds of burning objects, one that burns out fairly quickly and one that burns for quite a while.

First install Rubble as directed in it's readme.
Now create a new directory in the addons directory, call it something like "Bonfire Tutorial", this is your addon directory.

Let's start with the building. Create a new file in your addon directory and name it something like "building_bonfire_tutorial.txt", then paste the following code into that file.
Code: [Select]
[OBJECT:BUILDING]

{BUILDING_FURNACE;BONFIRE;ADDON_HOOK_PLAYABLE}
[NAME:Bonfire]
[NAME_COLOR:6:0:1]
[DIM:1:1]
[BUILD_KEY:CUSTOM_SHIFT_F]
[WORK_LOCATION:1:1]
[BLOCK:1:O]
[TILE:0:1:240]
[COLOR:0:1:6:0:0]
[TILE:1:1:'#']
[COLOR:1:1:6:0:0]
[TILE:2:1:19]
[COLOR:2:1:6:0:0]
[TILE:3:1:30]
[COLOR:3:1:6:0:0]
There are two things of note in this file. First there is no file header, Rubble adds this automatically, so renaming a file goes from an error-prone two step process to just a simple file rename. Second you will note that the building tag is replaced by some weird thing that uses curly-brackets and has an extra parameter, this is a Rubble template. This particular template is a direct replacement for the raw tag of the same name, but it also has one other very important function. This template (as well as lots of other related Rubble templates) registers a building with an object class. A Rubble object class is a list of items/buildings/reactions/whatever listed under a name. By using other templates you can extract a list of a specified type of items from a class and do things with them, in this case automatically add building permissions to entities.
ADDON_HOOK_PLAYABLE is a special class that can be used for items, reactions, and buildings, it is part of a special group of object classes created by the #ADDON_HOOKS template (which I will explain in more detail later).

Now that we have a building we need some reactions. Create a new file and name it "reaction_bonfire_tutorial.txt", then paste the following code into that file.
Code: [Select]
[OBJECT:REACTION]

{REACTION;BONFIRE_BIG_START;ADDON_HOOK_PLAYABLE}
[NAME:ignite large fire]
[BUILDING:BONFIRE:CUSTOM_L]
[REAGENT:A:5:WOOD:NONE:NONE:NONE]
[PRESERVE_REAGENT]
[PRODUCT:100:1:BOULDER:NO_SUBTYPE:INORGANIC:BIG_BONFIRE]
[FUEL]
[SKILL:SMELT]

{REACTION;BONFIRE_SMALL_START;ADDON_HOOK_PLAYABLE}
[NAME:ignite small fire]
[BUILDING:BONFIRE:CUSTOM_S]
[REAGENT:A:1:WOOD:NONE:NONE:NONE]
[PRESERVE_REAGENT]
[PRODUCT:100:1:WOOD:NO_SUBTYPE:INORGANIC:SMALL_BONFIRE]
[SKILL:SMELT]
The REACTION template is almost exactly like the BUILDING_FURNACE template (except, of course, it replaces the REACTION tag instead of the BUILDING_FURNACE tag)

Of course those reactions won't work without the inorganic materials BIG_BONFIRE and SMALL_BONFIRE.
Create a new file (name it "inorganic_bonfire_tutorial.txt") and paste the following code into it.
Code: [Select]
[OBJECT:INORGANIC]

{SHARED_INORGANIC;BIG_BONFIRE;
[STATE_NAME_ADJ:ALL_SOLID:bonfire]
[DISPLAY_COLOR:0:0:1]
[TILE:15]
[ITEM_SYMBOL:15]
[IGNITE_POINT:11000]
[MAT_FIXED_TEMP:20000]
[MELTING_POINT:NONE]
[BOILING_POINT:NONE]
[SPEC_HEAT:10000]
[SOLID_DENSITY:10000]
[IS_STONE]
[NO_STONE_STOCKPILE]
}

{SHARED_INORGANIC;SMALL_BONFIRE;
[STATE_NAME_ADJ:ALL_SOLID:firewood]
[DISPLAY_COLOR:0:0:1]
[TILE:15]
[ITEM_SYMBOL:15]
[IGNITE_POINT:11000]
[MAT_FIXED_TEMP:20000]
[HEATDAM_POINT:11000]
[MELTING_POINT:NONE]
[BOILING_POINT:NONE]
[SPEC_HEAT:10000]
[SOLID_DENSITY:10000]
[IS_STONE]
[NO_STONE_STOCKPILE]
}
Wow, what's this SHARED_INORGANIC thing? That is one of the SHARED_OBJECT templates. SHARED_OBJECT (and the templates based off of it, like SHARED_INORGANIC) provides a mechanism for replacing or modifying objects from other addons. In this case it's not terribly useful, but using it every time you can is a good habit to get into. I will not go into detail about exactly what SHARED_OBJECT (or it's children) does as that would take far too much time, I suggest you go read the documentation for the "Base Templates" for the whole story.

Now there is one last detail, "How exactly do I make my building/reactions usable?". To put it simply, you already have.
Earlier I mentioned the #ADDON_HOOKS template, this very useful template is already in every entity in the Base/Files addon. Basically #ADDON_HOOKS adds calls to all the required templates to insert entity permissions for items, reactions, and buildings for the following classes:
ADDON_HOOK_GENERIC
ADDON_HOOK_<entity name> (For example ADDON_HOOK_MOUNTAIN or ADDON_HOOK_PLAINS)
and if the entity is playable (dwarves only by default) ADDON_HOOK_PLAYABLE
This means that your new addon should be immediately usable by the dwarves and any other playable races that may be added by other addons.
Of course for #ADDON_HOOKS to work you need to have declared the item/building/reaction with the proper Rubble template, but as you have seen that is a simple matter for buildings and reactions. For items it is a little more complicated, but that is for a later tutorial.
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: HowTo Rubble - The Rubble tutorial thread
« Reply #2 on: November 22, 2013, 10:28:46 am »


Tutorial 2: Custom Templates

This tutorial introduces the simplest aspects of custom templates.

I will not be making a full addon in this tutorial, rather I will just make a template and a few reactions.

Say you want to make a workshop that allows you to produce metal weapons without needing an anvil. The first problem you will encounter is that writing enough reactions to make such a workshop useful is a tremendous amount of work. Using a Rubble template to cut out most of the redundant parts of the reaction allows you to make such reactions in as little as one line, allowing you to make dozens of reactions in very little time.

Anyway enough talk, time for the template:
Code: [Select]
{!TEMPLATE;FORGE_ITEM;id;name;type;mat;matname;count=1;
{REACTION;FORGE_%{id}_%{mat};ADDON_HOOK_SWAMP}
[NAME:forge %matname %name]
[BUILDING:WARCRAFTER_SAURIAN:NONE]
[REAGENT:metal:150:BAR:NONE:INORGANIC:%mat]
[PRODUCT:100:%count:%type:%id:INORGANIC:%mat]
[FUEL]
[SKILL:METALCRAFT]
}
The first thing to note is that the template body consists mostly of normal Rubble code with a few odd little bits prefixed with a '%' symbol. Each of these "Replacement Tokens" is defined just before the template body and just after the template name. For example the first of these tokens (also called "Template Parameters", or just "params") is named "id" and can be accessed via "%id" or "%{id}". The value of a template parameter is detremined when the template is called.

To really describe how a user defined template like this works we need values for the parameters, so here is an example call:
Code: [Select]
{FORGE_ITEM;ITEM_WEAPON_SPEAR_SAURIAN;small spear;WEAPON;STEEL_WATER;water steel}

That call will expand into the following:
Code: [Select]
{REACTION;FORGE_ITEM_WEAPON_SPEAR_SAURIAN_STEEL_WATER;ADDON_HOOK_SWAMP}
[NAME:forge water steel small spear]
[BUILDING:WARCRAFTER_SAURIAN:NONE]
[REAGENT:metal:150:BAR:NONE:INORGANIC:STEEL_WATER]
[PRODUCT:100:1:WEAPON:ITEM_WEAPON_SPEAR_SAURIAN:INORGANIC:STEEL_WATER]
[FUEL]
[SKILL:METALCRAFT]
As you can see it is just a straight forward variable expansion.
One thing sharp-eyed readers may have noticed is that there was never a value defined for "count", if you will look up to the template definition you will see that count is followed by an equals sign (=). If a parameter name is followed by an equals sign whatever is after the equals sign is used as the default value for that parameter if that parameter is not given a value, so in this case count defaults to "1".

There are a few more interesting things that standard templates like this can do, but most of them have been replaced by the much more flexible !SCRIPT_TEMPLATE (which is too advanced to detail here). For more on how templates work, and how they interact with other parts of Rubble, see "Rubble Addons.txt" and the last section of "Rubble Process.txt".

(The templates/items/materials used in this tutorial come from the "Better Dorfs/Saurian/Warcrafter" addon)
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

Urist McTeellox

  • Bay Watcher
    • View Profile
Re: HowTo Rubble - The Rubble tutorial thread
« Reply #3 on: November 23, 2013, 09:59:06 am »

Loving this! Looking forward to the next tutorial! :)

~ T
Logged

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: HowTo Rubble - The Rubble tutorial thread
« Reply #4 on: November 25, 2013, 10:51:25 am »

The next tutorial is ready, I just need to get it to a "real" computer so I can upload...

FYI: The next one will deal with Raptor scripting and the next after that will be tileset addons or basic tweak scripts.
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: HowTo Rubble - The Rubble tutorial thread
« Reply #5 on: November 26, 2013, 02:46:55 pm »

So the next tutorial is ready to go... But I forgot it at home, oops  :(
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: HowTo Rubble - The Rubble tutorial thread
« Reply #6 on: December 02, 2013, 12:59:37 pm »


Tutorial 3: Raptor Script, Some Basic Commands

This tutorial introduces some basic Raptor scripting commands.
WARNING! This tutorial assumes you have read the "Raptor Basics" document that comes with Rubble!
WARNING! The following information is very spotty, hey it's a lot of stuff to cover, let's see you do better ;)

Raptor is a custom scripting language I use for various projects, but the only thing that matters is that if you really want to get the most out of Rubble you need Raptor. Raptor scripts are used to make advanced templates and tweak scripts as well as a few other small things.

This tutorial will not try to teach you to program (that would take far too much time), nor will it try to teach you the Raptor syntax (that's what "Raptor Basics" is for), I will merely try to present some important commands that everyone should know.

Types:
There are three main "kinds" of types in Raptor, built-in types, indexable types, and user data.
The built-in types are integer, string, float, bool, command, and code. All built-in types can be converted to any other built-in type seamlessly, these types are purely internal.
Indexable types are defined by the same external packages as commands, there is only one indexable type built into Raptor (the type used by the "params" array). The version of Raptor used by Rubble has several indexable types, but they all act like map or array. map and array are the only two types that can be created by the user (outside of some commands), map is an associative array (you can use any string as the key) and array is a traditional linear array (you can only use integers as keys). I will talk more about indexables later.
User data is a catch-all term for anything a command wants to stuff into a value that is not an indexable or built-in type. Most of the time user data is only useful to commands from the same package as the one that created it in the first place.

len
len is very simple, just pass it an indexable value and it returns how many keys it has.

set and var
var is used to create new variables, very simple.
set allows you to change the value of a variable, also very simple, at least until you get to indexables...
set is used to add new keys to an indexable, for map all you need to do is set a non-existent key, for array the only key you can add is the one just passed the end, eg if len returns "10" for an array indexable that means that the existing keys are 0-9 and if you set key 10 you will be appending to the array.

exists
exists checks if a key exists in an indexable, invaluable when working with indexables

foreach
foreach is the first of the two native loop commands provided by Raptor (Rubble comes with some user command loops as well). foreach will iterate over all key/value pairs in an indexable until it gets to the end or you tell it to stop (by using breakloop or returning false)

loop and if
Raptor, unlike most programming languages, has no key words, so if and loop are commands like any other. This can lead to some odd issues for those used to the usual way of doing things.
if is simple, except for one thing: it returns a value just like every other command. if will return unchanged so whatever the last command is in the block if runs is what if returns.
loop is more complicated. loop will continuously run a block of code until the return value is "false" (for strings: "", for integers: 0, for booleans: false, for the other types: it's complicated, don't ask) or the BreakLoop, Exit, or Return exit state is set (eg you call exit, ret, or breakloop) This property is why most calls to loop either contain nothing but a call to if that wraps the whole loop body or the loop body ends in "(break true)" ("(break true)" is the Raptor equivalent of most language's "continue" keyword, sort-of, its complicated).
Most of the time you do not need to use the raw loop commands as Rubble comes with some predefined user commands that wrap loop into more familiar for and while commands.
Code: [Select]
# prints the numbers 0-9
(var count 0)
(loop {
(if (int:lt [count] 10) {
(console:print [count] "\n")
(break true)
}{
(break false)
})
})

breakloop
breakloop is a relatively new command that make loop and foreach interaction MUCH easier than it used to be. To put it simply (breakloop false) is like most languages "break" keyword and (breakloop true) is like "continue".

console:print
console:print will write data to the Rubble log and to the screen, good for status messages in tweak scripts.

I have only skimmed over the top of the most important commands, to find out more read the Raptor command documentation (in the "other/raptor command docs" directory in the Rubble download). How and where you can use Raptor scripts will be covered in later tutorials (there is also some information on the subject in the "Rubble Addons" document)
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: HowTo Rubble - The Rubble tutorial thread
« Reply #7 on: December 02, 2013, 01:00:05 pm »


Tutorial 4: Tileset Addons

This tutorial will show you how to build tileset support into your mod, as well as explain some simple procedures for porting existing tilesets to Rubble.

For details on how to use the templates mentioned here see the "Base Templates" documentation that comes with Rubble.

So you want your cool new mod to support tilesets other than the default? Good thing Rubble goes out of its way to make that easy.

There are 4 core templates that provide support for tilesets:
   {#TILE;<ID>;<DEFAULT>}
   {SET_TILE;<ID>;<TILE>}
   {#COLOR;<ID>;<DEFAULT>}
   {SET_COLOR;<ID>;<COLOR>}

(The SET_XXX templates insert a entry in the tile or color dictionary that is later retrieved by the #TILE or #COLOR template with the same <ID>, if no entry for <ID> is present in the dictionary <DEFAULT> is used.)

These templates are a little cumbersome to use but you don't have to. All the specialized SHARED_OBJECT templates will detect tile and color information in their contents and automatically inserts calls to #TILE and #COLOR.
This means that you do not need explicit calls to #TILE or #COLOR as plants, inorganics, tools, and material definitions are handled automatically (while creatures have some tile information included, no tileset that I know of modifies this data).

With #TILE and #COLOR handled, all you really need to worry about is SET_TILE and SET_COLOR. If you are adding support for a brand new tileset, the easiest way is to use #WRITE_TILESET. #WRITE_TILESET is a developer template that makes a list of all calls to #TILE and #COLOR and generates a file containing the corresponding calls to SET_TILE and SET_COLOR.
You would then edit the file generated by #WRITE_TILESET to change the tile numbers and colors to match what you tileset needs.

If you already have raws there is a shortcut you can use that will cut the time needed by a considerable amount. To put it simply you do a quick hack job of inserting the SHARED_OBJECT templates, then generate a temporary addon consisting of the edited raws with the last file containing a call to our friend #WRITE_TILESET.
THIS PROCEDURE IS ONLY FOR CASES WHERE YOU ALREADY HAVE A FULL SET OF RAWS FOR YOUR TILESET! It is, IMHO, much easier to generate a default tileset addon and then edit that than it is to edit the full raws.

These instructions are written with the assumption that you are using Notepad++, if you are using another editor you will have to make sure it is capable of regular expression search and replace operations.

First make a new folder in you addons directory, this will be temporary, so name it anything you want.
Now copy all the raw files that your tileset modified to your new temporary addon, you want only the changed files.
Next add a file named something like "zzz_write_tileset.rbl" and add this line to that file: {#WRITE_TILESET;./tileset.rbl}
Now open all the inorganic material files, to speed things up it's best to have them all open at once.
Open the search/replace dialog and make sure the "Regular expression" radio button is checked.
Then enter the following search text: "\[INORGANIC:([^:\]]+)\]"
And this a the replacement: "}{SHARED_INORGANIC;$1;"
Now go ahead and hit "Replace All in All Opened Documents".
One last step: go through each file and remove the first '}' and add a '}' to the end of the file.

Now follow the above steps for plant, item, and material template files using the following search/replace pairs:
   "\[PLANT:([^:\]]+)\]" -> "}{SHARED_PLANT;$1;"
   "\[ITEM_([^:\]]+):([^:\]]+)\]" -> "}{SHARED_ITEM;$1;$2;"
   "\[MATERIAL_TEMPLATE:([^:\]]+)\]" -> "}{SHARED_MATERIAL_TEMPLATE;$1;"

Now generate the raws, activating ONLY your temporary addon, "Base/Templates", and "Base/Clear", the generated raws are useless, what you want is the file "tileset.rbl" that should be in your current working directory (generally the directory containing "rubble.exe").

Once you have your tileset.rbl file ready to go (however you got it) create a new addon and add the tileset.rbl file as well as your tileset's font image.

To install you tileset image all you need to do is add a call to INSTALL_TILESHEET to the top of you tileset.rbl file, for example:
Code: [Select]
{INSTALL_TILESHEET;test_16x16.png}

Now for editing the init files. Rubble provides a set of templates specifically for editing the tileset related init settings found in "d_init.txt".
To set the "font" (eg the tilesheet) you use the SET_FULLSCREEN_TILESHEET and SET_WINDOWED_TILESHEET templates. (Both templates also set the font to be used in graphical mode)
To set things like track tiles you use OPEN_D_INIT, EDIT_D_INIT, CLOSE_D_INIT, and D_INIT_TO_DEFAULTS. The following example makes pillars look like smooth floors ;)
Code: [Select]
{OPEN_D_INIT}
{EDIT_D_INIT;PILLAR_TILE;'+'}
{CLOSE_D_INIT}
Note that CLOSE_D_INIT will set ALL tileset related init settings to their defaults unless a call to EDIT_D_INIT has explicitly set that value! This is so that it is easy to reset values changed by other tilesets you may have installed before.
If you use all default init settings all you need to do is call D_INIT_TO_DEFAULTS to make sure an different tileset didn't clobber your settings.
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: HowTo Rubble - The Rubble tutorial thread
« Reply #8 on: December 02, 2013, 01:00:29 pm »


Tutorial 5: Basic Tweak Scripts

This tutorial will introduce tweak scripts and attempt to show some uses for them.

I personally use tweak scripts all over the place in my Rubble addons, as (by design) tweak scripts are incredibly flexible.

The original use I had in mind for tweak scripts was allowing you to "tweak" the raws after generation in ways that are hard for templates to do.
For example, the Rubble addon "Zap Aquifers", this addon consists of a single "post script" (a tweak script that runs after generation) that disables all AQUIFER tags in inorganic materials.
Here is the whole script that I will be dissecting:
Code: [Select]
(var aquifercount 0)
(var aquifercounttotal 0)

(foreach [rubble:raws] {
(if (str:cmp "inorganic_" (str:left [params 0] 10)) {
(var file (raw:init [params 1]))
(var tag (raw:current))

(console:print "    " [params 0] "\n")

(loop {
(raw:advance)

(if (raw:valid){}{(breakloop false)})

(if (str:cmp [tag id] "AQUIFER") {
(raw:disable)
(++ aquifercount)
})

(break true)
})
(console:print "      Found Aquifers : " [aquifercount] "\n")
(set aquifercounttotal (int:add [aquifercounttotal] [aquifercount]))
(set aquifercount 0)

(set [rubble:raws] [params 0] (raw:dump))
})
(break true)
})
(console:print "    Found Aquifers Total : " [aquifercounttotal] "\n")

First we will start with the top:
Code: [Select]
(var aquifercount 0)
(var aquifercounttotal 0)

(foreach [rubble:raws] {
...
})
The two variables are for logging, they keep track of how many aquifer tags we found in the current file and in all the files together.
rubble:raws is an indexable that contains all the files in all the addons indexable by name.

Now for the body of the foreach loop:
Code: [Select]
...

(foreach [rubble:raws] {
(if (str:cmp "inorganic_" (str:left [params 0] 10)) {
(var file (raw:init [params 1]))
(var tag (raw:current))

(console:print "    " [params 0] "\n")

(loop {
(raw:advance)

(if (raw:valid){}{(breakloop false)})

...

(break true)
})
(console:print "      Found Aquifers : " [aquifercount] "\n")
(set aquifercounttotal (int:add [aquifercounttotal] [aquifercount]))
(set aquifercount 0)

(set [rubble:raws] [params 0] (raw:dump))
})
(break true)
})
...
First we have an if command to check if the file contains inorganics, if not we just go on to the next file, simple.
If the file does contain inorganics we setup a few temporary variables, initalize raw parsing for the file, and print the file name (in params 0). Raw parsing is provided by commands in the "raw" namespace, and is rather simple as all you can do is step through the file one tag at a time modifying the current tag if you wish.
The loop command steps through the file one tag at a time checking if the tag is "valid" (eg EOF has not been reached) and breaking out of the loop if it is not.
After all tags have been processed it prints a message to say how many aquifers it has found, adds the current count to the total, and resets the current count.
Finally the modified raws are dumped to a string and that string is used to replace the old file contents.

Now for the meat of the script, the few lines that actually DO something.
Code: [Select]
...

(foreach [rubble:raws] {
(if (str:cmp "inorganic_" (str:left [params 0] 10)) {
...

(loop {
(raw:advance)

(if (raw:valid){}{(breakloop false)})

(if (str:cmp [tag id] "AQUIFER") {
(raw:disable)
(++ aquifercount)
})

(break true)
})
...
})
(break true)
})
(console:print "    Found Aquifers Total : " [aquifercounttotal] "\n")
Right after we check for EOF we check if the tag id equals "AQUIFER" and call raw:disable if so (raw:disable just removes the square brackets around the tag). Also we increment the current aquifer count.
Finally at the end, after all files are processed we print a message saying how many aquifers we found total in all files.

As you can see there is a lot of stuff in a script of this type that will change but little for other scripts that walk the raws like this, unfortunately most of these scripts differ just enough to make some kind of universal raw walker command impractical :(

One of the other big uses for tweak scripts is checking dependencies, for example:
Code: [Select]
(rubble:requireaddon "Some/Addon" "Some/Other/Addon")
Will abort generation with the message:
Code: [Select]
The "Some/Addon" addon requires that the "Some/Other/Addon" addon be active!
Please activate that addon and try again.
(There is also a command for specifying incompatible addons)
Most of the time you would want your dependency checks to be in prescripts, so as to abort as soon as possible.

"So how does Rubble know what is a postscript and what is a prescript" you ask? Simple, the file extension. Rubble "knows" a file ending in .pre.rsf i a prescript and a file ending in .post.rsf is a post script.

There are many, many things that you can do with tweak scripts, for more examples see the addons that come with Rubble.
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS