{"id":249,"date":"2017-12-23T21:18:28","date_gmt":"2017-12-23T21:18:28","guid":{"rendered":"http:\/\/www.wieringsoftware.com\/ts2\/?page_id=249"},"modified":"2022-09-19T15:35:13","modified_gmt":"2022-09-19T15:35:13","slug":"scripting","status":"publish","type":"page","link":"https:\/\/www.wieringsoftware.com\/ts2\/learn\/scripting\/","title":{"rendered":"Scripting"},"content":{"rendered":"<p>Tile Studio II has support for LUA scripting. You can add scripts to your project and set them up to run when you press a function key (F1 &#8211; F12). Here is a little example of a script:<\/p>\n<pre>-- MENU_ITEM: PerlinNoise [F7]\r\n\r\nfunction PerlinNoise()\r\n  NoiseSeed(123);\r\n  ModifyBuffer(f);\r\nend\r\n\r\nfunction f(x, y, w, h, bp)\r\n  bp.Offset = 20 * Noise2(x\/5, y\/5) - 10;\r\n \u00a0bp.Alpha = 255;\r\n  return bp;\r\nend<\/pre>\n<p>The function <em>ModifyBuffer<\/em> calls the given function <em>f<\/em> for every pixel of the buffer, <em>NoiseSeed<\/em> and <em>Noise2<\/em> are functions provided by Tile Studio II. Running this function gives the following Perlin Noise pattern:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-257 size-full\" src=\"http:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/perlin.png\" alt=\"\" width=\"239\" height=\"239\" srcset=\"https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/perlin.png 239w, https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/perlin-150x150.png 150w\" sizes=\"(max-width: 239px) 100vw, 239px\" \/><\/p>\n<p>Most functions will look similar to the one above. The function f provides a value for every pixel, which can depend on the position (x, y), the size of the tile (w, h) and the value of the original pixel in the buffer (bp).<\/p>\n<p>Pixels are represented as a Gradient (0 = first, 1 = second, etc), Offset (0 = center, -1 = one entry to the left, 1 = one entry to the right, etc., and Alpha (0 = fully transparent, 255 = fully opaque).<\/p>\n<p>You can use the <em>log<\/em> function to show debug information, that will be shown on the console window, for example:<\/p>\n<pre>log(\"a=\", a);<\/pre>\n<p>Here is another example script, this one creates a circular gradient:<\/p>\n<pre>-- MENU_ITEM: CircularGradient [F4]\r\n\r\nfunction CircularGradient()\r\n  ModifyBuffer(CG);\r\nend\r\n\r\nfunction CG(x, y, w, h, bp)\r\n  bp.Alpha = 255;\r\n  local xx = 0.5*w-0.5-x;\r\n  local yy = 0.5*h-0.5-y;\r\n  local aa = 5*(xx\/w * xx\/w) + 3*(xx\/w * xx\/w);\r\n  local bb = 5*(yy\/h * yy\/h) + 3*(yy\/h * yy\/h);\r\n  bp.Offset = 5 - 2.5*(aa+bb);\r\n  if (bp.Offset &lt; 0) then\r\n    bp.Offset = 0;\r\n  end\r\n  return bp;\r\nend<\/pre>\n<p>This produces the following result:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-260 size-full\" src=\"http:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/circular-gradient.png\" alt=\"\" width=\"343\" height=\"241\" srcset=\"https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/circular-gradient.png 343w, https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/circular-gradient-300x211.png 300w\" sizes=\"(max-width: 343px) 100vw, 343px\" \/><br \/>\n<!--\nAnother example of using scripting is to copy a triangle from one tile into another to make a corner tile:\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2020\/11\/copydiag1-300x165.png\" alt=\"\" width=\"300\" height=\"165\" class=\"aligncenter size-medium wp-image-420\" srcset=\"https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2020\/11\/copydiag1-300x165.png 300w, https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2020\/11\/copydiag1.png 339w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/>\n\n\n<pre>-- MENU_ITEM: CopyDiagonal [F5]\r\n\r\nfunction CopyDiagonal()\r\n  ModifyBuffer(f);\r\nend\r\n\r\nfunction f(x, y, w, h, bp)\r\n  if (x < w \/ 2) then\r\n    if (x + y >= w \/ 2) then\r\n      bp = GetBufferPixel(x + w \/ 2, y);\r\n    end;\r\n  end;\r\n  return bp;\r\nend;<\/pre>\n\n\nThe result is:\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2020\/11\/copydiag2-300x165.png\" alt=\"\" width=\"300\" height=\"165\" class=\"aligncenter size-medium wp-image-421\" srcset=\"https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2020\/11\/copydiag2-300x165.png 300w, https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2020\/11\/copydiag2.png 339w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/>\n--><\/p>\n<p>Export scripts use the function <em>GetExportData()<\/em>, which generates a structure containing the bitmaps, maps and layers that can be exported. Here is an example of an export script:<\/p>\n<pre>-- MENU_ITEM: Export [F10]\r\n\r\nfunction Export()\r\n\u00a0 local prj = GetExportData();\r\n\u00a0 for i = 0, prj.TilesheetCount - 1, 1 do\r\n    ts = prj.Tilesheets[i];\r\n    log(ts.Name);\r\n    prj.Tilesheets[i]:SaveImage(\"ts_\" .. ts.Name .. \".png\");\r\n  end;\r\n  for i = 0, prj.MapCount - 1 do\r\n    map = prj.Maps[i];\r\n    log(map.Name);\r\n    for j = 0, map.LayerCount - 1 do\r\n      layer = map.Layers[j];\r\n      layer:Export(\"lyr_\" .. layer.Name .. \".txt\", \"[[\", \",\", \"],\\n[\", \"]]\");\r\n    end;\r\n  end;\r\nend;<\/pre>\n<p>This script calls the <em>Tilesheets.SaveImage<\/em> and <em>Layers.Export<\/em> functions to save the bitmaps and the map data. The location where the files will be saved depends on your projects active configuration (<em>OutputPath<\/em>).<\/p>\n<p>More examples and the complete structure of <em>ExportData<\/em> should be available soon.<\/p>\n<p><span style=\"color: #ff0000;\"><em>The following is only available in the Indie and Pro version<\/em><\/span><\/p>\n<p>In the Tile Designer, you can use the <em>Code<\/em> property to use scripting to modify your tiles. Here is an example, the following map only uses one tile and all edges are done by scripting:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-263\" src=\"http:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/tile.png\" alt=\"\" width=\"69\" height=\"69\" srcset=\"https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/tile.png 242w, https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/tile-150x150.png 150w\" sizes=\"(max-width: 69px) 100vw, 69px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-268 size-full\" src=\"http:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/map5.png\" alt=\"\" width=\"689\" height=\"540\" srcset=\"https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/map5.png 689w, https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/map5-300x235.png 300w, https:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/map5-383x300.png 383w\" sizes=\"(max-width: 689px) 100vw, 689px\" \/><\/p>\n<p>Here is the script:<\/p>\n<pre>-- adjust these for amount of light\/shadow\r\n\r\nlocal amount_x = 1.0;\r\nlocal amount_y = -1.0;\r\n\r\n-- use with 3x3 tiles\r\n\r\nlocal corners = 0;\r\nfunction OuterEdges()\r\n  corners = 0;\r\n  ModifyBuffer(ChangeEdges);\r\nend;\r\n\r\n-- use with 2x2 tiles\r\n\r\nfunction InnerCorners()\r\n  corners = 1;\r\n  ModifyBuffer(ChangeEdges);\r\nend;\r\n\r\nfunction f(x, y, a, b)\r\n  r = (a + b) \/ 2;\r\n  if (x &lt; y) then r = a; end;\r\n  if (x &gt; y) then r = b; end;\r\n  return r;\r\nend;\r\n\r\nfunction ChangeEdges(x, y, w, h, bp)\r\n  top = 0;\r\n  left = 0;\r\n  right = 0;\r\n  bottom = 0;\r\n\r\n  if (group_y == 0) then top = 1; end;\r\n  if (group_x == 0) then left = 1; end;\r\n  if (group_x == group_w - 1) then right = 1; end;\r\n  if (group_y == group_h - 1) then bottom = 1; end;\r\n\r\n  dx = (x - w \/ 2) \/ 3;\r\n  dy = (y - h \/ 2) \/ 3;\r\n  ex = 0;\r\n  ey = 0;\r\n\r\n  if (corners == 1) then\r\n    if (top + left == 2) and (dx &gt; 0) and (dy &gt; 0) then\r\n      a = Math.Min(Math.Abs(dx), Math.Abs(dy));\r\n      bp.Offset = bp.Offset + f(x, y, amount_x * a, amount_y * a);\r\n    end;\r\n    if (top + right == 2) and (dx &lt; 0) and (dy &gt; 0) then\r\n      a = Math.Min(Math.Abs(dx), Math.Abs(dy));\r\n      bp.Offset = bp.Offset + f(w - 1 - x, y, amount_x * a, amount_y * a);\r\n    end;\r\n    if (bottom + left == 2) and (dx &gt; 0) and (dy &lt; 0) then\r\n      a = Math.Min(Math.Abs(dx), Math.Abs(dy));\r\n      bp.Offset = bp.Offset + f(x, h - 1 - y, amount_x * a, amount_y * a);\r\n    end;\r\n    if (bottom + right == 2) and (dx &lt; 0) and (dy &lt; 0) then\r\n      a = Math.Min(Math.Abs(dx), Math.Abs(dy));\r\n      bp.Offset = bp.Offset + f(w - 1 - x, h - 1 - y, amount_x * a, amount_y * a);\r\n    end;\r\n  else\r\n    if (top == 1) and (dy &lt; 0) then\r\n      ey = h \/ (y + 1 + 1) - bp.Offset;\r\n      bp.Offset = bp.Offset - amount_y * (dy + ey \/ h);\r\n    end; \r\n    if (left == 1) and (dx &lt; 0) then\r\n      ex = w \/ (x + 1 + 1) - bp.Offset;\r\n      bp.Offset = bp.Offset - amount_x * (dx + ex \/ w);\r\n    end; \r\n    if (right == 1) and (dx &gt; 0) then\r\n      ex = w \/ (w - x + 1) - bp.Offset;\r\n      bp.Offset = bp.Offset + amount_x * (dx + ex \/ w);\r\n    end;\r\n    if (bottom == 1) and (dy &gt; 0) then\r\n      ey = h \/ (h - y + 1) - bp.Offset;\r\n      bp.Offset = bp.Offset + amount_y * (dy + ey \/ h);\r\n    end;\r\n  end;\r\n\r\n  if (ex &gt; w \/ 2 or ey &gt; h \/ 2) then\r\n    bp.Alpha = 0;\r\n  end;\r\n\r\n  return bp;\r\nend<\/pre>\n<p>In the tilesheet we place our one tile everywhere, but after setting up the script it looks like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-265\" src=\"http:\/\/www.wieringsoftware.com\/ts2\/wp-content\/uploads\/2017\/12\/tilesheet4.png\" alt=\"\" width=\"251\" height=\"171\" \/><\/p>\n<p>The 3 x 3 selected tiles here have the property <em>Code<\/em> set to <strong>OuterEdges();<\/strong>\u00a0and the 2 x 2 tiles at the right have <strong>InnerCorners();<\/strong><\/p>\n<p>To make it work properly, the code needs to know what the function is of each of the tiles. For that we have the <em>GroupPos<\/em> and <em>GroupSize<\/em> properties. The left part has 3&#215;3 as size and the right part 2&#215;2. Each tile has it&#8217;s own index (0,0), (0,1), &#8230; (2,2). This is automatically set up every time you make a selection like this and copy properties to all tiles in the designer.<\/p>\n<p>After having this set up, you can easily add new grounds by only drawing one new tile.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tile Studio II has support for LUA scripting. You can add scripts to your project and set them up to run when you press a function key (F1 &#8211; F12). Here is a little example of a script: &#8212; MENU_ITEM: &hellip; <a href=\"https:\/\/www.wieringsoftware.com\/ts2\/learn\/scripting\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":37,"menu_order":90,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"_links":{"self":[{"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/pages\/249"}],"collection":[{"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/comments?post=249"}],"version-history":[{"count":15,"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/pages\/249\/revisions"}],"predecessor-version":[{"id":423,"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/pages\/249\/revisions\/423"}],"up":[{"embeddable":true,"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/pages\/37"}],"wp:attachment":[{"href":"https:\/\/www.wieringsoftware.com\/ts2\/wp-json\/wp\/v2\/media?parent=249"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}