Change/Modify texture of individual tile

I have a small simulation engine I wrote that is basically a watered down harvest moon.

I’m trying to change a tile’s texture to represent: hoed dirt, planted seed, plant growth, etc. Basically changing/updating the texture at a tile location. I can’t figure out with the current api how to change a texture at a tile location.

I’m currently using the isometric demo map from tiled. It won’t let me attach the tmx file but it’s pretty basic and should be easy to get from their github page.

I am currently using Monogame.Extended 0.5.149 on OSX with xamarin. Am I overlooking some way to change the texture that a tile references?

EDIT:
I am not above modifying the source to add what I need if it’s not currently supported in the API I am just not sure where to start looking in the source to change things.

Edit: in the explanation below I use cell to refer to a location and tile to refer to a tile as in a tileset, as is done in Tiled itself.

If I remember correctly Tiled uses GID’s (global IDs) to figure out what texture should be used. A Tileset has a starting GID and every tile in it a local ID so the GID of a tile is the GID of the tileset + the local id of the tile within the tileset. If MG.Extended exposes the GID of a cell, changing that should change the tile (texture) drawn in the cell. I haven’t looked at the implementation, but the above is how it should work in Tiled, given the format (again, if I remember correctly, but I don’t think I’m far off).

I brought the source into my project so that I could modify it. The problem with that GID is that it wasn’t mutable. Every property is read only all over the tile apis. Like I said I may have missed something but you are correct about the IDs. The latest from nuget is all readonly, and that is my problem. It can’t be changed.

The develop source’s version of TiledTile has a TiledTileSetTile property that can be modified and a read only CurrentTileId. I’m having issues with the latest develop branch throwing an error parsing my tile data that worked fine from the nuget branch but that isn’t the main source of my problems currently.

@shadowprincess2 If I understand you correctly, you only want to change the tiles of a map loaded in the game’s memory? Saving the game’s map from memory to disk (.tmx file) is a difficult problem which is not supported currently.

Currently in the develop branch the code is creating a render target for each layer of tiles and rendering the tiles into this render target infrequently in a cache like fashion. Then each render target for each layer of tiles is rendered as one sprite using SpriteBatch. This means if you want to change the information of tiles like it’s image represented by the “ID” field on the fly you will need to update the render target for the layer of tiles. See https://github.com/craftworkgames/MonoGame.Extended/blob/develop/Source/MonoGame.Extended/Maps/Tiled/TiledTileLayer.cs#L90

Perhaps a boolean flag should exist in the TiledTileLayer class indicating the render target should be updated next frame. (The flag should be reset when render target is updated.)

Feel free to post a new issue on the GitHub issues for MonoGame.Extended and / or submit a pull request. :slightly_smiling:

Hey @shadowprincess25

First let me just say that I absolutely agree that we should keep improving the API so that it’s easier to do these kinds of things. After all, they are the kinds of things you’d want to do in a real game.

However, as @LithiumToast said, this is actually a pretty difficult problem. GID’s are immutable for a reason and the caching in the rendering code makes it a complex trade off between performance and flexibility.

One of the discussions about the Tiled renderer we’ve been bouncing around recently is to drop the SpriteBatch renderer and render the tiles as a mesh (kinda like a terrain engine in a 3D game). This should allow a much better balance between flexibility and performance.

In the mean time, have you considered trying to render tiles over top of the map instead. For example, you could render the map as base ground tiles and then render the hoed dirt, planted seed and plant growth tiles over the top of the existing tiles as a second pass, effectively overwriting the tile’s appearance.

The main issue I see with this approach is that the tiles won’t render in the correct order, which will most likely be a problem in an isometric map when tiles overlap. As a fairly quick change, maybe we could allow custom tile rendering functions to be set which would allow you to override the GID at render time.

Anyway, I’m just thinking out loud here. We should raise an issue on github and decide what we’re actually going to do about this.

I could render the changed tiles over the existing map that was the very first solution that had popped into my head actually. I just felt like there might have been a different way but if that’s the recommendation it’s not a bad one knowing I wasn’t alone thinking it ^-^

I may end up changing the code for my specific purposes. There is a great base to work from and you have done a wonderful job providing jumping off points so I don’t have to roll everything myself which is pretty, pretty nice.