Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tileset defined variant item sprites by context #52616

Closed
I-am-Erk opened this issue Nov 3, 2021 · 0 comments · Fixed by #52632
Closed

Tileset defined variant item sprites by context #52616

I-am-Erk opened this issue Nov 3, 2021 · 0 comments · Fixed by #52632
Labels
<Enhancement / Feature> New features, or enhancements on existing (P3 - Medium) Medium (normal) priority SDL: Tiles / Sound Tiles visual interface and sounds.

Comments

@I-am-Erk
Copy link
Member

I-am-Erk commented Nov 3, 2021

Is your feature request related to a problem? Please describe.

One of the contributing factors to our tilesets feeling simplistic and repetitive is that our furniture and terrain definition system makes it inordinately complex to show variants of furniture. For example, if we want to show countertops that look like an office breakroom, we need a separate furniture definition for each variant type of countertop, one with a coffeepot, another with some dishes sitting on it, another with a small sign reminding employees to wash their hands. This is possible, but a lot of work

Describe the solution you'd like

Allow tilesets to specify variant sprites for items to be used if they are in the same tile as a particular furniture or terrain, and layering for these.

This would require a new tileset definition file (one I think we will need for other uses anyway eventually), let's call it layering.json. A definition would look something like this:

"item_variants": [
  {
    "context": "f_desk",
    "variants": [
      {
        "item": "laptop",
        "sprite": "laptop",
        "offset": { "y": 8 },
        "layer": 100
      },
      {
        "item": "blotter",
        "sprite": "blotter_on_desk",
        "layer": 80
      },
      {
        "item": "paper",
        "sprite": [
          { "id": "paper_clutter_1", "weight": 10 },
          { "id": "paper_clutter_2", "weight": 10 }
        ],
        "layer": 90
      }
    ]
  },
  {
    "context": "f_bed",
    "variants": [
      {
        "item": "sheet",
        "sprite": "sheet_bed",
        "layer": 50
      },
      {
        "item": "pillow",
        "sprite": "pillow_bed",
        "layer": 80
      }
    ]
  },
  {
    "context": "f_table",
    "variants": [
      {
        "item": "paper",
        "sprite": "paper_clutter_1",
        "layer": 50
      }
    ]
  }
]
  • note that the laptop in this example uses the item sprite for 'laptop' without change, but moves it up 8 pixels, presumably so it looks like it's placed correctly on the desk.
  • note that the same sprites for paper_clutter_1, is used twice here for two similar spots. Not everything would have to be new in every situation.
  • The sprites here, eg "paper_clutter_1" would be defined in the tileset the same way as everything else, so they'd allow fg, bg, etc. Ideally they should support rotation as well, but that might depend on the code for how items are displayed. I don't think they need to support multitiles and variants within the sprite definition... I think that's better saved for here, in layering, so that we can keep certain variants for showing up in certain locations. For example, above, we could assume the variant "paper_clutter_2" has details that might make sense on a desk or in an office but would seem weird on a kitchen table.
  • Higher layer numbers are drawn later in the context sprites rendering process, so in this example you'd first draw the blotter, then the papers on top of it, then the laptop on top of the papers.

This code would allow tilesets to show books on bookshelves, computers on desks, place settings on tables, bedding on beds, sticks hidden in long grass, rocks scattered in the dirt, liquids filling toilet bowls and bathtubs, and more. Taken to its logical ends, it would dramatically transform our ability to make buildings look lived in, and for players to decorate their homes, without adding variant furnitures and things and without impacting gameplay at all. All other interactions with the item would be unchanged.

Not every element of this would need implementation at once. For example, allowing context sprites to rotate with the base sprite could be a later pass, so could allowing variants of context sprites. Even the "weight" feature to ensure items show up in the right order could be a second pass.

memory considerations
To avoid too much calculating we probably only want to check if an overlay option exists when a sprite is dropped or spawns for the first time. That would mean if you drag furniture into the same tile as an item, the item sprite wouldn't change... I don't think that's a problem.

We would also want to rerun all variant item checks if the tileset changes since this is tileset specific.

algorithm suggestions
Note: rendering context item sprites should occur immediately before the rendering of non-context items.

  1. item spawns/is dropped
  2. Is there furniture in the tile? In that case, scan the tileset's layering.json for any entries for that furniture.
    2a. If no furniture in the tile, scan the tileset's layering.json for any entries for the terrain.
  3. If layering.json has an entry for this furniture/terrain, scan the entry for references to this item id.
  4. If this item id is referenced, select a sprite from the available context variants instead of using the usual item sprite.
  5. Check for other context sprites in the tile - ideally perhaps there could be some way to flag this in the tile so that we don't have to search all other items in the tile each time, only search for the presence of the flag*.
  6. Adjust rendering order so that this new variant renders on top/beneath other context sprites in the tile as appropriate.
  7. Render all other non-context item sprites in the tile as usual.

*Flagging a tile for context sprites - considerations: If we could add metadata linked to the item that would be quickly picked up to indicate that there are context sprites already rendering in this tile, then we should keep that metadata tileset specific. For example we might have a context-specific blotter on a desk, and that would produce the flag "ultica-context" linked to the blotter item. Then if we switch tilesets to retrodays and back, the metadata remains present and might save some rendering time if we switch back to ultica. If the blotter was picked up in retrodays, the flag would have to be attached to it so we didn't see the blotter when we switched back to ultica.

Describe alternatives you've considered

Much of this can be achieved with variant furnitures but it is extremely clunky.

Additional context

Some furnitures could conceivably even be removed with this code. For example, a rug might just be an item on the floor. Posters and paintings could also be items placed on walls. A trash can might just be a container on the floor holding whatever items are in it.

We may want to add the option for items that have variant sprites like this to not count towards the "more items" icon somehow, ie. if you had a laptop and a blotter on a desk in the above example, you wouldn't see the tileset indicator to indicate there were multiple items in the tile.

We also might want to consider a context specific to "any floor with no furniture", and similar things based on terrain flags, eg. "any outdoor floor", "any wall"

Future directions

The general code for this might be used to allow variants of terrain and furniture sprites that showed up in other contexts, for example, having certain furniture items appear differently if placed in a particular map id, or if placed indoors or outdoors.

@I-am-Erk I-am-Erk added <Enhancement / Feature> New features, or enhancements on existing SDL: Tiles / Sound Tiles visual interface and sounds. (P3 - Medium) Medium (normal) priority labels Nov 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
<Enhancement / Feature> New features, or enhancements on existing (P3 - Medium) Medium (normal) priority SDL: Tiles / Sound Tiles visual interface and sounds.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant