godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

`TileSet` animation - allow arbitrary tile selection for frames #7290

Open samuelfine opened 1 year ago

samuelfine commented 1 year ago

Describe the project you are working on

I often use TileSet for prototyping 2D levels in the early stages of game development while testing level design and gameplay, usually with a single large sprite sheet texture and crudely drawn art for the sake of rapid iteration.

Describe the problem or limitation you are having in your project

With the current implementation of TileSet Animation in Godot 4.0 and later, animation frames must exist on the horizontal axis ("columns") to use Godot's built-in functionality.

image

As a result, if there is a non-zero chance that any tile in the TileSet will ever need to animate at any time in the future, artists much take a very specific approach when creating textures for tiles: a 1-by-y vertical layout of tiles, one tile per row, so animation frames can be added later on.

This approach is likely to be unexpected or unfamiliar to most game developers, as a square "powers-of-2" texture approach has been the recommended best-practice in the industry for decades. Modern GPUs can handle textures of any size, of course, but the current animation functionality swims against the current of industry "common knowledge", regardless of whether or not it's a hard requirement in modern game development.

The current TileSet animation functionality also implicitly encourages the use of multiple textures in a single TileSet to overcome this, especially if a user discovers the vertical layout requirement for animation mid-development. I would suggest that encouraging multiple textures within a TileSet that share all of the same properties, whose only uniqueness is that some textures are structured for animation while others are not, is an anti-pattern. Encouraging fewer textures in a TileSet with more flexibility per-texture reduces the overall project complexity, and presumably reduces memory overhead as well.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Instead of requiring a columnar texture layout and then defining a number of horizontal frames, I would like to recommend an approach similar to the existing Alternative Tile functionality: allow users to select any tile in a TileSet, indicate that it should animate (perhaps an Animated checkbox, or a "Make Animated" option in the right-click context menu), then allow the user to select any other tile from the current TileSet for additional frames.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

image

Apologies in advance for the janky mockup. 🤣

When Animation Enabled is active for a tile, it would provide a dynamic list of tile frames. When Add Element is clicked, a new empty frame is added. The user can click on the tile preview image, then click on any other tile in the TileSet to the right of the pane. Then, a preview of the tile and its position in the atlas will be populated in the list. Frame duration (in seconds) can be set, and frames can be rearranged or removed using icons on the left. The initial tile selected will always be frame 0, and cannot be re-sorted or deleted from the list of frames.

Of course, removing the existing row-based animation functionality would be a bad idea for existing projects; instead, it could be presented as an option that would show/hide the existing Columns and Separation fields, and display Frames as they are today.

If this enhancement will not be used often, can it be worked around with a few lines of script?

I don't believe so, but I'm certainly open to learning that I'm wrong! As far as I can tell, get_tile_animation_columns and get_tile_animation_columns are the only methods available in TileSetAtlasSource, which return or define the number of horizontal frames of an animation based on a starting atlas coordinate.

Is there a reason why this should be core and not an add-on in the asset library?

Godot's existing TileSet functionality is incredibly powerful, while still easy to understand. The open-endness of Custom Data, for example, offers practically any functionality that a developer would want; I myself was able to use a single Custom Data field to clearly and quickly indicate whether a tile should affect a player's step sound, should do damage, or adjust gameplay. I really enjoy it!

The core Animation functionality has the potential to be powerful as well. Updates made for 4.0 have streamlined the overall approach to tile animation, but in my opinion it's still surprisingly restrictive, prescriptive, and prone to cause unexpected mid-development refactoring. By implementing this proposal, a single texture could be used to contain tiles for level design, hazards, props, and more, from the initial prototype stage all the way through release.

KoBeWi commented 1 year ago

Of course, removing the existing row-based animation functionality would be a bad idea for existing projects

It would be bad in general, because with the current approach you can quickly setup animation for multiple tiles at once. Doing it frame-by-frame for e.g. 20 tiles would be super tedious.

samuelfine commented 1 year ago

@KoBeWi This is not very productive feedback. In my proposal, I explicitly recommended not removing the existing functionality—mostly to preserve backwards-compatibility, but also for those who would find it a useful approach—so "bad in general" isn't an accurate descriptor at all. My proposal is an enhancement on top of what exists today, not a replacement.

Please take the time to read a proposal in full before responding negatively and dismissively.

KoBeWi commented 1 year ago

My "bad in general" refers to removing the existing functionality, not the one added in proposal. I only wrote it, because you said removing it would be bad for existing users, as if it's some compatibility option.

samuelfine commented 1 year ago

So you're agreeing with me, it sounds like? My sentence about the removal being a "bad idea for existing projects" was not all-inclusive and did not include every possible scenario in which I think it would be a bad idea. I absolutely do believe it would be bad to remove existing functionality from Godot without a very good reason, for reasons that should be obvious, which is why I did not recommend it.

I'd love it if we could keep the conversation scoped to this specific proposal, not philosophical discussion about what's good or bad for Godot in general. :)

groud commented 1 year ago

Thanks for the proposal. I feel this is too complex for some problem that isn't really existing. The current implementation lets you already:

Requiring to organize your tiles in a predefined grid isn't that uncommon in most game engine, and is simpler to do in any image editor than just selecting your frames one by one in an animation panel IMO.

So well, the current setup probably works most of the time, and this proposal would make things more complex (both to maintain and for users to understand) for what seems to be a corner case situation. So I don't think it is worth implementing. But well, I'm open to more people's opinions on the matter.