A Good Egg Named Alice – Physics and Design of the Egg in Contraption Maker

aliceEgg

Alice rolls down next to Eggclops.

One of the parts in Contraption Maker is an egg. I’m going to write just a little here about its gestation and implementation.

I was looking through some old emails and chats to refresh my memory and found the chat listed below. The egg was originally going to be a breakable ball, but I decided to make it an egg instead.

eggChat

I thought that an egg would have more whimsy and character than a ball. It is obvious what it is to the end user and it is also very obvious that it is fragile. In addition to that it also has a different rolling motion than a ball has which gives the opportunity for more variety in the puzzles created.

One thing that I wanted to do to give the egg more personality was to have multiple versions with different names. And each of them also had a different look so they looked better and would give a more varied look on the screen than just a single white colored egg. Here are all the eggs along with the pop up window that lets the user select which egg to use.

cmEggs

Current batch of Contraption Maker eggs.

One other nice side benefit was that I was able to name the eggs after friends and acquaintances and let them be in game – if only as a egg. Once I had the egg implemented it seemed only natural to have it attract the dog Tinker if it broke. ¬†Once you’ve added a new part then suddenly more possibilities open up about how it can interact with all the other parts in the game. As you add more and more parts you end up with a rich cacophony of interactions between them all.

Here is a short animation of how the egg attracts the dog when it breaks.

dogEgg

If you look underneath the hood you’ll see that this is accomplished by a method in the egg class that is called when any other part sees it. If the calling part is a dog then the egg returns the dog attract info, otherwise it returns NULL which means no attraction.

CMPartAttractsInfo *CMPartEgg::getAttractsInfo(CMPart *part)
{
    if (mCracked && (part->mType == PART_DOG || part->mType == PART_SCAREDY_DOG))
        return &sDogAttractsInfo;

    return NULL;
}

This is the structure that is returned to let the dog know how attractive the egg is to it. Since the dog may see multiple other items besides the egg, it is up to the dog’s AI to take this attracts info along with any other attracts info it gets from other parts and then figure out what to do. (I’m formatting code below to look okay within this blog post.)

// Constructor for the attracts info returned
// - Att postfix is the attracts values
// - Rep postfix is the repulses values
CMPartAttractsInfo(
   int minDistFrontAtt, int maxDistFrontAtt, int minDistFrontRep, int maxDistFrontRep,
   int minDistBehindAtt, int maxDistBehindAtt, int minDistBehindRep, int maxDistBehindRep,
   int priorityAtt, int priorityRep,
   bool canLookBehind, bool shouldRun, bool edible,
   int repulseHighPriorityDist=FLOAT_TO_INT32(50))

// The attracts info for the egg attraction for dog
// Only attracted to eggs in front of it that aren't more than 230 units away
static CMPartAttractsInfo sDogAttractsInfo(
   FLOAT_TO_INT32(0),FLOAT_TO_INT32(230), 0,0,
   0,0, 0,0,
   ATTRACTS_PRIORITY_ONE,ATTRACTS_PRIORITY_ONE,
   ATTRACTS_CANT_LOOK_BEHIND,ATTRACTS_SHOULDNT_RUN,ATTRACTS_EDIBLE );

One last thing on how the design evolves. These are all “good eggs.” If there are “good eggs” then shouldn’t there be “bad eggs?” It is on my internal list of parts to someday implement. Bad eggs would be smelly and repulse lots of other creature/character parts.

In closing here is the code that implements the egg:

CMPartEgg.h

CMPartEgg.cpp

 

Leave a Reply

Your email address will not be published. Required fields are marked *