Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Drawing a background of tiles
#1
Megamarc, I am always wondering this... I'm sure the information may be out there in some form but it'd be good to just get a straight answer;

Retro game systems use tile based backgrounds - the bitmap data for each tile is just stored somewhere once.

My question is what happens when it's time to draw that on the screen (and I assume whatever the answer is, Tilengine will work this way too)


Is there an area of VRAM big enough for the screen (and a bit bigger) that filled with tiles using blitting, and then after that, the screen is scrolled very fast by shifting the bytes along in VRAM (which I understand is a very quick process) and then the next column of tiles are blitted to the new area of blank backround left behind

OR


is it even more memory conservative, and as the scanline draws down the screen, each relevant tile is accessed to draw the scan line (this would require a lot of jumping around in RAM)

Or is it a mix of these approaches depending on the hardware?

I know the Atari 2600 has the CPU doing the later (but no tiles per se), and it has to take a break and actually run game code, so you get these black short lines on the left of the screen where it was too busy working on the actual game processes to tell the rasteriser what colour pixels to draw!

And regarding the SNES and its multiple layers, would these be separate areas of VRAM for each layer?
Reply
#2
Hi Domarius,

Sorry for the late reply to your interesting question.

In classic systems, the tileset (the graphics) and the tilemap must fit inside the VRAM. The VRAM provided space to hold a portion of the tilemap that wast a bit bigger that the screen, so you could scroll a small window inside it.Scrolling the whole map required a combination of moving the window inside the viewport, that wrapped around the edges, and "streaming" new tileset data from the ROM to the VRAM. I recommend you to check an emulator with graphical debugging capabilities (like the Gens KMod or Meka). These emulators can show the VRAM area of the viewport updating the tilemap in realtime as the game progresses.

Tilengine is different in this regard. The whole tileset and tilemap are loaded into RAM, so you can locate the viewport at any section without having to stream tiles from another place. Of course the original behavior can be emulated in tilengine too, using a small tilemap layer that works as the viewport and then copy sections of the tilemap, but it would be really cumbersome.
Reply
#3
Thank you, it's really good to have this answer. I like to know these things, because think the best approach is some middle ground between the old ways, and just wasting resources using modern hardware, in case you ever have to push it to the point performance becomes an issue. So in the old days, the VRAM was always a bit bigger than the screen, and in modern 2D engines like Tilengine it's pretty normal to have a giant 2D surface that you scroll around in.

If you were to ever push this size (eg. maybe a mobile game, or a stupidly huge 2D game), then I suppose you could start breaking the level up into chunks using your own methods.

In my Jump n Bump game, each level is only a single screen level, so I didn't have to deal with scrolling yet (but I will for the next projects). But I did it using a graphical surface that is the resolution of the game, scaled to fill the screen, and the level is constructed by blitting the tiles from a tile atlas Smile And I wrote my own tile based collision. Which collides by rounding pixel locations down to a grid tile location.
Reply
#4
Hi!

That is not exactly true in tilengine. It doesn't create any huge surface and blit portions of it, as other 2D engines do. What is held complete in RAM is the tileset (the set of individual graphical tiles) and the tilemap (the arrangement and attributes of tiles). But the tilemap requires just 4 bytes per tile, and as it was done in the old days, the picture is composed in realtime fetching scanlines of tiles as the tileset data says. So you can build your stupidly huge 2D game in a small amount of RAM. Tilengine keeps track of the memory used by all loaded assets (tilesets, tilemaps, spritesets, palettes and animations) and you can query it with the TLN_GetUsedMemory() function at any time. For example, if you check it with the "platformer" example loaded (the one with the Sonic 1 assets, multi parallax scroll and animated tiles and palette), it yields about 143 kilobytes. As with classic 2D systems, what takes memory is the amount of different tiles, not the map size.

Or as another example, imagine you have a tileset that is 16x16 in size, with a screen resolution of 640x360 (TilenginePythonPlatformer does this). A map of 20 screens wide and 3 screens tall would be just 211 kbytes: (640*20) * (360*3) * 4 / (16*16) = 216,000 bytes. Add the size of the tilemap: each 16x16 tile takes 256 bytes (1 byte per pixel), if your tileset for that map is composed of 1,024 unique tiles (that's arcade quality), that's just another 256 kbytes. In contrast, the tileset of the foreground layer in Sonic world 1 is less than 352 unique tiles, and that one is a graphically rich game...

If you use tilengine for your next project, you'll have super easy scroll and low memory footprint with graphically rich huge maps  Smile
Reply
#5
Ah in that way Tilengine is the same as old game hardware, as far as drawing the tiles per line by fetching the tiles as it refers to the level map, and not from a giant bitmap.  That's really awesome.

I bet other 2D retro games just use giant bitmaps - unless they use the modern 3D acellerated technique of making the level out of a mesh where each tile is a quad, referring to a texture atlas.  Much more efficient than a giant bitmap. I would say it's still not as efficient as the way Tilengine does it, at least if you try to push it to stupidly huge levels.  If a float is typically 4 bytes (which is already the memory size of your tile), there are 3 of those for each vert, and 4 verts for each quad.  Faaaar less efficient.  Of course how much that really matters is dependent on the game and the target platform.  On desktops, I'd guess that you'd be hard pressed to reach any sort of limitation for 2D levels on even the oldest accelerated video card you're likely to encounter.  But if you were to keep scaling up the level size, that vert count would be what slows down the card first... whereas I assume it probably doesn't matter as much how big the level is in Tilengine?

Quote:If you use tilengine for your next project, you'll have super easy scroll and low memory footprint with graphically rich huge maps Smile

Yes, I am looking forward to using Tilengine for something Smile  I have a 2D retro game coming up but I want it released on mobile so I might be better off sticking to Godot with its touchscreen support and deploy to iOS built in.  When I do have a 2D retro game come up that doesn't require mobile, the main thing I'll have to address is setting up a Hackintosh, or a VM like you have.  Got to support those Mac users.
Reply
#6
(10-10-2018, 01:40 PM)Domarius Wrote: I have a 2D retro game coming up but I want it released on mobile so I might be better off sticking to Godot with its touchscreen support and deploy to iOS built in.

You might want to give this thread a look-see. I was able to get Tilengine embedded and running in Unity. I haven't tried Godot yet, but that might be possible too. Also, I'm not certain if Unity support would translate to mobile support. I haven't tried embedding a native plug-in into a iOS app. Might be a fun experiment to try next.
Reply
#7
Great work!

To run it on IOS, a binary build of the Tilengine library must be produced first. I have a working build for desktop OSX using command-line tools for Xcode (gcc in disguise), but I'm not an Apple user and I don't have experience with other kinds of projects. Somebody must provide a build for this platform first.
Reply
#8
(10-24-2018, 03:18 AM)Richard Kain Wrote:
(10-10-2018, 01:40 PM)Domarius Wrote: I have a 2D retro game coming up but I want it released on mobile so I might be better off sticking to Godot with its touchscreen support and deploy to iOS built in.

You might want to give this thread a look-see. I was able to get Tilengine embedded and running in Unity. I haven't tried Godot yet, but that might be possible too. Also, I'm not certain if Unity support would translate to mobile support. I haven't tried embedding a native plug-in into a iOS app. Might be a fun experiment to try next.

Thanks for the heads up!  I'll consider it Smile
Reply
#9
This is Kain's thread in Unity forums showing his progress integrating it:
https://forum.unity.com/threads/tilengin...ng.571372/

I'm impressed about how he's having success with some advanced topics considering the bad quality of Tilengine documentation! Cool I've never attempted external rendering from a binding myself haha
Reply
#10
It wasn't nearly as hard as I had thought it would be. And you do put a sizable number of comments in your code, which makes it a bit easier to follow. Also, Unity has supported the importing and use of third-party pre-compiled libraries for a while, and there are a sizable number of tutorials for doing that, even if they aren't specific to Tilengine.

I might give compiling Tilengine for iOS a try, I keep a Mac Mini around for iOS and Mac development. Ideally, it would be great to cook up a Swift 4 binding, but I shouldn't get ahead of myself. But it will have to wait until a little later in the year. I'm very busy with some home repairs, and a trip coming up, and of course the holiday season is fast approaching. I was able to sort out exporting 8-bit pngs from GIMP properly, so my asset pipeline for Tilengine has firmed up. And I've played around with dynamic palette generation and assignment, which has been going very well.

Also, the C# binding I was using didn't actually have an UpdateFrame function. But I've learned enough that I was able to add one, and took your suggestion about using that function instead of a for loop in the Update function. It worked great. I might look into using the separate thread approach to getting a Tilengine context when running the engine in the Unity Editor environment. I think that might help with a few of the issues I was running into.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)