Grid Systems

## Introduction

A grid is a method of 'marking' certain points (or 'coordinates') on a map without creating a location for each of the points. The ultimate goal of any grid is to move a location to the desired marked point and perform some actions at that point using that location. Often, having a grid system is the only way to achieve a goal, which is why grids are very important aspects of mapping.

There are three main typse of grids: Static Grids, Mobile Grids and Location Grids. Each type has its own advantages and disadvantages.

Some maps, such as Reflector and Maze Generator use multiple grid systems to achive their disired outcomes.

Static and Mobile grids use the way SC selects units from a location that are subject to certain actions. To understand how these two grid systems work, one must first understand the SC mechanics the systems are based on.

## SC Mechanics Regarding Static and Mobile Grids

The three most important actions for these grid systems are "Move (Center) Location", "Give Units to Player" and "Remove Units". When any of these actions are performed on a group of units in a location, SC selects the leftmost, last created or moved (in that order) unit. For example, arrange a test map with 5 Terran Marines owned by P1 (red) scattered in a location called "Arena" and a separate, 1x1 tile location called "scan", as shown:

These marines are our grid coordinates. They will represent the points on the map where we want to move our "scan" location. Note that all Marines are placed with a fine grid; from the two marines that are one under another, the top one was created first.

The first and simplest test would be to create a unit (Khalys Crystal) at the location of the first Marine (bottom left). To do that, make the following trigger:

```
   Trigger("Player 1"){
   Conditions:
       Switch("Switch1", set);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Terran Marine", "Arena", "scan");
       Give Units to Player("Current Player", "Player 2", "Terran Marine", 1, "Arena");
       Remove Unit At Location("Player 2", "Terran Marine", 1, "Arena");
       Create Unit("Player 1", "Khalis Crystal", 1, "scan");
       Set Switch("Switch1", clear);
   }

```

Once "Switch1" is set, the trigger will execute the actions in the specified order:

1. Move the location "scan" on the first Terran Marine it finds in the location "Arena". It will first find the leftmost Marine(s) in "Arena" - the one with the lowest X coordinate - and since there are no other marines with the same X coordinate, it will select the bottom-left Marine as desired, and move the location "scan" on it.
2. Select the bottom-left Marine with the same selction process and give it to Player 2.
3. Remove the only Marine owned by Player 2 in "Arena", which is the one it just gave to that player
4. Create Khalis Crystal at 'scan', which is at the location of the Marine that just got removed
5. Clear "Switch1" so that this trigger runs only once on request.

After this trigger runs, the situation will look like this:

Suppose it is needed to create a Khalis Crystal at the location of the Marine that is right below the middle of "Arena". This means the system will have to 'skip' 2 Marines and center "scan" on the required one. To achieve that, the following trigger must be run:

```
   Trigger("Player 1"){
   Conditions:
       Switch("Switch2", set);

   Actions:
       Comment("");
       Preserve Trigger();
       Give Units to Player("Current Player", "Player 2", "Terran Marine", 2, "Arena");
       Move Location("Current Player", "Terran Marine", "Arena", "scan");
       Remove Unit At Location("Current Player", "Terran Marine", 1, "Arena");
       Create Unit("Player 1", "Khalis Crystal", 1, "scan");
   Give Units to Player("Player 2", "Player 1", "Terran Marine", All, "Arena");
   Set Switch("Switch2", clear);

```

Following the same logics, it will skip two marines, remove the next one it finds and create the crystal at his position. After the trigger runs, the situation will look like this:

The trickiest case is when several units have the same X coordinate. In this case, SC will select the one that has been created, moved or placed last. Hence, if you followed the guidelines of this article and placed the top Marine (of the two that have equal X coordianates) first, and the bottom Marine last of the two, then running the first trigger associated with "Switch1" will create the crystal at the bottom Marine's location. Hence if you need a set of units all in with the same X coordinate, to know the order of their selection you must know the order in which they were created (or placed). If you want them to be selected from bottom to top, you must create (or place) them in reverse order - from top to bottom.

## Static Grids

A Static Grid uses preplaced (often burrowed) units as its coordinates. These units are not moved and in most cases, not removed, hence the name 'static'. These grids are very often used to save locations at the cost of units. Static grids function as it was shown in the previous section of this article; the only difference is that most static grids do not remove the grid units, so they can be used again.

Here is a setup of the most common static grid:

The burrowed units are Zerg Zerglings owned by Player 9 (neutral). All burrowed units used in Static grids should be owned by neutral players at all times, because burrowed units owned by active players tend to unburrow when given to another palyer. Note that the Zerglings are placed with a fine grid (even though it may appear that they are lower than the grid points). It is important that each Zergling in every column is placed after the one above it - it is just another way of saying that you must create them from bottom to top in order for the SC unit selection to be consistent.

The action for this example would be an explosion at any desired position. The trigger for it would be similar to this:

```
   Trigger("Player 1"){
   Conditions:
       Switch("Switch3", set);

   Actions:
       Comment("");
       Preserve Trigger();
       Give Units to Player("Player 9", "Player 10", "Zerg Zergling", N, "Arena");
       Move Location("Player 9", "Zerg Zergling", "Arena", "scan");
       Give Units to Player("Player 10", "Player 9", "Zerg Zergling", All, "Arena");
       Create Unit("Player 2", "Terran Wraith", 1, "scan");
       Kill Unit At Location("Player 2", "Terran Wraith", All, "scan");
       Set Switch("Switch3", clear);
   }

```

The given trigger is generalized to work with any number of grid units, as long as the variable N (in the first 'give units' command) is less than or equal to the number of grid units in the location "Arena" (in this case, there are 25 Zerglings). The units are given between two neutral players (9 and 10) to avoid unburrowing problems.

Problems

Static grids use the "Give Units" command to work, which is one of the most 'lag-heavy' commands in SC. Constantly giving too many units can make the map lag a lot, which is why constantly running big Static grids is a bad idea.

Another problem is the amount of units the grid uses. Some maps such as RPGs or RPs require a lot of units, which conflicts with the grid - it may happen that a too big Static grid will require too many units, causing the map to hit the unit limit.

Try not to use big and accurate (meaning the distance between the grid units is small) grids in areas the player may look at - even if it will not lag because of the give commands, it may lag because of too many units on-screen (even if they are burrowed, they still have this effect).

## Mobile Grids

Mobile grids are more 'fragile' systems than Static grids, but offer greater capabilities. A Mobile grid is a system that creates a set of air units (in most cases), using the "Remove Unit" action centers a location on the desired air unit and removes the remaining air units. To understand how Mobile grids work, one must understand the patterns in which certain air units are created and chosen by triggers.

There are two main types of Mobile grids: 1x1 and 1.5x1.5 grids. These sizes denote the distance in tiles between nearby grid points in the resulting grid.

The center of a Mobile grid is the location (or coordinate) where the first unit of the grid was created. An accurate mobile grid is one that produces consistent, equally spaced grid points.

1x1

An accurate, 9-unit 1x1 mobile grid is created with the following trigger:

```
   Trigger("Player 1"){
   Conditions:
       Switch("Switch4", set);

   Actions:
       Comment("");
       Preserve Trigger();
       Set Switch("Switch4", clear);
       Create Unit("Player 2", "Zerg Scourge", 1, "Arena");
       Create Unit("Player 2", "Protoss Observer", 1, "Arena");
       Create Unit("Player 2", "Zerg Scourge", 1, "Arena");
       Create Unit("Player 2", "Protoss Observer", 1, "Arena");
       Create Unit("Player 2", "Zerg Scourge", 1, "Arena");
       Create Unit("Player 2", "Protoss Observer", 1, "Arena");
       Create Unit("Player 2", "Zerg Scourge", 1, "Arena");
       Create Unit("Player 2", "Protoss Observer", 1, "Arena");
       Create Unit("Player 2", "Zerg Scourge", 1, "Arena");
   }

   //-----------------------------------------------------------------//

```

Meaning that one must create a Scourge at the center of th egrid, then an Observer at the center of the grid, then a Scourge, then an Observer... and so on. It is very important for the first unit to be a Scourge. The resulting grid contains 9 units, and the grid points are spaced by one tile, hence it is a 1x1 grid.

The units of this grid are created in the following pattern:

8 7 6

9 1 5

2 3 4

To center a location on the desired unit, one must know the order in which the units are selected by SC:

2 4 7

1 6 8

3 5 9

Thus, to center a location on the upper-right grid point (in the above diagram, represented by '7'), one must first remove 6 units from the grid and then center the location. If one could see triggers in slow-motion, this is how the creation and removal (or in this case, killing) of the grid units would occur:

Do note that this .gif image was represented using SCMDraft and not in-game.

1.5x1.5

An accurate, 9-unit 1.5x1.5 mobile grid is created with the following trigger:

```
   Trigger("Player 1"){
   Conditions:
       Switch("Switch5", set);

   Actions:
       Comment("");
       Preserve Trigger();
       Set Switch("Switch5", clear);
       Create Unit("Player 2", "Zerg Devourer", 9, "Arena");
   }

   //-----------------------------------------------------------------//

```

It is important that one uses Protoss Arbiters, Zerg Devourers, Zerg Guardians, or Zerg Mutalisks for 1.5x1.5 grids.

The units of this grid are created in the following pattern:

7 6 5

8 1 4

9 2 3

To center a location on the desired unit, one must know the order in which the units are selected by SC:

3 4 7

2 6 8

1 5 9

Thus, to center a location on the middle-right grid point (in the above diagram, represented by '8'), one must first remove 7 units from the grid and then center the location. If one could see triggers in slow-motion, this is how the creation and removal (or in this case, killing) of Devourers would occur:

It is important that the grid units are removed and the location is centered in the same trigger cycle (or even in the same trigger), because other air units or triggers may disrupt the air units of the grid if they are left unremoved for atleast one trigger loop.

Problems

Mobile grids cannot work properly if there are air units in their path, as they will cause the grid units to be displaced, bugging the grid. One must always make sure there are no air units atleast in the area where the grid is about to be made.

Lag is a problem of Mobile grids, just like it is of Static grids, the only difference is that now you create/remove units instead of giving them, which is quite laggy as well.

Lag Reduction and Partial Mobile Grids

A Partial Mobile grid is one where the units of the grid do not form a square with a center i nthe middle of the grid. In other words, it is any grid other than a 9, 25, 49, etc. unit grid.

If only one grid point is needed at a time, one can create the grid only until that point (thus making it a Partial grid). For example, one is interested in the grid point to the right of the grid center, then it is possible to create the grid units as follows:

For a 1x1 grid:

X X X

X 1 5

2 3 4

And for a 1.5x1.5 grid:

X X X

X 1 4

X 2 3

With 'X' representing no units at the grid point. This allows to create less units, hence cause less lag. Compare this with the unit selection patterns:

For a 1x1:

1 4 7

3 6 8

2 5 9

For a 1.5x1.5:

3 4 7

2 6 8

1 5 9

One can see that removing 4 units for a 1x1 grid and 2 units for a 1.5x1.5 grid and then centering the location will give the required result - the rightmost grid point is selected.

Examples

Mobile grids are a powerful tool in a mapper's arsenal, as it allows to do most things a Static grid can do without any preplaced units. For example, creating a line of crystals.

Spaced by 1 tile. Direction: up.

```
   Trigger("Player 1"){
   Conditions:
       Switch("Switch6", set);

   Actions:
       Comment("");
       Preserve Trigger();
       Create Unit("Player 2", "Zerg Scourge", 1, "Grid");
       Create Unit("Player 2", "Protoss Observer", 1, "Grid");
       Create Unit("Player 2", "Zerg Scourge", 1, "Grid");
       Create Unit("Player 2", "Protoss Observer", 1, "Grid");
       Create Unit("Player 2", "Zerg Scourge", 1, "Grid");
       Create Unit("Player 2", "Protoss Observer", 1, "Grid");
       Create Unit("Player 2", "Zerg Scourge", 1, "Grid");
       Remove Unit At Location("Player 2", "Men", 1, "Anywhere");
       Move Location("Player 2", "Men", "Anywhere", "Grid");
       Remove Unit At Location("Player 2", "Men", All, "Anywhere");
       Create Unit("Current Player", "Khalis Crystal", 1, "Grid");
   }

   //-----------------------------------------------------------------//

```

Spaced by 1.5 tiles. Direction: bottom-right.

```
   Trigger("Player 1"){
   Conditions:
       Switch("Switch7", set);

   Actions:
       Comment("");
       Preserve Trigger();
       Create Unit("Player 2", "Zerg Devourer", 3, "Grid");
       Remove Unit At Location("Player 2", "Men", 2, "Anywhere");
       Move Location("Player 2", "Men", "Anywhere", "Grid");
       Remove Unit At Location("Player 2", "Men", All, "Anywhere");
       Create Unit("Current Player", "Khalis Crystal", 1, "Grid");
   }

   //-----------------------------------------------------------------//

```

## The Offset Glitch

If a grid is created incorrectly, even if following all the instructions and precautions, one is most probably experiencing the Offset Glitch.

The Offset Glitch often occurs when the mobile grid is created at a unit that can move around (like a hero in an RPG). Please note that the unit's motion does not cause the glitch by itself, it is the unit's position that causes it.

SC divides each tile into 4 equal square segments or subtiles. These subtiles are equivallent to the fine grid in the editor. The first unit of the mobile grid is always created directly at the specified location, however, all the following units are created centered on the nearest fine grid point (where subtiles' corners meet). Hence, if the grid center is not on one of the fine grid points, the grid units are created incorrectly, thus ruining the grid:

To prevent this, first use a partial grid to move the center one grid point south (down) or south-west (bottom-left). That is, create 2 units (using a 1x1 grid); centre your mobile grid location on a unit there (this will be the south unit). Remove both units, then create a new unit at the mobile grid location (remember, this is now south of where we want the centre). Now we need to move the location back up to where we want it (but centred correctly). To do so, create 7 units and centre the mobile grid location on any unit just created (this will be north of your current location.) This will result in the grid center being centered on the subtile grid without offsets, hence allowing you to use mobile grids normally from that point.

### SC Mechanics Regarding Location Grids

To understand how Location grids work, one must know three facts:

1. A location can never leave the map in any of its dimensions.

2. If a location is attempted to be centered on a unit, the center of the location will be moved as close as possible to the center of the unit in both coordinates without breaking rule (1).

3. If a location A is attempted to be centered on a non-existing unit in location B, then the center of location A will be moved as close as possible to the center of location B in both coordinates without breaking rule (1).

Location grids are capable of moving a location to any grid point on the map. The closer the grid points are to each other, the more accurate the grid. Grid points are defined by the map maker - he has the ability to make a grid of any accuracy within the map limits.

The basic idea of Location grids is to use sets of locations as the X and Y axis along the map borders. Here is an example of a 1-tile-accurate Location grid:

The 1x1 tile "X=0" and "Y=0" locations are the coordinate start, the zeros for X and Y. All the axis locations must touch at least two borders of the map (all the shown locations touch the bottom and left borders of the map). All locations centers coinside with the corresponding tile centers. The shown grid can center a location on 9 possible points (3\*3=9) buy using rules (1) and (3). One of the axis is chosen to be the 'static' one, and th eother - the dynamic one. For this example, let X be static and Y be dynamic.

Then the actions taken to center a location on a grid point X=1, Y=2 are the following:
1. Center a 'middleman' location "scan" on the required X coordinate, X=1:

2. Center the required Y coordinate location (Y=2) on the 'middleman' location "scan":

The two triggers that rearrange the locations for this specific case are:

```
   Trigger("Player 1"){
   Conditions:
       Deaths("Current Player", "X Coordinate", Exactly, 1);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Cave-in", "X=1", "scan");
       Set Deaths("Current Player", "X Coordinate", Set To, 0);
   }

   //-----------------------------------------------------------------//

   Trigger("Player 1"){
   Conditions:
       Deaths("Current Player", "Y Coordinate", Exactly, 2);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Cave-in", "scan", "Y=2");
       Set Deaths("Current Player", "Y Coordinate", Set To, 0);
   }

   //-----------------------------------------------------------------//

```

First, it centers the 1x1 tile "scan" location on the required coordinate of X, then it centers the required coordinate of Y on "scan". This two-step process is much more trigger-efficient than having to make a trigger per grid point.

Note that all the trigger code in the Location Grid section is not valid in the text trigger editor, as the parameters "X Coordinate" and "Y Coordinate" are not accepted - they must be original unit names. They are used simply to make the triggers understandable.

The general trigger system for this grid would be the following:

```
   Trigger("Player 1"){
   Conditions:
       Deaths("Current Player", "X Coordinate", Exactly, 0);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Cave-in", "X=0", "scan");
       Set Deaths("Current Player", "X Coordinate", Set To, 0);
   }

   //-----------------------------------------------------------------//

   Trigger("Player 1"){
   Conditions:
       Deaths("Current Player", "X Coordinate", Exactly, 1);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Cave-in", "X=1", "scan");
       Set Deaths("Current Player", "X Coordinate", Set To, 0);
   }

   //-----------------------------------------------------------------//

   Trigger("Player 1"){
   Conditions:
       Deaths("Current Player", "X Coordinate", Exactly, 2);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Cave-in", "X=2", "scan");
       Set Deaths("Current Player", "X Coordinate", Set To, 0);
   }

   //-----------------------------------------------------------------//

   Trigger("Player 1"){
   Conditions:
       Deaths("Current Player", "Y Coordinate", Exactly, 0);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Cave-in", "scan", "Y=0");
       Set Deaths("Current Player", "Y Coordinate", Set To, 0);
   }

   //-----------------------------------------------------------------//

   Trigger("Player 1"){
   Conditions:
       Deaths("Current Player", "Y Coordinate", Exactly, 1);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Cave-in", "scan", "Y=1");
       Set Deaths("Current Player", "Y Coordinate", Set To, 0);
   }

   //-----------------------------------------------------------------//

   Trigger("Player 1"){
   Conditions:
       Deaths("Current Player", "Y Coordinate", Exactly, 2);

   Actions:
       Comment("");
       Preserve Trigger();
       Move Location("Current Player", "Cave-in", "scan", "Y=2");
       Set Deaths("Current Player", "Y Coordinate", Set To, 0);
   }

   //-----------------------------------------------------------------//

```

### Map Coverage

Since each next coordinate location is two tiles longer than the previous one, it is clear that with the setup shown above it is possible to cover only 25% of the map area. Meaning that each such set of coordinate locations covers one corner of a map. A logical solution is to make similar sets of locations for the other 3 corners of the map, but that will require too many locations. Alternatively, one could create 'origin' locations for each corner and reuse the same set of coordinate locations for all corners of the map buy centering them on the required origin locations. So if it needed to center a location on a point in the upper-right portion of the map, it would be enough to center the already existng coordinate locations on the new origin and work from there.

### Pros and Cons

Though lagless, Location grids eat up locations very fast. The good thing about them is that they make the use of locations not needed - they can detect whether a unit is in a location or not, detect a unit's coordinates and create events at locations; so if all used areas of the map are covered by a Location grid system, other locations are simply not needed.

## Grid Combinations

It is often wise to combine grid systems to complement the weaknesses of one system by the strengths of another.

### Static and Mobile

It is possible to reduce lag caused by a Mobile grid traveling too much by creating a spread-out Static grid and launching the Mobile grid from one of the points of the Static grid.

### Static and Location

To save locations (though sacrifice units) used in a Location grid, it is possible to replace the static axis of the grid with a line of units. One advantage of this is the ability to cover the entire map without going through the trouble of moving the coordinate locations from one corner to another - there are no coordinate locations; all that is needed are two lines of units along two parallel borders of the map or you can use shift locations to cut the units in half. Be advised that such a combination will not allow intense use due to lag that is brought into the system by the static grid unless you have enough units available so you don't have to give any at all.

### Mobile and Location

Another way of saving locations in a Location grid is making it less accurate and using its grid points as launch points for a more accurate, albeit more laggy and air unit incompatible, Mobile grid.

### Static, Mobile and Location

The combination of all three: use preplaced units as the static axis for the inaccurate Location grid, and use that grid's points to launch Mobile grids.