These pages describes the addin file format for World of Goo, specification version 1.1, as implemented by GooTool.
Addins are extensions to World of Goo that add or modify functionality. There are two types of addin: mod and level. Mods can modify or replace any file. Levels can do the same but also get a button added to Chapter 1 allowing them to be played. Addins can depend on other addins. For example the level addin MyLevel could depend on the MyOrangeBall mod addin.
The binary format of an addin is just a Zip file with a .goomod extension and a special directory structure. The directory structure of the Zip file follows:
Some knowledge of XML, XSLT and XPath may be helpful to create anything but the simplest addins. There are some examples in this documentation, and more in the addin development FAQ.
You can also look at existing addins in the download section, particularly the sample category which illustrates advanced addin techniques.
Specification version 1.0 was the first public goomod version and is supported by all versions of GooTool.
Specification version 1.1 is the updated version released in November 2009, and is supported in GooTool 1.0.1 upward. If your addin is a level addin, to upgrade to this version you will need to surround your <level> with a <levels> element.
Attempts to install a 1.1 goomod into an old version of GooTool will result in a message instructing the user to upgrade GooTool.
The following features were added in version 1.1:
Comments? Discuss in the forum.
The "addin.xml" file contains the definition of the addin and is read by GooTool. It contains descriptions of the addin for the user, and also technical data used by GooTool. It must be located in the root directory of the goomod file.
The root XML element is addin and this has one required property, spec-version. This describes the version of this specification that the addin follows. This document describes version 1.0. This is not related to your addin version at all.
Then follow a number of required and optional elements.
The format of the field is alphanumeric identifiers separated by periods. The field begins with your reversed domain name. This is your namespace and it is up to you to partition it as you wish. This is followed by any details needed to identify this particular addin. For example: com.mycompany.mods.mymod.
If you do not have a domain name, but you do have an account on goofans.com, you can use our domain and your username as your namespace: com.goofans.<yourname>. For example if your username is robert and you've made a level "Going Down", you might name the addin com.goofans.robert.levels.goingdown.
The format is a sequence of between 1 and 4 version number components separated by periods. Each component consists of decimal digits, and within each component the version should be numerically comparable. For example, version 1.11 must be a newer version than 1.2. It is perfectly permissible to have only 1 component to the version number, in which case no periods are needed.
Examples of valid version numbers:
1
0.1
1.0.2
1.5.0.1
Note that any unused components are treated as zeros. So version "1" is equivalent to "1.0.0.0" in terms of comparison.
The first choice is plain text, in which case any newlines in the description are preserved. CDATA is optional here.
The second choice is HTML, for which CDATA wrapping is required. HTML is identified by a description that begins with <html> and ends with </html>. You can use any basic HTML formatting allowed by Java within this description.
The format is a set of <depends> elements. Each of these elements has a required attribute ref, which is ths id of the addin you require. You can also specify optional min-version and max-version attributes, in which case your addin will not be enabled unless the other addin matches the versions you specify.
You should use this element rather than merge with chapter 1 yourself for several reasons. First, it allows GooTool to put your texts in text.xml automatically. Second, allowing GooTool to do it will ensure that multiple custom levels do not overlap each other on the display. And third, when World of Goo has better modding support, GooTool will add your mod to a custom chapter instead. If there are compelling reasons to still do overrides yourself, please contact the author so better support can be built into GooTool or this spec.
In goomod version 1.0, level was a direct child of addin. Goomod version 1.1 supports multiple levels, so level is now a child of levels, and there can be more than one of them present.
The level element has three required and three optional child elements.
The name and subtitle elements may also be internationalized in the same way that existing goo levels are using two-letter language attributes.
Here is the manifest file for an example mod. This one is taken from the Merger test mod in GooTool's test suite:
<addin spec-version="1.1"> <!-- The unique ID of this addin. Read the spec for uniqueness and format requirements. --> <id>net.davidc.test.merger</id> <!-- Short display name shown to user. --> <name>Merger Test</name> <!-- either "mod" or "level". For user display, and to determine whether to create a chapter 1 entry --> <type>mod</type> <!-- An optional thumbnail image of the mod (goomod 1.1+ only) --> <thumbnail type="image/jpeg" width="200" height="150">thumbnail.jpg</thumbnail> <!-- Version. Must be numerically comparable in each "."-delimited component. You could also do it without periods at all, e.g. 11281.--> <version>1.0</version> <!-- Description shown to user when mod is selected. Basic HTML is allowed if you put it in a CDATA and surround it with <html></html>. --> <description><![CDATA[ <html> <p>This addin is a test of the merger. It has the following functions:</p> <ul> <li><b>GoingUp</b> - Changes unattached balls to UglyProduct, and turns on visual debug.</li> <li><b>SmallDivide</b> - Removes all black balls and adds a new structure of drip balls.</li> </ul> <p>N.B. This test addin modifies existing game levels. It is intended for test purposes only, so don't make any changes that could allow leaderboard fudging (e.g. changing to ivy balls would allow them to save more balls).</p> </html> ]]></description> <!-- Author shown to user. --> <author>davidc</author> <!-- No dependencies. --> </addin>
<addin spec-version="1.1"> <id>net.davidc.gravitas</id> <name>Gravitas</name> <type>level</type> <thumbnail type="image/png" width="200" height="150">thumbnail.jpg</thumbnail> <version>0.5</version> <description>This is a lovely level you can play. It has awesome gravity!</description> <author>davidc</author> <!-- Other addins this one depends on. --> <dependencies> <depends ref="net.davidc.test.mynewball" min-version="1.0"/> </dependencies> <!-- Details about this level --> <levels> <level> <dir>Gravitas</dir> <name text="Gravitas" de="Schwerkraftas"/> <subtitle text="weighty matters" de="gewichtige Angelegenheiten"/> <ocd>balls,16</ocd> </level> </levels> </addin>
A future version of this spec may introduce a chapter addin type, if World of Goo ever supports this.
Like the override and merge directories, files inside the compile directory are relative to the World of Goo installation directory.
The compile directory directory contains XML files which are compiled (encrypted) into bin format. This allows GooTool to compile the file for you, so you don't have to distribute different versions of your addin for Mac and PC.
Files ending in .xml are automatically compiled to the same filename but with a .bin extension instead. For example, your addin file /compile/res/levels/MyLevel/MyLevel.level.xml is compiled to <WorldOfGoo dir>/res/levels/MyLevel/MyLevel.level.bin.
Once the .binltl format is figured out (if that turns out to be useful - it's only used for animations which seem to be programmatically triggered), another file extension will identify files to be compiled to .binltl format.
Like the override directory, files inside the merge directory are relative to the World of Goo installation directory. However that's where the similarity ends. Files in the merge directory are not replaced, they are merged with the 2dboy originals (and possibly also merged with the results of lower-priority mods). Consequently the merge directory only operates on XML files.
The format of files in this directory are XSLT stylesheets, enabling full control of the produced XML. For each file that you want to merge, GooTool decrypts the 2dboy original, merges in your changes, and encrypts it back. (It also makes a backup of the original; it always merges from the 2dboy original and doesn't do incremental merging as that would have unexpected results when enabling and disabling addins).
The filenames end with the .xsl extension instead of .bin. An example of a full filename relative to your goomod root would be merge/res/levels/GoingUp/GoingUp.level.xsl. Note that the .bin suffix is replaced with .xsl.
Some knowledge of XSLT and XPath will help create complex merging rules, but the rest of this page contains some examples. You may also find davidc's XML Diff tool helpful - you give it the original XML file and your modified XML file, and it gives you back an XSL file that will make the changes.
You need a default rule to copy across anything not matched by any other rules. Here it is:
<!-- Copy everything not matched by another rule --> <xsl:template match="* | comment()"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template>
You can modify existing elements by selecting them with your XPath. Remember to copy @* to preserve the other attributes, and to apply-templates to copy their child elements. The follow example selects all BallInstance elements, copies their attributes, and then overrides their type attribute:
<!-- Change existing balls to UglyProduct --> <xsl:template match="/level/BallInstance"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:attribute name="type">UglyProduct</xsl:attribute> <xsl:apply-templates/> </xsl:copy> </xsl:template>
Remember that the most specific rule matches, so here we select the balls where their id attribute is less than 4, and copy them unchanged. In this example, we're changing to UglyProduct balls, which don't have strands defined, so we don't want to touch the first 4 balls which are already connected.
<!-- But we must leave the first 4 balls alone, since --> <!-- Ugly balls don't have strand definitions --> <xsl:template match="/level/BallInstance[@id < 4]"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template>
In this example we modify the visualdebug attribute of the level element to enable graphical display of the level scene structure.
<xsl:template match="/level"> <xsl:copy> <xsl:copy-of select="@*"/> <!-- set visual debug. set attributes after copying them, so we can overwrite --> <xsl:attribute name="visualdebug">true</xsl:attribute> <xsl:apply-templates/> </xsl:copy> </xsl:template>
Here we match all strand elements and delete them simply by not copying them at all.
<!-- Delete existing strand instances --> <xsl:template match="/level/Strand"/>
If we wanted to add more Strands back in, we could select the "Arms" comment and add them there:
<xsl:template match="/level/comment()[contains(., 'Arms')]"> <xsl:copy/> <Strand .... insert our strands here > </xsl:template>
Or, because WoG doesn't validate against a DTD, we could just add them to the end of the level element. This is probably preferable in case comments are removed or changed by another addin or by 2dboy in a future release.
Note that the new stuff is inside the <xsl:copy> - if outside it would append after the level is already closed!
<xsl:template match="/level"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates/> <Strand .... insert our strands here > </xsl:copy> </xsl:template>
This example modifies the EconomicDivide (displayed name: Small Divide) level using the above examples. The first template copies everything that isn't matched by another template untouched. The second template removes all balls. The third inserts balls where the old balls were (after the Balls comment). The fourth deletes all strands. The fifth modifies the level element by enabling visualdebug, and adds new Strands to the end of the file (demonstrating the second method of adding elements).
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Copy everything not matched by another rule --> <xsl:template match="* | comment()"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <!-- Delete existing ball instances --> <xsl:template match="/level/BallInstance"/> <!-- insert drip balls into the place where the previous balls were --> <xsl:template match="/level/comment()[contains(., 'Balls')]"> <xsl:copy/> <BallInstance type="water" x="-459.69" y="262.68" id="0" angle="0" /> <BallInstance type="water" x="-341.64" y="279.34" id="1" angle="0" /> <BallInstance type="water" x="-232.63" y="284.03" id="2" angle="0" /> <BallInstance type="water" x="-122.63" y="284.03" id="3" angle="0" /> <BallInstance type="water" x="-122.63" y="184.03" id="4" angle="0" /> <BallInstance type="water" x="-329.74" y="411.84" id="5" angle="0" /> <BallInstance type="water" x="-329.74" y="411.84" id="6" angle="0" /> <BallInstance type="water" x="-329.74" y="411.84" id="7" angle="0" /> <BallInstance type="water" x="-329.74" y="411.84" id="8" angle="0" /> <BallInstance type="water" x="-329.74" y="411.84" id="9" angle="0" /> <BallInstance type="water" x="-329.74" y="411.84" id="10" angle="0" /> </xsl:template> <!-- Delete existing strand instances --> <xsl:template match="/level/Strand"/> <!-- Set visual debug and insert new Strands --> <xsl:template match="/level"> <xsl:copy> <xsl:copy-of select="@*"/> <!-- set visual debug. set attributes after copying them, so we can overwrite --> <xsl:attribute name="visualdebug">true</xsl:attribute> <xsl:apply-templates/> <!-- Here is where we can insert nodes at the end of the file --> <!-- As a demo, just insert the new strands at the end --> <Strand gb1="0" gb2="1" /> <Strand gb1="1" gb2="2" /> <Strand gb1="2" gb2="3" /> <Strand gb1="3" gb2="4" /> </xsl:copy> </xsl:template> </xsl:transform>
How the goo am I going to reach the exit now?

You can see a similar example in action in the merger-test addin.
The override directory inside the goomod file contains files that the addin provides or replaces. These can either override default files, or be entirely new files. Within this directory are files to override relative to the World of Goo installation directory.
For example to override the main body image of the Drained ball, the path relative to your addin zip file would be /override/res/balls/Drained/body.png
It is illegal to override a file in the World of Goo directory itself, and GooTool will not load the addin if it has files directly inside override.
Note that if you replace the same file that another addin does, the file will end up being overridden by the addin that has priority (as selected by the user by dragging the addins around).
The override directory is NOT the place to put XML (compiled or otherwise). Use the merge directory for this.
For Mac compatibility, ".png" files in the override directory are treated specially. They are automatically compiled into the Mac version's ".png.binltl" format, thus producing the same effect as on the PC version.
So, you want to create a goomod that changes the appearance of the Goo Balls in the game? Well, you've come to the right place! Read on!
You probably already know the graphics you want to change, right? Hopefully you do. But you'll have to find the actual image names, as they may be slightly different for each Goo Ball. To figure this out, browse to your World of Goo directory. You should see a few files, and two folders: "properties" and "res". Double-click on "res".
You'll see a bunch more folders. One of them will be called "balls". Double-click that one.
Now, hopefully you already know what kind of Goo Ball you want to change. If so, find the appropriate folder and double-click it. Take note, however, that the Goo Balls in World of Goo Corporation are actually in the "Drained" folder.
Now that you're in the folder of the Goo Balls you want to change, you'll see a bunch of files. Some of these will be .bin files. These are the actual Goo Ball properties, and you don't want to change them, or else you'll get a big fat red "cheater" badge, and you don't want that. The other ones are OGG files, which are the sounds that the Goo Balls make in certain instances. If you want to be really creative in your mod, you can change these too, but most people don't. So concentrate on the PNG images for now. I'll take the example of the Fuse Goo Ball for now. Note that other Goo Balls will be slightly different.
So in the /res/balls/Fuse/ directory, you'll see 6 PNG images:
body.png,
splat1.png,
splat2.png,
spring_goo.png,
spring_goo_burnt.png, and
strand_pull.png
Hopefully, it's fairly obvious what these images are and what they do. So now, you have a list of the images you'll need to create to make these Goo Balls look different.
Before you go editing the images, copy them somewhere that they're easy to access, like your desktop or your documents folder, and work of these copies. You don't want to change the originals, anyway, in case something goes wrong.
So, how do you edit these images? If you're getting the images from somewhere else, or if you've already created them, your job is easy. Simply make sure the images are the same size (in pixels, width and height), make sure they're the same names, and skip to the next step. If you haven't made any images yet, however, read on.
First things first: NEVER EVER EVER USE PAINT TO MODIFY THESE IMAGES. Paint does not support transparency, so any images you create will have white boxes around them and they'll look awful. What program you use is up to you, just don't use Paint. Kyle Gabler, when he created the original images, used Photoshop, so if you have that and know how to use it, you're good to go. I personally use GIMP, which is somewhat of a free alternative to Photoshop, others prefer Paint.NET or similar. Just find a program you like and use it. You've got a lot to choose from: http://en.wikipedia.org/wiki/List_of_raster_graphics_editors#List
Once you've got your images, make sure they have the right names. Capitalization matters, so if you've changed the "body.png" file and you save it as "BODY.png", "body.PNG", or "Body.png", it won't work. It has to be exactly the same name as the original.
Now you're ready to stick the files into a goomod!
Sounds scary, doesn't it? It isn't. I just like big fancy words. Basically, you want to make sure that the images you have changed are in the right folders. So, go someplace handy (Like your desktop or your documents) and create a new folder named "res".
Here, you'll want to make the full file path of the graphics you overrode. Huh? For example, I'll take overriding the Fuse Goo Balls, as I did in my mod Dynamite Fuse Goo Balls.
In this mod, I changed the following images:
body.png
(As you can see, you don't have to change all of the images to get the effect you're after!)
So, the full file path of these Goo Balls (starting from the World of Goo folder) is res/balls/Fuse/. Now you'll need to create this path. Go to someplace convenient (ie your desktop or documents folder) and create a folder. Name it something you'll remember. You'll put all the files for your goomod in here. Go into that folder, and create a folder inside that named "override". Then go into that folder. Now you'll want to create the right path. To do this, create a folder named "res", go inside that folder, and create a folder named "balls", and go inside THAT folder and create a folder named "Fuse" (In my case; if your path that you determined earlier is different, it'll be something else). Now stick the images you created into this final folder.
Are we done? Nope. It's time to edit some XML.
Oh, no! Programming! Actually, this isn't too bad. First things first: go back up to the folder in your desktop/documents (the folder that you created the "override" folder in) and create a new text document named "addin.xml" (See here if file extensions are disabled; they are by default). Right-click on this file and choose "Open With"->"Notepad". You can't just double-click on the file, since it'll open with Internet Explorer or whatever your default web browser is.
Now highlight the following code, press Control-C, go into Notepad, and choose "Edit"->"Paste" (or Control-V):
<addin spec-version="1.1"> <!-- The unique ID of this addin. Used to check if it's already installed or compare its version --> <id>com.goofans.yourname.modname</id> <!-- name shown to user --> <name>Your Mod Name</name> <!-- either "mod" or "level". For user display, and to determine whether to create a chapter 1 entry. For a ball-changing addin, this has to be 'mod'. --> <type>mod</type> <!-- Version. Must be numerically comparable at each "." boundary. You could also do it without periods. 11281 is a fine version number.--> <version>1.0</version> <!-- description shown to user --> <description>This mod IS THE BEST MOD EVAH!</description> <!-- author shown to user --> <author>yourname</author> </addin>
<!-- and --> tags is stuff that's there to help you fill it out). So, for my mod, I'll change the<id>com.goofans.yourname.modname</id><id>com.goofans.MOM4Evr.Dynamite</id><name>Your Mod Name</name><name>Dynamite Goo Balls</name><version>1.0</version><version>1.1</version>,<description>This mod IS THE BEST MOD EVAH!</description><description>This mod changes the fuse gooballs into sticks of dynamite. Version 1.1: Created an XML file out of the .bin to make it cross-platform.</description>,<author>yourname</author><author>MOM4Evr</author>.
Ok, that's done! You can save your file in Notepad and exit Notepad now.
Now that the hard part's over, all that remains is to select both the "addin.xml" and the "override" folder, right-click, and choose "Send to"->"Compressed (zipped) folder". Rename this new .zip file to "com.goofans.[yourname].[modname].goomod" (Remember that you'll have to have file extensions turned on to change this to a .goomod! See here if they aren't enabled). So in my case, I'll name mine "com.goofans.MOM4Evr.Dynamite.goomod". Note that this is the same thing I put in the <id></id> part of the addin.xml, only with a ".goomod" tacked on the end.
Are we done? Well, almost.
This goes for ANY addin. ALWAYS ALWAYS ALWAYS test it before you upload it to goofans. So fire up GooTool, install the addin, and launch World of Goo. Go to a level that has the Goo Ball type that you changed. If it shows up, great! But if it crashes the game, doesn't show some images, or something like that, go back and make sure you did everything correctly. If the level didn't even install with GooTool, check your addin.xml to make sure you did everything right. If your new images don't show, make sure you named all the folders right. If GooTool says that there was an "Uppecase file extension", that means that one of your images is named ".PNG" instead of ".png" as it should be. If you can't figure out what you did wrong, upload the goomod someplace, post a link to it in the forums, and we'll gladly help you troubleshoot.
What? Are you serious? Yep, I'm serious. DO NOT UPLOAD YOUR ADDIN TO THIS SITE. Us moderators don't like addins that just change one kind of Goo Ball's appearance. Yes, I just wasted a few minutes of your time reading this. See here. We don't want single-Goo-Ball-changing addins. If you beg and plead enough, we might publish it, but we'll do it reluctantly and you probably won't get very good ratings or many downloads anyway.
But what about the "Dynamite Fuse Balls" addin that you made, MOM4Evr? Why was that approved? Well, see the date I published it and see the date that Daft as Brush made that forum post? I snuck in under the radar before those rules were made. 
So don't upload your addin. Period. Ever.
No, I'm just messing with you. The point of this tutorial is that you can create awesome, new, exciting addins that don't just change ONE kind of Goo Ball, but that change A LOT of them. All you have to do is add the right folders and files inside your /override/res/balls/ folder. Notice what Daft as Brush says we like: "Theme Packs which make only graphical changes to the original balls and or levels". Note that this is plural. "ballS" and "levelS". So if you change more than one kind of Goo Ball (like Winter and Industrial Revolution. These levels are rated pretty high and have a lot of downloads!), we're happy.
Guess what? I just told you how to create addins that modify ANY of the original World of Goo graphics! All you have to do is make sure the file paths are right. So if you're changing the background image in the level Second Hand Smoke, all you have to do is create an image, name it "bg.png", and stick it in your goomod in the folder "/override/res/levels/SecondHandSmoke/". How's that for nifty? The "override" folder in goomods is awesome!
This book page will hopefully hold our tutorial for making your own chapter. It's not finished yet, but stay tuned...
If you want to make a chapter, the first step will be to make an island map. The accepted format is to call this level "island", then a number, then a letter. The letter should be different for each person: for example, my Another Planet chapters use an "X".
So if I create my first new chapter and decide to use the letter "H", I would call the level "island1H". My second would be "island2H", and so on.
Currently used letters are as follows:
I'll continue this later tonight. -AP
Recently, we've had a bunch of people who want to make more than one level per .goomod, so I've decided to make a step-by-step guide to help you guys out.
First, you need to get your .goomods unzipped. Remember that as per goomod specification (here), a .goomod is just a renamed .zip file. For Linux/Unix users, this isn't much of a problem, but as Windows hides file extensions by default, you'll need to do an extra step.
There are two possible methods (Thanks, thB):
- Open Control Panel (usually from the Start Menu)
- Search for "Folder"
- Click on "Folder Options"
- Open Windows Explorer (Win+E on your keyboard, or just Start Menu->Documents)
- Click "Organize" in that toolbar at the top (left).
- Click on "Folder and search options" in the menu
After you do either of these, a new window will appear. Click the "View" tab up top, and scroll down in the "Advanced Settings" box until you see a checkbox with the name "Hide extensions for known file types." Uncheck it. You should now see your levels have an extension of .goomod, and you ought to be able to rename them .zip easily (Ignore the warning message that Windows gives you when you try to do so).
As an alternative for method 2, if you have the toolbar enabled in Windows Explorer (You can show it even if you don't by pressing the Alt key), you can click the "Tools" menu, and reach "Folder Options" from there.
These directions are for Windows Vista and 7. Other flavors of Windows will be slightly different, but essentially the same.
After you've gotten them to be two (or more) .zip files, you can simply right click on them and select "Extract All...". Windows will guide you through the extration process with a nice little wizard.
Once you have two unzipped .goomods (preferably in two different folders), you'll see a couple folders (called "compile" and "override", and maybe one called "merge") and a couple XML files (called "addin.xml" and "text.xml"). If you're missing any of these, don't worry; not all goomods have to have them (Actually, all level goomods HAVE to have at least an "addin.xml" and a "compile" folder, but the rest of these are optional). Now, you'll want to copy these together. The easiest way to do this is to go to one of them, select the FOLDERS (not the "addin.xml" and "text.xml" files, but the "compile", "override", and "merge" folders themselves), press Control+C to copy them, browse back to the other extracted .goomod, and press Control+V to paste. Windows will prompt you, asking if you want to merge these folders together. Tell it yes. If any files conflict, skip those files. You won't need duplicates.
This is the hard part. Follow these steps EXACTLY or something may go terribly wrong:
Go back to the first goomod (The one you copied the folders out of before). Select "addin.xml" and "text.xml" and press Control+C to copy these. Go back to your second one and paste. Because these are named the same thing, Windows will prompt you. Choose to "Copy, but keep both files". This will cause the two .xml files from the first .goomod to get copied, but renamed to "addin (2).xml" and "text (2).xml" or similar.
Now right-click on "addin (2).xml" and choose "Edit" (If this isn't there, choose "Open with..."->"Notepad"). Notepad will open and you'll see a whole bunch of gobbledygook (Unless you've had previous XML experience before, in which case you'll probably drool over how nice and clean the code is). It ought to look something like this:
<!-- Created by WooGLE v0.77 Final -->
<addin spec-version="1.1">
<id>com.goofans.MOM4Evr.RabidManiac</id>
<name>RabidManiac</name>
<type>level</type>
<version>0.1</version>
<description>What kind of raving lunatic would do such a thing? Certainly not me... ?!</description>
<author>MOM4Evr</author>
<levels>
<level>
<dir>RabidManiac</dir>
<name text="Rabid Maniac" />
<subtitle text="He looks less evil than he is" />
<ocd>time,20</ocd>
</level>
</levels>
</addin>Now do the same thing to open "addin.xml" with Notepad. You'll see something similar to above.
The key now is to get the right stuff from "addin (2).xml" and stick it into "addin.xml". What is the right stuff? I'll tell you:
Select the stuff between the <levels> and </levels> tags, not including the tags themselves. In the case of the file above, this will be:
<level>
<dir>RabidManiac</dir>
<name text="Rabid Maniac" />
<subtitle text="He looks less evil than he is" />
<ocd>time,20</ocd>
</level>Of course, your addin will have your own level's name and all that, but it'll always be the stuff between <levels> and </levels>. Now, double-check that you've selected everything in there (Don't miss one little bracket) and press Control+C to copy it to the clipboard. Go back to "addin.xml". Now, you'll want this in the same spot it was in the previous file, only this time there's some stuff already there. To work this out, place your text cursor (not the mouse cursor) right past the </level> tag that's already there. That's the </level> tag, not the </levels> tag. Press Control+V to paste the text there. You should end up with something like the following:
<!-- Created by WooGLE v0.77 Final -->
<addin spec-version="1.1">
<id>com.goofans.MOM4Evr.RabidManiac</id>
<name>RabidManiac</name>
<type>level</type>
<version>0.1</version>
<description>What kind of raving lunatic would do such a thing? Certainly not me... ?!</description>
<author>MOM4Evr</author>
<levels>
<level>
<dir>RabidManiac</dir>
<name text="Rabid Maniac" />
<subtitle text="He looks less evil than he is" />
<ocd>time,20</ocd>
</level>
<level>
<dir>FarLands__L02</dir>
<name text="Far Lands - level 2"/>
<subtitle text="Far Lands"/>
<ocd>balls,16</ocd>
</level>
</levels>
</addin>Thanks, Hany. 
Now what? Well, it'll work now, so take a deep breath and press Control+S to save the file. But this file still has all the same stuff as the original (second) goomod had, like the same description and stuff. You'll want to change this all to reflect this brand new .goomod (No, you're not done yet, but I know you'd like to be).
So, update the appropriate fields. This will be the stuff between the <id></id> tags, the stuff between the <name></name> tags, the stuff between the <version></version> tags, and the stuff between the <description></description> tags (And in my case, the stuff between the <author></author> tags, but if you want to merge in someone else's level, you'll have to ask them first of course!). So the changes you make might look like the following when you're done:
<!-- Created by WooGLE v0.77 Final -->
<addin spec-version="1.1">
<id>com.goofans.MOM4Evr_Hany.ManiacalLevel2</id>
<name>Rabid Maniac with a piece of Level 2</name>
<type>level</type>
<version>1.0</version>
<description>What kind of raving lunatic would do such a thing? Certainly not me... ?! And why is there a "Level 2" in here now?</description>
<author>MOM4Evr and Hany</author>
<levels>
<level>
<dir>RabidManiac</dir>
<name text="Rabid Maniac" />
<subtitle text="He looks less evil than he is" />
<ocd>time,20</ocd>
</level>
<level>
<dir>FarLands__L02</dir>
<name text="Far Lands - level 2"/>
<subtitle text="Far Lands"/>
<ocd>balls,16</ocd>
</level>
</levels>
</addin>Of course, if you're feeling particularly confident, you can change anything else you want, too, just don't mess with anything that's between a less-than and a greater-than symbol.
Now that that's all over, save the file and close both Notepad windows. You're done! With this part, anyway...
If you put signposts in your levels, good news! You still have more work to do with XML. Of course, if you don't have signposts, skip this step altogether, and if you have signposts in one level, you should be set. Just make sure there's one file by the name of "text.xml" and you're done. But if you put signposts in both levels, read on.
First, you'll want to open both the "text.xml" and the "text (2).xml" files in Notepad, like I told you how to do with the "addin.xml" pair. These will look slightly less complicated (hopefully!) unless you have a bunch of signposts in each level. They'll look more like the following:
<!-- Created by WooGLE v0.78 RC3 --> <strings> <string id="SIGNPOST_BROKENBONES2_2" text="Huh...|You can say that you are back!|Back to the factory,|Back to the robot room!|Only...|Some things are changed...|The robots are simply destroyed...|Even more too bad...|They are broken...|But anyway try to use your previous skill how to explode the head...|-the Sign Painter" /> <string id="SIGNPOST_BROKENBONES2_1" text="Ones apone the time...|There were lots of robots...|After they have been destroyed...|The bones only left!|-the scary Sign Painter" /> <string id="SIGNPOST_BROKENBONES2_3" text="May be you don't see...|But next to me behing this big cog hiding one little gear|May be if it is ball buster then may be it can help you with the ugly|- the Sign Painter" /> </strings>
(Thanks, Wikigoo-4evr)
Note that there may be more than one <string>, and there may not. This is perfectly ok; it'll just depend on how many signposts you have in each level. Make sure you're in "text (2).xml" and select everything between the <strings> and </strings> tags. For this file, that would be the following:
<string id="SIGNPOST_BROKENBONES2_2" text="Huh...|You can say that you are back!|Back to the factory,|Back to the robot room!|Only...|Some things are changed...|The robots are simply destroyed...|Even more too bad...|They are broken...|But anyway try to use your previous skill how to explode the head...|-the Sign Painter" /> <string id="SIGNPOST_BROKENBONES2_1" text="Ones apone the time...|There were lots of robots...|After they have been destroyed...|The bones only left!|-the scary Sign Painter" /> <string id="SIGNPOST_BROKENBONES2_3" text="May be you don't see...|But next to me behing this big cog hiding one little gear|May be if it is ball buster then may be it can help you with the ugly|- the Sign Painter" />
Then press Control+C to copy the data, go to "text.xml", and position your text cursor right BEFORE the </strings> part. Press Control+V to paste. You should end up with something along these lines:
<!-- Created by WooGLE v0.78 RC3 --> <strings> <string id="TEXT_SHIFTINGMACHINE_STR1" text="Welcome back to the factory!|Here is one more thing that haven't been done!|These goo balls need your help!|Ouch!|These spikes realy hurt everyone!|But not the goo balls|I mean they KILL the goo balls!|So be careful!|-the Sign Painter" /> <string id="SIGNPOST_BROKENBONES2_2" text="Huh...|You can say that you are back!|Back to the factory,|Back to the robot room!|Only...|Some things are changed...|The robots are simply destroyed...|Even more too bad...|They are broken...|But anyway try to use your previous skill how to explode the head...|-the Sign Painter" /> <string id="SIGNPOST_BROKENBONES2_1" text="Ones apone the time...|There were lots of robots...|After they have been destroyed...|The bones only left!|-the scary Sign Painter" /> <string id="SIGNPOST_BROKENBONES2_3" text="May be you don't see...|But next to me behing this big cog hiding one little gear|May be if it is ball buster then may be it can help you with the ugly|- the Sign Painter" /></strings>
The cool thing about XML is that indentation and spacing and such don't matter. So even though this example here looks odd because of the gap in the middle and the </strings> tag being butted right against the pasted data, it'll still work fine.
Now that that's done, save the "text.xml" file and close Notepad. Yay! You're done! Well... almost. Read on.
Now that all the above is done, the rest should be fairly easy. What you'll want to do is get the right stuff back into a .goomod and put it on goofans! What is the right stuff? Well, it's easy. Select the folders you have in the second goomod (In case you haven't guessed, this is the one you're going to upload), which will be the "compile" and "override" folders (and maybe "merge", if it's there). Also select the "addin.xml" and "text.xml" files. Ignore the other xml files here; you're done with them. Now, with these four items (And these four items ONLY) selected, right-click and choose "Send To"->"Compressed (zipped) Folder". A new file will appear called "[something].zip", where [something] may be your level name, or it could be something else. Rename this to [your addin ID].goomod . Remember that in "addin.xml" there's this part that is between the <id> and </id> tags? Well, this is your addin ID that you specified in WooGLE. In the case of my addin above, mine was "com.goofans.MOM4Evr_Hany.ManiacalLevel2". So I'll name this addin "com.goofans.MOM4Evr_Hany.ManiacalLevel2.goomod". You can name it anything you want, but it's a good idea to give it the same name as your addin ID.
Now are we done? Yes, we are! But before you upload it to goofans, INSTALL IT IN GOOTOOL AND MAKE SURE BOTH LEVELS WORK. If either of them don't work, go through all the steps above and make sure you followed them exactly. If you can't find the problem, ask in the forum or in the comment section below.
I hope this helps! Of course, you can make more than just 2-level addins following these steps. Just use your brain and make sure all the XML comes out looking like above, and you should be fine. If you're merging more than 2 addins together, though, I'd recommend merging two together, testing it, merging a third one into the result, testing that, and so forth, so it's easier to figure out if/when you've made a mistake.
Have fun!
An addin may supply strings to be added to the game's text.xml file. These strings are stored in a file called text.xml in the addin's root directory. This facility is only available in goomod format 1.1 onwards.
This allow addins to easily add or replace text in the game's text.xml file without having to write a merge XSLT. For example, you can quickly add signpost text.
The addin's text.xml file may contain both new strings (specific to that addin) and existing strings (which override entries already in the game's text.xml file).
The format of this file is the same as World of Goo's existing text.xml. The root element is strings which contains a number of string children.
Each string has two mandatory attributes: id and text (the English/default text). Optionally it can have additional attributes, where the attribute name is the 2-letter language code supported by World of Goo.
It may be important to watch the encoding of your file if you are using international character sets. Particularly, make sure you are using a UTF-8 aware editor, and specify the encoding in the <xml> directive.
The following example is taken from Jingle Balls version 1.3:
<?xml version="1.0" encoding="UTF-8"?> <strings> <string id="SIGNPOST_JINGLEBALLS_1" text="'Twas the night before Christmas, when all through the house|Not a creature was stirring, not even a mouse.|The Goo Balls were nestled all snug by the fire.|In hope of avoiding the Sign Painter's ire.|Fat chance. Let's open the present early.|-Ebenezer Sign Painter" es="Era la noche antes de Navidad, y en toda la casa|ni una criatura se movía, ni tan sólo un ratón.|Las Bolas de Goo se acurrucaban junto al fuego|deseando escapar de la ira del escritor de carteles.|Gran oportunidad; pongámoslas a trabajar.|-el escritor de carteles de las Navidades pasadas." ru="В рождественскую ночь, когда все дома у меня|И даже мышь не шевельнется в норке.|Все шарики устроились уютно у огня.|В надежде избежать Авторской порки.|Но нет им шанса отдохнуть. Придется отправляться снова в путь.|-трудолюбивый Автор" de="In der Nacht vor dem Christfest, da regte im Haus|sich niemand und nichts, nicht mal eine Maus.|Die Goo-Bälle machten es sich vor dem Feuer bequem.|In der Hoffnung der Wut des Schildermalers zu entgehen.|Gute Chancen. Lasst uns das Geschenk früh öffnen.|-Ebenezer Schildmaler" nl="'t Was de nacht voor Kerstmis, en in heel het huis,|Was geen teken van leven, zelfs niet van een muis.|De Goo-ballen lagen bij het vuur te dromen,|In de hoop aan de bordjesschilder te ontkomen.|Mooi niet! Laten we het cadeau alvast openmaken.|-Ebenezer Bordjesschilder" fr="C'était la veille de Noël, lorsque dans toute la maison|Personne, pas même une souris, ne laissait entendre un son.|Les Boules de Goo étaient nichées bien au chaud près de l'âtre.|Dans l'espoir d'éviter la colère du peintre des pancartes.|Pas de chance. Ouvrons les cadeaux en avance.|-le peintre des pancartes Ebenezer" /> <string id="SIGNPOST_JINGLEBALLS_2" text="A bundle of toys lying here 'neath the tree?|Could Chapter Six be there just waiting for me?|Bah, only more Goo Balls in festive attire.|But yummy, let's roast them all over the fire." es="¿Hay acaso regalos esperando bajo el árbol?|¿Estará allí el Capítulo 6 esperándome?|Bah, sólo más navideñas Bolas de Goo.|Ñam ñam, vamos a asar las castañas." ru="Гора игрушек, возлегающих под елкой?|Или шестая часть игры там ждет меня?|Эх нет, и только шарики Гуу одеты как с иголки.|И значит нужно их поджарить, сидя у огня." de="Ein großer Geschenkeberg liegt neben dem Baum so fein?|Könnte es das wartende, sechste Kapitel sein?|Bah, nur noch mehr Goo-Bälle im festlichen Gewand.|Lasst uns sie über dem Feuer rösten mit knusprigem Rand." nl="Zie ik speelgoed liggen onder de boom?|Hoofdstuk Zes misschien, waar ik al tijden van droom?|Bah, meer Goo ballen met muts en baard.|Maar wel lekker, geroosterd boven de haard." fr="Qu'est-ce derrière l'arbre, un tas de jouets?|Est-ce le chapitre six que depuis longtemps j'attendais?|Oh, ce ne sont que des Boules de Goo dans un déguisement joyeux.|Miam, faisons-les rôtir au-dessus du feu." /> <string id="SIGNPOST_JINGLEBALLS_3" text="As I drew in my head, and was turning around|Up the chimney escaped the Goo Balls with a bound.|But I heard them exclaim, 'ere they climbed out of sight,|"Happy Christmas to all, and to all a good-night!"" es="Tal y como había imaginado, y así sucedía|por la chimenea escapaban las Bolas de Goo.|Pero las oí gritar, al escapar de mi vista,|"¡Feliz Navidad a todos y Próspero Año Nuevo!" " ru="Я обернулся так, что растянул всю шею, что за наказанье|И дымоход скрывает шариков бегущих, что есть мочи.|Но прежде чем убраться с глаз долой, услышал я их восклицанье,|"Счастливого Рождества, и всем спокойной ночи!"" de="Dann wollt' ich die Fensterläden zuzieh'n|und sah den Haufen durch den Kamin entfliehen.|Doch ich hört' sie noch rufen, von fern klang es sacht:,|"Frohe Weihnachten allen, - und allen gut' Nacht!"" nl="Toen ik even niet oplette, namen ze de benen,|En zijn de Goo-ballen door de schoorsteen verdwenen!|Maar ik hoorde ze roepen, door de schacht,|"Vrolijk kerstfeest allemaal, en een goede nacht!"" fr="Alors que je levais la tête, en regardant partout|Par la cheminée s'échappaient les boules de Goo.|Alors qu'elles disparaissaient, leurs paroles j'entendis,|"Joyeux Noël à tous, et à tous une bonne nuit!"" /> </strings>
This ANT build file is used by davidc to build distributions of multiple addins. It's not required for general addin development but is provided here for anyone who may wish to use ANT.
You will need ant-contrib for the <foreach> task. Addins should be in individual subdirectories. It will automatically read the addin.xml file to pick up the IDs and version numbers.
<?xml version="1.0"?> <!--$Id: build.xml 263 2009-04-22 23:53:12Z david $--> <project name="addins" default="build" basedir="."> <property name="addins.src" value="src"/> <property name="addins.dest" value="dist"/> <taskdef resource="net/sf/antcontrib/antlib.xml" classpath="../lib/build/ant-contrib-1.0b3.jar"/> <target name="build" description="Builds all addins in the src directory"> <mkdir dir="${addins.dest}"/> <foreach target="-foreach-addin" param="src.dir"> <path> <dirset dir="${addins.src}" includes="/*/"> </dirset> </path> </foreach> </target> <target name="-foreach-addin"> <!-- Read the XML file to get the addin name and version --> <xmlproperty file="${src.dir}/addin.xml"/> <fail unless="addin.id" message="No Addin ID set in ${src.dir}"/> <fail unless="addin.version" message="No Addin version set in ${src.dir}"/> <property name="out.file" value="${addins.dest}/${addin.id}_${addin.version}.goomod"/> <zip file="${out.file}"> <fileset dir="${src.dir}"> <exclude name="**/.svn"/> <exclude name="**/Thumbs.db"/> </fileset> </zip> </target> <target name="clean" description="Removes everything that was built"> <delete dir="${addins.dest}"/> </target> </project>