Netting C++

EEK! An Introduction

Stanley B. Lippman

In my previous series of columns, we moved an existing ISO-C++ application to the Microsoft® .NET Framework incrementally, illustrating the interoperability features of C++/CLI, and highlighting differences in the C++ and .NET object models. In this next series of columns, we’ll explore using C++/CLI as a purely .NET-compliant language. The application, for reasons that will soon become apparent, is code-named EEK! Because I am currently spending most of my time working on the server side of MMOGs (Massive Multiplayer Online Games), EEK! draws from certain aspects of that domain, although simplified to accommodate the limited bandwidth of a column, and with considerably more modest ambitions.

My out-of-office hobby, in an equally modest fashion, is molecular biology and questions of how the things that happen at that level of detail makes possible the behaviors we observe around us. Mice have been extensively studied by science, perhaps more so than any other living creature with the possible exceptions of the fruit fly and E. coli (a bacteria), neither of which I find particularly compelling. But mice are strangely familiar if you observe them over time. They cooperate to retrieve a pup that has fallen out of its nest, they exhibit differences in personality, and they seem to remember and learn from experience, both individually and as a group across generations.

As a sort of domestic Dian Fossey on a shoestring budget, I have, in the past, maintained an aquarium populated with mice that I anthropologically observed (a bit randomly, admittedly) and photographed. EEK! is my attempt to model that environment and the behavior of a mouse. I’ve code-named the framework EEK! in homage to my computer graphics friends at Disney Animation. They assure me it is the sound a mouse makes when it discovers it has been vectorized.

So, how do I begin? First off, I need to uncover the set of classes with which to implement my design. Some of these fall out of the description of the application. I’ll need my tank, the mouse, some way to tick off the passage of time, and some method of displaying and possibly storing the changes that occur over time. I’ll try to make use of as many .NET technologies as possible in the course of this series.

The classes that fall out of a design are in large part determined by the intention of the application. Were I to make EEK! an online virtual environment in which users logged on as virtual mice and interacted both with one another and the environment, then the design I’m going to pursue in the following months would be less than optimal because it does not facilitate interactive gameplay. It would be, in other words, the wrong level of detail to model. That is, the design that emerges from the same domain space is largely a consequence of the intention of the application, not of the domain space itself.

While a mouse is a mammal, and therefore shares many human characteristics, its intentions seem far less complex and purposeful. So what causes a mouse to do any particular behavior at any particular time? Well, it turns out that much of its behavior is driven at a molecular level that it is totally unconscious of, often by smells in its environment—emitted by chemicals called pheromones. That is what I hope to capture and explore in this design, and what makes it challenging.

Both the tank and mouse are concrete instances of a more abstract set of classes that root the hierarchy of our simulation framework. Figure 1 gives a sense of that hierarchy.

Figure 1 Hierarchy of the Simulation Framework

public ref class Environment abstract;
public ref class Entity abstract;
public ref class NonSentientEntity : Entity abstract;
public ref class SentientEntity : Entity abstract;

public ref class Mouse : SentientEntity;
public ref class Tank : Environment;

public ref class ExerciseWheel : NonSentientEntity;
public ref class WaterDispenser : NonSentientEntity;

Figure 1 Hierarchy of the Simulation Framework

public ref class Environment abstract;
public ref class Entity abstract;
public ref class NonSentientEntity : Entity abstract;
public ref class SentientEntity : Entity abstract;

public ref class Mouse : SentientEntity;
public ref class Tank : Environment;

public ref class ExerciseWheel : NonSentientEntity;
public ref class WaterDispenser : NonSentientEntity;

A sentient entity is capable both of perceiving its environment and of sensing its internal state and responding with purposeful behavior. I’ll need, therefore, to represent a set of behaviors and be able to initiate, terminate, and evolve these behaviors. This means that behaviors need to capture both action and state, where state represents a form of memory and modifies subsequent behavior.

A non-sentient entity is anything in the environment that the sentient entity may interact with. It may or may not have a function, but it maintains a state that represents its presence in the environment. This presence somehow needs to be communicated.

How should the mouse become aware of its environment and the things within it? For one thing, not all entities are aware of all aspects of their environment. Similarly, not all entities become aware of aspects of their environment in the same way. For example, because a mouse is so small, its visual acuity is limited. It can distinguish light and shadow, but it does not depend on sight the way we do as humans. It compensates for that by having a far greater acuity of smell, and a number of behaviors, as I mentioned earlier, are triggered by that. Sight, smell, touch, hearing—these are spoken of as modalities, and these are what we will model.

The environment consists of a collection of modalities that change their composition over time. A modality connects an entity to its environment in an analogous fashion to the way an iterator connects a container to an algorithm in the design of the Standard Template Library (STL). That is, each entity maintains a set of streaming modalities by which it imparts information into all or a subset of the environmental modalities—it may reflect light, for example, it may impart a smell, and so on. It is this set of information that represents its presence within the environment. Each sentient entity has a set of perceptual modalities through which to sample the environmental modalities and thus to perceive the world it inhabits in EEK!

A sentient entity has bound to its perceptual modalities a set of programmed behaviors—that is, actions it makes in response to its perceptions. If the outcome of that response is memorable, either negatively or positively, the behavior is either modified or reinforced. For example, if the mouse eats what it perceives as a food item and subsequently becomes wretchedly ill, the next time the mouse perceives that item it will avoid eating it.

The mouse moves between a finite set of states. The mouse begins in a state of Rest. When stimulated, either internally or by some perception of its environment, it enters a state of Restlessness, and will execute a sequence of behaviors with the goal of returning to Rest. If it receives neither external nor internal stimulation for some period, it moves to a state of Sleep. Alternatively, if it is frustrated in its goal-seeking, it can move into a state of Distress.

I’ll model an internal stimulation as a Drive. The mouse has a Metabolic component that drives its animate life, for example. This system requires energy, and as its energy quotient falls, a metabolic drive pushes the mouse to a state of restlessness with the goal of seeking out food.

An external stimulation arises through one of the entity’s perceptual modalities, and triggers an Emotion, which may combine with a drive. An emotion is the primary motivation that pushes the entity from a state of Rest to a state of Restlessness. The system will support eight fundamental emotions that vary in intensity.

For example, the mouse can feel Apprehension, which represents a low intensity response to something that is perceived as alien and therefore potentially threatening within its environment, such as my hand, perhaps, rooting around in the tank. That feeling can heighten to Fear, if I should clumsily reach to grab it, and it might boil over into Terror if I should seize hold of it. A stereotypic behavior maps to each emotion. For example, only a terrified mouse will actually bite.

There is a Motor component that bounds and determines the forms of behavior the entity can make. A mouse, for example, cannot inquire as to my intention in rooting around its tank, nor can it break through the glass siding and escape. It is physically constrained in its range of behaviors.

And this leads us to the fourth and most interesting component (at least in terms of the simulation) of EEK! That is an entity’s Cognitive component, which consists of a Genetic disposition and a personal History. For example, it may be disposed to feel Apprehension in situations that another entity of its kind might find of Interest. Based on its history, its disposition may strengthen or weaken or be transformed. It is this Cognitive component that allows an individual entity to modify its stereotypic behaviors over time.

Each capitalized word in the above descriptions, such as Emotion, Apprehension, Fear, and so on, represents a candidate class abstraction in my application. I’ll need to put it all together, of course. But I’ll look at that in later columns when I begin to implement the mouse.

The next question is how do I drive the simulation? Unlike the rodent entities within EEK!, I can’t depend on emotion. Rather, I must depend on the main logic of the simulation as listed in Figure 2.

Figure 2 Main Logic of Simulation

void EEK::run()
{
    Init(); // initialize our environment 
    while ( Time < EndTime )
    {
        Tick();    // advance time, trigger events
        Update();  // update modalities
        Poll();    // SEs perceive() and behave()
        Display(); // communicate what has happened
    }
    Terminate(); // capture final state
}

Figure 2 Main Logic of Simulation

void EEK::run()
{
    Init(); // initialize our environment 
    while ( Time < EndTime )
    {
        Tick();    // advance time, trigger events
        Update();  // update modalities
        Poll();    // SEs perceive() and behave()
        Display(); // communicate what has happened
    }
    Terminate(); // capture final state
}

In order to support multiple simulation implementations, I’ll abstract the simulation as an interface, and instantiate EEK as an instance. This is listed in Figure 3.

Figure 3 EEK as an Instance

public interface class ISimulation
{
    void Run();

    void Init();
    void Tick();
    void Update();
    void Poll();
    void Display();
    void Terminate();
    
    property int Time    { int get(); }
    property int EndTime { int get(); } 
}

public ref class EEK : ISimulation { ... };

Figure 3 EEK as an Instance

public interface class ISimulation
{
    void Run();

    void Init();
    void Tick();
    void Update();
    void Poll();
    void Display();
    void Terminate();
    
    property int Time    { int get(); }
    property int EndTime { int get(); } 
}

public ref class EEK : ISimulation { ... };

Initialization will be supported through a set of XML configuration files, and I’ll parse that using the XML Document Object Model (DOM) support within the Base Class Library (BCL) of the .NET Framework. I’ll persist the state of the simulation within a database, either Access® or SQL Server™, using the BCL Data support. I’ll use Windows Presentation Foundation for the display component. Eventually, I’ll want to provide some sort of Web presence, but I’ll defer that for the time being. I’ll encapsulate each of these services in an associated Manager class.

Of course, in programming, talking about a design can only get you so far, no matter how much thought you’ve given it. It doesn’t become truly interesting until you begin its implementation. I’ll initiate that in the next column.

No vectorized mice were harmed during the writing of this column.

Figure mouse

Figure mouse   

Send your questions and comments for Stanley to  purecpp@microsoft.com.

Stanley B. Lippman began working on C++ with its inventor, Bjarne Stroustrup, in 1984 at Bell Laboratories. Later, Stan worked in feature animation both at Disney and DreamWorks and served as a Software Technical Director on Fantasia 2000. He has since served as Distinguished Consultant with JPL, and an Architect with the Visual C++ team at Microsoft. He is currently a senior software engineer at Emergent Game Technologies.