I’ve tried to express this before, but with questionable success. In working with a student today I came up with this summary. I am also aware that I still have not completed the final part describing my Proc system (I kind of took a break from all this online community thing in June). I will get to it again in time for when I next teach my AI course. I have ported it to C# in Unity, by the way. That was an interesting journey, which I hope to blog about too in the future. Anyway back to, once again, searching for a good way to explain my perspective on this whole problem of reusable behaviours and implementing complex behaviours in games.
Resuable AI (modular behaviour) is a desirable thing to have in game programming, which seems to present a greater challenge that it should. After all reusable code is what good programming is all about, and we don’t have to jump through hoops (if you will pardon the pun) to implement the reusability of a function in most programming languages.
It is indeed interesting that this issue does not exist in most modern programming languages, which are implemented on an FSM (albeit hierarchical) architecture. A point that is often missed is that these issues are reflected in the original problem of modularity in early computers. The solution to this was the invention of the subroutine, which became the first important abstraction in computer science (See “The Humble Programmer” by Dijkstra). This abstraction allowed for reusable code.
Often when programmers talk about Finite State Machines what they really mean is an implementation of a virtual (state) machine which suffers from the same kind of problems that would occur if computers did not have the necessary hardware to implement a subroutine. In fact, sometimes these virtual machines are so primitive that they even lack conditional branching (part of the basic minimal functionality required of any central processing unit).
So the problem is not in the concept of the Finite State Machine per se, but naive implementations of virtual machines implementing finite state mcahines which do not include the equivalent of a subroutine, and thus do not allow for modularity. A hierarchical finite state machine (HFSM) is what you get by default in all procedural programming languages, and this provides the ability to create modular code.
This therefore begs the question “Why do programmers create a virtual machine, and call it a (Hierarchical) Finite State Machine, instead of simply programming what they need directly in the HFSM of the native language?” The answer is simple: It is because of the need to support multitasking when working in a language that does not readily support it.
This causes me to ask “Why don’t we just build our computers and languages to support what we need in the first place?”.