I feel like I am missing something.
Given a map, you can get a tile number from an X and Y coordinate.
Given a tile number, you can use that as an index in an array of tile information.
Given an information template that contains 8 bits or less, you have one byte per tile number.
Given an information template that contains 9 to 16 bits, you have two bytes per tile number.
Given information where one of the bits is solid, you know which bit it's in because that's defined, and similarly you know which array of bytes it's in, even if you can create arbitrary information in an arbitrary number of arrays of bytes.
Say I have a love bit, and a strength bit and a 2 bit palette value as my tile information. For every tile number, I can change any of those values, and it will be output in a byte array with 4 bits free per byte. I'm not understanding the need for comparing multiple times for the tile situation.
I guess, even assuming your abstraction levels are map->screen->tiles->types, the type number can still refer to a similar arbitrary number of arrays of bytes with known definitions in them and you end up in the same place as far as not needing multiple compares.
I guess what I must be missing is that you assume users might create arbitrary information outside the tool, but then isn't it also their responsibility to handle it? If you allow them to create types and tile definitions in the tool, the tool always knows where everything is.
Edit: I guess one more thing. Assume the user creates a "strength", "love" and "palette" definition. If they want to also use the subroutines you've written that say... eject from solid tiles, you can reserve keywords the user can add to get that behavior, and you can output the correct bitmask for the solid tile the user can use if they want to do their own stuff with the detection. Which I really think is the solution to the problem. If you provide ejection routines, and ladder routines, the user has to use your keywords. I think that's fair. If they want to add crazy love and strength bits, the tool will output where they are and they can use that info however they wish.
Edit2: So further, A generic routine will pull a tile number from the map and return it in say... Y. Then, an ejection routine (for example), will load from a tool-created define file that is which byte it's in.
Code:
jsr generic_thing_that_returns_tile_in_y
lda whichever_byte_array_the_tool_says_contains_solid,y
and #%bit_for_solid
bne tileissolid
Edit3: If they wanted to get that love bit from a tile
Code:
jsr generic_thing_that_returns_tile_in_y
lda whichever_byte_array_the_tool_says_contains_love,y
and #%bit_for_love
bne tileislove