I would concur and add that the main risk one runs in deploying any new, widespread abstraction to game code is an architectural meltdown, where perf bottlenecks are appearing everywhere, too many code paths have been locked in by the abstraction so you can't iterate on them fast anymore, you have race conditions you can't analyze properly, etc.
Iteration times across the whole development lifecycle are hard to optimize because in the near term the iteration problem is specific to writing basic functionality, then later on it's adding and adjusting a wide variety of assets, and then even later it's debugging and optimizing. Care too much about one and you mess up the others.
If you soak up pain up front to keep the core of the code in an unadorned imperative style, crunching on plain data, avoiding deeply nested callstacks or polymorphism, you get a huge assurance that you can handle anything that happens later on - it follows the grain of the tooling and the happy path of the optimizer.
The way in which I last approached the live-reload problem was to write a data model, and then bolt a scripting language on to generate data. Then reload the scripts - you get the fast iteration, without being particularly invasive on the main loop.
Edit: And similarly I've focused most of my abstraction braincycles on making it easier to access and swap out assets. One of the biggest recurring problems in engine code is deriving runtime assets from combinations of static assets and parameters. This has led me down the road of developing an addressing scheme.
Iteration times across the whole development lifecycle are hard to optimize because in the near term the iteration problem is specific to writing basic functionality, then later on it's adding and adjusting a wide variety of assets, and then even later it's debugging and optimizing. Care too much about one and you mess up the others.
If you soak up pain up front to keep the core of the code in an unadorned imperative style, crunching on plain data, avoiding deeply nested callstacks or polymorphism, you get a huge assurance that you can handle anything that happens later on - it follows the grain of the tooling and the happy path of the optimizer.
The way in which I last approached the live-reload problem was to write a data model, and then bolt a scripting language on to generate data. Then reload the scripts - you get the fast iteration, without being particularly invasive on the main loop.
Edit: And similarly I've focused most of my abstraction braincycles on making it easier to access and swap out assets. One of the biggest recurring problems in engine code is deriving runtime assets from combinations of static assets and parameters. This has led me down the road of developing an addressing scheme.