A largish piece of it is the fact that so many data and logic dependencies in the engine and game become implicit, and not articulated in any sort of manner that can be automatically checked ( like by the compiler, for instance ).
I been thinking one way to improve things would be to add explicit dependencies into the core of an engine, as a fundamental concept. A limited version of this would be ref-counting, where you at least prevent pulling an object away from another that's using it, although there are no guarantees w.r.t what state the object might be in.
Rather than ref-counting, which only tells you how many folks care about you, you might do reference linking, where you have a pointer back to the interested parties. With this you can create a rudimentary subscription ( or signal/slot ) model.
The next step would be to have an all-seeing, all-knowing subscription manager class that could manage subscriptions, something like this :
ntNone = 0x0,
ntRead = 0x1,
ntWrite = 0x2,
ntConnect = 0x4,
ntDisconnect = 0x8,
ntFrame = 0x10,
ntPause = 0x20,
ntUnPause = 0x40,
ntCreate = 0x80,
ntDestroy = 0x100,
ntUpdate = 0x200,
ntSceneAdd = 0x400,
ntSceneTraverse = 0x800,
ntSceneRemove = 0x1000,
ntContact = 0x2000,
ntTrace = 0x4000,
nwPre = 0x0,
nwOn = 0x1,
nwPost = 0x2
std::vector< uint32 > _subscribers;
// can hold history here, rather than in subscriber or subscribee
Datum::Value _history[ 16 ];
std::map< uint32, Subscription > _subscriptions;
typedef void (__cdecl* Notify )( ( const Datum* const pDatum, const Subscription* pSubscription, const uint32& notify_type, const uint32& notify_when, const int32& datum_age );
One potentially interesting idea possibly beyond a standard signal/slots mechanism is the history, which can include the previous values of the data, for weapon trails, interpolation, etc. It could also be useful for futures and reading 1-frame behind data. You would subscribe to history -1 for the last frame, choose 0 for this frame, etc.
I also like the separation of the Pre/On/Post flags from the subscription type. That way any subscription type can be combined with the Pre/On/Post flags to allow you to hook in where you need to.
The scope value is there as a differentiator, for instance, an object may get added to multiple scenes, so you could have different scopes that would have separate subscriptions.
It seems this would allow things to be more data-driven, which can be good, but also places a larger burden on having tools to display & manipulate these dependencies...