Otherwise, things will get out of hand very quickly. A good way to design for generality may be to follow the paradigms of Inventor, and design your application around Inventor subclasses. Behavior systems for the creatures are represented as Inventor scene graphs, and the creatures' behaviors are updated by applying a BehaviorUpdateAction to these scene graphs. The main disadvantage to this design approach is a strong coupling between the graphics library and your application. However, in this case this might not be a disadvantage.
Inventor exhibits a lot of patterns common in good object-oriented designs.
Using Inventor as a model may help you improve your own programs. The surest way to write better software is by gaining experience writing software. Rather, they reuse solutions that have worked for them in the past. When they find a good solution, they use it again and again. Such experience is part of what makes them experts.