So you want to create a chapter? Great! This tutorial will guide you through the steps of doing so, and will show you how I created my Chapter Tutorial example chapter. Before you begin making your own chapter via this tutorial, though, I'd like to stress a few very important points:
Creating chapters is hard. Really hard. It's the most complex kind of addin development out there, and it takes a lot of time and effort. But it's super cool, and chapter addins are a great way to put together a lot of levels of yours that have one over-arching 'theme'. Don't despair; if you ever have any questions, post below or in the forums. Just follow these directions and you should be good to go.
Also please note that this is an intermediate-level tutorial, and not all of the small common-sense details are explained; if this is your first time working with goomods, you may be better off checking some of the other tutorials here first.
Knowledge of how addins work, how XML and XSL work, and the goomod format will help you big time. If you haven't already toyed around with the addin format, made a ton of levels already, made a few theme packs (even if you haven't posted them on this site), taken apart goomods that you think are cool, merged addins together into levelpacks, and more, then I would strongly recommend that you stop now. You'll be making it a lot harder on yourself if you don't at least have a basic understanding of how everything works already. But then again, you may learn how it all works by actually creating the chapter. If you are overwhelmed by the complexity or are running into problems left and right, then I would strongly urge you to stop working on the chapter, and get more experience with how goomods work first. davidc's level "Jingle Balls" is a great example here. It's one of the best levels I've ever played, and it was created with the old "wogedit" program (which was really hard to use!) and by hand-editing XML to create the Goo Balls. No Goo Ball editor, no nothing. It was the first .goomod released on this site, and was launched to promote GooTool. Knowledge of how everything worked was absolutely essential in those days. And it's a fantastic level, probably because of it.
File size is important, and can potentially be an issue. If your addin includes a ton of custom music, graphics, and such, it may be too large for this site. The upper limit for a .goomod is 20 MB, and anything above this just won't upload. If you're running into filesize issues, and your goomod isn't uploading, try to keep your images 1024x1024 or smaller (this will also help people with lower-end graphics cards), and your music clips 45 seconds or less. If your goomod is just slightly too large, you can try using a more advanced archiver than Windows' default one (I personally like 7-zip) and compress more than the default settings. It'll take a bit longer to compress, but should be able to squeeze the file size down a bit. Be sure you're still using .zip format, though! You can also check and make sure to remove transparency from any .png image, if it's a background image and doesn't need it. You can even save your .png's as .jpegs, and rename them ".png"; the latest versions of GooTool and WooGLE support this "thB JPEG Hack" as it's called.
If worst comes to worst, and you simply can't shrink your goomod down any more, fear not. Send an email to our trusted site leader Davidc (davidc at goofans dot com) with a way for him to download it, and hopefully he'll be around to upload your goomod for you. He's generally good about that sort of thing.
Please give us moderators time to test your goomod. You should have tested it yourself extensively (Being as complex a thing as a chapter, you should have played through the chapter more than once yourself while testing), but we'll need to test extensively, also. We'll try to be fast about it, if we can, but it may just take us a long while to test it. Please don't spam the publish request button; it may take a few weeks for us to finish testing it.
Copyright issues. This goes for any goomod, really, so I'll make this brief. Don't use any images or music you don't own the copyright to, or that has a nonfree license. If you make your own images or music, you're fine. OCRemix and Newgrounds are great places to look if you want new music; there's some really talented musicians in both places, and everything there is free. Also, don't use images, music, Goo Balls, or other assets from other people's goomods without asking permission first, just to be on the safe side.
Thou shalt not add any new chapters. Thou must only overwrite the ones that are there. A whole bunch of really brilliant goomodders have tried to add new chapters, and have all failed. Chapters are hardcoded, and there are only five of them. And will only ever be five, unless 2DBoy releases the source (hasn't happened yet, and they don't seem too eager to do so) or unless 2DBoy makes the changes necessary (which Ron said would be difficult, so that isn't likely either).
"But there's already a chapter 6 button in MapWorldView..." Yes, there is. And no, it doesn't work. It's hardcoded to not work. There's absolutely nothing you can do about it. If you're making chapter addins, you can only change the chapters that are here, which brings me to:
Please don't try to edit Island 1. It's a whole, big, huge can of worms that nobody should have to open. Seriously, it's a nightmare. I spent days on end making WorldSpin, and fried my brain in the process. In contrast, editing Island 2 took about 2 days of work and was totally easy in comparison (That's not to say it was easy, but it was way easier, and keep in mind that chapter development is a tricky business!). I'm a guy who knows what he's doing, and it was hard for me. The reason you shouldn't ever edit Chapter 1 is that level addins are merged into Chapter 1, and if somebody installs a level addin while your Chapter-1-overriding addin is installed, there will be very major problems. Island 1 is special and should be treated as such.
But I know nobody's going to listen. "But, MOM4Evr, I already have this great 5-chapter addin all planned out! I can't possibly compress this brilliant idea into chapters 2-5!" So, if you do edit Island 1, the below tutorial doesn't apply. At least, mostly. There's three ways you can edit Island 1, if you have to:
The Good Way
If you want to be a good addin developer, and want to impress us mods by knowing what you're doing, this will make up for ignoring our advice and overriding Chapter 1 when we asked you not to. What you'll have to do is merge in your changes to island1.scene.bin (the .resrc.bin and .level.bin files don't have to be merged if you don't want to merge them) rather than sticking the xml in compile/ in the goomod like normal. An ok way to do this is to use Davidc's XML Diff Tool (here) to create an XSL stylesheet from the original and your intended XML. I've personally run into glitches with the tool before, and the XSL it spits out is completely unreadable and quite a lot larger than it needs to be, but for people like me who know basically nothing about XSL, it's better than nothing. The better way is to read up on XSL (the goomod-specific tutorial here is great, or you can google for XSL tutorials, or read the W3C specs for XSL here) and create the XSL by hand. It's more time-consuming, but it's more readable, usable, and generally a lot easier to edit (This is what goomatz does because goomatz is awesome). While editing Chapter 1, though, there's a few things that GooTool counts on that you have to keep in mind:
-- Don't change the scene's maxy attribute. GooTool will change this automatically, and you'll mess everything up if you change it yourself. So don't.
-- Don't touch the buttongroup "levelMarkerGroup". GooTool will stick the buttons for levels in there, and this will fail if the buttongroup isn't there. You can change/remove the actual buttons of course, but don't remove the buttongroup.
-- Don't remove the resources for the buttons and OCD flags. I think the game crashes if you do so. In any case, GooTool expects the resources to be there, and it fails if they aren't.
-- Try to check and see if any other island1-merging addins aren't compatible with yours, and say so on your addin page. The addins that I know of at the time of this writing that merge into island1 are "WorldSpin", "Intelligent Islands", "Island 1 Enlarger", and "Island 1 Infinite".
The Bad Way
"But XSL is too hard! It doesn't make any sense at all!" Well, there is a tolerable way to override Chapter 1 if you absolutely have to, just follow the directions below for overriding Chapter 2, and you'll point the actual island to open your level map instead of the default "island1" map. Thing is, this will cause all level addins to not be playable, since they're stuck in the "island1" map. You'll need to explicitly state on your addin page that this should be the only addin installed in GooTool, and we (the mods) will tolerate it gladly enough. We won't be completely happy, but we won't force you to change everything.
The Ugly Way
You override res/levels/island[number] (i.e. you stick an "island1.scene.xml" in compile/res/islands/island1/ in your goomod). Addins that override any original level, chapter maps included, aren't tolerated on this site. Something will likely explode if you override island1. This shouldn't be an issue, since you can't directly edit original levels in WooGLE, but just in case anybody tries, it won't be published.
But enough with warnings and such. Let's make us a chapter!
Step 1. Create the Levels
Simple enough, really. Use WooGLE as normal to create each individual level and export them as .goomods. You're going to have to merge them all together, so keep them all in a folder where you can find them easily. Once you're done, rename all the .goomod's to .zip's (following the directions in Steps 1 and 2 here if you don't know how to already), and extract them all. Now, you should have a bunch of folders named "com.goofans.yourname.levelnames" all in the same folder. Create a new folder named something appropriate (like "alltogether"), and copy all the files in there. Note that you can't just copy com.goofans.yourname.level1 into that folder; you have to open the com.goofans.yourname.level1 folder, select all the files in there, go into your "alltogether" folder, and paste everything in there. Also note that you won't have to merge the "addin.xml"'s together, that'll come later. You will need to use data from each level's addin.xml, though, so hang on to them. I personally just let Windows rename those files to "addin (2).xml" and so forth. Once you're done with the goomod, though, be sure they aren't included in the final product.
However, your text.xml's will need to be merged. So follow the directions in Step 5 here to stick them all together. Once you're done, make sure your final one is named "text.xml" and you're good to go. Once again, be sure you don't include any "text (2).xml" files in the final goomod.
Step 2. Create the chapter map
Once you're done creating the levels, you'll need to have your chapter map where you can actually click on them and play them. This is the main difference between a chapter addin and a levelpack; if you don't need a chapter map, and you're perfectly fine with all your levels appearing in Chapter 1 in the upper left corner, then ignore this tutorial and follow this one.
There are quite a few major differences between creating a normal map and creating a chapter map that are important and need going-over.
First off, there's the buttons. You need some way to click on a button to play a level. To add a button, in the Scene tab in WooGLE, right-click the "scene" element and choose "Add button". A new button will appear. Change the id of the button to "lb_[levelname]" where [levelname] is replaced by the directory of your level (what the level is named in WooGLE, not the title you specified in the Addin tab of the level). So, if you want to play your level "The Jungle", which has a directory name of "TheJungle", then the button id should be "lb_TheJungle". Capitalization matters. Note that while you can scale the button directly using the handles on the corners, there are no rotation handles, so you'll have to specify rotation manually in the "rotation" field. Now set the "up" and "over" fields to be the images you want for the button to show. The "up" field will be the button when the mouse cursor isn't near it, and the "over" field will be the image that displays when your mouse cursor is overtop the button. This is used in the original levels to make the button slightly larger and lighter-colored when the cursor is near.
If you want to show off some cool skills, you can make dynamic buttons, like the kind in my example addin, and in WorldSpin. To do this, specify the "anchor" attribute of the button to be a dynamic piece of geometry. Now, the "center" field in the button is a relative offset from the geometry the button is anchored to, and as the geometry moves, the button will as well. Generally this isn't too terribly useful, but it's really cool to toy around with, and opens up some neat possibilities. However, level text won't be displayed properly, since the text will be displayed in the same position as when you moused over the button, and the button will move away from the text. To fix this, you can change the "over" image to have the level name actually on it, making this "over" image bigger than the "up" image if needed (It'll still display properly, and behave the same). Then, leave the "onmouseenter" and "onmouseexit" fields blank, and don't worry about creating text resources for this level later. You can see me doing this with the "MOM4EvrSonic" level in my example addin.
World of Goo will automatically make this level button appear if the dependency levels you specify are completed (which we'll do later, in the island's XML). Now, to make the button play a level, set the button's "onclick" field to "pl_[levelname]", and to make the level's name display properly, change the "onmouseenter" field to "ss_[levelname]" and the "onmouseexit" field to "hs_[levelname]". Repeat this for all the levels in your chapter, place them all correctly, and test out your level in WooGLE. Because of a bug in the game, actually clicking them will do nothing, and the level name won't display, but you'll be able to see the onmouseenter and onmouseexit images being displayed.
Now for the OCD flags. These are fairly simple. Make a scenelayer with your OCD flag image and set the "id" field to "ocd_[levelname]". Change the "anim" to "ocdFlagWave" if you want, and you're good to go.
TL;DR NOTE 2:
Actually, it doesn't have to be a scenelayer. If you have a dynamic button, make it a dynamic piece of geometry with the image set to the OCD flag, and hinge it to the object the button is anchored to. It'll display if you've gotten the OCD, and will remain hidden if you haven't, just like a "normal" scenelayer OCD flag, as long as the id is "ocd_[levelname]".
Now for the pipes that go between levels. These are fairly easy as well. Just make a SceneLayer, position it right, and set the id to "levelpipe_[levelname]", where [levelname] is the name of the second level you're connecting to. For example, if I have a button for "TheJungle" and a button for "WreckingBall" beside each other, and I want "WreckingBall" to be the level that's unlocked when "TheJungle" is complete, for the pipe going between WreckingBall and TheJungle I'll set the pipe's id to "levelpipe_WreckingBall". Note also that pipes are completely optional; some of the original levels (all of chapters 4 and 5, Welcoming Unit, etc) don't have them. Actual level dependencies (i.e. Unlock level Y when you complete level X) are set in the island's (not the map's) xml.
Now, test the level and see if it works. You should see all the level buttons, pipes, and OCD flags. Since the game doesn't recognize it as an island yet, it just displays all the images for now. This will change when you add the island's xml, as long as you have all the buttons and scenelayers named right. Make sure everything you want displayed is displayed, make sure everything is at the proper depth so that buttons display on top of pipes and such, add some particles and bushes and whatever you'd like, and get the chapter looking how you want it to look to players. When you're all done, go to the "Level" tab, select the "level" element, and changed "letterboxed" to "true" (Save this as the last step, since this will prevent you from panning around in the level when you launch it from WooGLE). Now that you're done, fill the "Addin" tab fields in with random garbage (you won't be using the addin.xml generated by this level), export it as a .goomod, rename it to a .zip, extract it, and copy everything (except addin.xml) into your folder with all your other goomod data. Merge in your text.xml if you have any text strings in your chapter, and you're done here.
Step 3. Merge in the island changes
You can also compile the changes in, but in this case, merging is both cleaner and easier. Just use goomatz's handy template:
<?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 levels --> <xsl:template match="/island/level"/> <xsl:template match="/island"> <xsl:copy> <xsl:copy-of select="@*"/> <!-- Change name and map attribute --> <xsl:attribute name="name">island name</xsl:attribute> <xsl:attribute name="map">folder name</xsl:attribute> <xsl:apply-templates/> <!-- Here is where you can insert your levels --> <level id="[LevelName]" depends="[Level]" name="LEVEL_NAME_" text="LEVEL_TEXT_" ocd="[OCD]"/> </xsl:copy> </xsl:template> </xsl:transform>
In my case, I want it to be named "MOM4Evr's Island", so I'll change the name to that, without the quotes (Note that the name is actually arbitrary; name it whatever you want). The folder name for the chapter map I created is MOM4EvrTutorialIsland2, so I'll change the folder name to that. Now for the levels.
<level id="[LevelName]" depends="[Level]" name="LEVEL_NAME_[LEVEL]" text="LEVEL_TEXT_[LEVEL]" ocd="[OCD]"/>
the id is the actual folder name of your level, like it's called in WooGLE. depends is what level should come before this one, so that this level will unlock when that level is completed. name and text are for text resources, which I'll go over later; for now, just name them LEVEL_NAME_[LEVEL] and LEVEL_TEXT_[LEVEL], where [LEVEL] is the UPPERCASE name of your level. ocd is the OCD for your level, in the format "balls,[ballnumber]", "time,[seconds]", or "moves,[movesnumber]", where [ballnumber], [seconds], and [movesnumber] are a number specifying how many Goo Balls, how many seconds, or how many moves respectively.
So, for example, my first level is named "TheJungle", it's the first in my mod, so it doesn't depend on anything, and it has no OCD. Therefore, for this level I'll have:
<level id="TheJungle" name="LEVEL_NAME_THEJUNGLE" text="LEVEL_TEXT_THEJUNGLE" />
My second level is called "WreckingBall", and I want it to unlock right after someone completes TheJungle, and it has an OCD of 5 seconds, so this one will look like:
<level id="WreckingBall" depends="TheJungle" name="LEVEL_NAME_WRECKINGBALL" text="LEVEL_TEXT_WRECKINGBALL" ocd="time,5" />
Note that a whole chapter will unlock when the first level (That you put in the XSL here) in that chapter has a depends="[level]" criteria that's met. If the first level in that chapter that has no depends, that chapter will stay unlocked, and that level will be playable from the beginning. For my mod here, I'm not worried about it, since it's a one-chapter addin. But if you want to make multiple chapters, you'll want to make the first level of one chapter depend on the last level of the previous chapter. For example, in the original game, Drool (The first level of chapter 2), depends on RegurgitationPumpingStation (The last level of chapter 1). This way, Chapter 2 unlocks when you complete Chapter 1.
Note also that the when the last level in the XML here is completed, the game will pan back to the main menu, and the particle effect for unlocking the next chapter will be displayed. So, in my case, even though "MOM4EvrSonic" is a random level I tacked on at the end, I want it next-to-last in the XML so that the chapter officially ends when "AllAboard" is completed.
My final XSL looks like this:
<?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 levels --> <xsl:template match="/island/level"/> <xsl:template match="/island"> <xsl:copy> <xsl:copy-of select="@*"/> <!-- change name and map attribute --> <xsl:attribute name="name">MOM4Evr's Island</xsl:attribute> <xsl:attribute name="map">MOM4EvrTutorialIsland2</xsl:attribute> <xsl:apply-templates/> <!-- Here is where you can insert your levels --> <level id="TheJungle" name="LEVEL_NAME_THEJUNGLE" text="LEVEL_TEXT_THEJUNGLE" /> <level id="WreckingBall" depends="TheJungle" name="LEVEL_NAME_WRECKINGBALL" text="LEVEL_TEXT_WRECKINGBALL" ocd="time,5" /> <level id="GravityHole" depends="WreckingBall" name="LEVEL_NAME_GRAVITYHOLE" text="LEVEL_TEXT_GRAVITYHOLE" ocd="moves,20" /> <level id="StackEm" depends="GravityHole" name="LEVEL_NAME_STACKEM" text="LEVEL_TEXT_STACKEM" ocd="moves,7" /> <level id="CrushingTest" depends="StackEm" name="LEVEL_NAME_CRUSHINGTEST" text="LEVEL_TEXT_CRUSHINGTEST" ocd="balls,20" /> <level id="CutTheChain" depends="CrushingTest" name="LEVEL_NAME_CUTTHECHAIN" text="LEVEL_TEXT_CUTTHECHAIN" ocd="balls,25" /> <level id="CableCar" depends="CutTheChain" name="LEVEL_NAME_CABLECAR" text="LEVEL_TEXT_CABLECAR" ocd="moves,2" /> <level id="CrushingZone" depends="CableCar" name="LEVEL_NAME_CRUSHINGZONE" text="LEVEL_TEXT_CRUSHINGZONE" ocd="balls,40" /> <level id="JobCriteria" depends="CrushingZone" name="LEVEL_NAME_JOBCRITERIA" text="LEVEL_TEXT_JOBCRITERIA" ocd="balls,25" /> <level id="MOM4EvrSonic" name="LEVEL_NAME_MOM4EVRSONIC" text="LEVEL_TEXT_MOM4EVRSONIC" ocd="balls,45" /> <level id="AllAboard" depends="JobCriteria" name="LEVEL_NAME_ALLABOARD" text="LEVEL_TEXT_ALLABOARD" cutscene="levelFadeOut,x,gooTransition_out"/> </xsl:copy> </xsl:template> </xsl:transform>
Wait, what's the cutscene="levelFadeOut,x,gooTransition_out" doing in AllAboard? Don't worry; I'll talk about cutscenes a bit later.
Step 4. Creating the text resources
In the last step, I told you to pretty much ignore the LEVEL_NAME_[LEVEL] and LEVEL_TEXT_[LEVEL] tags, just to name them according to your level names. Well, what are they? In World of Goo modding, resources are generally named in UPPERCASE, so these are resources, but we haven't defined them yet. We'll do so here. Since they're text resources, open up your text.xml for your addin that I told you to put to the side, and take a look. So far, mine looks like:
<!-- Created by WooGLE v0.78 RC3 --> <strings> <string id="TEXT_CRUSHINGTEST_STR1" text="Hi there!|This is a signpost.|It probably tells you to hurry or you'll be toast|or something like that|-The Sign Painter" /> <string id="SIGNPOST_JOBCRITERIA_1" text="Deep in the darkest factory...|I went searching for a new job.|And ended up here.|I guess the idea is to eject these Goo Balls onto this conveyor belt.|But someone else wants this job, too.|I don't know why.|It looks pretty boring to me.|I mean, I could do this for a few hours, but the rest of my career?|No thanks. You can have the job.|I hope they pay you minimum wage.|-The Sign Painter" /> <string id="SIGNPOST_WRECKINGBALL_1" text="Behold! The latest product of genetic engineering!|This Goo Ball, when attached, emits a high wavelenghth of photovoltaic electromagnetic radiation.|The last time one of these guys attached to another, my car started, all the lights in my house turned on,|and my toaster oven started singing 'My Bonnie Lies Over the Ocean.'|I guess that this radiation will turn on any machinery that's nearby.|What kind of machinery could get these other guys to the pipe, though?|...|Signed, The Sign Painter"/> </strings>
Well, first things first. Let's organize things a bit, and also solve a slight problem while we're at it. World of Goo by default defines Chapter 2's name in MapWorldView as "Little Miss World of Goo". Unless your chapter is named that, also, you'll probably want to change that. So let's add that. The text resource we want to override is "CHAPTER2_DESCRIPTION":
<string id="CHAPTER2_DESCRIPTION" text=""MOM4Evr's Island""/>
What's with the
"on either side? These are defined as quotation marks by the W3C (Remember them? They're the people who defined what XML is). The problem with a formatting language with XML is that you may want to use special characters, like <>/"' and that sort of thing inside an attribute field. If you try to, however, an XML parser (What reads the XML into the actual game) will have a hard time figuring out what you're trying to do. For example, since I want the text to be "MOM4Evr's Island", with the quotes, if I just type:
<string id="CHAPTER2_DESCRIPTION" text=""MOM4Evr's Island""/>
the parser will read the text attribute as text="", an empty string. Then it'll see
MOM4Evr's Island"", which isn't valid XML, and it'll stop there with an error. If you're using non alpha-numeric characters, here's a list of the ones World of Goo and GooTool support:
| = newline
Ok, enough about XML specifics. If we insert our line overriding CHAPTER2_DESCRIPTION right after the
<strings> field (which is where GooTool will start parsing the XML), we'll have:
<strings> <!-- Override chapter name in MapWorldView --> <string id="CHAPTER2_DESCRIPTION" text=""MOM4Evr's Island""/> <!--Signpost texts --> <string id="TEXT_CRUSHINGTEST_STR1" text="Hi there!|This is a signpost.|It probably tells you to hurry or you'll be toast|or something like that|-The Sign Painter" /> <string id="SIGNPOST_JOBCRITERIA_1" text="Deep in the darkest factory...|I went searching for a new job.|And ended up here.|I guess the idea is to eject these Goo Balls onto this conveyor belt.|But someone else wants this job, too.|I don't know why.|It looks pretty boring to me.|I mean, I could do this for a few hours, but the rest of my career?|No thanks. You can have the job.|I hope they pay you minimum wage.|-The Sign Painter" /> <string id="SIGNPOST_WRECKINGBALL_1" text="Behold! The latest product of genetic engineering!|This Goo Ball, when attached, emits a high wavelenghth of photovoltaic electromagnetic radiation.|The last time one of these guys attached to another, my car started, all the lights in my house turned on,|and my toaster oven started singing 'My Bonnie Lies Over the Ocean.'|I guess that this radiation will turn on any machinery that's nearby.|What kind of machinery could get these other guys to the pipe, though?|...|Signed, The Sign Painter"/> <!-- Level names --> </strings>
I added a few other things while I was at it. The stuff between the
-->tags are called comments, which basically serve no other use than to tell someone looking at the XML what the XML is doing. So my comment "Level names" right before the final
</strings>line is telling us to insert our level names in there. Let's do that.
For my first level, I want the level name to be "The Jungle". Notice that now I can finally put that space in there. Before now, I've been calling it "TheJungle", since that's the directory name in WooGLE, and World of Goo doesn't support spaces in folder names. However, we'll name it "The Jungle" here, since this is the text resource telling World of Goo what to display the name as. We can name it "Wharrgarbl" if we want to and it won't make any difference. So anyway, right after our comment I was just talking about, I'll add two more lines:
<string id="LEVEL_NAME_THEJUNGLE" text="The Jungle"/> <string id="LEVEL_TEXT_THEJUNGLE" text="By Gooton Sinclair" />
The LEVEL_TEXT_THEJUNGLE attribute here is the subtitle for the level, and here's where we get to specify it.
Ok, here's the important part. You'll want these to be named exactly the same as the XSL names you typed in Step 3. Let's look back at the XSL again for our level TheJungle:
<level id="TheJungle" name="LEVEL_NAME_THEJUNGLE" text="LEVEL_TEXT_THEJUNGLE" />
Notice that the LEVEL_NAME_THEJUNGLE part matches up exactly with our string we just made. If there's a typo anyplace, you'll have troubles, so your best bet is to copy the names and paste into the strings, so you know they match up precisely. Or just type really carefully.
Once we've got all our text made, our final text.xml will look like this:
<strings> <!-- Override chapter name in MapWorldView --> <string id="CHAPTER2_DESCRIPTION" text=""MOM4Evr's Island""/> <!--Signpost texts --> <string id="TEXT_CRUSHINGTEST_STR1" text="Hi there!|This is a signpost.|It probably tells you to hurry or you'll be toast|or something like that|-The Sign Painter" /> <string id="SIGNPOST_JOBCRITERIA_1" text="Deep in the darkest factory...|I went searching for a new job.|And ended up here.|I guess the idea is to eject these Goo Balls onto this conveyor belt.|But someone else wants this job, too.|I don't know why.|It looks pretty boring to me.|I mean, I could do this for a few hours, but the rest of my career?|No thanks. You can have the job.|I hope they pay you minimum wage.|-The Sign Painter" /> <string id="SIGNPOST_WRECKINGBALL_1" text="Behold! The latest product of genetic engineering!|This Goo Ball, when attached, emits a high wavelenghth of photovoltaic electromagnetic radiation.|The last time one of these guys attached to another, my car started, all the lights in my house turned on,|and my toaster oven started singing 'My Bonnie Lies Over the Ocean.'|I guess that this radiation will turn on any machinery that's nearby.|What kind of machinery could get these other guys to the pipe, though?|...|Signed, The Sign Painter"/> <!-- Level names --> <string id="LEVEL_NAME_THEJUNGLE" text="The Jungle"/> <string id="LEVEL_TEXT_THEJUNGLE" text="By Gooton Sinclair" /> <string id="LEVEL_NAME_WRECKINGBALL" text="Wrecking Ball" /> <string id="LEVEL_TEXT_WRECKINGBALL" text="That's the way we like it" /> <string id="LEVEL_NAME_GRAVITYHOLE" text="Gravity Hole" /> <string id="LEVEL_TEXT_GRAVITYHOLE" text="...And cold, cold, cold" /> <string id="LEVEL_NAME_STACKEM" text="Stack 'Em" /> <string id="LEVEL_TEXT_STACKEM" text="...Or not" /> <string id="LEVEL_NAME_CRUSHINGTEST" text="Crushing Test" /> <string id="LEVEL_TEXT_CRUSHINGTEST" text="Ouch" /> <string id="LEVEL_NAME_CUTTHECHAIN" text="Cut The Chain" /> <string id="LEVEL_TEXT_CUTTHECHAIN" text="Unleash the rabid rabbits" /> <string id="LEVEL_NAME_CABLECAR" text="Cable Car" /> <string id="LEVEL_TEXT_CABLECAR" text="Turn on the mine machinery" /> <string id="LEVEL_NAME_CRUSHINGZONE" text="Crushing Zone" /> <string id="LEVEL_TEXT_CRUSHINGZONE" text="Hydraulics to the rescue!" /> <string id="LEVEL_NAME_JOBCRITERIA" text="Job Criteria" /> <string id="LEVEL_TEXT_JOBCRITERIA" text="Friendly warfare..." /> <string id="LEVEL_NAME_ALLABOARD" text="All Aboard" /> <string id="LEVEL_TEXT_ALLABOARD" text="Out we go..." /> <string id="LEVEL_NAME_MOM4EVRSONIC" text="Sonic" /> <string id="LEVEL_TEXT_MOM4EVRSONIC" text="It's super" /> </strings>
Note that apostrophes are replaced by
'since ' is another special character in XML.
Ok, now we're finally done with the text.xml. Let's turn our attention to the addin.xml.
Step 5. addin.xml
Because we're merging all the levels and such in manually, the addin.xml is actually really really simple in comparison.
<addin spec-version="1.1"> <id>com.goofans.MOM4Evr.Chapter2Tutorial</id> <name>Chapter 2 Tutorial Example Addin</name> <type>mod</type> <!-- May put a thumbnail in later version --> <version>1.0</version> <description> See the forum links and such for how to create chapters; this one was made in a couple of days. </description> <author>MOM4Evr</author> </addin>
See the addin.xml specification (here) if you're interested in what each individual field does. For now, just change the id, name, version, description, and author to match what you want, and you're good to go.
Step 6. Finishing touches
So what about that cutscene tag? What about making your chapter look different in MapWorldView? What about WOGCorp? Ish signposts? Having more than one chapter? Changing random other stuff to make your addin more awesome? All will be revealed in the next episode of... no wait, I mean all is revealed here.
So, there's this tool called GooVIE. It's super hard to understand, it's completely unlike WooGLE and GooBLE, there are no tutorials for it, and generally everyone leaves it alone. There's no Mac or Linux version, and the source wasn't even released until recently. What gives?
Well, here's a small tutorial for using it to make cutscenes. There's a ton here that isn't said, and maybe somebody will make a full-fledged tutorial someday, but for now, hopefully this will help a bit.
GooVIE is an editor for making custom cutscenes (or animations, but I won't go into that here) for World of Goo. It's such an early alpha version that there's basically zero error-checking, and nothing's protected, so you can edit the original cutscenes and break them if you're not careful. Nonetheless, it's the only feasible way to make your own movies, and movies are part of what makes World of Goo awesome. Everybody wants a cool cutscene at the end of their chapter, right? It's cool.
Note that davidc and Daft As Brush wanted to make a specific XML format for cutscenes, but neither of them agreed on anything, and thus we're stuck with sticking cutscenes in the override folder of goomods. It's hackish, it likely doesn't work cross-platform very well, but it's all we got.
Cutscenes in World of Goo are made from a series of actors with keyframes. You go to a particular location in the time scale, you move, rotate, or scale an actor, make a keyframe, and the actor will move to that position, rotation, and scaling when it gets to that timestep. In fact, the movement will be interpolated, which basically means that if you have more than one keyframe on that actor, it'll gradually move from one keyframe to the next. If it's supposed to take one second to move from the bottom left corner of the screen to the upper right corner, it'll move at the right speed to get there in one second. Pretty nifty.
Animation in general is tricky. You'll have to toy with a cutscene a lot to get it to do what you want, and chances are you'll accidentally break something in the process, so back up your work often. Once you're done, save it as .binltl and copy those two files into the proper folder (override/res/movie/[moviename]/) in the goomod. Now decrypt the [moviename].resrc.bin (Which will be inside the /res/movie/[moviename]/ folder in the World of Goo directory that GooVIE is working from) to [moviename].resrc.xml and copy this to /compile/res/movie/[moviename]/ in your goomod.
Now back to the cutscene tag in my XSL I pointed out. I'll show it again here:
<level id="AllAboard" depends="JobCriteria" name="LEVEL_NAME_ALLABOARD" text="LEVEL_TEXT_ALLABOARD" cutscene="levelFadeOut,x,gooTransition_out"/>
So what's with the cutscene="levelFadeOut,x,gooTransition_out" part? Well, cutscenes are played right after levels end, and they come in groups of three. "levelFadeOut" is a cutscene that gradually fades the screen to black, and "gooTransition_out" is the cutscene you get when you enter a chapter map. "x" means no cutscene. So "levelFadeOut,x,gooTransition_out" all together means that once the level is done, the level fades to black, then immediately transitions back to the chapter. If I had the time, I would have made some cutscene showing the rocket blasting off, and I'd probably have named it something like "MOMRocketBlastoff", and stuck it in here. Then I would have had cutscene="levelFadeOut,MOMRocketBlastoff,gooTransition_out". But oh, well. I'll save that for later; maybe I'll make a movie tutorial sometime.
Instead, I let XDBoy do all the work, and used his "MOOvie" that he made as a joke to override the intro "2dboyLogo" movie, just sticking the proper files into the proper places in my goomod. Thanks, XDBoy.
Well, this is tricky. I chose not to do it for my chapter addin, and you're better off if you don't either. But of course everyone will want to, so here goes. There's more than one way to do it. You can't edit it directly in WooGLE because it's an original level, so you'll have to clone it and make changes there. Before you make changes, though, READ THIS: MapWorldView Specification. Daft as Brush spent a lot of time figuring out what'd crash the game and what wouldn't, and wrote it all down there. If you break one of the rules there, the game will crash. So read it, and pay attention.
Once you're done editing MapWorldView to your liking, you'll have to either merge or compile in the changes. If you want to be a good little goomodder, you'll merge them in. But merging is tricky and I quite frankly don't blame you one bit if you want to compile in the changes instead. In fact, that's what I would do. The problem is, since you had to clone MapWorldView, you'll have to rename everything to compile the changes. So, once you're done editing, save the .goomod, rename it .zip, unzip it, and open it up. You should have your standard compile and override folders. First, rename the folder /compile/res/levels/[yourMapWorldView]/ to /compile/res/levels/MapWorldView/, and open the folder. You'll see three files there: [yourMapWorldView].level.xml, [yourMapWorldView].scene.xml, and [yourMapWorldView].resrc.xml. Rename these MapWorldView.level.xml, MapWorldView.scene.xml, and MapWorldView.resrc.xml, respectively. Now, open MapWorldView.resrc.xml with a text editor (NOT Notepad, ok? Notepad stinks. I personally prefer Notepad++). At the top of the file, you'll see:
change this to:
and you're good to go. All your custom resources will still be in res/levels/[yourMapWorldView], but this still works fine. Copy the data inside this goomod (everything except addin.xml) into your main goomod folder, and you're done.
So, what should you do about World of Goo Corporation? If you edit it and add geometry, you'll make others (and likely yourself) get a "cheater" badge, so don't do that. If you want to be awesome, make a themepack that changes how the level looks and you're good to go. Or you can make your own sandbox and stick it in one (or all) of your chapters. Unfortunately, you cannot make the World of Goo Corporation button in MapWorldView link to this level, since it's hardcoded to only play the original WOGCorp. If you want, you can move the WOGCorp button off the screen of MapWorldView, so nobody can click it, and not worry about it. If you're really ambitious, you can edit the map res/levels/islandUi to remove the buttons for WOGCorp there, too. Just follow my directions for editing MapWorldView above to rename it when you're done.
The NotWOG2 team, back when we were planning on making the first ever chapter addin (which Tacomann beat us to), were planning on editing WOGCorp for a longest-bridge rather than tallest-tower contest. We were going to add a line at y = 0 and have the bridges underneath that so there'd be no chance of anybody using this to cheat. Basically, do whatever you want with WOGCorp, just make sure that nobody can cheat because of changes you make. Also, don't add anything that can kill Goo Balls, since if any of your 300 die in WOGCorp, they're gone forever.
Here's where another hardcoded thing comes into play: Signposts in chapter 4 of the original game are hardcoded to use the ISH signpost variation, so if you override anything there, or stick any levels in that chapter, keep in mind that they'll have the ISH signposts. If you don't want ISH signposts at all, copy puggsoy's addin "Wooden Signs" (available from the "ISH Signs" download page here) into yours, just ignoring his addin.xml.
But if you want ISH signposts in one chapter, never fear. The chapter numbering is arbitrary. You can have the chapters in any order, since each chapter is unlocked when one of its levels' "depends" condition is met (See Step 3 for a description of the "depends" attribute). You can make Chapter 4 be your second chapter, if you'd like. No problem at all.
Of course, if you feel really ambitious, you can replace the ISH signposts with another signpost type of your own making. The sky's the limit!
If you want to do a "total conversion" mod that overrides the entire game with one of your making, first off good luck! You have a lot of work cut out for you. If you change Chapter 1, be sure to merge it in properly (unless you choose not to), and give us mods quite a while to test your mod!
You should have the technical know-how to make multi-chapter addins by now. Just copy the files from each level into the right folders in your goomod, make sure to merge changes into the proper island, and keep adding to your text.xml as you go along. If you have any troubles, post in the forums. We're here to help.
Other random stuff
To make your chapter all that much more chapter-like, consider overriding the image that World of Goo displays while loading a level in that chapter. For example, for my chapter addin, I added an image in the goomod: /override/res/images/islandicon_2.png to make a cool rocket (drawn by Martin33 for the NotWOG2 project) replace the default windmill image for Chapter 2. It adds a nice touch.
If you're nearing the 20 MB cap for goomods, or if you just want to make your addin as small as possible so people can download it faster (Read: People will like you if you do this), you'll want to make sure that the same image isn't being included more than once in your goomod. WooGLE, by default, copies all custom images for a level into that level's folder, which can be a problem if you're merging more than one level together that use the same custom image. The best way to do this is to stick the image in question into /override/res/images/[yourname]/ in the goomod, or someplace like that, and edit each level's .resrc.xml file by hand to point to that image. Or just stick that image there in the first place, and make WooGLE look there rather than using the "Import Resources" button. It's a bit of extra work, but it really pays off in file size.
Step 7. TEST
Select "addin.xml", "text.xml", the "compile", "override", and "merge" folders, zip them up, rename it .goomod, and test like mad. You may even want to point GooTool at an empty folder, so you can have a clean World of Goo installation to test on. Create a new profile to test the levels, if you've played them before out of GooTool, so you can have an experience as close to a new player as possible. Then, play the mod. All the way through. More than once. Fix any bugs you find, and if you can't, post in the forum. We're here to help. But test it extensively, so you can troubleshoot and fix any problems you see. It'll make the publishing process that much faster if we don't have to stop playing, tell you about an error, and wait for you to fix it. Have a couple friends play the mod, or ask a fellow GooFan or two. The more beta-testing you can get, the better. But at least test it yourself extensively.
Step 8. Upload!
Yay! You're done. Upload your final .goomod here on goofans, add some cool screenshots, describe it thoroughly, and request for it to be published. Give us a while to test it; we'll try to get it approved ASAP, but we may take a while. If your levels are really difficult, though, we'll likely take longer. This isn't to say that challenging levels are bad in any sense (I personally prefer challenging, but not overly hard or tricky, levels), but it's just a fact that they'll take us longer to test. Especially because we have to complete every level in order to test them all. But basically, your work is done. Hopefully you had fun and learned a lot in the process, and I'm personally looking forward to the awesome goomods that everyone is going to create.