Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Add script API / make it scriptable #949
Most people are not into C++ / Qt and compiling Tiled themselves, and as such small additions that would benefit their productivity are often not even started on. There should be an easy way to write scripts to perform actions in Tiled. Examples of things that should be possible:
Examples of where scripting would have been useful (also see issues referencing this issue below):
referenced this issue
May 15, 2015
@kkworden Great to hear you'd like to help out with this! All your suggestions would be nice things to have eventually. My approach would be the following:
Since I'd like the scripting support to extend to a QtQuick based version of Tiled later, I think it may be good to do this in the
Sounds interesting and something i would need at the moment. So i have to stick to exporting the map, modifying it with scripting and then reopening it.
I would suggest the PostgreSQL approach of developing such a feature: Start with an easy implementation and make it more powerful over time. The first iteration could simply be the automappig feature implemented for scripting. So whenever the map is modified the script will be called with the changed element and the script can modify the map. This would enable:
This was referenced
Sep 5, 2015
referenced this issue
Nov 29, 2015
I wanted to suggest the using Lua is the easiest way to implement this after just replacing a huge mess of AI code in a game to Lua. It's was really easy and had a very small learning curve.
Here's a possible implementation idea:
function brush(x, y, palette) if get_tile(x, y) == 1 then -- if the tile under the brush is id 1 set_tile(x, y, palette) -- set the tile under the brush to tile #1 from the palette end end
Here's the basic outline of how the C bindings work but my pseudo code is Pascal:
// create a new lua instance // you'll want to keep track of this unless the user changes scripts on the brush l := luaL_newstate(); luaL_openlibs(l); // bind 2 c functions (LuaGetTile, LuaSetTile) to Lua lua_pushcfunction(l, @LuaGetTile); lua_setglobal(l, 'get_tile'); lua_pushcfunction(l, @LuaSetTile); lua_setglobal(l, 'set_tile'); // run the lua script from a string you loaded early luaL_dostring(l, scriptText); // when the user uses the brush tool retrieve the lua instance you created early and call: lua_getglobal(l, 'brush'); lua_pushnumber(L, 1); // ??? we need an array of tile IDs passed in! I'll provide that code also since passing arrays to lua is confusing imo. lua_pcall(L, 1, 0, 0); // when get_tile() is called from lua it will run this C function (mine being Pascal, sorry) function LuaGetTile (l: Plua_State): integer; cdecl; var x, y: integer; tileID: string; begin // get the x and y coords that were passed from lua x := luaL_checkinteger(L, 1); y := luaL_checkinteger(L, 2); // find the tile ID at x,y and return the value back to lua tileID := FindTileID(x, y) lua_pushstring(L, tileID); result := 1; end;
This is trivially easy to implement and would mean the user could have precise control over what tile the brush will insert and what tiles are around the cursor. I'm happy to help answering any questions.
The danger with starting with two simple API functions like in your example, is that there will be no end to requests for more functionality to be exposed. Maybe the tool wants access to tile properties, maybe it wants to base its decisions on data from other layers, etc. So in the end, we need a solution that can provide a full API and does not require extra maintenance.