# 3d-tilemap example (tilemap to mesh)

**URL:** <https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068>\
**Category:** The Defoldmine\
**Created:** [August 16, 2020, 6:48pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068 "2020-08-16T18:48:59Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dragosha](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/dragosha/32/5103_2.png) [@Dragosha](https://forum.defold.com/u/Dragosha)\
**Post date:** [August 16, 2020, 6:48pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/1 "2020-08-16T18:48:59Z")

</div>

Hi there!

Here is my code example for creating a mesh from a tilemap in runtime:

> **[defold-things/3d-tilemap at master · Dragosha/defold-things](https://github.com/Dragosha/defold-things/tree/master/3d-tilemap)**
>
> Defold examples. Contribute to Dragosha/defold-things development by creating an account on GitHub.

An example is well commented, hope it helps someone to open the wonderful world of Defold meshes 🙂

Try it here: [HTML 5 demo](https://dragosha.com/defold/3d-tilemap/index.html)

[https://forum-defold-uploads.b-cdn.net/original/3X/1/f/1f166f2245e699990d47842cb2319792a910c5cd.mp4](https://forum-defold-uploads.b-cdn.net/original/3X/1/f/1f166f2245e699990d47842cb2319792a910c5cd.mp4)

How to use:

1. Copy ‘mtool.lua’ module to your project.
2. Create a standard tilemap.
3. Add to scene a game object with a mesh component. We will use it as target later.
4. In your code require mtool: `local mtool = require "src.mtool"`
5. Fill the options table:

```lua
local options = {
		tilemap = "level#level", -- Tilemap URL.
		layer = "layer1", -- Tilemap layer name.
		w = 16, -- Horizontal number of tiles in tileset (texture atlas).
		h = 16, -- Vertical number of tiles in tileset (texture atlas).
		tilesize = 16, -- Size of tile in pixels (it will be use as scale factor when a script generates quads).
		
		-- Note: The same image that using as tilesource image we are using as a texture for generated mesh.
		-- Each tile in tilemap layer will represented as box.
		-- 
		-- Each box contains 6 edges (faces). We can replacement their textures by setting tile number for each edge.
		-- '1' is front edge, '2' - top, etc.
		-- [2]
		-- [4][1][5][6]
		-- [3]
		-- For example we want see a mixed grass tile (N) on front edge and pure green tile (M) on top edge.
		-- So, mapping it as: [N] = {N, M, N, N, N, N}
		-- 
		
		tile_info = {
			[2] = {2, 18, 34, 1, 1, 1},
			[3] = {3, 19, 35, 1, 1, 1},
			[4] = {4, 20, 36, 1, 1, 1},
			[6] = {6, 19, 35, 1, 1, 1},
			[51] = {51, 49, 49, 49, 49, 49},
			[53] = {53, 49, 49, 49, 49, 49},
		},

		-- You also can setup function 'tile_info_fn' for dynamic setting tile number. It may useful for generating levels in runtime.
		-- tile_info_fn = function(tileno, x, y)
		-- if tileno == 1 then return {1, 4, 1, 1, 1, 1} end
		-- end

		optimize = false, -- If 'true' a script will culling the hidden by neighbors faces (edges 2,3,4,5).
		optimize_back = false -- If 'true' a script will culling back face (6) for all tiles.

		-- Also you may setup a texture atlas and setup for some tile numbers UV coordinates directly way.
		-- It's optionaly and made for further commits.
		-- All units are in pixels. Top-left corner is 0,0.

		-- For example:
		-- texture = {
		-- width = 512,
		-- height = 512,
		-- [2] = {x = 128, y = 0, w = 128, h = 256},
		-- }
	}

```

1. Create a mesh from tilemap:

```lua
	self.grid = mtool.create_mesh_from_tilemap("go#mesh", options)

```

1. Hide origin tilemap.

```lua
	msg.post(options.tilemap, "disable")

```

* * *

An example contains utility camera contoller script and uses **rendercam** extension.  
Custom render script is modified rendercam render script where fixed render ordering 3d models and 2d objects. In example you may see that sprites are drawing in the same space as mesh tilemap and their can overlap each other.

If you do not need to see light source and want to do flat colors then remove “Diffuse light calculations” sections in the mesh fragment shader (assets/material/mesh.fp). In this case it should looks like

```lua
void main()
{
    // Pre-multiply alpha since all runtime textures already are
    vec4 tint_pm = vec4(tint.xyz * tint.w, tint.w);
    vec4 color = texture2D(tex0, var_texcoord0.xy)*tint_pm;
    gl_FragColor = vec4(color.rgb*var_color0.rgb, color.a*var_color0.a);
}

```

Happy Defolding!

---

<div class="post-metadata">

**Author:** ![britzl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/britzl/32/23_2.png) [@britzl](https://forum.defold.com/u/britzl)\
**Post date:** [August 16, 2020, 7:43pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/2 "2020-08-16T19:43:38Z")

</div>

This is really great! Thank you for sharing.

---

<div class="post-metadata">

**Author:** ![Pawel](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/pawel/32/24623_2.png) [@Pawel](https://forum.defold.com/u/Pawel)\
**Post date:** [August 17, 2020, 5:59pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/3 "2020-08-17T17:59:17Z")

</div>

How did you?! 😳 Looking soo cool! 🤩

---

<div class="post-metadata">

**Author:** ![Epitaph64](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/epitaph64/32/39288_2.png) [@Epitaph64](https://forum.defold.com/u/Epitaph64)\
**Post date:** [August 22, 2020, 4:46am UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/4 "2020-08-22T04:46:19Z")

</div>

Thanks for sharing this, this looks like a great way to do a classic brawler game like Super Smash Brothers or something along those lines. Would it be cool to adapt this example for use in a game I started working on? This would be a great way to render the levels since I’m working on a top down shooter style game.

---

<div class="post-metadata">

**Author:** ![Dragosha](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/dragosha/32/5103_2.png) [@Dragosha](https://forum.defold.com/u/Dragosha)\
**Post date:** [April 14, 2021, 11:52am UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/5 "2021-04-14T11:52:08Z")

</div>

> Another great optimization is for the mesh components. They will no longer upload their vertex buffer each frame, but only if the buffer is modified. The Native Extension api got the new  
> [Don't upload vertex buffers unless they've changed · Issue #5167 · defold/defold · GitHub](https://github.com/defold/defold/issues/5167)

Seems, this changing of mesh component in the latest release has broken some cool mesh behavior. I mean able to change vertex properties (color, position, uv) in the realtime. In the demo above that feature was used for changing a quad color in the generated before mesh component. (Click on tile within a 3d tilemap). If build a demo with a new engine version, nothing will happen.

> <https://github.com/Dragosha/defold-things/blob/master/3d-tilemap/src/mtool.lua#L299>

How to let know the mesh component need to change his state (upload the buffer) now? @Mathias_Westerdahl

---

<div class="post-metadata">

**Author:** ![Mathias\_Westerdahl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/mathias_westerdahl/32/228_2.png) [@Mathias\_Westerdahl](https://forum.defold.com/u/Mathias_Westerdahl)\
**Post date:** [April 14, 2021, 12:10pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/6 "2021-04-14T12:10:39Z")

</div>

Ah, that’s unfortunate and it’s not intentional.

From C++ you’ve have to use the new special function [dmBuffer::UpdateContentVersion(dmBuffer::HBuffer)](https://defold.com/ref/stable/dmBuffer/#dmBuffer::UpdateContentVersion:type).

From Lua, we should be able to detect accesses and writes to the buffer.  
The (C++) implementation for updating a buffer stream from Lua is here.

> <https://github.com/defold/defold/blob/dev/engine/gamesys/src/gamesys/scripts/script_buffer.cpp#L875>

What type is the `mesh.color0` and how do you update the underlying mesh stream?

---

<div class="post-metadata">

**Author:** ![Dragosha](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/dragosha/32/5103_2.png) [@Dragosha](https://forum.defold.com/u/Dragosha)\
**Post date:** [April 14, 2021, 12:21pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/7 "2021-04-14T12:21:42Z")

</div>

> [@Mathias\_Westerdahl](#):
>
> What type is the `mesh.color0` and how do you update the underlying mesh stream?

As I understand the type declare in buffer.create method here:

> <https://github.com/Dragosha/defold-things/blob/master/3d-tilemap/src/mtool.lua#L212>

Then this color table getting as buffer stream `local color0 = buffer.get_stream(buf, "color0")` and stored in mesh _object_ (this is just a table with fields like buffer, streams etc).  
So, in the code I just change values in this streams and can see changes immediately.

May be we need for special method in Lua to call c++ update buffer function?

---

<div class="post-metadata">

**Author:** ![Mathias\_Westerdahl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/mathias_westerdahl/32/228_2.png) [@Mathias\_Westerdahl](https://forum.defold.com/u/Mathias_Westerdahl)\
**Post date:** [April 14, 2021, 12:44pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/8 "2021-04-14T12:44:18Z")

</div>

```lua
local color0 = buffer.get_stream(buf, "color0")
color0[0] = ...

```

Using this _should_ have worked, so I need to debug that.  
And once it works, there would be no need for a Lua version of the buffer update function.

---

<div class="post-metadata">

**Author:** ![Dragosha](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/dragosha/32/5103_2.png) [@Dragosha](https://forum.defold.com/u/Dragosha)\
**Post date:** [April 14, 2021, 4:13pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/9 "2021-04-14T16:13:57Z")

</div>

> [@Mathias\_Westerdahl](#):
>
> Using this _should_ have worked, so I need to debug that.

I’d be nice!  
For example this [Mesh Component - #40 by Dragosha](https://forum.defold.com/t/mesh-component/65137/40) little demo doesn’t work too.

---

<div class="post-metadata">

**Author:** ![Mathias\_Westerdahl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/mathias_westerdahl/32/228_2.png) [@Mathias\_Westerdahl](https://forum.defold.com/u/Mathias_Westerdahl)\
**Post date:** [April 15, 2021, 6:25am UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/10 "2021-04-15T06:25:09Z")

</div>

Fix is coming in 1.2.182 ([PR](https://github.com/defold/defold/pull/5745) is in review)

---

<div class="post-metadata">

**Author:** ![Dragosha](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/dragosha/32/5103_2.png) [@Dragosha](https://forum.defold.com/u/Dragosha)\
**Post date:** [April 19, 2021, 5:20pm UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/11 "2021-04-19T17:20:54Z")

</div>

> [@Mathias\_Westerdahl](#):
>
> Fix is coming in 1.2.182

Checked in beta 182. Works correct. Thanks!

---

<div class="post-metadata">

**Author:** ![Dragosha](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/dragosha/32/5103_2.png) [@Dragosha](https://forum.defold.com/u/Dragosha)\
**Post date:** [July 14, 2021, 7:21am UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/12 "2021-07-14T07:21:03Z")

</div>

Another example:

[![](https://img.youtube.com/vi/N-iy_LMoLhU/maxresdefault.jpg "Defold. Simple 3D. Converting the tilemap to 3d mesh.") ](https://www.youtube.com/watch?v=N-iy_LMoLhU)

---

<div class="post-metadata">

**Author:** ![britzl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/britzl/32/23_2.png) [@britzl](https://forum.defold.com/u/britzl)\
**Post date:** [July 14, 2021, 9:28am UTC](https://forum.defold.com/t/3d-tilemap-example-tilemap-to-mesh/66068/13 "2021-07-14T09:28:22Z")

</div>

This is absolutely fantastic! It looks like a really nice workflow. I’d like to share more about this in a future blog post.
