That doesn’t make it spaghetti code though. In well-written OOP code you shouldn’t care where a function is implemented. The problem is a much too high level of abstraction. If your high level code is so abstract that it is only running tasks and handling messages there’s no way to write it in a way that prevents mistakes because you couldn’t possibly know what the actual implementations do.
It’s not reductive, it’s misrepresentative. A puzzle game is only a puzzle game as long as coming up with the solution is the main task. There are more than enough games where coming up with the right solution is not difficult, but performing it is.
Also the name puzzle game implies that there are designed puzzles. Any game where you have to make decisions in generated situations aren’t puzzle games. For example if you take a specific chess situation and ask which move would lead to check mate in x moves then that’s a chess puzzle. That doesn’t make the game of chess itself a puzzle.