Monday, June 2, 2014

Rationing rare occurrences in Chalo Chalo

I like when unexpected things happen in games. Better still is when the unexpected thing happens just when you feel that you've gotten to know the how the game world works. Its impact is maximised at that moment.

We have some unexpected things that happen now and then in Chalo Chalo, we call them rarities. They're designed to foster a sense that the game world has hidden depth and mystery, and to keep players on their toes.

The simplest way to implement these rarities would be to assign each rarity a likelihood. A random number would be generated and compared to the likelihood of the rare thing happening, if the likelihood was lower than the random number, the rare thing would happen. But given that the aim is to have the unusual things happening just as players feel familiar with the game, a better way to set this up is to arrange things so that the longer you've played without seeing anything out of the ordinary, the more likely you are to see something out of the ordinary in the next race (which would not be the case with the simplest set up).

Chalo Chalo is built to include a concept of 'rarity pressure'. You can think of it as 'something in the air' that influences how likely strange things are to happen. The higher the pressure, the more likely that a rarity will manifest itself. When nothing out of the ordinary is happening, the rarity pressure is incremented after each race. We want rare things to be more likely if you didn't see any for a while, and less likely if you did. so to complete the scheme, each rarity has a 'rarity_pressure_release' value. The rarity pressure drops by this amount after the rarity manifests itself.

We use a JSON file to describe all our rarities. In this file we assign likelihoods, we can also set up relationships between rarities so that they can be nested, and add directives to have rarities exclude or require one another. We have a class that's responsible for modifying/reporting rarity pressure, and another that's in charge of parsing the JSON file and selecting rarities for the next race. Because we want rarity pressure to persist between play sessions, we're currently storing it in playerprefs.