- A new look at layered grids: setting up neighbors The layered grid is a very generic type of grid....
- A simple path-finding example This example shows how to use the path-finding algorithm that...
- Grids 2.2 Grids 2.2 was accepted in the Asset Store last week....

We ask ourselves two questions:

- Can we add a mechanism to create simple grids in one line of code?
- And if so, should we?

Before delving into these questions, let’s go over the way we can create grids in code now. There are two types of grids – grids that are used as data structures, and or not in the scene – and grids that are used as scene objects; **logical** and **physical** grids. In the typical scenario, you set up your grid in the scene using a grid builder, and add logic to that through grid behaviours. If you need a separate logical grid, you clone the physical grid in the new type, and fill the contents with what you need. You can also use the grid behaviour to configure the physical grid from data or a logical grid (that can be constructed from data in a file, for example).

This works fine for games where the grids are fixed-shaped. However, in many games, you need to construct grids of different shapes or sizes. In this case, you have two options.

The first is to assemble your grids from scratch. This involves building grid, and a grid map, which in turns is composed of a round map and a space map. And each of these involves a few concepts that you need to understand for everything to work, so it is somewhat complicated. It is also a far from a one-liner – typically about 10 lines are necessary. Since this will typically be only in one place in the game, I don’t consider the amount of code a problem. But the mental strain is.

The second method is to construct a “bounding” grid in the inspector. This grid should be big enough to contain all the shapes you intend to use. You then add a grid behaviour that can activate the cells in the desired shape you want. All you have to understand using this method is how shapes work – maps, mouse interaction, cell creation are all taken care of by the grid builder. This method works well when your grids occupy the same place in space so that the holding shape is not much bigger than the typical grid.

So there are three scenarios – using grid builders for fixed grids, using code to build dynamic grids from scratch, and using a grid behaviour to filter active cells of a fixed grid built from a grid builder to get dynamic grids.

Of these, only the second presents a problem (in terms of complexity); so this is the situation we wanted to address.

Now lets look at the first question – is it possible?

If we were to consider only logical grids, it is possible, and very simple. For physical grids – grids that involve objects in the scene – the situation is more complicated. There are a few reasons for this:

- Cells can be of various types – sprites, 3D objects, or part of a mesh.
- Physical grids require grid maps to handle mouse input. So we cannot simply return a grid object from a method to create a grid – we somehow need to bind the grid and map. Ideally, the grid and map needs to be wrapped in a single object.
- Grids in code are generic, while Unity components are not. As it stands, grid builders are not generic – the “conversion” happens in grid behaviours. So your grid behaviour can access typed grids because it extends from a generic grid behaviour. This makes wrapping a grid and map more complicated – should the object be generic, or should we provide a different type for each possibility? The first makes it impossible to make this type a component, so we need to handle interaction with the grid in a somewhat clumsy way.

It is complicated, but possible. The best solution requires a new type, PhysicalGrid<tpoint, tcell=””>, that holds the grid, grid map, and game object that is the root of the grid; and that allows you to add a grid event trigger. It requires 16 methods (4 shapes, object vs mesh, and XY vs XZ). The implementation of this requires many small changes to the library to hook everything up.

Then…should we add this to the library?

I am not convinced.

First, the PhysicalGrid class is awkward. It really “needs” to be a component – but it cannot. It’s not a class that is idiomatic to either Unity or the Grids library, and working with it makes code look strange.

Second, it is adding one more grid class. It’s already difficult to keep track of the concepts; how does this class fit with the other classes?

Third, it is adding 16 more methods; 16 methods that need to be tested, documented, and maintained.

Fourth, it goes against the way we intended grids to be used and the rest of the library design. Once we add it, there will be demand for more features – features that already exist through the existing mechanism, but would need to be converted to work with PhysicalGrids.

Fifth, it adds an extra choice when building a game – should you use this way, or another? There are already a lot of choices: in the scene, or in code? Using tiles, or a mesh?

We are still mulling this over in the studio. There are also some alternative design possibilities.

We could, for instance, refactor our classes so that PhysicalGrid become the core component of grids in scenes, regardless of whether they have been built with a builder or from code. Like grid builders, they will not be generic, and you will need to add behaviour in GridBehaviours and attach these programmatically. This would be a very big and complicated change – and a breaking one at that.

Another would be to provide methods for creating logical grids, and some utility methods to build physical grids with objects or meshes.

So far, there are two takeaways from this investigation.

- Most of the complexity of the library lies in grid creation. This has also been the case with Grids 1, although there the complexity in the rest of the library and its usage was increased by the separation of different grid types (such as rect and hex grids).
- It seems impossible to reduce the complexity without reducing the features. We would not need the concept of “maps”, “shapes”, and “grid points” if we only wanted to represent simple cases. If you make one thing simpler, another becomes more complicated or impossible. There are no silver bullets.

Our investigation continues; let us know if you have any ideas!

]]>

- Grids 2.2 Grids 2.2 was accepted in the Asset Store last week....
- Day 3 Game 3: 30 games in 30 days using Grids Game 3 is a version of the famous game Ludo....
- Grids 2 is out: What changed Grids 2 has finally been released in the asset store....

The technology is not very complicated, but it took us a long time to get here.

First, we had to realize that the grid data structure was not just useful for game boards (or game worlds), but also for game pieces (and sections of game worlds). The first example where we used this idea was in this tri-grid game.

Second, we had to realize that the part of the grid that was usually useful in such cases is the **grid shape**. In Grids 1, shapes were second class citizens – merely used to make grids. The usual way to get a shape was to make an empty grid from it. This is one of the things we changed in Grids 2: shapes can now be used completely independently. (A useful tip: you can declare a ShapeGraph field in a MonoBehaviour and use the node editor to make shapes for your own purposes too).

Third, we had to make it easier to define more complicated shapes. Shapes used for playing fields are usually simple, symmetric shapes. However, shapes used for pieces are often much more complicated. Although you *could* define polyominoes using a union of a bunch of rectangles, it is awkward to work with. In this version, we introduce “bitmask” shapes: a shape defined by a bunch of bools that says whether a point is inside a shape or not. We provide a few methods to define these shapes. The easiest is to use an array of strings, like this:

var cross = ExplicitShape.BitMaskShape(new [] {"010", "111", "010"});

Which defines a 3×3 cross:

010 111 010

(The other methods allow you to specify a 2D array of int or bool instead of strings – under the hood all these are converted to the same thing).

There are nodes for these shapes too, but when it comes to using shapes for pieces, you are likely to require a whole bunch of shapes, so it’s easier to make a set of pieces in code. The class Polyominoes defines shapes for all polyominoes up to hexominoes. There are also enums, and dictionaries linking the enums to the actual shapes.

We also added an example that shows how to use these shapes in a typical game. The example shows two important techniques: how to define a custom shape data structure with more information to make it easier to write algorithms, and how to define a custom grid data structure to make it easier to deal with pieces that span multiple cells.

*TightShape2* is a shape that guarantees that the shape’s bounding box is as tight as it can be. (IExplicitShapes make no such guarantee, even though it is usually the case). If the bounding box is tight, it is much easier to compare shapes and determine whether they are they same. You can use the bounding box dimensions as early bail-out tests, and then move them to canonical positions and compare the shapes point-by-point.

*PuzzleGrid* is a grid-data structure that keeps track of multi-cell pieces. For example, it has a contains method that can check an entire shape (not just a single point), it can return the shape (appropriately translated) of a piece at any location (if there is a piece), and place a piece at a location. This type of grid should be useful in any type of game where you have multi-cell pieces that cannot occupy the same space, but moreover, shows the type of thinking in designing algorithms for grid games.

]]>

- Grids 2.1 Grids 2.1 was accepted today. It contains a few minor...
- Grids Version 1.2 Now Available in the Asset Store Since the first release, we have been working hard fixing...
- Support for Bitmask Shapes and Polyominoes in Grids 2.3 Polyominoes are used as pieces in many puzzle games, and...

We fixed some small bugs and warnings.

In the previous update we made our division operator consistent with that of Unity’s, but we did not change the mod operator to match! In this update, we do this. We also deprecated the old Div and Mod methods, and added two versions for each (one for floor division, and one for trunc division). Floor division (where (-1)/2 = -1) is the one you should find most useful in grid algorithms. Trunc division (where (-1)/2 = 0) is a method that implement ts the same behaviour as the operator. In all cases, mod has been implemented so that (x div n)n + (x mod n) = x.

The most interesting new features involve new methods and nodes for 3D shapes. We added layered shapes which allows you to use 2D shapes (either the same, or different ones) as layers of a 3D grid. We also added a new node that creates a 3D grid shape from 2D orthographic projections (the shapes in the image above was created with this node from only 4 different 2D shapes).

We also added a new “graph shape node” that allows you to use one shape graph in another. This makes it easier to construct complicated shapes.

We also added a new round map (both in code and to grid builders) called HexBlockRound, which is suitable to use for layered hex grids.

Finally, we also added inspectable versions of Interval, GridInterval, GridRect and GridBounds so these cfan be used in the inspector.

]]>

- Day 2 Game 2: 30 games in 30 days using Grids Game 2 is a maze traversal puzzle game; as in...
- What is coming in Grids 2.0 The new version of Grids is a major upgrade, with...
- Grids Lite is now available for free! Grids Lite is now available for free in the Unity...

First, we fixed all the examples that were not working. (We also removed two “examples” that was really our “scratch pad” testing scenes and should not have been part of the package in the first place.) We also removed some warnings that we did not spot before. There are a few remaining; they will be eliminated in the update we will post by the end of the week.

We also added a range-finding example. Range-finding gives you all the cells that lie within a certain range (where cells can have arbitrary costs or distances), or alternatively, give you all the cells in range and their costs.

We also improved memory allocation in all the path-finding and range-finding algorithms. We did not entirely eliminated memory allocation though. In many games, this is not a problem, but sometimes it is. We cannot completely solve this problem without reducing the flexibility of the algorithm (which makes it possible, for instance, to specify an arbitrary neighbor function). However, the algorithm is very straight-forward to adapt to avoid allocations completely. If you find it to be a problem, you can create a version form ours pretty quickly to do this. Mostly, this entails replacing generic code with specific code to avoid delagates and behind-the-scene foreach methods. If you need help with this, please ask us on the Knowledge Base.

The node editor we shipped with the first version of Grids is still a bit rough around the edges (from a UX viewpoint). As a first step to improve it, we made it possible to rename nodes (click on the name to edit it) and gave nodes better default names. We also made it possible to disable nodes. When a node is disabled, it simply routes the inputs to the outputs. This is useful especially when working with maps, where you may want to temporarily “take out” a node to see what is going on. We used to do this manually *all the time* when constructing more complicated maps.

One user pointed out that our division operator, as defined on GridPoints, were inconsistent with the C# division operator on integers. This affects only negative numbers. In C#, division by a negative number -n is defined as (-n) / m = – (n / m). There is an alternative definition (this is used by some languages such as Python) where (-n) / m = floor(- ((float) n / m)). In grids, we only use the latter type of division – because we use division to partition grid, and the latter definition gives equal-sized partitions. So we defined the division operator to implement this behaviour. However, it is probably not what programmers expect: if p is a grid point, then most programmers would expect p / n = (p.X / n, p.Y / n). So now we made it so. The old functionality is still there (in the method Div), and that is probably the one you should use in most cases. But at least most programmers will not get surprising behaviour.

On a side note: division is a big deal for us when it comes to grids. In the early days of the development of Grids 1, we frequently looked at how square grid algorithms and data structures could be adapted to hex grids. The algorithms fell into three classes – those that rely on neighbor relationships, those that rely on the notion of straight lines (like “three in a row” in match games), and those that rely on partitioning (such as quad trees and correlated noise). The first class was easily adapted because they were essentially graph algorithms. The second class was also easy to adapt, because hex grids – like square grids – can be treated like a vector space where a line is formed by adding a direction to a starting point. But it took a long time to crack the last class in a general way. We did some of it using grid-colorings as a strut – but over time we discovered the key is a type of division (as we explain in the third section of Hex Geometry for Game Developers). A lot of the design of Grids 2 was shaped by those ideas, and we will write more on that in the future.

In the meantime, we always like to hear your questions, so please ask us

]]>

- Grids 2.0 will be free for all Grids Pro users Hi Everyone, We’re happy to announce that all Grids Pro...
- Support Upgrade We have upgraded our support system to make responding to...
- Grids Lite is now available for free! Grids Lite is now available for free in the Unity...

Grids 2 is out and we’re offering an upgrade to all of our Grids users.

**Grids Pro users can upgrade to Grids 2 (Pro version) for 1USD.****Grids Basic and Grids Lite users can upgrade to Grids 2 (Pro version) for 5USD.**

If you own a version of Grids Pro, Basic or Lite, simply go to the Grids 2 Asset Store page and click on upgrade.

Grids Pro has already been deprecated and the Lite and Basic versions will follow shortly. We wont be providing any further updates to Grids 1, Grids Basic or Grids Lite, so be sure to upgrade as this wont be available indefinitely. For the immediate future we will be shipping Grids 1 with Grids 2.

If you have any questions or problems feel free to check out or post on the Grids 2 Knowledge Base.

For anyone interested in buying Grids 2, we’re selling it at a discounted price (60% off) as part of a release sale. You can pick it up for 40USD (normal price 100USD).

Gamelogic Team

]]>- Workarounds for AOT compiler limitations Applications running on iOS cannot generate and dynamically execute code...
- Gamelogic Extensions for Unity 1.2 is now available The newest version of our free extensions library is now...
- Extensions for Unity A few weeks ago we released a new (free!) package...

class MyBehaviour : MonoBehaviour { int count; public void Start() { count = CalculateCurrentCount(); } public void Update() { var currentCount = CalculateCurrentCount(); if(currentCount != count) { count = currentCount; DoSeomtingExpensive(); } } }

The idea is, you check or calculate some value very often (every frame, for example), but only perform some action when it changes. In this example it is not too bad, but when you have a few of these in a file, it can become messy. It’s also a bit error prone, especially if you update the value in several places and want to do checks right after you changed them instead of in the Update method.

ObservedValue (a new class in our free Extensions library) is meant to package this code neatly; it takes care of the boiler plate part, and at the same time makes it easy to move around in your code without having to worry about performing the actions when the value changes. Here is how the code above looks rewritten with ObservedValue:

class MyBehaviour : MonoBehaviour { ObservedValue<int> count; public void Start() { count = new ObservedValue(CalculateCurrentCount()); count.OnValueChanged += DoSeomtingExpensive; } public void Update() { count.Value = CalculateCurrentCount(); } }

This does exactly the same as first version, but it is much cleaner.

One important use case is when using the immediate GUI mode (typically, in editor code), where you want to change something when the user changes a value. In fact, we wrote this class when a level editor we developed for a client had about 20 variables that could influence what should be drawn on the screen, and started to run into many bugs as we made improvements to the tool.

Another useful strategy is to combine it with a state machine to prevent multiple calculations per frame (this is normally done with a dirty flag). Here is how it looks without a state machine:

class MyBehaviour : MonoBehaviour { bool isDirty; ObservedValue<int> count1; ObservedValue<int> count2; public void Start() { isDirty = false; count1 = new ObservedValue(CalculateCurrentCount1()); count1 += () { isDirty = true; }; count2 = new ObservedValue(CalculateCurrentCount2()); count2 += () { isDirty = true; }; } public void Update() { count1.Value = CalculateCurrentCount1(); count2.Value = CalculateCurrentCount2(); if(isDirty) { DoSomethingExpensive(); isDirty = false; } } }

Again, in this simple case it is not too bad. The code can become more complicated when spread across multiple classes, or if you have a few things that can become dirty independently, or if you have different “levels” of dirt.

Here is how the example above looks with a state machine

class MyBehaviour : MonoBehaviour { public enum DirtyState {Dirty, Clean}; StateMachine dirtyManager; ObservedValue<int> count1; ObservedValue<int> count2; public void Start() { dirtyManager = new StateMachine(); dirtyManager.AddState(DirtyState.Clean); dirtyManager.AddState( DirtyState.Dirty, null, () => { DoSomethingExpensive(); dirtyManager.SetState(DirtyState.Clean); }); count1 = new ObservedValue(CalculateCurrentCount1()); count1 += () { dirtyManager.SetState(DirtyState.Dirty); }; count2 = new ObservedValue(CalculateCurrentCount2()); count2 += () { isDirty = true; }; } public void Update() { count1.Value = CalculateCurrentCount1(); count2.Value = CalculateCurrentCount2(); dirtyManager.Update(); } }

In this simple example there is not a benefit from using the state machine; benefits come only once the situation becomes a bit more complex.

Of course, the code above has many boilerplate aspects, so you may want a DirtyManager class to take care of it (and this is a good candidate for a future addition to our Extensions library).

Here is a draft of such a class:

public class DirtyManager { private enum DirtyState {Dirty, Clean}; private StateMachine dirtyManager; public event OnShouldCleanDirt; //needs a better name! public DirtyManager() { dirtyManager = new StateMachine(); dirtyManager.AddState(DirtyState.Clean); dirtyManager.AddState( DirtyState.Dirty, null, () => { if(OnShouldCleanDirt != null) { OnShouldCleanDirt(); } dirtyManager.SetState(DirtyState.Clean); }); } public void Update() { dirtyManager.Update(); } public void Observe(ObservedValue observedValue) { observedValue.OnValueChanged += SetDirty; } private void SetDirty() { dirtyManager.SetState(DirtyState.Dirty); } }

Now the example can become this:

class MyBehaviour : MonoBehaviour { DirtyManager dirtyManager; ObservedValue<int> count1; ObservedValue<int> count2; public void Start() { count1 = new ObservedValue(CalculateCurrentCount1()); count2 = new ObservedValue(CalculateCurrentCount2()); dirtyManager = new DirtyManager(); dirtyManager.Observe(count1); dirtyManager.Observe(count2); dirtyManager.OnShouldCleanDirt += DoSomethingExpensive; } public void Update() { count1.Value = CalculateCurrentCount1(); count2.Value = CalculateCurrentCount2(); dirtyManager.Update(); } }

The code is much cleaner now, and much more robust against additional complexity.

One question is, do we really need the state machine? We don’t; we could use a bool just as easily to keep track. But in more complex cases, a state machine can offer value. For example, to deal with levels of dirt, or to deal with special circumstances. (For example, when we want to delay the calculation until something else happens.)

]]>- Porting Grids from Unity to GameMaker When GameMaker announced their Marketplace, we thought it would be...
- One Dimensional Grids Today I implemented a custom grid that is useful for...
- What is coming in Grids 2.0 The new version of Grids is a major upgrade, with...

One thing we have not completely taken into account is how much work it would be to convert the more than 70 examples we have for Grids 1 to Grids 2. Rather than delay the release even further, we decided to ship with a minimal set of examples, and add new ones gradually. The same goes for the tutorials; over the next few weeks we will add some tutorials, starting with the most common tasks. In the meantime, please ask us any questions on the Knowledge Base.

You may also want to read the Key Concepts (explained from a pure Grids 2 viewpoint).

**Grids 2 has only 2 types of grid points. **All 2D grid points (such as RectPoint, PointyHexPoint) have been replaced with GridPoint2, and all 3D grid points (LayeredPoint) with GridPoint3. All 1D grid points LinePoints use integers now instead. GridPoints are meant to be the integer counterparts of Vector2 and Vector3. Certain of the old functions (such as distance functions) are specific depending on the point type. Those still exist – now as static methods in classes such as RectPoint (which are static classes with no data).

**There are only 3 types of built-in grids.** Grid1, Grid2, Grid3. Grid1 is indexed with integers, Grid2 with GridPoint2, and Grid3 with GridPoint3. Grids don’t “know” whether they are hex grids or rect grids or any other type of grid. Grid1 corresponds to the LineGrids in Grids 1, and Grid3 corresponds roughly to LayeredGrids in Grids 1, but uses a “proper” 3D representation instead.

This also means there are no more spliced grids (such as specific grids for tri grids and rhom grids) or nested grids. Both these are now simply represented with grids that contain grids (or, in many cases, something even simpler).

**Grids don’t know how neighbors are connected.** In Grids 1, grids had a GetNeighbors method. On the one hand, it does not make sense for the new grid types to have these functions (since it depends on the grid type, which is not something the grid knows), and on the other hand we made the idea of “neighbor” more flexible (for example, you can define neighbors to be squares in a chessboard that can be reached by a knight). Functions that use neighbors take an extra parameter that specifies how neighbors should be calculated. For your own needs, you can define your own function, or use one of the ones provided (that correspond to the simple cases of direct neighbors in rect and hex grids).

**Algorithms that work on lines and rays have been generalized.** You can now use a more general description for a line (using maps described below) so that match algorithms can be used in more cases. As with neighbor definitions, line definitions are provided for simple cases.

**The type arguments in the IGrid interface has been swapped. **All grids still implement the IGrid interface. The new order reflect the order used by dictionaries (index type followed by contents type), which helps emphasize that grids are just special dictionaries with grid points as keys.

**Maps have been generalized. **Maps in Grids 1 were used to convert between grid points and world points. Maps work now more like the mathematical maps after which they have been named, and they can do general conversions on any type to any other type, much like the Func<t, tresult=””> class. The main difference is that maps are roughly invertible. They support Forward and Reverse methods. Maps can be composed and inverted. Because maps can be from one type to the same type, the indexing syntax does not work anymore. It is now necessary to call Forward and Reverse explicitly.

**Concrete map types are hidden.** All maps implement the IMap interface, and all concrete maps are hidden. To construct built in maps, you need to use the functions in the static Map class. This design reflect the design of the new generators. Dozens of small classes are needed to implement operations supported in Grids2. There is no need to know these classes (especially since inheritance is an especially poor choice to make a new map, and no map has any methods other than the interface methods).

**Maps used with grids now convert between grid-space vectors and Unity world space. **Before, maps only converted between **grid points** and world points. There was no concept of a grid point between (0, 0) and (1, 0). Now, there is a concept of “fractional” grid points (and we simply use the Vector classes to represent those). This makes it, for example, easy to build meshes, and work with vertices and edges of cells. For example, the point (1/3, 1/3) represents the north-east vertex of a pointy hex cell; you can now pop that into a map and find the world position of that vertex. Because of this unification of grid points and vectors, we dropped the concept of “edge” and “vertex” grids. We may revive it, but so far it looks like all algorithms can be implemented using coordinates directly.

**We added float and integer matrices for 2D and 3D that work with vectors and grid points. **Using linear transform can simplify many geometric algorithms. We added these specifically to allow implementation of various rect grid ideas for hexes, for example, septet-trees (similar to quad-trees, but for hexagonal grids) and hexagonal Perlin (or Perlin-related) noise.

**Grid shapes has been reworked. **Many grid algorithms only work on grid shapes, not on the actual data. In Grids1 it was necessary to build these algorithms with empty grids, but this is not always convenient (especially when the grid shapes are very big, or thousands are necessary). For this reason we wanted to separate the concept of a grid shape from the actual data structure “arranged” in that shape. Moreover, the old shape technology was very complicated and it had some very hard-to-fix (and luckily, hard to stumble upon) bugs. Finally, the old shape technology was very hidden and mysterious (even to us). It is not exactly clear how a shape gets turned into a grid.

The new technology addresses all these issues. There are now two types of shapes implicit shapes are objects that can tell whether a given grid point is inside the shape or not. An explicit shape is a shape that knows its bounds, and moreover can produce all the points inside the shape. Grids are explicit shapes that can hold a piece of data (the cell) at each point. It may sound a little abstract, but in practice it is simple to use these concepts – make a function that defines a shape, turn this into an implicit shape, turn this into an explicit shape by giving it bounds, and turn it into a grid. There are many common implicit shapes defined (and for most games, you should be able to set up shapes using the node editor instead).

We also plan to define some abbreviations for common scenarios in the future, but for now we are happy that the system is easy to extend in use in a wide variety of cases, without needing very deep knowledge of how the system works.

**There are new classes for float and integer intervals, integer rectangles and integer bounds. ** This makes it useful for certain geometric algorithms. The discrete versions of these are explicit shapes, so they also work with other shape algorithms.

**Maps and shapes can be built in the editor using a node system. **This makes it easy to create and modify maps and shapes. Over the last two years or so, we made examples of grids warped into spheres, cylinders, torusses, helixes, and Mobius bands; in each case we had to make a custom map. It is now possible to make all these maps with the node editor.

**GridBuilders have been reworked. **There used to be a grid builder for each type of grid. Now, there is only one grid builder for each representation type. We ship with tile grid builders and mesh grid builders, that can be used for all types of grids. Grid builders themselves are much simpler too. Things like dimensions, shapes and so on are now handled by the node editors.

**Grid input is now handled through an event system.** In Grids 1, you could define OnClick methods in either your GridBehaviour or cells. In Grids 2, you can add a GridEventTrigger that allows you to hook up a method from any component. The event trigger is also the new home for the MousePosition property (which returns the mouse position in grid coordinates).

**Mesh building technology has been unified.** We made the mesh generation technology (which before only existed as examples and a few special cases) much more general. A mesh can now be built for any type of (periodic) grid; all you have to do is provide a map (which you need for any representation in any case), and how each cell should be constructed in terms of grid-space coordinates. For example, the vertices of a hex can be specified as (1/3, 1/3), (2/3, -1/3) and so on. The map takes care of how those are interpreted in world space. This means if your map transforms your grid onto some shape such as a torus, you don’t need to change the cell construction coordinates *at all*. It will just work.

]]>

- Introducing Generators We added generators to version 1.2 of Extensions. A generator, in...
- Introducing Response Curves A response curve is an easy-to-define piece-wise linear curve. They...
- Gamelogic Extensions for Unity 1.2 is now available The newest version of our free extensions library is now...

In the latest version of Extensions (which came out yesterday!), we introduced the completely redesigned generators. A generator, if you don’t know the concept as we use it, is simply a class that has a Next method that always gives you an object of a certain type. They work a bit like random generators, except the elements may or may not be random. They support various LINQ-like methods, and so also resemble sequences (although generators are always infinite).

There are a few “primitive” generators that you can construct directly with the various static methods in the Generator class. These include:

**Constant:**a generator that always generates the same element.**Count:**a generator generates the sequence 0, 1, 2, 3, …, n, 0, 1, 2, forever.**Repeat:**generator that generates the elements of a given list repeatedly in sequence.**Iterate:**a generator that applies a given function to the last k elements to generate the next one.- Various random number and bool generators (uniform, arbitrary distribution, Markov chains)

By themselves these generators are not very interesting. But there are several methods that manipulate and combine them to make more interesting generators. Some of the most important are these:

**Where:**generates only elements from a source generator that satisfy a predicate**Select:**transforms the elements of a source generator and generates the transformed copies**Choose:**a generator that uses an integer generator to select from a list of objects**Group:**groups elements of a source generator, and generates the groups.**Combine:**uses several source generators to generate parameters for a function**RepeatEach:**uses a source generator, and repeats each generated element several times.

For a full list on all the generators and methods that can manipulate them, see the Extensions API documentation.

Here are some simple examples:

var generator = Generator .RamdomUniformInt(500) .Select(x => 2*x); //Generates random even numbers between 0 and 998 var generator = Generator .RandomUniformInt(1000) .Where(n => n % 2 == 0); //Same as above var generator = Generator .Iterate(0, 0, (m, n) => m + n); //Fibonacci numbers var generator = Generator .RandomUniformInt(2) .Select(n => 2*n - 1) .Aggregate((m, n) => m + n); //Random walk using steps of 1 or -1 one randomly var generator = Generator .Iterate(0, Generator.RandomUniformInt(4), (m, n) => m + n - 1) .Where(n >= 0); //A random sequence that increases on average

In each case, elements are only being produced each time you call the Next method or one of its variants. Most calculations are done lazily, so the bulk of the processing is spread over getting the elements and most generators don’t required much memory.

Generators are useful in creating procedural content, or alter properties of game entities (such as their strength) procedurally. A place where you want to use randomness is the ideal candidate, especially when you want to inject some order to make the playable experience more interesting or coherent.

In our own games, we have used generators that generate sky colors that change over time, scene decoration next to an infinite road, for obstacle patterns, for implementing AI that looks like they move with purpose, for controlling the current difficulty of the game, for making random interesting paths, and for generating letters that have a good chance to make words.

One of the programmers in our studio asked me to give him some exercises to help him practice thinking in terms of generators; they may be helpful to you too, so here they are below. They are roughly in increasing difficulty order; beware the last ones may be very difficult!

Write a generator that will produce:

- the even numbers (0, 2, 4, …)
- k! (1, 2, 6, 24, …)
- an item from either of two generators, randomly selected.
- an item from either of two generators, randomly selected, but advances both generators.
- noise added to a float generator.
- a read-only dictionary that counts the number of items generated so far by another generator.
- random integers below 10 with no two successive numbers equal.
- pairs of floats between 0 and 1 with negative correlation (of -0.5).
- random integers below 10 with no two successive numbers a difference larger than 4.
- 0s and 1s, where the distance between consecutive 1s is determined by another generator.
- 0s and 1s where the probability of successive values being equal is given by another generator.
- a sine wave sampled 10 times per revolution.
- items from a number generator with each for elements in sorted order (if the original sequence is 7, 4, 9, 2, 5, 8, 2, 0, 4, 4, 7, 3, … the new sequence will be 2, 4, 7, 9, 0, 2, 5, 8, 3, 4, 4, 7, …
- a function summing 10 sine waves with a random frequency and amplitude each.
- a function made of sine waves, where the amplitude is a new random number each revolution, sampled at 10 times per revolution.
- a function summing 10 generators of the previous type.
- a random smooth curve in 3D (a 3D “scribble”) where the curve is composed of pieces of circles, and the curve has no sharp bends.
- Vector2s around a circle sampled 10 times per revolution.
- Vector3s in an upwards spiral sampled 10 times per revolution.
- a random 3D walk.
- random vectors on a unit sphere. (Steps are equal distance).
- a random walk on a sphere. (Steps are equal distance).
- random floating point numbers normally distributed.
- 1D Perlin noise.
- the convolution of a number generator with a list of numbers.
- all the permutations of 3 from a list of 5 (and repeat). (0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, … After 0, 0, 4, the sequence continues 0, 1, 0, 0, 1, 1, 0, 1, 2)
- all the combinations of 3 from a list of 5 (and repeat). (0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, … After 0, 0, 4, the sequence continues 0, 1, 1, 0, 1, 2, 0, 1, 3)
- cubic interpolation for a generator of Vector3 (sampled at 10 times per original interval).
- Bezier interpolation for a generator of Vector3 (sampled at 10 times per original interval).
- the Fibonacci numbers (1, 1, 2, 3, 5, …)
- the tribonacci numbers (1, 1, 1, 3, 5, 9, 17, …)
- the prime numbers (2, 3, 5, 7, …)
- GridPoint2s that traverse a rectangle diagonally ((0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2), (3, 0), …)
- 1 element from a generator, restart the generator, generate two elements from the generator, restart the generator, generates 3 elements from the generator, and so on. If the base generator generates 1, 2, 3, this generator must generate 1, 1, 2, 1, 2, 3, 1, 2, 3, 4, …
- GridPoint2s in a spiral on a rect grid.
- GridPoint2s in a spiral on a hex grid.
- GridPoint2s in a Hilbert curve on a rect grid.
- GridPoint2s in a Gosper curve on a hex grid.
- GridPoint2s in a 3D Hilbert curve.
- Write a generator that will Zip another generator.

- Two South Africans in Santiago; our Global Game Jam experience Last year we attended the Global Game Jam in our...
- The birth of Game Dev Santiago 4th March 2015 Make Games SA is the official game...
- Our first Unity workshop in Santiago We recently started working with Wintek, a games publisher here...

- Grids 1.8 Grids 1.8 is finally out 🙂 This is quite a...
- Grids 1.10 is out! This is mostly a maintenance update, where we made many...
- What is coming in Grids 2.0 The new version of Grids is a major upgrade, with...

**So what happened?** There were some distractions with other projects, but the main delays were caused by technical reasons and underestimating the sheer size of Grids 1.

One of the purposes of Grids 2.0 is to make the frame work more unified. This was somewhat easy to do with the mathematical classes, but we started to run into problems with the classes that extend the editor (actual components, inspectors, the node editors and so on). At the heart of these issues lies the fact that Unity has poor support for generics in the editor classes, and we had to go through a few iterations to get a design that was simple to use, but still flexible and powerful. For example, we did not want separate Grid builders for each dimension (1D, 2D and 3D) – we already need separate builders depending on whether you need sprites, or game objects, or complete meshes. Since all the related aspects (the graph editors, the nodes, the maps, the grid points), depend on dimension, we had to make a builder that *is *generic, but does not require language features for this to work. So there is a drop down in the grid builder, and you can select the dimension, and automatically all the other right components are used behind the scenes. The graphs (used to edit grid shapes and maps) are different for each dimension – but from the user’s perspective they all look the same. The right types of nodes are automatically available, and right type of conversions happen so that the grid shape and map are of the right types.

We also somewhat underestimated just how many features Grids 1 has, and how much work it is to make them complete within the new framework. For example, we introduced mesh grid builders in Grids 1 not too long ago. Because we did it for 2D grids, we could re-use the maps used for normal grid-to-world calculations. In Grids 2.0, it makes sense to do the same, but in trying to make something that works consistently for all dimensions we found out that there is quite a fundamental difference on approach between what we think of a 1D grid and 2D and 3D grids, and the initial clever code we wrote had to be discarded for something less clever that *actually* reflects the types of grids developers are likely to use in their games. For similar reasons, concepts like wrapping, splicing, nesting, and layering, turned out to be slightly more complicated than we thought after we had the basics in place. Moreover, maps that need to know grid points (like Voronoi maps) did not fit so neatly into the initial simple structure.

**So where are we now?** We have basic grids, points, maps and shapes implemented for all dimensions, with a tile grid builder that can be used for all of these with sprites or game objects as cells. We implemented algorithms using the new structures (and made them also work with other concepts of “neighbors” and “lines”). We are almost finished making some adjustments to support mesh grids in the way we want, and the basic mesh grid builders are done. After that, we need to implement more defaults (currently we have everything for hex and rect grids), and the support for the more advanced features like wrapping and splicing (which we will not implement for all dimensions for now).

**When will it be ready?** We cannot give a definite estimate. We have done chunks in the last few months but started to work full time on it last week, and we are trying to get it out as soon as possible. Several users have asked for an early beta; as soon as we are confident that the basic interfaces are stable, we will make this available.

Thanks for being patient, and for all the support! We are really excited to bring Grids 2.0 out, and are working hard to make it so.

]]>