Designing a level editor

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Designing a level editor
by on (#84809)
I decided to start working on a metatile based level editor. I want to design it properly before doing any actual coding. I'd like some suggestions on features it could have.

Here are some of the features such an editor would need, IMO:

- Arbitrary metatile sizes (and maybe "metatiles of metatiles" as well, although that adds a lot of complexity)
- Attributes/properties for metatiles, for specifying stuff such as solidity. Would be nice to be able to use configurable symbolic constants for these, instead of just numbers.
- Object support.
- Palette editor (although loading from an image might be sufficient).
- Reading the metatiles from an image. That is, make an image with the metatiles (with the correct palette, of course), and the metatiles are built automatically from that. No need to manually build them from a CHR file...
- Export plugins in Python: Data can be exported in whatever format the game needs it.

Open questions:

- If "metatiles of metatiles" are supported, how to expose that in the GUI?
- What features are needed for object support?

Comments?

by on (#84811)
Image

Here's a level editor I made a while ago, and never did anything with it.
But it shows a good example of "Metatiles of metatiles". You could right-double-click, and it would make a new metatile as a copy of the currently selected metatile. Or you could left-double-click and edit the metatile.
Otherwise, it was Right Click to capture a rectangular area as the brush, and Left Click to paint with the selected brush, loosely inspired by RPG Maker 95.

As for setting attributes of tiles, RPG Maker 95 had a good example of that, when viewing a big set of tiles, there was a button that showed what type of tile each tile was treated as, and you could edit them by "painting" attributes on top of the tile set.

by on (#84814)
My editor's GUI and input totally sucks, but works with advance/decline keys for compression levels that is very helpful for me.

Let's say you're currently working with screens. Press "s". You can then place 32x32 metatiles. Press "s" again. 16x16 metatiles. "s" again. 8x8. Press "a". 16x16.

Whatever mode you're in allows you to see the tiles of that mode in a tileset, as well as the main map. (except screens, because they're too big to display in a tileset and they're not reused that often, anyway) You can select the one you want from the tileset, or just recreate it on the actual map and it will be automagically given that (meta)tile's number.

If you're working in 8x8, you can click anywhere to place a tile, and it'll create a new identical 16x16, 32x32 tile and screen with identical data so that every other use of the metatile number you've just changed isn't also changed in your map. (Though there's also a way to force all tiles/metatiles/screens of that current number to change if you wish).

Same with 16x16 and 32x32. Basically it creates dummy tiles of everything above the level you're working at, while you're stuck in a tile.

Whenever you navigate to a new tile (i.e. change a tile that's not contained in the metatile you're currently editing), it figures out if the tile (metatile, screen etc) you've most recently changed already exists. If it does, it sets the number of the tile (metatile, screen etc) to the one that already exists.

This way you can place tiles at any compression level, and you'll never use extra space for repeating tiles (metatiles, screens etc). Basically, you can just draw your map using whatever size pieces you want, and it will figure it out.

I hope I explained that well... It also keeps track of how many times all the tiles are used, so if you see a metatile that's only used once you can change it to a different one on the map that's used more to save space. (If there's another one that fits that is)

It's a cool editor. But... the GUI is just abysmal. I plan to rewrite it soon, since I need to add object support and make it not use tekken style button combos for map editing. (I haven't done mouse support. Heh.)

by on (#84817)
thefox wrote:
- If "metatiles of metatiles" are supported, how to expose that in the GUI?

You can see how I dealt with multiple levels of metatiles in my Blaster Master level editor (Blaster Master uses meta-meta-metatiles). It's not ideal, but it was the best thing I could work out, given the restrictions that come with editing an existing game's levels.

http://www.youtube.com/watch?v=MbxS60M7tvM
(Or give it a whirl)

If you add in Kasumi's auto-metatile generating, I think you're in business, but it would be good for the editor to give lots of easy-to-understand stats about metatile counts and current data size.

When you talk about objects, is this object-based level design (as in SMB3) or sprites (power-ups, enemies, etc.)?

Also, just curious, what language will the editor be written in?

by on (#84819)
Thanks for the input.

Kasumi wrote:
I hope I explained that well... It also keeps track of how many times all the tiles are used, so if you see one that's low you can change it to a different one to save space.

I think I got it.

Right after posting I thought this was getting too complex already, so I think I'm dropping "metatiles in metatiles" support from the editor itself because I don't need it for my current project. If I need that at some point, I'm just going to write an export plugin that optimizes the data in that way.

So, what I basically need in the GUI is 1) list of metatiles 2) list of objects 3) the map view itself 4) a metatile attribute editor.

I'm wondering if the object support should have anything more than being able to place them on the map. Maybe an object editor that lets one assign an image to the object.

snarfblam wrote:
When you talk about objects, is this object-based level design (as in SMB3) or sprites (power-ups, enemies, etc.)?

Enemies etc.

Quote:
Also, just curious, what language will the editor be written in?

C# probably. I might go with C++ to learn Qt though.

by on (#84820)
thefox wrote:
Thanks for the input.

I'm wondering if the object support should have anything more than being able to place them on the map. Maybe an object editor that lets one assign an image to the object.


How about placing them, and a list of bytes associated with them? (In addition to the image)

Say each object universally needs two bytes. You double click an object, and put in two values. Done. Then if you later decide you needed three bytes for every object, your editor doesn't even need to change. Just change the global number of bytes each object needs from two to three and put in the extra value for each object. Your export plugins can deal with the output.

by on (#84826)
snarfblam wrote:
http://www.youtube.com/watch?v=MbxS60M7tvM
(Or give it a whirl)

I tried it, it's really nice! Nice source of inspiration.

Kasumi wrote:
How about placing them, and a list of bytes associated with them? (In addition to the image)

Say each object universally needs two bytes. You double click an object, and put in two values. Done. Then if you later decide you needed three bytes for every object, your editor doesn't even need to change. Just change the global number of bytes each object needs from two to three and put in the extra value for each object. Your export plugins can deal with the output.

Are you talking about values that are specified for each object instance? I can't think of any examples where each object instance would need additional data, though there probably are some.

Specifically I'm trying to think what data belongs to the level editor, and what would be better in a separate tool (an object editor). Maybe the level editor should read the object definitions from a separate file (generated by the object editor), even.

by on (#84830)
thefox wrote:
I can't think of any examples where each object instance would need additional data, though there probably are some.

Sure there are. You might use these extra parameters to differentiate similar objects for example. Say that all item boxes in a game behave exactly the same, and the only difference between them is the item they contain, so you use a single object and specify the item it contains as a parameter. Other uses for these parameters might be flipping objects vertically or horizontally, changing their color, the number of hits it takes to kill them, a pointer to a RAM location where they can save their status (i.e. you might want to keep some of the object's state even after it's deactivated and reactivated)... Just about any parameter you might want to give to their constructors.

In my game I have only one parameter byte, so there are cases where the object code itself contains some parameters (i.e. two different object codes point to the same constructor method, which has to look into the code to retrieve some info about the object). Another solution when the parameters don't fit in a byte is to use that byte as an index into a table that contains the actual parameters for the objects of the current level.

by on (#84832)
I may actually be able to use a generic tile editor like Tiled for my purposes, just have to write some tools to convert the data. Tiled in particular seems pretty good. It even has a simple object support, but unfortunately all the object and tile properties have to be specified manually, so it probably gets pretty chaotic after a while. It's very flexible, though.

All the other ones I tried didn't seem very good or flexible enough.

tokumaru wrote:
You might use these extra parameters to differentiate similar objects for example. Say that all item boxes in a game behave exactly the same, and the only difference between them is the item they contain, so you use a single object and specify the item it contains as a parameter.

Yeah, you're right.

by on (#84849)
I've decided to use Tiled. I may make a customized fork out of it, but we'll see. Just to wrap this up, here's what I plan to do:

* Have two layers: background and objects.
* 16x16 tileset for the background tiles.
* Attributes such as solidity as properties of the background tiles (they can be strings, so the same symbolic constants could be used as in the 6502 code).
* 64x64 tileset (or something) for the objects. Every object is represented by a 64x64 tile, and they are added to the object layers as Tile Objects. The tile image is used just to represent the object graphically in the map, it doesn't have to be the same as in the game, or can display a string/etc for special objects. (There's only one problem: tile object coordinates are relative to the bottom left corner of the object, and it's not possible to move the hotspot, so the coordinates need to be adjusted at export time.)
* Every 64x64 tile has a property "type" that specifies the type represented by the tile (like ENEMY1).
* Object instances can have additional properties, like the destination map for doors, or an item ID for items contained in a box.
* Shell commands to convert the level and run it in an emulator.
* Starting point/scroll stoppers/etc special objects are defined with normal objects.
* Tool to convert the .tmx (the map) and .tsx (the tileset) XML files to data for NES.

I really like the elegance of Tiled compared to other generic map editors.

by on (#89276)
Nice!!!!

by on (#89278)
Hey thefox...I forgot all about this thread -- thankfully it got bumped! Where are you with this? Did you decide to do C++/Qt? You know why I'm asking. :D EDIT: Doh. Read the thread backwards...what is Tiled written in?

Currently the Tile Editor in NESICIDE is all I've got, but Map Editor is on the horizon...

thefox wrote:
* 16x16 tileset for the background tiles.


My Tile Editor supports {8,16,32,48,64,80,96,128} x {8,16,32,48,64,80,96,128} tiles. Each tile bigger than 16x16 carries its color attributes with it. I don't know why I stopped at 128...is there a need to go bigger?

thefox wrote:
* Attributes such as solidity as properties of the background tiles (they can be strings, so the same symbolic constants could be used as in the 6502 code).
* Every 64x64 tile has a property "type" that specifies the type represented by the tile (like ENEMY1).
* Object instances can have additional properties, like the destination map for doors, or an item ID for items contained in a box.


I currently support string, integer, and user-defined enumeration types for Tile properties. Each can have a global default and each Tile can have its own unique value for any property. Adding properties adds them for all tiles, etc. Enumeration definitions are emitted to a user-specifiable file for inclusion in the rest of the source.

I'm not sure how to best emit the individual Tile property values for use within the source code yet, though. I suppose scopes could be used to reduce pollution.

If you're still thinking about this or even working on it I'd like to hear!

by on (#89280)
Some of the Sonic games use 256x256 pixel tiles, which are recursively broken up into smaller tiles. Sonic 2 uses 128x128. Tokumaru's Sonic tribute uses a quadtree: 256x256 made of four 128x128, each made of four 64x64, etc.

by on (#89283)
tepples wrote:
Some of the Sonic games use 256x256 pixel tiles, which are recursively broken up into smaller tiles. Sonic 2 uses 128x128. Tokumaru's Sonic tribute uses a quadtree: 256x256 made of four 128x128, each made of four 64x64, etc.


Does it make sense to support non-power-of-two sizes like 48, 80, 96? From a "I'm an artist I just want to do drawings" perspective I think so...I was thinking, for example, of being able to draw things like level entrances [think Zelda underworld doors--48x32 [but I haven't a clue how they're stored in the Zelda map info]].

But from a map perspective, the map-to-nametable conversion would probably be complicated by having such strange sized metatiles.

by on (#89285)
I can't think of any NES examples at the moment, but Kirby Super Star for Super NES uses 24x24 pixel metatiles. So does Panel Action Bingo for Game Boy. And I seem to remember at least one game using metatiles that were 48 pixels tall so that five of them would be as tall as a screen.

by on (#89286)
The Sonic Advance games use 96x96-pixel metatiles I think.

If a game uses metatiles there will always be cases where objects don't align properly to the grid. You you really don't want to deal with that, maybe you'd be better using the object approach rather than the grid approach.

by on (#89287)
tokumaru wrote:
The Sonic Advance games use 96x96-pixel metatiles I think.

Which would sort of fit a game that may have been originally planned for a system with a 320x224 pixel display (Genesis) and then scaled down to 240x160 (GBA).

by on (#89288)
I had never thought about this, but you are absolutely right! The number of blocks that fit in a screen horizontally is the same. The GBA games are nothing like the Genesis games though, so I'm not sure why they'd go through the trouble of using an odd metatile size like that... An obvious disadvantage is that when converting world coordinates into metatile coordinates the program has to perform actual divisions, instead of simply shifting/ignoring bits. On the NES this would be suicide.

by on (#89290)
ARM7TDMI has a fast hardware multiply, and lots of GBA games use it for division by a constant.