C7-Game / Prototype

An early-stage, open-source 4X strategy game
https://c7-game.github.io/
MIT License
33 stars 9 forks source link

Tall terrain graphics don't display greatly #347

Open QuintillusCFC opened 1 year ago

QuintillusCFC commented 1 year ago

One of the more challenging terrain packs to draw is the Manhattan terrain, because of the skyscrapers. C7 is affected by this as well. Consider this part of the map, by the Williamsburg Bridge:

image

It's obviously incorrect that Delancey Street is drawn on top of the skyscrapers to its southeast. But also note the skyscraper closest to the bridge - FDR drive is drawn over part of it, but not all of it. This is because tiles that are partially-hidden by fog currently only have the base terrain rather than the overlays drawn. Since the tarmac of FDR drive is an overlay, the upper part of the skyscraper is not drawn over, though part of the upper-midsection.

Fundamentally, the problem is that we're kind of cheating on isometrics. Here's out map drawing code at a high level:

            foreach (LooseLayer layer in layers.FindAll(L => L.visible)) {
                layer.onBeginDraw(this, gD);
                foreach (VisibleTile vT in visibleTiles)
                    layer.drawObject(this, gD, vT.tile, vT.tileCenter);
                layer.onEndDraw(this, gD);
            }

We draw each layer in turn, finishing that layer before going on to the next one. Other than a tweak to exclude the FogOfWar layer (which is drawn after everything else), this is unchanged since 2/16/2022.

It works well most of the time, and we order our layers so that e.g. forests draw before mountains, so tall mountains aren't covered by forests from another tile at the top. There's also an optimization around drawing the same thing multiple times (see https://github.com/C7-Game/Prototype/pull/81), which adds a significant performance boost. We may lose that by switching to drawing everything on a tile at once before moving to the next tile, rather than everything in a layer and then the next layer.

Manhattan is unique because the base terrain regularly exceeds the tile bounds, but is intended to take full advantage of the isometric view, and also because some of the overlays, especially roads/railroads (highways) take up the whole tile. It's kind of a worst-case test scenario for this. But there should probably be at least an option to have slower performance but full graphical fidelity in these cases. We might be able to detect what is best based on graphics dimensions.

Probably not a near-term priority but I wanted to get it written up since it's easy to forget otherwise.

QuintillusCFC commented 1 year ago

One other Manhattan map challenge, in the logs I got gobs of these messages:

[WRN] 02:54:00 C7.Map.ResourceLayer: Resource icon for Dairy Queen is too high 

I haven't dug into the DQ problem yet but from a logging standpoint the issue is this message gets spammed, apparently every time it tries to draw a tile with a Dairy Queen. Logging it once is useful, a thousand times is not so great though.

pcen commented 1 year ago

I'm re-implementing map drawing using godot 4's TileMap class here: https://github.com/C7-Game/Prototype/pull/407 which will resolve this issue because the tilemap comprises z-indexed layers, and y sorting is a toggleable feature of each layer