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

By Kevin Ryan

Posted on May 16th, 2016

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

 


Inspiration – How I Designed a Hole in Sierra’s Bestselling 3D Ultra Minigolf

By Kevin Ryan

Posted on May 5th, 2016

Designing in a Meadow

I used to do quite a bit of computer game design work at a meadow near Kaiser Pass which is up around the 9,200 foot level of the Sierra Nevada Mountains. It’s about 40 minutes from our home at Shaver Lake. This was back in 1997 and I would sit with a yellow pad sketching down ideas and hole layouts for 3D Ultra Minigolf Deluxe while my kids would run around and have fun. It was a good work environment.

kaiserMeadow1

Kaiser Meadow – Kids way off in distance on the right. Wife and toddler in foreground at left.

It was a neat place for the kids because there were a lot of frogs and if we came at the right time of the year there were also tadpoles or big groups of frog eggs. I can remember coming up to the same meadow back in the 1960s when I was their age.

kaiserMeadow2

Looking for frogs in one of the ponds.

Because it is at such a high elevation it would get very cold at night so things could freeze over even in the late summer. Depending upon the winter there could also be snow patches until late in the summer too.

kaiserMeadow3

My son finds some ice.

So I got to sit outside in a beautiful environment and work on my game.

Eventually I’d have to go inside and sit down at a computer in my home to get the ideas into a specific digital form. It has been like that for me lately in that I can get a lot of creative work done, or inspiration on how to solve a problem, while just walking through the forest or even just driving somewhere in the car. For the minigolf game the “sit down at computer and implement” step would involve creating models of each hole in 3D Studio Max. I’ll write about that process a few paragraphs down.

 

Raindrops and Opening Screens

The idea for the opening of one of my very first published games, Black Belt (not the Sega game of same name), came back in 1983 when I was driving home from college in Oregon to my parent’s house. Somewhere near the Oregon-California border it started raining big fat occasional raindrops on my windshield and the way I wanted the opening title screen for Black Belt just magically occurred to me.

So when I got back to my apartment in Eugene across from Beall Music Hall (which I recently learned is pronounced “bell” not “be-all”) I implemented the idea. It is nothing awe-inspiring or great or anything, but the genesis of the idea seemed pretty neat to me and I’ve remembered it. Ha, someone uploaded it on YouTube, so you can see the opening here:

I suppose writing is like that too in that you can come up with general plot ideas, characters, situations, etc. anyplace, but eventually you have to sit down at a computer (anyone still use a typewriter?) and write down the specific words that make up the story.

 

A Minigolf Hole

The drive up to the meadow at Kaiser took about 50 minutes and on the way we’d drive past the Shaver Lake dam and the marina. The road there curves along the lakeside and I suddenly saw an alignment of geography that could be used as a hole in my game. When I got up the meadow that day I sketched out a design for the hole while thinking of any technical challenges that various elements would cause. Here is a view of the area courtesy of Google Earth:

marinaGoogle

Shaver Lake marina and highway 168 along lakeside.

And here is the sketch of the minigolf hole:

marinaSketch

At this point the next work on a hole would be done in my home office where if I thought the concept was okay and had enough fun elements then I would spend a few days creating a playable 3D model of the hole. I would putt around on it, making different adjustments so that it played well and adding and/or removing different elements. Fun to play and works? Okay, good, keep it. Otherwise it goes into the trash.

The 3D model that I’d make didn’t have any of the artwork detail, only the shapes need to make the hole playable. The following scans are from the artwork design document. There would be three views of a hole: overview, tee, and top down. The top down view also had a very general description. (Sorry, printed them in black and white back then):
marinaPlayablePolys
marinaPlayablePolys2

After making sure that it played well the last step was to get a concept drawing done of the hole that could be used by the artists who would be rendering out all the artwork. I was very lucky because I worked with Don Carson on this project. He designed Mickey’s Toontown in Disneyland and a bunch of other stuff. Click here to see some of the neat things he has made. And some more here in Part Two. Really click – his stuff is awesome. His blog is here and is worth following. I always knew that the concept artwork that I’d get back from him on any of my games would be just amazing! Here is the concept he drew for this hole:

 

marinaConcept

Unfortunately I can’t show you how this hole turned out in the game because it wasn’t implemented. My design had 18 holes and I got them all to the playable state and Don did concept artwork for all of them, but because of budget issues only 9 of them were actually rendered off and put into the game. The rendering of all the artwork took a long time. Below is the Moon Base hole so you can get a sample of what a final hole did look like.

We had musical themes for each hole and that really added a lot to the atmosphere. Chris Stevens along with Ken Rodgers creates the music and sound effect. Chris has gone on to win multiple Grammy awards. Hit the play button and you can hear the moonbase theme.

 

Dynamite Cows

So we come to Dynamite Cows. I live high up in the mountains and will occasionally make trips to Fresno, the closest large town, to do shopping. When driving through the foothills I’d see lots of cows in the fields. One day for some reason the thought popped into my head, “How about herding cows with dynamite.” I actually spent some time developing a product from that idea. Here is the title screen. Sorry again, don’t have anything but black and white printouts with me now. I’m sure I have source code and nice real art backed up somewhere on a CD.

 

dynamiteCowsTitle

Here is a very rough first pass at a game play screen.

dynamiteCowsGameplay

And here are a few of the cows. Wish I had a color version of these screens.

dynamiteCowsCows

Mercifully (for end users) I never got past some very preliminary work on this one. It was fun for me though and sort of a joke. “Mooooves” “Cowleidoscope” – shakes head. It is the nature of the beast to have things that don’t pan out. If you never have failed projects perhaps you’re not challenging yourself enough?

I’ll end with this little story from a biography of G. K. Chesterton.

Restaurants and pubs, in fact, not newspaper offices, were much more likely places to find Chesterton writing his articles. Charles Masterman remembered one such Fleet Street restaurant where Chesterton used to write articles,

mixing a terrible conjunction of drinks, while many waiters hovered about him, partly in awe, and partly in case he should leave the restaurant without paying for what he had had. One day…the headwaiter approached [Masterman]. ‘Your friend,’ he whispered, admiringly, ‘he very clever man. He sit and laugh. And then he write. And then he laugh at what he write.’

That seems to be the key for me. Enjoy what you do so much that you can laugh as you do it. My work has never felt like a job.


Aidan’s Cooler in Contraption Maker – Implementation Details

By Kevin Ryan

Posted on April 22nd, 2016

Preliminary Note 1: Part one  of this subject can be found here: Aidan’s Cooler in Contraption Maker – The Backstory

Preliminary Note 2: So after trying, I find that embedding the code within this post just doesn’t work well. So you can find it all in one spot here. I’ll hook up the links in all the sections below as I write about each element.


aidansCooler

In this second post about Aidan’s Cooler I am going to briefly discuss and list the specifics about how I implemented it.

First you can find the code for the Aidan’s Cooler class here:

CMPartAidansCooler.h
CMPartAidansCooler.cpp

For Contraption Maker I wanted everything to be as data-driven as possible. So I created a CMPartManager class that would be responsible for making all the different parts in the game. My idea was that all the parts would be defined by JSON files which describe all the physical attributes of the part and then I’d have a base CMPart class that took care of all shared/general part methods. And then part specific code needed would be in part specific classes. In the end it almost worked that way.

This line is still in my CMPartManager.cpp file right before all the different sets of arrays that define all of the parts in the game:

// Hard coding here for now just to get 1st pass structure/data in place to work with
// -- will move into loadable JSON files

So unfortunately because of time constraints, something that sometimes happens during development, things never got moved into JSON files. It was a lower priority task. All the part definitions are data-driven, but from hard coded arrays instead of loadable JSON files. It may eventually happen, especially if I end up creating a part editor so that end users can create their own parts, but for now Aidan’s Cooler is defined by a few arrays. It’s not a hard thing to do, just takes time.

Here is the initial artwork that I received in order to create the cooler.

aidansCooler

Aidan’s Cooler Art

The Arrays

The group of arrays that completely define the cooler are here:

Code Excerpt #1

In each short section below I’ll briefly explain the details of each.

Preliminaries

Let me list out a couple of the macros before going over each separate element. These are used because I modified the physics engine we are using to used fixed point instead of floating point math and so I made a few macros to easily convert values between regular floating point and our integer system. You can read about the reason why used fixed point in this post: The Butterfly Effect

Code Excerpt #2

Polygon Vectors

First thing listed in Code Excerpt #1 above are the cpVect arrays. Each array contains the points of a polygon collision shape for the cooler. In the Chipmunk physics engine the polygons must be convex so for many parts multiple polygons are needed because their shape is irregular. The values in these arrays look ugly with lots of numbers and subtractions which were half the width/height of the artwork because I transferred each points value by hand from the artwork in Photoshop. I should have automated the process. Here is a sample of how I went about it from the Contraption Maker bear. Not a pretty process:

cmBearPolyVerts

Dynamic Bodies

Next up are the dynamic bodies which are just point masses. There is one body for the cooler body, another body for the cooler’s handle, and a third body for the wheel. Each of these bodies can move and rotate independently of each other. They are attached to each other by joint constraints that are described further down in this post. Here is the constructor for the dynamic body class:

Code Excerpt #3

Most of the variables are self explanatory.

  • id – Unique id for the body. Used by contraints, shapes, attachments, and artwork.
  • pos – Is just (surprise) the position of the body. It is usually just (0,0).
  • Mass – Mass of body
  • Density – Density of body
  • noGravity – Whether body is affected by gravity. Billiard balls aren’t effected by gravity. This is a carry over from what I did in The Incredible Machine where I was planning on making a billiard ball computer.
  • dampsRope – Whether this body will apply damping to attached ropes
  • shouldSave – Whether this body info should be saved in level files
  • next – Pointer to next body. All the different properties the describe a part are in null terminated linked lists.

The cooler has three bodies: the main container of the cooler, the handle, and the wheel. The main thing you see here is the offsets to the positions of the handle and wheel to the main cooler body and also the relative masses of the the three bodies.

Constraints

After the dynamic bodies are the constraints. There are joints that attached one body to another. You can check out this YouTube video which shows all the different Chipmunk constraints and joints in action. Here are the constructors for the rotary limit constraint:

Code Excerpt #4 – Rotary Limit Constraint

  • id – Unique id for the constraint
  • body1Id – First body that this joint connects
  • body2Id – Second body that this joint connects
  • minAngle – Minimum angle between these two bodies
  • maxAngle – Maximum angle between these two bodies
  • shouldSave – Whether this specific constraint info should be saved in the level file
  • next – Pointer to next constraint for this part

This rotary limit constraint is used to control how far the handle can rotate relative to the cooler body. The other two constraints are pivot joint constraints and they are used to connect the handle to the body and also the wheel to the body. Here is the constructor for the pivot joint constraint.

Code Excerpt #5 – Pivot Joint Constraint

  • id – Unique id
  • body1Id – First body that this joint connects
  • body2Id – Second body that this joint connects
  • pivot – Offset to location of where the two bodies are connected
  • shouldSave – Whether this specific constraint info should be saved in the level file
  • next – Pointer to next constraint for this part (null terminated linked list)\

If you look at the pivot joint arrays you’ll see that the body ids are set to hook the main body to the wheel and the main body to the handle.

Collision Shapes

The collision shapes for the cooler are made up of one circle and quite a few polygon shapes. As mentioned above polygons must be convex so many parts will need multiple polygons to correctly represent their irregular shapes. All of the collision shapes have Chipmunk group, type, and layers associated with them. Here is the code that has the defines for them:

Code Excerpt #6 – Defines for Collision Group, Type, and Layer

There a quite a few different shape properties that are defined. This code excerpt has the struct which has the three types of values define for each type of property and also a list of all the different types that Contraption Maker is currently using:

Code Excerpt #7 – Shapes’ Physics’ Properties

And there are also defines for different shape properties. This is so shapes can automatically play the correct sound effect when they hit different surfaces.

Code Excerpt #8 – Shapes’ Sound Properties

And here the constructor for the circle shape which is used by the cooler’s wheel:

Code Excerpt #9 – Circle Collision Shape

  • id – Unique id
  • pos – Offset to the position of the center of the circle
  • bodyId – The body that this collision shape is attached to
  • shapeProperty – Description of the friction and elasticity of the shape
  • shapeSfxProperty – Sound that this shape makes when hitting something
  • radius – The radius of the circle
  • group – The Chipmunk collision group this shape is in
  • collisionType – What type of collision callbacks this shape uses
  • layer – Which Chipmunk collision layers that this shape is in
  • shouldSave – Whether this specific collision shape should be saved in the level file
  • next – Pointer to next collision shape in a linked list

And this is the constructor for polygon collision shapes:

Code Excerpt #10 – Polygon Collision Shape

  • id – Unique id
  • pos – Offset to the position of the polygon
  • bodyId – The body that this collision shape is attached to
  • shapeProperty – Description of the friction and elasticity of the shape
  • shapeSfxProperty – Sound that this shape makes when colliding with something
  • verts – Pointer to an array of the vertices of the polygon
  • numVerts – Number of verts in the polygon
  • group – The Chipmunk collision group this shape is in
  • collisionType – What type of collision callbacks this shape uses
  • layer – Which Chipmunk collision layers this shape is in
  • shouldSave – Whether this specific collision shape should be saved in the level file
  • next – Pointer to next collision shape in a linked list

There are quite a few polygons for the cooler because there need to be separate shapes for the sides and the bottom on the cooler.

Rope Attachments

The cooler is set up so that a rope can be attached to the handle. This is handled in Contraption Maker by adding a rope attachment to a part. Any part can have any number of rope attachments. They just need to be part of the linked list of attachments in the part definition array. This is the rope attachment constructor:

Code Excerpt #11

  • id – Unique id
  • pos – Offset of the position of the rope attachment to the body it is attached to
  • bodyLinkId – The id of the body that this rope attachment is connected to
  • shouldSave – Whether this attachment should be saved in the level file
  • next – Point to the next attachment in a linked list

Nothing fancy with the rope attachment. Its location is just at the end of the handle and it is on the handle body.

Artwork

The final element describing the cooler is the only element that is actually seen on screen – the artwork. Everything else goes on behind the scenes. Each sprite is connected to a body and then tracks its position and/or rotation. There are few special cases where the artwork is connected to an attachment (like a rope attachment) instead of a body. Here is the rope attachment constructor:

Code Excerpt #12

  • id – Unique id
  • layer – Which layer it is draw on. Controls which sprites are drawn in front or behind each other
  • posLinkId – The id of the body whose position this sprite will track. -1 means don’t track any body’s position.
  • rotLinkId – The id of the body whose rotation this sprite will track. -1 means don’t track any body’s rotation.
  • spriteName – The sprite’s file name
  • width – Sprite’s display width
  • height – Sprite’s display height
  • partAttachmentId – Only used for special cases where we want this sprite to track an attachments location (like a rope attachment where the sprite would be the knot)
  • pos – Offset to the sprite’s location relative to the body
  • useFrameCache – Set to true if the sprite is inside of a sprite sheet
  • usedForBb – Set to true if this sprite should adjust size of part’s bounding box – use by the gui
  • shouldSave – Whether the info about this sprite should be saved in a level file
  • shouldPostProcess – Set to true if this sprite needs to be processed after physics have run. Used for cpu efficiency purposes so we can ignore lots of sprites each frame and only spend cpu time on those that need it.
  • opacity – Ranges from 0 to 255.  Used to control sprite’s transparency.
  • next – Pointer to next sprite in a linked list.]

If you take a look at the CMPartAidansCooler.cpp code, you should be able to figure out why the artwork for the word “Aidan” is reversed on one of the sprites.

Chipmunk Calls

Each of these constructors then use the definitions from the arrays to make calls to various Chipmunk routines to build up all the elements that make up the part. In the code excerpt below I’ve just put all those various calls in one place.

Code Excerpt #13

Final Wrap up

That is pretty much it. Here is a quick diagram of the various elements that make up Aidan’s Cooler.

coolerOverview

 

This post ended up being quite a bit longer that I thought it would be. Hope it is at least halfway helpful to someone.


The Butterfly Effect

By Kevin Ryan

Posted on February 29th, 2016

Chaos Theory

I have been reading Nate Silver’s The Signal and the Noise and in one of his chapters he discusses weather forecasting and chaos theory. Chaos theory is where very small differences in the starting conditions of a dynamic system can result in completely different final results.

He writes about Edward Lorenz, the man who coined the term “butterfly effect”. When Lorenz was working on a weather forecasting program on a computer they were getting widely divergent results. This was when running through the exact same code using what they thought was the exact same data. According to Silver sometimes the forecast would be clear skies over Kansas and sometimes thunderstorms.

They spent quite a while trying to figure out what the problem was. Eventually they tracked it down to the setting of barometric pressure in one area of the grid where the floating point number was being rounded differently. A difference of just 0.0002 in the barometric pressures caused huge changes in the final results.

Edward Lorenz: “Chaos: When the present determines the future, but the approximate present does not approximately determine the future.” – quoted from here

A second thing that Silver writes about is a European weather model. In December 1999 they were trying to make a prediction of the storm Lothar for Germany and France. The model was completely deterministic. They ran many simulations, in some modifying the barometric pressure in Hanover slightly and in others making a tiny change in wind in Stuttgart. The results would sometimes show clear weather in Paris and in others a huge storm. The fifty different forecasts from this model are pictured below.

European Weather Forecast

Contraption Maker

Now this discussion hit home for me because I’ve been working on Contraption Maker (CM) recently and had to deal with many of these same issues. Contraption Maker is a sand box physics game in the same vein as The Incredible Machine and is currently available on Steam. I’ve been working on it with Spotkin which is made up of my old Dynamix business partner Jeff Tunnell, his son Jonathon, and Keith Johnston. I was responsible for getting the physics right. To get a sense of the game, here is a user created perpetual motion machine.

A user created perpetual motion machine running in Contraption Maker.

When you have a contraption made up of possible hundreds of parts that are interacting with each other for hundreds or thousands of frames then the butterfly effect becomes very obvious. Move a tennis ball over by just 0.0001 units and it may bounce off a teeter-totter a fraction of a second later and then make something else bounce left instead of right and divergence is off to the races.

Floating Point

But as long as the initial starting positions of all the parts were the same then the contraption should always run exactly the same. This is where the floating point problem came into play. Contraption Maker is cross platform. It runs on Windows machines, Macs, mobile devices (very soon), and who knows what future devices. Is the CPU within all these different devices going to calculate floating point results exactly the same? One small difference messes everything up.

After some research online the answer I got was that if you set up things right then the answer was maybe “yes” and maybe “no”. There were also indications that some things like like sin, cos, sqrt, and others could be a problem.

I found this page which summaries a lot of what I found scattered across the Internet: http://gafferongames.com/networking-for-game-programmers/floating-point-determinism/

This wasn’t the completely definitive answer that I was looking for, but I got the sense that if I set up the compiler settings correctly it would probably work. Probably… made me a little uneasy. So I wrote our own routines for sin, cos, etc so that I knew that they would give the same results no matter what computer/mobile-device CM was running on.

At this point everything was going along fine. Contraptions were running exactly the same on Windows and Macs. Development was cruising along. Parts were being implemented. Floating point didn’t seem to be causing a divergence to occur. Some minor changes were needed to handle adding new parts to an already existing Contraption so that all the parts were still processed in the exact same order. A few minor bumps that were easily solved. And then the copy/paste problem reared its head.

The problem was that there would be a group of parts that did something neat and then you’d want to copy and paste that whole group of parts to another area in the world. With floating point you could not guarantee that they would run exactly the same. Floating point has that weird thing – the point floats. You have more resolution close to zero than you do farther out. So a group of parts close to the origin are not going to have the same floating point results as the same group farther away from the origin.

Argh… Integers

Argh, sigh… At this point the simplest solution was to just convert everything to be an integer physics engine. And do the same with the trig routines. I had had to do the same for The Incredible Machine because floating point just wasn’t fast enough back then. So that is what I painfully did. Here is a group of parts that have been copied and pasted and are running the same.

Copy and Paste group of parts running exactly the same.

Keith set up an automated determinism check where we have generated hash values for a few hundred contraptions that are calculated after each one has run for a thousand frames or so. This way we can just run “testcompat” and it then runs each of those contraptions and then compares their hash values with the saved hash values to verify that everything is running the same on all different machines.

So far so good – physics are matching as we start building mobile versions on new devices- and the hash value checks have also caught a few times where code changes made earlier contraptions run differently. Our goal was to never have an update make a preexisting contraption have a different result when run. The hash check let us find and fix these problems before an update was released.