State diagrams are indeed an effective way to model the event-driven behavior of a single object.
Relative time event
The relative time interval
after(3 minutes) requires the player to not move. Whenever the player moves, for example making a step, the interval is reset.
The easiest way to model this is a self-transition for the move events, and a self-transition for the timing event. This way, every move re-enters the state and the timer starts anew.
Important remark: the
after(delay) does specify a time related event. It does not impose any way to implement such an event. In other words, you are not forced to actively (and inefficiently) monitor the passing time, and could very well use some efficient timer event of your OS.
Repetitive time event
The "every 15 minutes" is also a relative time event, that could be expressed with
after(15 minutes). It's just that its count-down cannot be disturbed by any other state transition.
One way of modeling this, would indeed be to have a separate very simple state diagram for an object that would send the periodic events, e.g.
Tick15 to the Player object. In your state machine, you would then react to such a
Tick15 event with the appropriate transition. The inconvenience is that you loose the oversight (and have a more complex model with more objects).
A typical alternative is to keep the logic in your single object and use a composite state with nested orthogonal state machines. This allows separation of concerns: One orthogonal region would model the lifecycle around an
Alive state, and would only capture the repetitive time events. Another orthogonal region would be for tracking movement-related events around an
Instead of going directly from
Alive to the pseudo-end-state, you may prefer to add a state
Dead that could care for things such as showing some animation of the player's end, showing the game score, or whatever. This state would then fire a transition to the pseudo-end-state upon its completion (outgoing arrow without any event).
when(condition) expresses a change event if the condition is true. So you'd typically use it to detect the end of the game:
when(energy<=0). But you would not use it for
when(step) since it's not about a boolean expression. If
step is an event, just write
The diagram could look like:
(At any given time, each orthogonal region has one active state, so
Idle are active at the same time, each having independent state transitions, until a transition of the enclosing composite state is fired)
Alivestate, but that other things are happening. Perhaps a timing or activity diagram is more suited to what you want to model?