The software crisis is, in concrete terms, a complexity crisis. Using standard techniques, there is a quadratic increase in the complexity of code per additional software feature. Once a piece of software accumulates n features, it is no longer able to be extended further without highly severe pain and cost. The standard techniques I talk about are imperative and mutation-based programming.
(Please note the graph commentary in this post are experiential - I have no hard data).
Objects have turned out not to be an exception to this crisis. They are themselves premised on imperative programming and mutation. Even though their implementation complexity is hidden via encapsulation, much complexity still leaks through because of sequential dependencies inherent in externally-observable state changes. After decades of the best effort, refactoring, and design techniques, object-oriented software always (at least from my observation) leads to monolithic software, the only variance being in degree. Though some low-level OO code is reusable in libraries, most of the higher-level stuff is exposed as monolithic 'frameworks'.
Some answer that we can make objects work with better development methodologies like agile, XP, et al. But these only address the change curve - that is changing out one feature for another. It does not seem to adequately address the cost of additional features as that is in the orthogonal realm of complexity - Simple made Easy
So the motivation here is to get the 'complexity curve' under control. Once we do that, we solve a general crisis that our projects face.
The first tool we have in are arsenal is stateless (AKA mutation-free) programming. By eliminating the use of mutation in our software in the general case (a little here and there is fine so long as it doesn't leak all over the rest of the app), we can get real modularization of complexity that, unlike encapsulation, doesn't silently leak out all over. While this is a great and powerful tool, it only gets us down to about n log n complexity per feature. I want software development to have linear complexity. So we should go further.
DSLs are the next tool we have, and is a great one for apps like games and simulations. When we have a non-trivial set of features to implement, it is often best to first build a language to describe those features. This way, that set of features can be implemented in linear time (and maintained with linear resources) for the given subset of features. Additionally, feature implementation leveraging the DSLs can be delegated out to less expert programmers such as the typical game designer.
With these two tools alone, we get the complexity curve down to linear growth over features. Instead of building beastly and fragile frameworks, we can build small and dependable libraries and domain languages. Once we have some knowledge of functional and declarative programming, and throw in powerful type and / or contract systems, software implementation becomes comparatively straight-forward. On top of that add convenient access to lazy evaluation for algorithms as we need it, life for the software developer actually becomes much less burdened.
A free advantage of stateless programming is that it gets the complexity curve of parallel programming down as well.
Once we have a general tool for DSLs, we can build a language to describes simulation objects in a purely declarative way, thus subsuming OOP in the general case. This goes back to the AML and DOL technology that I'm currently working on as specified in this post - AML and DOL