Terrain rotation inconsistent, strategy?

Started by Simon, February 06, 2016, 07:18:53 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Simon



Hi,

Nepster has shown me a level that breaks in D Lix, because the terrain rendering is subtly different than in C++ Lix. We now have to decide -- which version has the bug. :-) And what our strategy should be.

The problem

Frame a) shows a terrain tile with odd dimensions, 57 x 57 pixels. There was an inconsistency in Allegro 4.x in how odd-dimensioned terrain was rotated. C++/A4 Lix built for Windows would rotate the terrain differently than C++/A4 Lix built for Linux.

To combat this inconsistency, I load the tile like frame b) in C++/A4 Lix: Odd dimensions are rounded up, padding at the right and bottom if necessary. The level format says where the top-left corner of each tile is, thus padding doesn't affect physics yet.

D/A5 Lix is written as if this bug/bugfix never existed, loads the tile like a), and rotates the tile like frame c).

C++/A4 Lix instead rotates the tile like d). Since the level format remembers the top-left corner of the rotated tile, the padding introduces a 1-pixel offset between the rotated tile c) and the rotated tile d).

Impact

This offset was enough to break 6 of Nepster's 107 replays.

Nepster has sent me a level where the above wooden tile, matt/earth/30, is aligned in a very precise way with the surroundings. The 1-pixel difference makes an intended walker's path impossible in D lix.

6 out of 107 is not that much. But it's enough for replay collectors to worry about this.

Solution strategies

Leave inconsistent: This doesn't require any work. We call it a bug in C++ Lix, don't fix it there, and continue to rotate like frame d). We hope that D/A5 Lix dosen't need a similar workaround, and continue to load the tiles as in frame c).

Port bug: I write code in D/A5 Lix to mimick the 1-pixel offset in C++/A4 Lix's handling of graphics and physics.

New level format: We could introduce a new level format that breaks C++/A4 Lix's forward compatibility with D/A5 levels.

geoo is considering tile-grouping instead of no-overwrite. I'm considering multiple skillsets per level, to enable handicapped games, asymmetric multiplayer maps, and different hatch numbers per player. All this would benefit highly from a better level format that allows grouping. I'd like to look into JSON or SDLang for this. <LetsAvoidMaking="Another">Bloated</XMLformat>

Unrelated improvement

No matter what we do, in D/A5, I want to infer the physics mask from the tile before rotating it, then rotate both graphics and mask. In C++/A4, I rotate the tile first with the graphics library, then check pixels of the rotated tile for solidness. This behavior as in C++/A4 has caused the inconsistency in the first place. I should have been carefully moving the graphics into place, keeping the physics simple and straightforward.

-- Simon

Nepster

#1
Edit Simon: I (Simon) am an idiot and have edited Nepster's post instead of replying to it.

I (Simon) am restoring this post to the few parts I've quoted from it, and what I remember. Here goes.




It broke 5, not 6 levels. That's not too much. So I would say: Code rotations as cleanly as possible in D-Lix and don't worry about C++-Lix too much.

How would tile-grouping work? And how would one update levels that currently use no-overwrite?

Just one question: Assume only one of two neighboring high-res pixels is terrain. Whether both or none of the pixels are solid is still determined after rotation, or not? If not, then this will cause lots of buggy effects (details available on demand).

-- Nepster

Simon

QuoteSo I would say: Code rotations as cleanly as possible in D-Lix and don't worry about C++-Lix too much.

Okay, will do.

Nonetheless, it's great to know the causes of inconsistencies, then we can make educated judgements.

QuoteHow would tile-grouping work? And how would one update levels that currently use no-overwrite?

Yet to be determined. :-) But I suppose porting no-overwrite automatically will be hard. >_>

When no steel is involved, no-overwrite can be replaced with regular drawing, and physics stay the same. Only the looks of the resulting terrain would be different.

QuoteJust one question: Assume only one of two neighboring high-res pixels is terrain. Whether both or none of the pixels are solid is still determined after rotation, or not? If not, then this will cause lots of buggy effects (details available on demand).

Yes! First generate the level-sized hi-res mask from all tile masks, then query the large mask for solidity of 2x1 blocks. (Solid iff at least one pixel is solid.)

-- Simon

NaOH

Quote from: Simon on February 06, 2016, 07:18:53 PM
New level format: We could introduce a new level format that breaks C++/A4 Lix's forward compatibility with D/A5 levels.

geoo is considering tile-grouping instead of no-overwrite. I'm considering multiple skillsets per level, to enable handicapped games, asymmetric multiplayer maps, and different hatch numbers per player. All this would benefit highly from a better level format that allows grouping. I'd like to look into JSON or SDLang for this. <LetsAvoidMaking="Another">Bloated</XMLformat>

This is a great idea. It's a hassle to create n-player versions of multiplayer maps when it's just one cell tessellated in some way.

The current work flow for symmetrical levels is:
- author creates one cell
- author copies cell 40 times to create n-player levels for n from 2 to 8, creating 7 distinct levels
- author bangs head in frustration when they want to make an edit.
- in multiplayer, user selects the level corresponding to the number of players in the session
- a new player joins, some user must select the new correct level

The better work flow would be
- author creates one cell and specifies the tessellation pattern
- in multiplayer, user selects the level
- a new player joins, Lix automatically updates the tessellation (or warns that there is the wrong number of players)

Simon

#4
Yes. This suggestion came up in 2009 already. I've always considered it too complicated to put tesselation-recognizing code into the game.

Adapting the level format instead, and making the level suggest to the game how it should tile the space, sounds much more interesting. We don't have to rush the specification, but can peacefully collect design goals for now.

Quote Icho: "NaOH is so right about this."

-- Simon

Nepster

Quote from: Simon on February 06, 2016, 10:15:44 PM
QuoteHow would tile-grouping work? And how would one update levels that currently use no-overwrite?

Yet to be determined. :-) But I suppose porting no-overwrite automatically will be hard. >_>

When no steel is involved, no-overwrite can be replaced with regular drawing, and physics stay the same. Only the looks of the resulting terrain would be different.
If you decide to remove the no-overwrite option completely and don't have any automatic way to update the level, someone here will be very unhappy. Download the three attached levels and compare them in C++-Lix and D-Lix. And with a total of almost 15000 terrain pieces, I will think twice before updating them by hand.
These are extreme examples, but among the levels, that I have ported from NepsterLems to Lix until now, are more than a few with >1000 terrain pieces and I frequently use the no-overwrite setting.

I see the problem with the current level format for multi-player levels, but surely one can solve this problem without removing compatibility for C++-Lix levels and requiring level designers to recreate their levels by hand.

Simon

#6
Acknowledged -- I'm in full agreement with your concerns. I didn't put no-overwrite on the cull list either, because I am concerned about the huge existing level base, too.

Will be on the lookout for a good solution, or good backwards compatibility.

A warning that applies to both C++ and D Lix: No-overwrite is comparatively slow. Always try to put tiles in the background. Use no-overwrite only when no other solution is possibe. No-overwrite was implemented to get an exact replication of Lemmings 1 rendering, not as a handy overriding of tile order.

-- Simon