Spelunky Wiki
Advertisement

Description on how to change the contents of containers by modding Spelunky's source. Will cover pots, crates, and chests. Each has similar changes to the code, but are found in different places.

Pots[]

Or "jars" as they are called in game. Simply go into the objects folder and locate oJar. Here you will see a list of events;

  1. Create
  2. Destroy
  3. Step
  4. oWhip
  5. oBullet

The Create event makes it an active object so it can be picked up, thrown, etc. We don't need to change that. The Destroy event we are interested in, as items are spawned when the jar is broken or destroyed. The Step event deals with its position while held, velocity when thrown, and results when thrown into different objects. We don't need to change this either. The last two are collision events with those objects, but we only need to change the collision with the whip.

Removing the contents[]

Let's say for example you are tired of Snakes popping out of jars when you break them. Starting with it's Destroy event, you will see this listed in the code:

if (breakPieces)
{
   playSound(global.sndBreak);
   instance_create(x, y, oSmokePuff)
   for (i = 0; i < 3; i += 1)
   {
       piece = instance_create(x-2, y-2, oRubbleSmall);
       if (colLeft) piece.xVel = rand(1,3);
       else if (colRight) piece.xVel = -rand(1,3);
       else piece.xVel = rand(1,3)-rand(1,3);
       if (colTop) piece.yVel = rand(0,3);
       else piece.yVel = -rand(0,3);
   }
   
   if (rand(1,3) == 1) instance_create(x, y, oGoldChunk);
   else if (rand(1,6) == 1) instance_create(x, y, oGoldNugget);
   else if (rand(1,12) == 1) instance_create(x, y, oEmeraldBig);
   else if (rand(1,12) == 1) instance_create(x, y, oSapphireBig);
   else if (rand(1,12) == 1) instance_create(x, y, oRubyBig);
   else if (rand(1,6) == 1) instance_create(x-8, y-8, oSpider);
   else if (rand(1,12) == 1)
   {
       if (colLeft) instance_create(x, y-8, oSnake);
       else if (colRight) instance_create(x-16, y-8, oSnake);
       else instance_create(x-8, y-8, oSnake);
   }
   
   if (held)
   {
       oPlayer1.holdItem = 0;
       oPlayer1.pickupItem = "";
   }
}

You can see the random chances for each object appearing. Under this list is the oSnake parameters. You can easily delete this entire block:

else if (rand(1,12) == 1)
   {
       if (colLeft) instance_create(x, y-8, oSnake);
       else if (colRight) instance_create(x-16, y-8, oSnake);
       else instance_create(x-8, y-8, oSnake);
   }

Now snakes will never spawn from a thrown jar, but if you whip them they still might. Let's take care of that too. In the collision with oWhip event, open up the code. You'll see a very similar one to what we just looked at. Again simply delete the line containing the chance for a snake to be spawned. Now no matter what you do, a snake will never come out of a jar again. But what if you want something else in there?

Adding contents[]

To add an item it's simple, just do the opposite of what we just did. You could also replace one item with another simply by changing the instance_create parameter. Let's look at this by now changing the snake into something useful, like a rope!

Go back to the Destroy event for oJar, and look at where the snake code is/was.

else if (rand(1,12) == 1)   
{
       if (colLeft) instance_create(x, y-8, oSnake);
       else if (colRight) instance_create(x-16, y-8, oSnake);
       else instance_create(x-8, y-8, oSnake);
   }

We don't actually need all this for an item like a rope, because it will only sit there. So you can easily copy/paste one of the other lines to replace all these, let's use the ruby.

else if (rand(1,12) == 1) instance_create(x, y, oRubyBig);

The object we want is oRopePile, but it might be nice to get it a little more often. For this we will change the random chance as well, so we end up with something like:

else if (rand(1,5) == 1) instance_create(x, y, oRopePile);

Then just replace the oSnake line from the collision event of oWhip with the same line. You could even make it more likely to show when whipped if you like!

Chests[]

The code for opening chests and crates can be found in the oPlayer1 objects step event, under a code with the comment ACTION. Scrolling down you will find a comment which states:

//open chest

Under which you will find quite a bit of code dealing with changing stats when opening the chest, switching the sprite to an opened chest, and the random bomb trap. Below this are the events to determine what will come out of the chest (besides bombs).

else {
       playSound(global.sndChestOpen);
       repeat(rand(3,4))
       {
           n = rand(1,3);
           switch (n)
           {
               case 1: { obj = instance_create(chest.x, chest.y, oEmerald); break; }
               case 2: { obj = instance_create(chest.x, chest.y, oSapphire); break; }
               case 3: { obj = instance_create(chest.x, chest.y, oRuby); break; }
           }
           obj.xVel = rand(0,3) - rand(0,3);
           obj.yVel = -2;
       }
       if (rand(1,4) == 1)
       {
           n = rand(1,3);
           switch (n)
           {
               case 1: { obj = instance_create(chest.x, chest.y, oEmeraldBig); break; }
               case 2: { obj = instance_create(chest.x, chest.y, oSapphireBig); break; }
               case 3: { obj = instance_create(chest.x, chest.y, oRubyBig); break; }
           }
           obj.xVel = rand(0,3) - rand(0,3);
           obj.yVel = -2;
       }}
       
       kAttackPressed = false;
   }
}

Messing with chests[]

Near the top you see

repeat(rand(3,4))

This means the following code will be repeated either three or four times, which gives you 3-4 gems instead of one. Let's make it a better payoff shall we? Increase the numbers to something ridiculous like

repeat(rand(15,20))

Now plenty of gems will come out, but you might not see them all. That's because the chest throws them out with a random x,y velocity. You don't really need to change it, but if you want to see shininess tossed everywhere, you could do something like:

obj.xVel = rand(0,14) - rand(0,7);

Gems galore

It's raining gems!

Your result would be something like this. Note that this is not really practical in the normal game, but is a good example of what you can change.

Adding to chests[]

You may notice there is a gem which never spawns from the chest, the diamond. So let's put some of those in there too.

All you need to do is add another line to the bottom, we'll use the second set (the big gems):

case 4: { obj = instance_create(chest.x, chest.y, oDiamond); break; }

Then change the random chance to reflect the new option:

n = rand(1,4);

Its appearance will be somewhat rare, but that's a good thing.

Crates[]

After learning what's come before, crates are extremely simple to edit. Open up the same code as before (action code in the step event of oPlayer1). Just below where the open chests code is found you see an //open crate comment. Under this is a long list of items which will spawn from crates and their probability. Most items will spawn out of crates already, but you can make them more, or less likely simply by changing the random chances at the start of each line.

Let's add one of the most desired items in the game to be very likely to spawn from a crate. Add the following line to the bottom of the item list:

Kapala

All the favor I need!

else if (rand(1,3) ==1) obj = instance_create(chest.x, chest.y, oKapala);

Now you can open a box and find your own Kapala! No matter what your favor with Kali!

That's all there is to adding items to crates, simple as can be.With this knowledge, you should be able to add, take away, and change anything you want to containers. Even adding your own custom items will be simple if you follow the original game's examples.

Advertisement