Using raw pointers in C++ is rarely really needed.
Using raw pointers in C++ is rarely really needed.
More info on performance loss due to cache thrashing:
https://lmax-exchange.github.io/disruptor/
https://lmax-exchange.github.io/disruptor/files/Disruptor-1....
http://martinfowler.com/articles/lmax.html
http://mechanical-sympathy.blogspot.com/2011/08/disruptor-20...
And http://mechanical-sympathy.blogspot.com/ is great in general.
The reason that raw pointer management works in gamedev is because gamedev is closer to crafting than traditional programming. No one will die if a game crashes, and the iteration loop is a tight feedback cycle of code-compile-run code-compile-run.
Due to the nature of the entertainment industry, the codebase also loses much of its value within a year of releasing the game, as opposed to traditional software that typically gains value with time, meaning it's more important to get code out the door than to get it right. History is littered with the skeletons of game companies that disregarded this unfortunate truth.
The reason this works is because of discipline. Generally, there is a FooManager class which owns Foos. The FooManager is responsible for both allocating and deallocating Foos, regardless of where they're used. And in a game, "When should something be deallocated?" usually has a clear answer: When the level loads, for example, or when you move from one part of the continuous world to another part.
Then there are Subsystems (singletons) for each division of the engine: GraphicsSubsystem, InputSubsystem, etc.
Between those two patterns, there aren't a lot of ways to lose track of a pointer.
So limiting lifetime of the object by some scope should work pretty well for it, and if you can pass raw pointers to transfer ownership, you can as well pass managed ones. At least it's safer.
Anyway, by using something like Rust a lot of such problems are solved by the language itself.
I don't know where Rust came from, since the discussion was about C++. But feel free to write an engine in Rust. It seems like a promising approach.
I think another important factor is the pseudo-realtime update loop that synchronization is tied to.
Unless there is some garbage collection between game state changes (unloading unused resources during a level, etc...), its rare that references are invalidated unexpectedly, or accessed in parallel to the cleanup step between game state changes.
eg. a global state change from RUN to CLEANUP tells the subsystems to stop using a resource, so during the CLEANUP state the subsystems can safely delete any resources they have ownership of.
The more time I've spent understanding and building game engines, the more I see it as an organised network of state-machines managing and working with collections of data.
More often than not, shared state has clear ownership and lifecycle management built into the relevant state-machines. By isolating creation and destruction of resources in the transitional states (load and start a level, open a menu, change to Game Over screen), most of the code can safely reference data from other subsystems without reference counting, under the assumption that references are only valid until a global, shared transition in state.
Imagine a player entity that stores a reference to a model, texture, sound effect, input state, etc... If that data is loaded at the start of the level, and destroyed when the level ends, is there really a need to inc/dec a reference count if an enemy entity shares a sound effect reference?
Shared pointers (as in ref counting) is just an example of that, so I understood the above comment as implying that game development somehow encourages manual pointers management. May be I just understood the intention wrong, and it didn't mean to exclude other types.