Lightning fast Tile engine (supports Tiled LUA and JSON export). Need testers.

I am on the verge of releasing for sale my tile engine code, and am looking for comments on what features people would like. Including a name of some sort :slight_smile:
Comments, ideas and possibly testers are all welcome (testers from IRC are more likely to be accepted - I lurk there as Rakoonic).

WHAT IT CAN DO:

  • Import LUA and JSON levels direct from Tiled.
  • Draw levels incredibly quickly.
  • Handle levels of any size (coming soon - SNES Zelda overworld test!).
  • Alter levels on the fly.
  • Automatically back-up level data for resets (IE change a level then revert it).
  • Tile animations at virtually no additional cost (all set up within Tiled).
  • Tile groups (lets you change lots of tiles
  • Resolution and tile-size / shape independant.
  • Merge your own display groups with them (eg foreground and background done in Tiled, player and enemies in the middle of the ā€˜sandwichā€™).
  • Easy parallax.
  • Unlimited tile layers.
  • Loads object groups and makes all the data easily accessible.
  • Window set up.
  • Areas (limit your view to areas within the map).
  • Convert between tile coordinates and screen coordinates and vica versa.

WHAT IT WILL PROBABLY BE ABLE TO DO SOON:

  • Wrap the map.
  • Additional scaling.
  • Clip scrolling to device pixel boundaries, to minimise visual distortion by attempts to move fractions of a second.
    WHAT IT CANā€™T DO:
  • Physics. No. I hate black box physics :slight_smile:
  • Collision detection (that may come later as a seperate module)

It is designed to load a Tiled level and get at the data easily, and draw it as simply as possible.
Nothing more, nothing less. But, it *is* quick! My demo game runs at 60 fps on an ipad with 4 fullscreen layers of 96x64 tiles (why not square? Donā€™t askā€¦! ) along with multiple enemies, full level collision and parallaxed backgrounds. The levels are many screens in size (wouldnā€™t matter how big they are though).

SAMPLES:

  • Videos are oooold, I donā€™t have the hardware to record decently. Hence some screenshots as well, although they donā€™t really do the smoothness justice!


http://imgur.com/a/wcBMk#2
http://www.youtube.com/watch?v=GSeWKQYCDTo
http://www.youtube.com/watch?v=C2D-2e3Pf0M

COMMENTARY:

I find myself in a bit of a tricky position - Iā€™ve been thinking about selling my tile-map drawing code for a while now (6 months or more), and it has been moving, albeit slowly, in the direction of being a useable set of code, but it wasnā€™t exactly progressing at lightning speed (was on hold due to Corona bugs that lasted months).

Then a few days ago I stumbled across Dyson122ā€™s thread: http://developer.coronalabs.com/forum/2012/10/29/million-tile-engine-any-interest-feature-requests

Heā€™s doing the sameā€¦ Doh!

I had a tough choice - do nothing, or try to beat him to the punch. Given how the code was actually already very close to release and is stable, I figured Iā€™d go for the latter. I am not a fan of competing so directly with anyone (which is why I wasnā€™t in rush to release until Lime basically went dead, although the focus with my code is very different to Lime, but from an outsiderā€™s perspective it ā€˜draws Tiled levelsā€™.

I am also aware of Lime apparently going open-source, and some guys also getting together to try to do another Tiled loader - open source. Well, weā€™ll just have to see if there is a market for something paid, but I can promise you at least some highly optimised and just plain quick code!

If you must complain about this perceived competition then please - keep it civil! I can trace my own code back to at least April last year (http://www.youtube.com/watch?v=P0jEtpuZZoY), although obviously this is *working* code with collision detection, so it pre-dates that by several months at least :wink:
In fact, the main reason I did nothing for a long time was the transition to image groups and their bugs (which lasted many, many months, rendering them unusable). By the time the bugs were fixed, I was working on other projects! [import]uid: 46639 topic_id: 36175 reply_id: 336175[/import]

I donā€™t see the problem. Competition is good. To be honest weā€™ve needed competent culling tile engine solutions for Corona for quite some time, and while both engines clearly have the same goals, each seem to have different advantages and weaknesses. Performance may be the same but there are a lot of things to vary in terms of documentation, extra functions, and special case stuff like world-wrap, sprite handling, etc.

The key to success is really going to be which solutions are supported the most going forward in terms of updates and features. (Lime wasnā€™t fast, but it did have a fairly wide function set, complete support for all Tiled formats, and pretty good online documentation.) Stuff like world wrap, safe sprite handling, safe load/reload/teleport, that sort of thingā€¦
[import]uid: 41884 topic_id: 36175 reply_id: 143674[/import]

Lime was a victim of its own success though.
It tried to do too much, a jack of all trades, and ended up pleasing very few people.

The aim of my code is simplicity and speed - so really it shouldnā€™t need too much support, and functionality is limited by the fact it is purely meant to load and draw. Realistically it only needs a few more things and it should be there - for its stated aims, it does everything needed now, but obviously if I can help with something simple, I will.

As for formats, I did read somewhere that JSON and LUA exports donā€™t preserve all the data from Tiled. With LUA this is definitely true, and frankly I doubt Iā€™ll continue developing that importer - it is there for now because it is the quickest way to load (external tile sets? Forget it!). The JSON exporter Iā€™ve found to be very complete - so far there isnā€™t anything missing, although Iā€™ll admit I probably donā€™t push Tiled too far (I do use object layers and lines / shapes etc though - all this data comes in fine from the import process).

Documentation? Yeah ummā€¦ thatā€™s another reason why it is good to keep it small, less of the boring stuff for me to do :slight_smile:

But, hereā€™s the simplest example code to get a map drawn and displayed:local tileMapClass = require( "libs.tiles\_map" ) -- Load the library levelTileMap = tileMapClass.new{ file = levelFile } -- Create the tile map levelTileMap:TL\_DrawAll( 0, 0 ) -- Draw it at 0, 0Obviously there are more options to it, and the defaults arenā€™t going to always be useful, but, at the end of the day, it isnā€™t brain surgery.

One of the more useful features Iā€™ve found in mine is working in Tiled units - so you are not working in pixels, but fractions of tiles. [0.5, 0.5] would be half a tile in horizontally and vertically. Iā€™ve been playing around with different tile sizes and this makes it really easy to swap around, especially for collision code (although that *wonā€™t* be included).

One thing I want to get in is the pixel-movement. I *think* it should be possible, but havenā€™t tried it yet. Despite what I said above about using Tiled units, displaying the levels in pixel units should make it easier for people to do scrolling with minimal visual glitches. Sadly the only way right now to remove all these glitches is to work without a zoom mode. I do this, but I know most people donā€™t, so I want to try to factor that in, because it can range from a tiny distraction to massively hideous :slight_smile:

I know many people want a complete solution, but that would lead down the path towards Lime again, something I explicitly donā€™t want. What I hope to offer is code that will help people do what they want without the perceived limitations of Lime and/or Corona. At the end of the day it benefits me if more people take Corona seriously in the industry. [import]uid: 46639 topic_id: 36175 reply_id: 143683[/import]

I like the name Grout.

You know, the stuff that holds tiles together and makes them more than a bunch of pieces?

Itā€™s kind of a weird name, I know, but I think itā€™s kind of cool. :slight_smile:

Jay
[import]uid: 9440 topic_id: 36175 reply_id: 143693[/import]

Iā€™m very interested in something that would import from tiled and do it well. I am using Lime at the moment but if your code could deliver alot of the same but in some way better or faster Iā€™d have no problem paying for it. But in order for me to buy something like this I would have liked to see some documentaion of what i does, examples, tutorial code etc. That in combination with the price ofc :slight_smile: in the end its all about how much time it would save me and how much I would have to do to get any non supported feature that I need. [import]uid: 17969 topic_id: 36175 reply_id: 143705[/import]

Pretty nice :slight_smile:

May I ask how youā€™re handling physics, as you said in ā€œWhat it Canā€™t Doā€ that you didnā€™t include physics?

C [import]uid: 147322 topic_id: 36175 reply_id: 143711[/import]

I do actually like the name Grout - bad puns appeal to me :slight_smile:

@borgb - it is essentially rendering code, nothing more. It does have some functions to get at the data, and includes backing up (IE so you can change the level while playing it, then reset the data immediately later on), as well as painting into it. Also, you can get at all the values you put in Tile (map level, layer level, tilesets etc) although I may work on that to make it slightly easier.
It naturally only supports 1 active tileset (by default the first in the tileset list, but you can put flags in as well to select another) as that is a (more than) reasonable limitation of image sheets, and speed = good.

@Caleb B - I donā€™t use the physics engine. I *loathe* physics engines, and they just arenā€™t needed 9 times out of 10. Black boxes annoy me. OK, Iā€™ve got that off my chest :wink: Basically Iā€™ve coded my own collision routines. Which wonā€™t be included in the source (but am considering making a simple box VS box routine available for the simplest type of collisions).
Besides, culled views donā€™t work very nicely with physics (which work best when you set up the whole world beforehand - this is what Lime does but the trade off is vastly slower rendering). [import]uid: 46639 topic_id: 36175 reply_id: 143744[/import]

Great looking tile engine! when would it be available? i have longed for an efficient tile engine since Lime to continue my Pokemon style game which had to be stopped. [import]uid: 114118 topic_id: 36175 reply_id: 144088[/import]

@ rakoonic: Hehe, funny. I really loathe physics too! Iā€™ve been programming my own tile-based engine and physics in Corona for a while now and Iā€™m really curious to see what youā€™ve cooked up. Iā€™ve just been hammering out my own tile-based engine with level editor last week - it was actually just about done in 3 full-time days so it turns out itā€™s not that much work. Iā€™ll try to record a video of my engine and editor running and share it here!

Cheers,
Thomas [import]uid: 70134 topic_id: 36175 reply_id: 144119[/import]

I echo borgbā€™s sentiments. I bought lime, found performance was murdered, and didnā€™t touch it after messing with it for a couple weeks. Iā€™ve rolled my own kind of option that works somewhat, but like everyone else here, weā€™re trying to wring every last iota of juice from the Corona performance stone. Iā€™d pay for something that did it well. [import]uid: 135394 topic_id: 36175 reply_id: 144136[/import]

One of the things Iā€™m curious about is what features of Lime did people actually use?
Physics really is out of the possibilities, I have no interest in supporting it and it isnā€™t really compatible with what I am trying to do.
But apart from that, what sort of things?
I donā€™t aim to supply lots of helper functions because most are really easy to do through own code (eg, scroll to X, Yā€¦ this should not be part of a rendering engine), and I donā€™t want to end up supporting code that I personally never use.
But, if there are notable patterns, Iā€™d consider simple things, for sure. [import]uid: 46639 topic_id: 36175 reply_id: 144205[/import]

I of course donā€™t want to speak for everyone, but I feel, like you originally did, that I need a solution renders the map fast, and gets rid of garbage just as quickly. I thought most of the other stuff in Lime (set objects to sensors, tileset management, parallax) were just bells and whistles compared to what I wanted it to do: render tiles well. If you have that down, Iā€™ll buy two! [import]uid: 135394 topic_id: 36175 reply_id: 144208[/import]

Scrolling is I guess something I canā€™t disagree more about. Almost any tile engine is going to be using interpretive addressing, which means that the act of scrolling around the map (or focused on a character) is a huge pain in the ass and almost impossible to do unless you understand the engine drawing the tiles.

Not supporting focus or scrolling are deal breakers for the games I work on. [import]uid: 41884 topic_id: 36175 reply_id: 144213[/import]

@Richard, good call. I wasnā€™t really thinking about scrolling options, only because I thought rendering well would include scrolling, but one should never assume. Scrolling would be huge. [import]uid: 135394 topic_id: 36175 reply_id: 144217[/import]

Richard9, youā€™d just call the draw() function with the X and Y coordinates of the thing you are following. It really isnā€™t something that warrants helper functions.
Interpolating stuff might be considered trickier, but again, it is just easier for someone to write a little helper function once that is external to my code, it would really only be a few lines after all.

One thing that I should explain is it doesnā€™t use transitions or anything.
I work on the assumption that each game frame you call the draw routine once. Hereā€™s an example of some code that achieves that:[code]--------------------------------------------------------------
ā€“ GAME FRAME ------------------------------------------------

local gameFrame = 0
function enterFrame()

gameFrame = gameFrame + 1
levelTileMap:TL_DrawAll( 0, 0, gameFrame )

end

ā€“ Add in the frame event
Runtime:addEventListener( ā€œenterFrameā€, enterFrame )[/code]where the 0, 0 in TL_DrawAll() are the X and Y coordinates you want to view.
ā€˜gameFrameā€™ is there for the tile animation code - you can stop incrementing it so the animations pause, or even go negative or change how much you add to it for rewind or fast forward etc.

If you wanted to track a player, instead of the 0, 0 youā€™d just put in ā€˜obj.x, obj.yā€™ instead. [import]uid: 46639 topic_id: 36175 reply_id: 144219[/import]

Not sure I follow the scrolling arguement, unless you are indeed looking for a function along the lines of:

scrollTo( x, y, time)

Realistically, the engine has no concept of scrolling, it just draws where you want to see super quick. The ā€˜whereā€™ can be literally any part of the map and could be completely different each frame if you wanted to induce epilepsy or something :slight_smile:
Basically the speed of drawing is not dependant on where it was showing the previous frame, as it redraws the entire view completely with every draw call. [import]uid: 46639 topic_id: 36175 reply_id: 144221[/import]

I donā€™t want to speak for Richard, but what I was thinking was just touch-draggable maps. A big map with Lime would absolutely crawl when scrolling around. Richard, is that what you meant? [import]uid: 135394 topic_id: 36175 reply_id: 144223[/import]

If you are referring to something like that, the code needed to achieve it with my engine is trivial, to say the least. I imagine it would be one of the samples Iā€™d release, since yes, I can see it being quite a popular feature.

One thing I need to cater for is how other people code - I may have ideas about what is the best way of doing things, but that doesnā€™t mean Iā€™m going to ignore people who do things differently, so fear not! [import]uid: 46639 topic_id: 36175 reply_id: 144224[/import]

I do understand the enterFrame drawing (unless youā€™re doing something completely different Iā€™m guessing youā€™re using ā€œthe tiles are already drawn, just update the sprite frames at runtimeā€ method.) That way you only have minimal (~1 tile) movement. I also think itā€™s fair to want to keep scrolling functions out of yourengine.lua.

But *providing* those functions is still critical for use. You can include them via a secondary lua file, if needed. But I know from working on one of these engines that managing position is an incredible headache and that means Iā€™d need to see some provided scrolling functions up front, among other things.

a) Independent scroll (ie: scrollTo(tileX, tileY, time) ā€“ so the map can be moved
b) Focus (update position based on character position) ā€“ so the map can move according to the player
c) warp (set to tileX, tileY) ā€“ jump to and fro based on real position
d) converter suite (screen X to world X to tileX, for example) ā€“ since .x and .y are not reliable
e) fetch suite (if I have tile X, how do I know anything about it?) ā€“ beats running converters every frame
f) sprite management (how do I bind a sprite to the map?)

I guess those are the basics. I need to somehow load a map, bind a character to it, and then move around. It sounds like your solution can do some/all of these things, maybe? But if I have to build the enterFrame myself then it gets a whole lot murkier.

Panc: I think youā€™d have to use some kind of custom variable tracker along with the enterFrame function rakoonic posted. event.x/y wouldnā€™t work in this case since theyā€™re just reporting screen position. Maybe something like world.x + event.x? (Like I said, this kind of math gives me a headacheā€¦)
[import]uid: 41884 topic_id: 36175 reply_id: 144225[/import]

@Richard, agreed, and my terrible math is what broke most of my larger maps. If push came to shove, I figured I would just do it old-school FF1 style and have a pause function that shows a less-detailed, smaller map to scroll around. I would hope people would read that as ā€œretroā€ and not ā€œtoo stupid to put in a proper scrolling functionā€! [import]uid: 135394 topic_id: 36175 reply_id: 144226[/import]