Advanced Topics

Here are a few more examples of how to create great missions with M.  These were written by Crakerz, who was one of the original mission contributors.  Scroll down the page to read all the Topics.  They are numbered so you can scroll down to the one you want to read.
  1. Split Window
  2. Terrain Tips
  3. More Terrain Tips and Tricks
  4. Troubles & Tribbles - a few debugging tips
  5. Who's your daddy? - all about allies
  6. Mission Loaded
  7. PVARS!
  8. Using text pvars
  9. Using pvars as Counters
  10. Passing pvar values
  11. Restricted Areas
  12. Forcible Entry
  13. Rank and File
  14. Troubleshooting 101
TOPIC 1: Split Window

Most people know that the Mission Editor can show multiple windows or levels simultaneously, but did you know that you can have a split window of the same level?

Open a level. Move the cursor to the thin bar just above the retractable tool bar above the map screen. The cursor should change to two thin lines and arrows pointing up and down. Left click and hold to drag the bar down. When you release it, two editing screens are shown, each with their own retractable tool bar.

So what? Well, one use is to reduce the magnification of one window so as to see most or all of the map, and use the other to place objects. You can see the overall map picture progress as you work.

To turn off this feature, close the level, or drag the split bar back to the top of the screen.

 TOPIC 2: Terrain Tips

The terrain of WI is half the game. Creating a great map is an art. But have you noticed that sometimes things don't always fit the way you want? Here are a few tips:

TIP: Use the big blank square known as "background" in the grassy/desert terrain palette to cover areas you don't want seen. You can layer them to cover any shape. Careful, they "disappear" easy!

TIP: If you want to place a structure in a spot and you get the error that the structure is on top of "Unreachable", try laying the "background" square over the area you want to use, then placing your structure on top of it.

TIP: Use trees or bushes to cover things like uneven seams where river segments join.

TIP: You can layer terrain to create new effects. Try overlapping different segments. (Note the use of this in the MP BoH to create the spawning cages)

TIP: Objects are layered in the order of placement. This includes templates, gobs, and areas.

Templates: what we call terrain, such as rivers and mountains. Everything in the grassy or desert window on the lower left side.

Gobs: What we call scenery, buildings/structures, and mobile units. Everything in the "side" object window on the upper left side, with the exception of areas. Short for "Graphic Objects".

TIP: Walls are great for limiting movement, but might not look right in the location you want. So, cover "em with bushes!

TRICK: To bring an object to the forefront: Click it to highlight, then click/hold as if to drag it. Move the cursor down slightly, but not enough to actually move the object. The object should jump to the top of the layer stack. If you move an object, it automatically moves to the top of the stack. (Wish there was a way to move objects down the stack!)

TRICK: Use the buttons on the retractable toolbar to turn visibility on/off for Templates, Gobs, or Areas. This is very useful to manipulate a particular object. I usually turn Areas off until the end.

TOPIC 3: More terrain tips and tricks

TRICK: Right click on an object to see the popup: "Remove" and "Select Same". If you chose select same, every object on the map that is the same will be highlighted (if the object is side-specific, all sides are selected). This is also useful to find all those "background" squares that "disappeared".

TRICK: Use the control key while click/dragging an object or group of objects to drag a duplicate. Sure this is an old one, but bears repeating. Be careful with this one. It is easy to create lots of duplicates on top of each other that you don't know are there, and that will bump up the size of your level. If the object is a wall tombstone, you will get an error at compile time. This is very easy to do. See tip below:

TIP: At higher magnifications, you can see a shadow on the left side of wall tombstones that are on top of each other.

TRICK: If you get an error window at compile, such as:

            0> (11,7): Error: m.Wall is on top of: Wall

You can use the X,Y (the 11,7 in this example) to find the offending object. The error Output screen will stay on top if you don't close it. Look at the lower right side of the editor window for "Coords:" (short for coordinates) and two numbers. That is the X,Y position of the cursor. Move the cursor so that the numbers match that in the output window. In the example above, a wall is on top of a wall. The solution is to click the top one and delete it.

TIP: If you are like me, and turn Area visibility off, try this tip: use a bit of scenery, such as a type of bush or tree, to mark where your areas are. I usually put one near the top left corner. That way, I keep track of where my significant areas are while laying out terrain or units. Of course, you need to turn the Areas on to double-check every so often. One reason I use this method is to avoid having the upper left corner of an area over something other than a bush or tree. If I am spawning into this area, and something is in that corner, the spawn just won't happen!

TOPIC 4: Troubles and tribbles

TIP/TRICK: Create a trigger that you use for debugging:

                        -Mission Loaded 
    ACTIONS: {place debug actions here}

TIP: Many level builders use this secret: while troubleshooting, create an area that covers the entire map (something I do on almost all my levels). I call mine "SECTOR". In the Debug Trigger, place the Action: Defog area "SECTOR". This will allow you to watch the action and help pinpoint trouble spots.

TIP: Create a switch called "DEBUG". Turn it On or Off in the Debug Trigger. Place it in the CONDITIONS of triggers you want to disable (but not delete) while troubleshooting. ON enables the trigger, OFF disables it (or visa versa, your choice).
                        -(the rest of my conditions)

You can then delete just that switch from the triggers after debugging is completed.  

TOPIC 5: Who's your daddy?

The "Allies" action is one that can have some interesting effects. Allies can be changed at any time during the game.

If you are "allies" with someone, you can't attack them. Period. But they can attack you! The important thing to remember is the action is not reciprocal. If you want A to be allies B and vice versa, then two actions are required:

Side1 allies with Side2
Side2 allies with Side1

Here's a fun one:
Side1,Side2,Side3,Side4 allies with SideNeutral
SideNeutral allies with SideNeutral

In this scenario, nobody can attack SideNeutral, but SideNeutral can attack everybody else! When a Side allies only with itself, then everybody else is an enemy. It's the action to use to break an alliance.

Here's another one - Everybody is friends:
Side1,Side2 allies with Side3
Side3 allies with Side1,Side2

Later in the level, though:
Side3 allies with Side3
Now, Side3 attacks Side1 and Side 2, but they don't attack back, nor attack each other.

One more example:
Side1 allies with Side2 (Side 1 attacks Side3 only.)
Side2 allies with Side3 (Side2 attacks Side1 only)
Side3 allies with Side1 (Side3 attack Side2 only)

Remember: if you are not an ally, you are an enemy! Lastly, remember not to use the virtual sides "Allies" or "Enemies" for either side of the action.  

TOPIC 6: Mission Loaded

TIP: The Mission Loaded condition is "true" as long as the mission is loaded, not just when it is loaded. That is an important distinction that could cause problems. Good example:

Say you have three triggers to set up your difficulty levels, like so:
CONDITIONS:  -Comment: Easy Level 
                        -Mission Loaded 
                        -Persistent variable "$difficulty" is Exactly 1 
    ACTIONS:  -Side1's Credits: Set 5000

CONDITIONS: -Comment: Normal Level 
                        -Mission Loaded 
                        -Persistent variable "$difficulty" is Exactly 2 
    ACTIONS:  -Side1's Credits: Set 4000

CONDITIONS:  -Comment: Hard Level 
                        -Mission Loaded 
                        -Persistent variable "$difficulty" is Exactly 3 
    ACTIONS:  -Side1's Credits: Set 3000

Now, the Player starts out on "Hard", but later changes to "Easy". Bam! Their credits are set to 5000 (that could be good or bad, depending on what they had to start!) Later they change to "Normal" and that trigger fires.

TRICK: I use a switch called "PLAY" or something similar that is placed in most triggers. I turn it ON for game play after I have set everything up, like so:  (This is the last trigger in the list that uses "Mission Loaded")

CONDITIONS:  -Mission Loaded 
                        -Switch "PLAY" is Off 
    ACTIONS:  (whatever) 
                        -Switch "PLAY" ON

If this was placed in the above "difficulty triggers", it would avoid the accidental firing:
CONDITIONS:  -Mission Loaded 
                        -Switch "PLAY" is Off (Once gameplay starts, I don't want this to fire) 
                        -Persistent variable "$difficulty" is Exactly 1 (or 2 or 3) 
    ACTIONS:  -Side1's Credits: Set to (whatever)  


Short for "persistent variable", pvars can make a level very interesting. Here is a short tutorial on what they are, how they work. What you can do with them is covered in subsequent topics.

Pvars are stored in memory as a text string, but they can be used as integers (whole numbers). Not including the built-in ones (see the FAQ), pvars are created when they are referenced by name for the first time, either by testing or modifying, and have a default value of "0". The name is case-sensitive; so "MYPVAR" is different from "MyPvar" and "mypvar". Since you have to type it in each time, be careful!

By design, pvars persist in memory until the game is exited, even between linked levels (in single player only). If you exit the game (but not the level) the pvars are preserved for when you return. Same thing occurs when you save a level. (exiting the game during a level actually creates a save file also, one that loads when the game is restarted). Restarting or aborting the current level, or starting a new level, resets the pvars to their starting values. For example, if you are restarting a saved game, the values will be whatever they were when the level was saved.

One condition and two actions are associated with pvars:
CONDITION:  -Test persistent variable "text" is quantity

This can only be used to test for an integer value, not a text value. The value tested can be AtMost, AtLeast, or Exactly the test quantity. An example of each:
-Test persistent variable "MyPvar" is AtMost 10 (True if MyPvar is 10 or less, but not more. The same as saying "Equal to or less than")
-Test persistent variable "MyPvar" is AtLeast 10 (True if MyPvar is 10 or more, but not less. The same as saying "Equal to or greater than")
-Test persistent variable "MyPvar" is Exactly 10 (True if MyPvar is 10, but not more or less. The same as saying "Equal to")

ACTION:  -Set persistent variable "text" to "text"

The pvar is set to a text string. However, MyPvar can only be modified and tested as an integer. An example of both being set:
-Set persistent variable "MyPvar" to "10" (Text or Integer)
-Set persistent variable "MyOtherPvar" to "Ten" (Text)

ACTION:  -Modify persistent variable 'text': Set/Add/Subtract quantity

Can only be used on pvars that are being used as integers. An example of each:
-Modify persistent variable 'MyPvar': Set 0 (Doesn't actually work. In later versions of the editor, the previous "set" action is transparently substituted at compile time. Suggest that you don't use at all.)
-Modify persistent variable 'MyPvar': Add 1 (Adds one to the integer value. If the pvar contains a text string, the value is zero, so the result is "1")
-Modify persistent variable 'MyPvar': Subtract 1 (Subtracts one from the integer value. If the pvar contains a text string, the value is zero, so the result is "-1")

One recommendation I have: At Mission Load, Set all the pvars you intend to use, even if you only set them to "0". If you are using pvars from previous levels, then this isn't needed, per se. But if someone accesses your level directly, and a pvar isn't explicitly declared, it might cause minor problems. To avoid clearing a pre-existing pvar, but to make sure it is declared if it doesn't exist, use the following:

ACTIONS:  -Modify persistent variable 'MyPvar': Add 0 (This doesn't change the value if it exists, and has the effect of "declaring" with a starting value "0" it if it doesn't exist).  

TOPIC 8: Using Text Pvars

Using pvars for text can allow you to reduce the number of triggers used. Here are a few examples of how they can be used:

Using a common "alert" trigger for special effects:
CONDITIONS:  -{whatever} 
    ACTIONS:  -{whatever} 
                    -Set persistent variable "AlertText" to "OMNI is at the Gate!" 
                    -Set switch "ALERT" On 

                        -Switch "ALERT" is On 
    ACTIONS:  -Set switch "ALERT" Off 
                    -Show Alert " {AlertText}" 
                    -Wait 1 seconds 
                    -Show Alert " <{AlertText}>"- 
                    -Wait 1 seconds 
                    -Show Alert " <<{AlertText}>>" 
                    -Wait 1 seconds 
                    -Show Alert "<<<{AlertText}>>>" 
                    -Preserve Trigger

Alert will look something like this:
OMNI is at the Gate! 
    <OMNI is at the Gate!> 
        <<OMNI is at the Gate!>> 
            <<<OMNI is at the Gate!>>>

Another example:
CONDTIONS:  -Comment: Player as Free Radicals Wins! 
    ACTIONS:  -Set persistent variable "Winner" to "The Free Radicals" 
                    -Set switch "WIN" On 
                    -Wait 1 seconds 
                    -End Mission: Win

CONDTIONS:  -Comment: OMNI Wins! 
    ACTIONS: -Set persistent variable "Winner" to "OMNI" 
                    -Set switch "WIN" On 
                    -Wait 1 seconds 
                    -End Mission: Lose

CONDITIONS:  -Switch "WIN" is On 
    ACTIONS:  -Set formal objective 2 text to "And the Winner is:" 
                    -Set formal objective 2 status to "{Winner}"  

TOPIC 9: Using Pvars as counters

Here's an example of what I used in the MP SWAK mission to keep a custom game clock that quite adequately demonstrates the use of pvars as counters:

CONDITIONS:  -Every 1 seconds 
    ACTIONS:  -Modify persistent variable "GS": Add 1 
                    -Start Countdown Timer with 1 seconds and show this string: "GameTime {GH}:{GM}:{GS}" 
                    -Preserve trigger

CONDITIONS:  - Persistent variable 'GS' is Exactly 59 
    ACTIONS:  -Set persistent variable "GS" to "0" 
                    -Modify persistent variable "GM": Add 1 
                    -Preserve trigger

CONDITIONS:  - Persistent variable 'GM' is Exactly 59 
    ACTIONS:  -Set persistent variable "GM" to "0" 
                    -Modify persistent variable "GH": Add 1 
                    -Preserve trigger

Here"s another example of a counter, tracking how many times a switch is activated. Note that even thought the same name (TopGate) is used for an area, switch, and pvar, they are not the same. I often do this to help keep track of what goes with what.

CONDTIONS:  -Comment: The use of a switch here acts as a toggle to keep the trigger from firing repeatedly while the area is occupied. 
                        -Switch "TopGate" is Off 
                        -Area "TopGate" contains AtLeast 1 AnyUnit owned by Side2 
    ACTIONS:  -Set Switch "TopGate" On 
                    -Modify persistent variable "TopGate": Add 1 
                    -Preserve trigger

CONDTIONS:  -Comment: Once the area is cleared, so is the switch 
                        -Switch "TopGate" is On 
                        -Area "TopGate" contains Exactly 0 AnyUnit owned by Side2 
    ACTIONS:  -Set Switch "TopGate" Off 
                    -Preserve trigger

CONDTIONS:  Comment: Once the area has been accessed 5 times, an attack is formed! 
                        - Persistent variable 'TopGate' is Exactly 5 
    ACTIONS:  -Set persistent variable "TopGate" to "0" 
                    -Create Unit Group "AttackSquad" 
                    -Preserve trigger  

TOPIC 10: Passing Pvar Values

This example shows how a pvar value can be passed to another level:

CONDITIONS:  -Comment: Player wins quickly (between 30 and 40 minutes), so earns bonus 
                        -Elapsed mission time is AtLeast 1801 seconds 
                        -Elapsed mission time is AtMost 2400 seconds 
                        -Enemies owns Exactly 0 Any Unit 
    ACTIONS:  -Set persistent variable "Bonus" to "2500" 
                    -End Mission: Win

CONDITIONS:  -Comment: Player wins even quicker, so earns bigger bonus 
                        -Elapsed mission time is AtMost 1800 seconds 
                        -Enemies owns Exactly 0 Any Unit 
    ACTIONS:  -Set persistent variable "Bonus" to "5000" 
                    -End Mission: Win

CONDITIONS:  -Mission Loaded 
                        -Persistent variable 'Bonus' is AtLeast 2500 
    ACTIONS:  -Side1's Credits: Add 2500

CONDITIONS:  -Mission Loaded 
                        -Persistent variable 'Bonus' is AtLeast 5000 
    ACTIONS:  -Side1's Credits: Add 2500

In the above examples for Level B, the Bonus test could have been for "Exactly" the amount, or any other method that works. Often, programming is choice. 

TOPIC 11: Restricted Areas

Say you have an area that must be accessible, but not really. For example, you have an enclosed space to protect a structure, and you absolutely positively do not want anybody near it. You can't block it off, or you get errors at compile time. Here is a method I use:

First, create an area that covers the desired restricted zone. I'll call mine "RestrictedZone". Second, create an area close nearby, if not actually adjoining the "restricted zone". I'll call mine "RallyPoint".

CONDITIONS:  -Area "RestrictedZone" contains Atleast 1 AnyUnit owned by AllSides 
    ACTIONS:  -Move AllSides AnyUnit from 'RestrictedZone' to 'RallyPoint' 
                    -Preserve Trigger

You could modify the above to only restrict certain sides. You could also add the Elapsed Time condition to end the restriction after so many seconds.  

TOPIC 12: Forcible Entry

This is kind of the opposite of the previous post, but not really. It is just a different application. Say you want to force a unit to move to an area, no matter what. This is very effective, especially if you only have one of the units to move, or one type. I used this to kill off the extra Andys at the end of The Crossroads, as well as to suicide the Trooper in FragTag.

First, create an area that covers the entire map (something I almost always do anyway). I'll call mine "SECTOR". Second, create an area that you want the troops to move to. I'll call mine "KillZone".

CONDITIONS:  Comment: If KILL is On, this remains active until all Andys are dead 
                        -Switch "KILL" is On 
                        -Side1 owns AtLeast 1 Andy 
    ACTIONS:  -Move side1Andy from 'SECTOR' to 'KillZone' 
                    -Preserve Trigger

CONDITIONS: -Switch "KILL" is On 
                        -Side1 owns Exactly 0 Andy 
    ACTIONS:  -Set Switch "KILL" Off 
                    -Preserve Trigger  

TOPIC 13: Rank and File

Here are all the ranks that are possible to achieve in WI, in order:

Rank.    Title
0. Mining Operations Trainee
1. Mining Operations Specialist
2. Certified Basic Miner
3. Mining & Security Specialist
4. Certified Secure Miner
5. Senior Secure Miner
6. Lead Secure Miner
7. Secure Mining Site Supervisor
8. Secure Mining Supervisor
9. Secure Mining Base Commander
10. Jr. Director of Secure Mining
11. ACME Up-and-Comer
12. Operations Fast Tracker
13. Operations Management Trainee
14. Operations Manager
15. Operations Middle-Manager
16. Operations Bureaucrat
17. Being Groomed for Executive
18. Operations Executive
19. Director of Icarus Operations
20. Director of ACME Ops Resources
21. Vice President of Operations
22. Executive VP of Operations
23. Senior Exec. VP of Operations
24. ACME Chief Operations Officer  

The left value is what the pvar "rank" holds. If that value is -1, then that person is a "Challenger", if zero, then a newcomer. You can modify this pvar during gameplay. The companion text pvar "$ranktitle" holds the actual text shown above. It can't be modified.  

TOPIC 14: Troubleshooting 101


A. MAKE A BACKUP: Every time you compile, the level is saved first. This means that you must save a MASTER or original copy before you start to troubleshoot, and leave it alone. Otherwise, after many little changes, the mess will be worse that before!

B. AVOID PFM: Change only ONE thing at a time. Tempting as it is (especially to amateurs) avoid the "scattergun method" of troubleshooting (ie changing more than one thing at a time). Even if you get lucky and fix it, you will have no idea what the real problem was, and the answer will be PFM {pure frikkin' magic}. Overall, you will save time doing it the long way, and you will learn more as well.

C. NARROW YOUR FOCUS: If you have a big mess, start by narrowing your focus to one area of the level at a time, such as triggers (by side), unit groups, or gobs.

    For example, say you have a level with three sides, and each side has twelve triggers. 
    1. Delete all of two sides' triggers. Compile then test. If the problem is gone, it is one of the other two sides' triggers. Reload the level from the Master Copy, and try again using a different side.

    2. On the "offending" side, delete (or disable - see BUILD TO TEST below) one trigger at a time, compiling after each try, and testing. Once the problem goes away (i.e. in most cases, it loads without freezing up), then look at the last trigger deleted. This is where your problem usually is.

    3. Delete one condition or action at a time until the problem goes away (This may not always work, as conditions and actions are somewhat inter-dependent).

    If the offending trigger is duplicated in the other sides, then you need to fix those sides as well.  The above also applies to Unit Groups and Gobs (Graphic objects, like structures, terrain, scenery, galaxite, etc).

D. DON'T BE PROUD: If you still can't figure it out, ask by posting your question on the Mission Authoring section of the WI Forum. If at all possible, post JUST the offending trigger. Give clear details of the problem (Don't just say "it's broke") That's the beauty of this forum, so many brainiacs out there that might just know what the problem is.

CRAKERZ' RULES FOR AVOIDING TROUBLE:   " 'tis better to avoid trouble than to find it!"

A. HAVE A PLAN: Having a general idea of the storyline or objective is a good start, but the level needs to be blocked out. Document everything! 
    1. Create an outline of how the level should progress (the story). 
    2. Draw a map of the what the Player(s) will see. 
    3. List objectives, trigger areas, situations (ie "if A then B"), switches, unit groups, pvars, and communications or advisories. Know the limits and stay within them.

Only after these things are completed can you actually start to create the logic that drives everything.

SoLan once said: "If your story is too long or complicated to fit comfortably in one level, or if your storyline requires lots of different map details, consider splitting the storyline over more than one level and linking them into a multi level mission pack. A very elaborate storyline may make a level confusing for players as well as developers, and splitting the action into "chapters", you can let the player accomplish parts of the overall mission before moving on.

"Also having more than one map will let you design new surroundings for further action without having to make it fit with what you made for the beginning of the story. If you have a large map on paper, try cutting it in half and move the action from one half to the other for the next part of the mission. You could have the player finish the level by moving his units out the side of the map, and then enter the next map as if by the same road. Or you could "transport" your player to an entirely different part of the planet for the next part."

B. FOLLOW THE PLAN: During creation, after each plan step, compile and download. Sure it takes time; nothing great created by man is done quickly.
Step: 1. Create the map (ie terrain, structures, etc.), and then compile it. Correct errors. 
        2. Create the Areas on the map. 
        3. Create the Switches to be used. 
        4. Create the Unit Groups to be used. 
        5. Create each sides' triggers, A FEW AT A TIME! Compile and download and test OFTEN. This way you may find problems immediately, instead of searching for them. 
        6. Run the level and try to break it as many different ways as you can. The old adage applies: "The problem with making something foolproof, is that fools are so damn ingenious!"

C. TEST NEW CONCEPTS FIRST: I have a test level (called "Test Range"), with just a few areas (I mark them with a bush) and a few troops. I use this to test my logic, a few triggers at a time. (Many of my triggers are interdependent), Once I have the concept working, I'll put it into my "real" level. This avoids corrupting my "real" level with faulty logic.

D. BUILD TO TEST: By following good programming practices, you will have an easier time when things do go wrong: 
        1. Follow and update your documentation! If you change something in the level, update the documentation. 
        2. Use an area that covers the entire map, and defog it on Mission Load. Use this while building your level to see all that is going on. 
        3. Use debug switches. If your level is complicated, being able to disable instead of delete triggers can be useful. Create a switch or pvar called DEBUG, and insert it into the conditions of triggers that you want control over:

CONDITONS: -Switch "DEBUG" is Off {To disable this trigger, turn DEBUG ON at Mission Load} 
                    -Elapsed mission time is 360 seconds 
    ACTIONS:  -{Whatever}

E. COMMENT! COMMENT! COMMENT! This is the one most people fail to do, but is so useful. Use the comments to label what the trigger does. You won't remember three weeks from now unless this prompt is there. It also makes it easier to find when you are scrolling down the list. Examples: