You need to anyway. Anybody ever created a nontrival software, had found that thinking ahead of a problem most of the time does not work, simply because there is so much that can go wrong, especially with complex systems.
So the most successful strategy is to keep things simple until you are forced to add another layer of complexity. Then design this layer taken into account the use-case you currently know of and refactor. You’ll find that you will do this more than once.
Trying to fight future problems with complexity will most likely fail. The worst complexity you’ll find in a system is the one you introduced to make something look simple and hide complexity. This not only introduce invisible complexity, but also inflexibility, because you have no clear vision of the control flow where you can handle stuff, you didn’t think of while designing your abstraction.
A scripting layer is something way more complex and involves more work that you typically think beforehand:
- You need to define an API that is public to your scripting and provides access to the needed subsystems
- You need to document this well, because you might loose IDE support for code-completion
- You might (partly) loose debugebility, since you cant step through scripts or over script/engine boundaries easily
- You might (partly) loose refactoring, since IDEs might not recognize your scripts calling refactored classes and methods
- You need to make your engine thread-safe, since scripts usually run in threads and might access you engine objects arbitrary
- You need to find a way to organize/limit those threads with pooling and execution schedules, since you don’t want a thread per entity for larger games
- You need to handle script contexts and their garbage collection to not introduce memory leaks
- etc.
Depending on the language choosen and the use-case implemented, not all of the above might hold, but on the other hand you might get a lot more of those in other cases, so you get the idea…
All in all I would go for just using java and maybe some continuations framework to be able to write non-stepped behaviours.