{"_id":"59a9f7b428ab5f000f239574","category":{"_id":"59a9f7b328ab5f000f23954e","version":"59a9f7b328ab5f000f23954a","project":"543b9b0065bf840e00b473d5","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-03-18T09:27:45.529Z","from_sync":false,"order":3,"slug":"terrain","title":"Terrain"},"user":"543b9aa865bf840e00b473d1","parentDoc":null,"project":"543b9b0065bf840e00b473d5","version":{"_id":"59a9f7b328ab5f000f23954a","project":"543b9b0065bf840e00b473d5","__v":1,"createdAt":"2017-09-02T00:13:39.834Z","releaseDate":"2017-09-02T00:13:39.834Z","categories":["59a9f7b328ab5f000f23954b","59a9f7b328ab5f000f23954c","59a9f7b328ab5f000f23954d","59a9f7b328ab5f000f23954e","59a9f7b328ab5f000f23954f","59a9f7b328ab5f000f239550","59a9f7b328ab5f000f239551","59a9f7b328ab5f000f239552","59a9f7b328ab5f000f239553","59a9f7b328ab5f000f239554","59a9f7b328ab5f000f239555","59a9f7b328ab5f000f239556","59a9f7b328ab5f000f239557"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"7.2.0","version":"7.2"},"githubsync":"","__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-03-17T15:13:31.211Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":0,"body":"[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Introduction\"\n}\n[/block]\nAll 2D strategy games use seamless tiles to build their environments. Most of this art is either illustrated or produced in 3D programs. This includes famous games like Clash of Clans or Command and Conquer: Red Alert. Huge environments can be built from relatively small sprite atlases. Each sprite can be flipped horizontally or vertically, for variation. The 3D appearance of the environment is a clever illusion, and the repetitive tiles are almost unnoticeable.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/sBeoBfLLScKbccpEp4NC_game.jpg\",\n        \"game.jpg\",\n        \"800\",\n        \"600\",\n        \"#80674b\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. Command & Conquer - Red Alert 2 - Yuri's Revenge (2001)\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Mobile's Limited Memory & Efficient Tiling\"\n}\n[/block]\niPhones/iPod Touches/iPads all have a Unified Memory Architecture which mean that both the CPU and GPU share system memory. There is no dedicated video memory on these devices. Here's a breakdown of the memory on older devices you might still be targeting: \n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"iPhone 4S\",\n    \"0-1\": \"512 MB of RAM\",\n    \"1-1\": \"1 GB of RAM\",\n    \"1-0\": \"iPhone 5 - iPad 3 - iPhone6\",\n    \"2-0\": \"iPhone 7 / 7 Plus\",\n    \"2-1\": \"2-3 GB of Ram\"\n  },\n  \"cols\": 2,\n  \"rows\": 3\n}\n[/block]\nThe reason for using a tiled environment and not a pre-rendered, high quality image is that a single 1024x1024 px ARGB32 Texture2D *can use up to 4-8MB of memory*. Now considering the limited RAM seen above, you can see why it's important to keep texture sizes down?\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/me9gJcc4RGmpIa1owIt3_mapsize.jpg\",\n        \"mapsize.jpg\",\n        \"800\",\n        \"600\",\n        \"#f13938\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger.\"\n    }\n  ]\n}\n[/block]\nOur island tile map example has a size of 17920 x 25340 px, each tile has 256x181 px. So without using tiles, a lot of memory would be consumed by the map alone.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/OdCBwIDSNOErADCIqJop_full-size.jpg\",\n        \"full-size.jpg\",\n        \"800\",\n        \"600\",\n        \"#6fa832\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\nBut with tiles, the source image of the entire base environment layer is a single 1024 px image, and the tiles are diced to reduce the total size of the image atlas/sprite collection.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/LmVQbYSrToGhlIaJKKdO_templatezz.jpg\",\n        \"templatezz.jpg\",\n        \"800\",\n        \"600\",\n        \"#406a98\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\nImagine the efficiency!\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Our Game Stats\"\n}\n[/block]\nAll the space saving techniques we're about to mention have lead to amazing performance on our mobile 2D game engine. See our stats – for explanations for each element, please see Unity's [Rendering Statistics Documentation](http://docs.unity3d.com/Manual/RenderingStatistics.html)\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/eTqQu6P7RKaP7tpOAUL0_template-stats.jpg\",\n        \"template-stats.jpg\",\n        \"800\",\n        \"600\",\n        \"#74a636\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. Unity Rendering Stats of the Pro Kit\"\n    }\n  ]\n}\n[/block]\nFor example, to preserve performance, the UI is updated only when necessary - something happens in the game - \"event based\", if you will call it, although events has a different, specific meaning in programming. For example, when construction is finished in ConstructionSelector.cs, we call a reference to update the UI. By doing this when the event is complete, rather than regularly, massive performance improvements can be made.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/WXzDB017TuyP38epicAV_storage_capacity_UI_update.png\",\n        \"storage_capacity_UI_update.png\",\n        \"1920\",\n        \"1050\",\n        \"#70b24c\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. UpdateUI is called when a building finishes to increase performance.\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Clipped Sprites\"\n}\n[/block]\nUnfortunately, the base environment is only one of many elements who will take up video/unified memory.\n\nIn most cases, buildings cannot be tiled or even sliced in the atlas, since at the time of this writing, a sliced image can not be used as a clipped sprite in 2D Toolkit. \n\nClipped sprites are necessary to make units or other objects appear in front or behind the buildings. The sprites have a different Z position – different depth layers, with negative values closer to the camera. This is the structure of one of our buildings, with both the top and the top shadow being clipped/animated sprites. (*See the shadow section further below to learn about shadows*)\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/KtNmN7biTcCUpjneYgKH_templateabdsag.jpg\",\n        \"templateabdsag.jpg\",\n        \"800\",\n        \"600\",\n        \"#75af36\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. Clipping makes it easier for units\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"What 2D Toolkit does\"\n}\n[/block]\nThe buildings and environment elements are stored as is, with 2D Toolkit making best use of the image surface by rotating and stacking them in the most efficient positions. The apparent defects are just artifacts who appear in transparent areas – the images are, in fact, perfectly clean. To avoid a clean, plane appearance, for variation, dirt, darker areas, transparent sprites can be added as decals over the base tiles. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/OzoCN8JfSHCCJhqM9kFW_transparent-aritifcats.jpg\",\n        \"transparent-aritifcats.jpg\",\n        \"800\",\n        \"600\",\n        \"#92705a\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. 2D Toolkit atlas file\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Scaling Graphics to Save Space\"\n}\n[/block]\nAnother technique commonly used to save space is to scale some of the graphics at twice the size– this is the reason buildings and characters may appear a little fuzzy in some games, due to the bilinear/trilinear filtering – the grass here is a perfect example:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/bUpDa1L7RQHkaZ87Tt33_scaled-background.jpg\",\n        \"scaled-background.jpg\",\n        \"800\",\n        \"600\",\n        \"#6a7f36\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. Clash of Clans\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Seamless isometric tiles\"\n}\n[/block]\nThe base environment is composed of several seamless isometric tiles. There are numerous tutorials for creating seamless tiles, square or isometric, in either Photoshop or Gimp. There are simple tiles representing a single element – sand, grass, water - and transition tiles, from grass to sand, for instance. You can also play with irregular, winding shapes by copying and flipping the gradient masks. \n\nThis is the structure of our isometric tiles, marked with the help of our pathfinder grid.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/Q05mAMS5Q9ucStVzA1nl_grid.jpg\",\n        \"grid.jpg\",\n        \"800\",\n        \"600\",\n        \"#79a623\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. iso tilegrid in our mobile game kit\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Creating Tiles\"\n}\n[/block]\nYou can create tiles easily. Here's how to do this with the free image editor GIMP. For simple isometric tiles, start from a 256x181 image. Although we recommend you work in a higher resolution while keeping it in the same proportion like 512x362(twice of 256x181) and scale it down. This can make for a better quality image.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/AUmIsQX3TBadlTlE0ZSo_tileage.jpg\",\n        \"tileage.jpg\",\n        \"800\",\n        \"600\",\n        \"#4abe46\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n1) Create a black/transparency layer with the intended texture shape – a black, hollow rotated square\n\n2) Insert a small grass texture in a separate layer\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/hft0YjkfSy25jucxEov7_steps12.jpg\",\n        \"steps12.jpg\",\n        \"800\",\n        \"600\",\n        \"#4fbc51\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n3) Offset it by half and erase the seams, if necessary – vertical/horizontal edges might be visible in the middle\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/Aky5iwxeQKuozsuHErlS_step3.jpg\",\n        \"step3.jpg\",\n        \"800\",\n        \"600\",\n        \"#48bb46\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n4) Insert a layer mask and paste the black/transparency layer\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/cWtZwnbVTx6lq7yMDImS_templateste4.jpg\",\n        \"templateste4.jpg\",\n        \"800\",\n        \"600\",\n        \"#47bb45\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n5) Export the tile. 2D Toolkit will use separate tiles to build the atlas\n\n**Tip:** For transition tiles, from grass to sand for instance, you will need to apply a different layer mask, this time with an oblique black and white gradient, which will allow the texture below to become partially visible.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/7xdQ1aSMST8s8hsK0vAg_templatetransitonal.jpg\",\n        \"templatetransitonal.jpg\",\n        \"800\",\n        \"600\",\n        \"#275a44\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Shadows - Special Tricks and How the City Building Kit Saves Memory\"\n}\n[/block]\nAny shadow in our environment is, in fact, a rotated/scaled sprite with black tint and a lower alpha for transparency. Sometimes, the best shadow of an object can be the sprite of another object, depending on the size and position of the projected shadow. We have created a single irregular shadow for groups of rocks, since no existing sprite could be used for this purpose. \n\nIn most cases, the shadow sprites can be very small, to save space, and stretched. Still, you must avoid overlapping shadows, or even partially transparent textures, since the common areas are visible – they become twice as opaque. \n\nObjects can have shadowed sides, or shadows in the foliage for high quality renders. What you will not need are the large shadows on the ground, or on walls – storing those for your objects would be a waste of resources. In most cases. they can be recreated from the same sprites, clipped or flipped as needed, with a black tint and a decreased alpha.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/n21arQuwSyS0P3Zv24MO_shadow1.jpg\",\n        \"shadow1.jpg\",\n        \"800\",\n        \"600\",\n        \"#3e8bcf\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Vegetation\"\n}\n[/block]\nYou can also consider storing your vegetation into separate elements – they are much easier to combine in different sizes, since you don't have to hide defects in the clipped sprites, like remaining foliage on a tree trunk, fragments of another trunk visible under foliage, etc. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/w8guatMKQnSYdedwxmMs_veg.jpg\",\n        \"veg.jpg\",\n        \"800\",\n        \"600\",\n        \"#bf9214\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\nAny large object, tree, building or rock is cut into two components, base and top, on different Z layers. The units moving around them (on a constant Z layer) must appear both in background and foreground, depending on object height and unit position. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/pq7z0sRQ0yaeVjghAJHg_clippinga.jpg\",\n        \"clippinga.jpg\",\n        \"800\",\n        \"600\",\n        \"#5696cd\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\nFor this reason, the units must never get too close to objects, since the “cuts” separating the base and top clipped sprites might become visible. These separation lines are usually, right in the middle of buildings, and units cannot go there because the grass patches under the buildings are marked as obstacles on the pathfinder grid. \n\nAlso, visible projectiles must never cross these areas, as they might go both under and above the sprites. You can mask that with explosion effects, or make the projectiles explode much earlier, at the apparent first contact with the building (some explosions will be partially visible, as happening behind the buildings). \n\n**New Kit Owners: Another possibility introduced recently in our kit, is the pivot, or anchor, at the base of vertical objects**, which pushes the element slightly towards the camera or back, based on Y position. This allows units to go near such objects, while still appearing correctly behind or in front of them. This Z correction is calculated for all moving units at intervals of 0.3 or 0.5 seconds, and only once for static objects – when they are instantiated. \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Recreating Complex Geometry\"\n}\n[/block]\nMost, if not all isometric 2D games graphics are built from 3D rendered environments. Arguably, for the base tiled layer, the rendered environment must be free of all decoration, small objects, gradients, decals (dirt, grass), possibly even shadows. Let's take this image, for instance, ignoring the buildings, vehicles and trees. Say this was a 3D render of your environment.\n\nEvery straight line in the rendered image must be consistent with the angle of your isometric tiles, and the position/rotation of the camera must be consistent with any element that will be rendered for your game. Otherwise, buildings will lean in different directions, roads will appear in perspective, etc. \n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/IIZoF0iST6ljm61wHX3g_cd.jpg\",\n        \"cd.jpg\",\n        \"800\",\n        \"600\",\n        \"#cc3428\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. Command and Conquer Red Alert 2\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"success\",\n  \"title\": \"Tutorial GIMP Source Files\",\n  \"body\": \"For the following **How to Make an Isometric Tile Grid** tutorial, you can download the [GIMP editor source files here and follow along](https://www.dropbox.com/s/gqnit4epkd3e12a/GIMP-Isometric-Samples.zip?dl=0)\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"How to Make an Isometric Tile Grid\"\n}\n[/block]\nFor this example, we will use the image above. From this image above, you can extract a few isometric tiles for the pavements, roads, grass patches etc. \n\n1) We will start from a single, hollow tile, on a black layer, and a white background to better visualize our tiles.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/TuROSTo9TetlarU4UoLw_isonmet.jpg\",\n        \"isonmet.jpg\",\n        \"800\",\n        \"600\",\n        \"#9f9a4a\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n2) Duplicate and offset the layer with the width/height of your tiles, until you will have a grid that covers the entire area. Each layer's opacity is set to 10%, so you can see them simultaneously in the example image below. \n\nAgain, each separate tile is on a different layer, in a different position. Put these in a folder, if you want, and duplicate one of them. Offset it once with half the tile size, and then keep duplicating and offsetting with the full tile x and y sizes to obtain the other missing tiles (to cover the darker squares between tiles from the first set).\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/2BNBiQwmSumItd1Jjd5l_examplea.jpg\",\n        \"examplea.jpg\",\n        \"800\",\n        \"600\",\n        \"#839bc5\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\nThe second group of tiles will look like this:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/Mup4EgCTESOOiwjYwseA_titles2.jpg\",\n        \"titles2.jpg\",\n        \"800\",\n        \"600\",\n        \"#644544\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n3) Now that you've setup the tile grid, you're ready to take your 3D art and paste into it. Paste your render image into a separate layer and duplicate it like:\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/f1Bwp3HQTheUfZpiBxF8_pasete.jpg\",\n        \"pasete.jpg\",\n        \"800\",\n        \"600\",\n        \"#77564c\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\n4) Find an area of interest, and copy the black layer into an image layer mask. \n\n**Note:** Obviously for this example, this randomly selected environment/camera are not aligned with our tiles, and there is some perspective effect that will prevent our tiles from fitting in the finished result below, but this will be enough for an example.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/SYxzoKJQXS3yKaqtKpWR_paste2.jpg\",\n        \"paste2.jpg\",\n        \"800\",\n        \"600\",\n        \"#888341\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. Randomly selected art for the tile\"\n    }\n  ]\n}\n[/block]\n\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/6SCTGIikQeaeqt9kuqHP_paste33.jpg\",\n        \"paste33.jpg\",\n        \"800\",\n        \"600\",\n        \"#785d54\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger. Copying the black layer into the image mask\"\n    }\n  ]\n}\n[/block]\n5) Crop the image, disable the white background, and export as png. Undo a back to step 3 to revert to the full image, and repeat the previous steps for other areas.\n[block:image]\n{\n  \"images\": [\n    {\n      \"image\": [\n        \"https://files.readme.io/02n7jHiRVaB7mBO7KpB2_pavementtitle.jpg\",\n        \"pavementtitle.jpg\",\n        \"800\",\n        \"600\",\n        \"#f2e5ad\",\n        \"\"\n      ],\n      \"caption\": \"Click on image to view larger\"\n    }\n  ]\n}\n[/block]\nDo this for several other tiles, until you have enough to recreate the road in the middle. With a little help from the perspective tool, to correct the alignment and camera perspective effect, we now have two tiles to create a repeating portion of the road seen in the above result.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Conclusion\"\n}\n[/block]\nYou've learned about memory limitation with modern day mobile devices and why 2D games use sprites to render larger maps and tricks with reusing the same sprites to build complex scenes, shadows, and even splitting to mimic the appearance of walking around objects for in-game NPC characters. \n\nPlus, we've shown you have to create tiles you can use in the kit. Use the above instructions to create your own tile grids from 3D art, then read the terrain documentation to learn how to insert your new terrain asset into the kit.\n\nFor customizing building art or building sprites. Please see the building documentation.","excerpt":"Your 101 introduction to creating your own 2D assets using your 3D art.","slug":"2d-graphics-manual","type":"basic","title":"2D Graphics Manual"}

2D Graphics Manual

Your 101 introduction to creating your own 2D assets using your 3D art.

[block:api-header] { "type": "basic", "title": "Introduction" } [/block] All 2D strategy games use seamless tiles to build their environments. Most of this art is either illustrated or produced in 3D programs. This includes famous games like Clash of Clans or Command and Conquer: Red Alert. Huge environments can be built from relatively small sprite atlases. Each sprite can be flipped horizontally or vertically, for variation. The 3D appearance of the environment is a clever illusion, and the repetitive tiles are almost unnoticeable. [block:image] { "images": [ { "image": [ "https://files.readme.io/sBeoBfLLScKbccpEp4NC_game.jpg", "game.jpg", "800", "600", "#80674b", "" ], "caption": "Click on image to view larger. Command & Conquer - Red Alert 2 - Yuri's Revenge (2001)" } ] } [/block] [block:api-header] { "type": "basic", "title": "Mobile's Limited Memory & Efficient Tiling" } [/block] iPhones/iPod Touches/iPads all have a Unified Memory Architecture which mean that both the CPU and GPU share system memory. There is no dedicated video memory on these devices. Here's a breakdown of the memory on older devices you might still be targeting: [block:parameters] { "data": { "0-0": "iPhone 4S", "0-1": "512 MB of RAM", "1-1": "1 GB of RAM", "1-0": "iPhone 5 - iPad 3 - iPhone6", "2-0": "iPhone 7 / 7 Plus", "2-1": "2-3 GB of Ram" }, "cols": 2, "rows": 3 } [/block] The reason for using a tiled environment and not a pre-rendered, high quality image is that a single 1024x1024 px ARGB32 Texture2D *can use up to 4-8MB of memory*. Now considering the limited RAM seen above, you can see why it's important to keep texture sizes down? [block:image] { "images": [ { "image": [ "https://files.readme.io/me9gJcc4RGmpIa1owIt3_mapsize.jpg", "mapsize.jpg", "800", "600", "#f13938", "" ], "caption": "Click on image to view larger." } ] } [/block] Our island tile map example has a size of 17920 x 25340 px, each tile has 256x181 px. So without using tiles, a lot of memory would be consumed by the map alone. [block:image] { "images": [ { "image": [ "https://files.readme.io/OdCBwIDSNOErADCIqJop_full-size.jpg", "full-size.jpg", "800", "600", "#6fa832", "" ], "caption": "Click on image to view larger" } ] } [/block] But with tiles, the source image of the entire base environment layer is a single 1024 px image, and the tiles are diced to reduce the total size of the image atlas/sprite collection. [block:image] { "images": [ { "image": [ "https://files.readme.io/LmVQbYSrToGhlIaJKKdO_templatezz.jpg", "templatezz.jpg", "800", "600", "#406a98", "" ], "caption": "Click on image to view larger" } ] } [/block] Imagine the efficiency! [block:api-header] { "type": "basic", "title": "Our Game Stats" } [/block] All the space saving techniques we're about to mention have lead to amazing performance on our mobile 2D game engine. See our stats – for explanations for each element, please see Unity's [Rendering Statistics Documentation](http://docs.unity3d.com/Manual/RenderingStatistics.html) [block:image] { "images": [ { "image": [ "https://files.readme.io/eTqQu6P7RKaP7tpOAUL0_template-stats.jpg", "template-stats.jpg", "800", "600", "#74a636", "" ], "caption": "Click on image to view larger. Unity Rendering Stats of the Pro Kit" } ] } [/block] For example, to preserve performance, the UI is updated only when necessary - something happens in the game - "event based", if you will call it, although events has a different, specific meaning in programming. For example, when construction is finished in ConstructionSelector.cs, we call a reference to update the UI. By doing this when the event is complete, rather than regularly, massive performance improvements can be made. [block:image] { "images": [ { "image": [ "https://files.readme.io/WXzDB017TuyP38epicAV_storage_capacity_UI_update.png", "storage_capacity_UI_update.png", "1920", "1050", "#70b24c", "" ], "caption": "Click on image to view larger. UpdateUI is called when a building finishes to increase performance." } ] } [/block] [block:api-header] { "type": "basic", "title": "Clipped Sprites" } [/block] Unfortunately, the base environment is only one of many elements who will take up video/unified memory. In most cases, buildings cannot be tiled or even sliced in the atlas, since at the time of this writing, a sliced image can not be used as a clipped sprite in 2D Toolkit. Clipped sprites are necessary to make units or other objects appear in front or behind the buildings. The sprites have a different Z position – different depth layers, with negative values closer to the camera. This is the structure of one of our buildings, with both the top and the top shadow being clipped/animated sprites. (*See the shadow section further below to learn about shadows*) [block:image] { "images": [ { "image": [ "https://files.readme.io/KtNmN7biTcCUpjneYgKH_templateabdsag.jpg", "templateabdsag.jpg", "800", "600", "#75af36", "" ], "caption": "Click on image to view larger. Clipping makes it easier for units" } ] } [/block] [block:api-header] { "type": "basic", "title": "What 2D Toolkit does" } [/block] The buildings and environment elements are stored as is, with 2D Toolkit making best use of the image surface by rotating and stacking them in the most efficient positions. The apparent defects are just artifacts who appear in transparent areas – the images are, in fact, perfectly clean. To avoid a clean, plane appearance, for variation, dirt, darker areas, transparent sprites can be added as decals over the base tiles. [block:image] { "images": [ { "image": [ "https://files.readme.io/OzoCN8JfSHCCJhqM9kFW_transparent-aritifcats.jpg", "transparent-aritifcats.jpg", "800", "600", "#92705a", "" ], "caption": "Click on image to view larger. 2D Toolkit atlas file" } ] } [/block] [block:api-header] { "type": "basic", "title": "Scaling Graphics to Save Space" } [/block] Another technique commonly used to save space is to scale some of the graphics at twice the size– this is the reason buildings and characters may appear a little fuzzy in some games, due to the bilinear/trilinear filtering – the grass here is a perfect example: [block:image] { "images": [ { "image": [ "https://files.readme.io/bUpDa1L7RQHkaZ87Tt33_scaled-background.jpg", "scaled-background.jpg", "800", "600", "#6a7f36", "" ], "caption": "Click on image to view larger. Clash of Clans" } ] } [/block] [block:api-header] { "type": "basic", "title": "Seamless isometric tiles" } [/block] The base environment is composed of several seamless isometric tiles. There are numerous tutorials for creating seamless tiles, square or isometric, in either Photoshop or Gimp. There are simple tiles representing a single element – sand, grass, water - and transition tiles, from grass to sand, for instance. You can also play with irregular, winding shapes by copying and flipping the gradient masks. This is the structure of our isometric tiles, marked with the help of our pathfinder grid. [block:image] { "images": [ { "image": [ "https://files.readme.io/Q05mAMS5Q9ucStVzA1nl_grid.jpg", "grid.jpg", "800", "600", "#79a623", "" ], "caption": "Click on image to view larger. iso tilegrid in our mobile game kit" } ] } [/block] [block:api-header] { "type": "basic", "title": "Creating Tiles" } [/block] You can create tiles easily. Here's how to do this with the free image editor GIMP. For simple isometric tiles, start from a 256x181 image. Although we recommend you work in a higher resolution while keeping it in the same proportion like 512x362(twice of 256x181) and scale it down. This can make for a better quality image. [block:image] { "images": [ { "image": [ "https://files.readme.io/AUmIsQX3TBadlTlE0ZSo_tileage.jpg", "tileage.jpg", "800", "600", "#4abe46", "" ], "caption": "Click on image to view larger" } ] } [/block] 1) Create a black/transparency layer with the intended texture shape – a black, hollow rotated square 2) Insert a small grass texture in a separate layer [block:image] { "images": [ { "image": [ "https://files.readme.io/hft0YjkfSy25jucxEov7_steps12.jpg", "steps12.jpg", "800", "600", "#4fbc51", "" ], "caption": "Click on image to view larger" } ] } [/block] 3) Offset it by half and erase the seams, if necessary – vertical/horizontal edges might be visible in the middle [block:image] { "images": [ { "image": [ "https://files.readme.io/Aky5iwxeQKuozsuHErlS_step3.jpg", "step3.jpg", "800", "600", "#48bb46", "" ], "caption": "Click on image to view larger" } ] } [/block] 4) Insert a layer mask and paste the black/transparency layer [block:image] { "images": [ { "image": [ "https://files.readme.io/cWtZwnbVTx6lq7yMDImS_templateste4.jpg", "templateste4.jpg", "800", "600", "#47bb45", "" ], "caption": "Click on image to view larger" } ] } [/block] 5) Export the tile. 2D Toolkit will use separate tiles to build the atlas **Tip:** For transition tiles, from grass to sand for instance, you will need to apply a different layer mask, this time with an oblique black and white gradient, which will allow the texture below to become partially visible. [block:image] { "images": [ { "image": [ "https://files.readme.io/7xdQ1aSMST8s8hsK0vAg_templatetransitonal.jpg", "templatetransitonal.jpg", "800", "600", "#275a44", "" ], "caption": "Click on image to view larger" } ] } [/block] [block:api-header] { "type": "basic", "title": "Shadows - Special Tricks and How the City Building Kit Saves Memory" } [/block] Any shadow in our environment is, in fact, a rotated/scaled sprite with black tint and a lower alpha for transparency. Sometimes, the best shadow of an object can be the sprite of another object, depending on the size and position of the projected shadow. We have created a single irregular shadow for groups of rocks, since no existing sprite could be used for this purpose. In most cases, the shadow sprites can be very small, to save space, and stretched. Still, you must avoid overlapping shadows, or even partially transparent textures, since the common areas are visible – they become twice as opaque. Objects can have shadowed sides, or shadows in the foliage for high quality renders. What you will not need are the large shadows on the ground, or on walls – storing those for your objects would be a waste of resources. In most cases. they can be recreated from the same sprites, clipped or flipped as needed, with a black tint and a decreased alpha. [block:image] { "images": [ { "image": [ "https://files.readme.io/n21arQuwSyS0P3Zv24MO_shadow1.jpg", "shadow1.jpg", "800", "600", "#3e8bcf", "" ], "caption": "Click on image to view larger" } ] } [/block] [block:api-header] { "type": "basic", "title": "Vegetation" } [/block] You can also consider storing your vegetation into separate elements – they are much easier to combine in different sizes, since you don't have to hide defects in the clipped sprites, like remaining foliage on a tree trunk, fragments of another trunk visible under foliage, etc. [block:image] { "images": [ { "image": [ "https://files.readme.io/w8guatMKQnSYdedwxmMs_veg.jpg", "veg.jpg", "800", "600", "#bf9214", "" ], "caption": "Click on image to view larger" } ] } [/block] Any large object, tree, building or rock is cut into two components, base and top, on different Z layers. The units moving around them (on a constant Z layer) must appear both in background and foreground, depending on object height and unit position. [block:image] { "images": [ { "image": [ "https://files.readme.io/pq7z0sRQ0yaeVjghAJHg_clippinga.jpg", "clippinga.jpg", "800", "600", "#5696cd", "" ], "caption": "Click on image to view larger" } ] } [/block] For this reason, the units must never get too close to objects, since the “cuts” separating the base and top clipped sprites might become visible. These separation lines are usually, right in the middle of buildings, and units cannot go there because the grass patches under the buildings are marked as obstacles on the pathfinder grid. Also, visible projectiles must never cross these areas, as they might go both under and above the sprites. You can mask that with explosion effects, or make the projectiles explode much earlier, at the apparent first contact with the building (some explosions will be partially visible, as happening behind the buildings). **New Kit Owners: Another possibility introduced recently in our kit, is the pivot, or anchor, at the base of vertical objects**, which pushes the element slightly towards the camera or back, based on Y position. This allows units to go near such objects, while still appearing correctly behind or in front of them. This Z correction is calculated for all moving units at intervals of 0.3 or 0.5 seconds, and only once for static objects – when they are instantiated. [block:api-header] { "type": "basic", "title": "Recreating Complex Geometry" } [/block] Most, if not all isometric 2D games graphics are built from 3D rendered environments. Arguably, for the base tiled layer, the rendered environment must be free of all decoration, small objects, gradients, decals (dirt, grass), possibly even shadows. Let's take this image, for instance, ignoring the buildings, vehicles and trees. Say this was a 3D render of your environment. Every straight line in the rendered image must be consistent with the angle of your isometric tiles, and the position/rotation of the camera must be consistent with any element that will be rendered for your game. Otherwise, buildings will lean in different directions, roads will appear in perspective, etc. [block:image] { "images": [ { "image": [ "https://files.readme.io/IIZoF0iST6ljm61wHX3g_cd.jpg", "cd.jpg", "800", "600", "#cc3428", "" ], "caption": "Click on image to view larger. Command and Conquer Red Alert 2" } ] } [/block] [block:callout] { "type": "success", "title": "Tutorial GIMP Source Files", "body": "For the following **How to Make an Isometric Tile Grid** tutorial, you can download the [GIMP editor source files here and follow along](https://www.dropbox.com/s/gqnit4epkd3e12a/GIMP-Isometric-Samples.zip?dl=0)" } [/block] [block:api-header] { "type": "basic", "title": "How to Make an Isometric Tile Grid" } [/block] For this example, we will use the image above. From this image above, you can extract a few isometric tiles for the pavements, roads, grass patches etc. 1) We will start from a single, hollow tile, on a black layer, and a white background to better visualize our tiles. [block:image] { "images": [ { "image": [ "https://files.readme.io/TuROSTo9TetlarU4UoLw_isonmet.jpg", "isonmet.jpg", "800", "600", "#9f9a4a", "" ], "caption": "Click on image to view larger" } ] } [/block] 2) Duplicate and offset the layer with the width/height of your tiles, until you will have a grid that covers the entire area. Each layer's opacity is set to 10%, so you can see them simultaneously in the example image below. Again, each separate tile is on a different layer, in a different position. Put these in a folder, if you want, and duplicate one of them. Offset it once with half the tile size, and then keep duplicating and offsetting with the full tile x and y sizes to obtain the other missing tiles (to cover the darker squares between tiles from the first set). [block:image] { "images": [ { "image": [ "https://files.readme.io/2BNBiQwmSumItd1Jjd5l_examplea.jpg", "examplea.jpg", "800", "600", "#839bc5", "" ], "caption": "Click on image to view larger" } ] } [/block] The second group of tiles will look like this: [block:image] { "images": [ { "image": [ "https://files.readme.io/Mup4EgCTESOOiwjYwseA_titles2.jpg", "titles2.jpg", "800", "600", "#644544", "" ], "caption": "Click on image to view larger" } ] } [/block] 3) Now that you've setup the tile grid, you're ready to take your 3D art and paste into it. Paste your render image into a separate layer and duplicate it like: [block:image] { "images": [ { "image": [ "https://files.readme.io/f1Bwp3HQTheUfZpiBxF8_pasete.jpg", "pasete.jpg", "800", "600", "#77564c", "" ], "caption": "Click on image to view larger" } ] } [/block] 4) Find an area of interest, and copy the black layer into an image layer mask. **Note:** Obviously for this example, this randomly selected environment/camera are not aligned with our tiles, and there is some perspective effect that will prevent our tiles from fitting in the finished result below, but this will be enough for an example. [block:image] { "images": [ { "image": [ "https://files.readme.io/SYxzoKJQXS3yKaqtKpWR_paste2.jpg", "paste2.jpg", "800", "600", "#888341", "" ], "caption": "Click on image to view larger. Randomly selected art for the tile" } ] } [/block] [block:image] { "images": [ { "image": [ "https://files.readme.io/6SCTGIikQeaeqt9kuqHP_paste33.jpg", "paste33.jpg", "800", "600", "#785d54", "" ], "caption": "Click on image to view larger. Copying the black layer into the image mask" } ] } [/block] 5) Crop the image, disable the white background, and export as png. Undo a back to step 3 to revert to the full image, and repeat the previous steps for other areas. [block:image] { "images": [ { "image": [ "https://files.readme.io/02n7jHiRVaB7mBO7KpB2_pavementtitle.jpg", "pavementtitle.jpg", "800", "600", "#f2e5ad", "" ], "caption": "Click on image to view larger" } ] } [/block] Do this for several other tiles, until you have enough to recreate the road in the middle. With a little help from the perspective tool, to correct the alignment and camera perspective effect, we now have two tiles to create a repeating portion of the road seen in the above result. [block:api-header] { "type": "basic", "title": "Conclusion" } [/block] You've learned about memory limitation with modern day mobile devices and why 2D games use sprites to render larger maps and tricks with reusing the same sprites to build complex scenes, shadows, and even splitting to mimic the appearance of walking around objects for in-game NPC characters. Plus, we've shown you have to create tiles you can use in the kit. Use the above instructions to create your own tile grids from 3D art, then read the terrain documentation to learn how to insert your new terrain asset into the kit. For customizing building art or building sprites. Please see the building documentation.