That's an interesting concept - I'm not sure I'm fully understanding though.
In your example - in the 'reduce' step - the implication is that the attack and debuff are handled in a deterministic way, regardless of their order? I feel like then that would require the logic for reducing all game commands needs to reside in the engine loop, which doesn't seem right to me.
Background. There are two ways gamers think about games "real-time" and turn-based. The question about a bullet is most likely referring to what gamers would call a "real-time" game. The thing is, we programmers are forced to make the game happen in discreet steps. There are multiple ways to accomplish this.
The naive way is to give every object in your game an Update() then on each discreet step you iterate through the list of objects in your game and call Update(). This way lies madness because every object can interact with every other object from any Update() and you can never know where the changes are coming from.
The concept above is that you move up a layer of abstraction and you create a GameState object that contains all objects. You instead give each object a GenerateUpdates() method that returns a list of GameStateChanges. Thus to update the game, you take the GameState, iterate through each of the objects in GameState and get a list of GameStateChanges. You then pass both to either GenerateNewGameState (if game states are cheap) or ApplyChangesToGameState (if they are expensive). This reduces all of your mutations to one method and is much easier to update/debug/fix/understand.
From what I understand, it is more that by collecting events that occur in a frame and then applying them on the next. It is easier to debug since you can print out the events on every frame. Which if there is a bug, makes it easier since you'll be able to see the events and the order they came in on.
Determinism is indeed a major benefit of the structure I described. I'm curious about your objection, though - where else could the logic be other than in the game loop? In this architecture, your game loop is basically three steps - collect actions, reduce actions, render, repeat.
In your example - in the 'reduce' step - the implication is that the attack and debuff are handled in a deterministic way, regardless of their order? I feel like then that would require the logic for reducing all game commands needs to reside in the engine loop, which doesn't seem right to me.