flame-engine / flame

A Flutter based game engine.
https://flame-engine.org
MIT License
9.15k stars 895 forks source link

Tap/drag/other events continue working when the engine is paused #1734

Open st-pasha opened 2 years ago

st-pasha commented 2 years ago

Currently, the pauseEngine() function stops the internal GameLoop's ticker, which in turn pauses the update/render cycles for the entire game. However, it doesn't stop any of the events from propagating.

This could lead to "cheating" in games with a pause menu, where you need to to tap enemies to kill them, or to drag your character out of danger.

spydon commented 1 year ago

Hmm, I see your point, but I also think that we need to have gestures working while the engine is paused, because how would the user otherwise get out of a paused state if they have their menus written as Flame components? We also don't want to force the user to check whether the engine is paused everywhere, maybe we could have a mixin or something that states that the component should be allowed to take input while the engine is paused and then don't propagate the events to the rest of the components?

A test was just added for this use case: https://github.com/flame-engine/flame/pull/2040/files

ufrshubham commented 1 year ago

An inspiration: In Godot engine, each node (similar to components) has a Pause Mode which controls what should happen when game is paused. It has 3 modes:

Here is a link to full docs.

spydon commented 1 year ago

I don't think we'd like to add something to the base component just for this though, with a mixin we could just propagate the events to the components with that mixin (and maybe their children?) when the engine is paused.

st-pasha commented 1 year ago

Generally, "pause engine" is a very crude tool: on one hand, if you pause the engine then nothing should be happening in the game whatsoever, and on the other hand it is frequently used in situations where we may not want a 100% pause.

One scenario when a full pause is needed is when an app goes into background. In this case it would be useful to have some kind of callback when that's happening, but I guess it could be done via FlutterBindings.

In case of an intentional game pause, a better solution would be to use the "stop time" functionality of the Route component -- assuming the game is built with the RouterComponent navigation system.

This being said, I'm not sure what to do about this issue. Should we just document that pauseEngine does not pause events and recommend not to use it to implement in-game pause? Or should we turn it into a full engine pause?

ufrshubham commented 1 year ago

One scenario when a full pause is needed is when an app goes into background. In this case it would be useful to have some kind of callback when that's happening, but I guess it could be done via FlutterBindings.

Although this is true for a large percentage of games, it is not always the case. City builder style game or some strategy games do need to receive updates even when the are not in foreground. Virtual Cottage is probably the best examples of such a game. By design it is meant to be played in the background.

In case of an intentional game pause, a better solution would be to use the "stop time" functionality of the Route component -- assuming the game is built with the RouterComponent navigation system.

Not the perfect way to go, because not all game will make use of RouterComponent. But if this is explicitly mentioned in Flame docs, I think users can be guided into using routes in future.

This being said, I'm not sure what to do about this issue. Should we just document that pauseEngine does not pause events and recommend not to use it to implement in-game pause? Or should we turn it into a full engine pause?

Yes, documenting this is the least we can do for now. But instead of recommending not to use pauseEngine, we can ask them to check value of paused while handling events.


All that being said, I still feel that components should be able to choose if they want to receive updates while the game is paused. It is common to have some animations running even while the game is in pause state. It just allows users to have a fine control over their game.

spydon commented 1 year ago

Although this is true for a large percentage of games, it is not always the case. City builder style game or some strategy games do need to receive updates even when the are not in foreground. Virtual Cottage is probably the best examples of such a game. By design it is meant to be played in the background.

That will not help here though, the only thing that will happen is that a really big dt value is sent back when the app comes into focus again.