I will attempt to re-state my case here in hopes that (A) I can get a sanity check on the design principles and (B) I can have a more productive discussion about the design itself.
First, a motivating example.
Suppose we have a game in which there are cameras. A camera consists of a Position and a FocalPoint, both 3-coordinate vectors. For simplicity we'll ignore other attributes.
Now, the game begins creation when there is only need for one camera and one controlling mechanism: player input. But as time goes on, as always happens, the design is iterated upon and more features become desired.
All told, we will end our game's journey with several things wanting to control cameras:
- Player inputs
- Networked input (spectator cam)
- Game replays
- Pre-scripted cutscenes
- Dynamic "temporary" cameras that do things like zoom to a target region, show it briefly, then return to player control
My proposal is simple: apply some dependency inversion and wrap the notion of a "vector" inside a notion of a "vector source."
Instead of player input, netcode, replays, and cutscenes all pushing state into the camera, they instead hand the camera a "vector source" and say "ask me for your position and focal point whenever you need to."
The bottom line is that suddenly we have no dependencies between modules. Camera controllers can publish their stream of data anywhere - including into a buffer for replays or debugging - and the camera itself only needs to depend on a single interface.
If you're with me thus far, permit me to take this design a step further.
Any time you have a stream of data that changes as the game plays, apply this dependency inversion. Instead of having a push-into mechanism for propagating new state through the game, favor a pull model.
This does not need to imply a performance penalty; for example the camera module could update its position once per frame (by querying its source) and use an internally cached copy of the vector do set up view matrices etc. So really it's about the same as having external code push the value into the camera, just cleaner.
My hypothesis is that uniformly supplying runtime data in this way would make certain things much easier.
Consider the camera above. Once we have a position controller that works on the network, we can apply that vector source to any game object and it suddenly has "free" replication capabilities.
Or think about the way replays work. Any value in the game can be streamed into a replay file with uniform logic; just write an entry to a log every time the value source changes its state. To "replay" the log, just attach a value source to the relevant game object's properties, and the game will suddenly be driven by a replay instead of live data. No extra infrastructure or hard-coded logic necessary.
Now think about debugging. If a stream of values looks wrong, dump it to disk. Or plot it on a graph in UI. Or whatever. But you only have to write the debug monitoring code once. Any other compatible set of data (e.g. another vector-3) can be dropped in without any fuss.
I feel like I've been doing a terrifically poor job explaining this, because so far the biggest reaction I get from people is being offended that I'd suggest departing from ECS or whatever holy architecture is sexy to them.
I personally think it's not much more than a judicious application of age-old design principles (dependency inversion and abstraction) but it feels like an interesting way to make a game.
For the record, I have worked on games that did this (at my urging) and built a few tech demos that were designed entirely this way. I'm pretty happy with it as a strategy but I'm also very motivated to understand the outright hostility the idea gets from others.