Main shops & math 🧮

Main shops & math 🧮

Feb 23, 2025

Hi everyone, Ben here. Once again, it’s been a while! It’s funny - with this check-in, there are quite a few massive Grundo’s Cafe dev undertakings in the rear-view mirror. There's the volcano plot, Rodolfo's mobile redesign, and Hannah and the Pirate Caves. There are also quite a few personal milestones for me. In December of 2024 I finished the last semester of grad school and earned my masters in Computer Science. And earlier this month I got married! To a doctor (shout-out GC user lumpia)!!! Even though the ceremony was small, I've never been so overwhelmed with planning in my entire life.

Needless to say, it’s been a chaotic year. And that year has yielded a bevy of things to talk about. So what will I write about in this post? For a while I was considering a ramble on water physics in HATPC titled "How I learned to stop worrying and love recursion". But instead I landed on everyone’s two favorite topics: restocking and math :)

In short, I want to describe the current state of how we tune main shops. Then I want to use that information to contextualize some overdue restock rate changes that we're about to roll out--mostly buffs, but a few nerfs as well.

This topic has been gnawing at me for a while now - especially in the past few months as life has gotten busier. While I take pride in the HTML5 game conversions and am constantly in awe of new art releases, the vision behind Grundo’s Cafe for me is synchronizing those games & that art with a virtual pet economy. I think game economies are incredibly neat microcosms of reality. They give structure to on-site goals and incentivize fun user-to-user interactions - whether it is in the form of a Bony Grarrl Club lending chain or nty glt’ing someone’s low-ball offer on that paint brush you just won. All involve making decisions based on time invested, perceptions of scarcity, and all the other subjective factors you can imagine (how cool is that avatar, how prestigious is that trophy, etc).

I was a big fan of restocking on neopets.com. It’s a nice passive activity, and the thrill of snagging a rare item is tough to match. At the same time, restocking on neopets.com is a bit obscene in its disproportionate power as a money-maker. 

On Grundo’s Cafe I like that we’ve moved away from that paradigm with worthwhile features like world challenges, creative contests, and thoughtfully balanced dailies. But even still, restocking continues to be a profitable endeavor on GC. It is the main vehicle by which many types of items (stamps, morphing potions, plushies, books, etc.) enter the game economy. Game economies require maintenance. Given that restocking represents such a substantial supply of items, it follows that restocking requires maintenance.

But that maintenance is HARD! Here is where I have an impulse to gesture at the flurry of opinions on all the items that should be more common, and all the other items that are frustratingly hard-to-sell. And how sometimes these are paradoxically the same items...

But in my heart, I know the real issue is self-inflicted. The math behind which items restock, and when, is a wasps’ nest of math. These formulas and equations get the job done, but are a massive pain to forecast & simulate.

The Wasps' Nest

Here is where I will try to explain the aforementioned wasps’ nest. Before I get into the equations, I want to explain in broad strokes what happens at xx:06:00 NST when shops are about to restock:

  • A script iterates through every active shop in the game by ascending ID (food: 1, magic: 2, etc)

    • The script fetches that shop’s configuration + all of the active items that stock in it (anything rarity 1 to 100)

    • For each item in the shop, the script assigns a probability P. Common items have a high P, and rare items have a lower P.

    • The script decides how many unique items should stock in the shop, and pulls that many items from the above list with each item weighted by its assigned probability. In other words, the likelihood that any given item will stock equals that item’s P divided by the sum of all P’s.

    • For each selected item, the script calculates the quantity based on item rarity. If rarity is less than 40 -> stock a random number between 5 and 9. If rarity is 41 to 55 -> stock between 3 and 7. And so on.

    • The script clears all existing items from the shop, and then stocks the above list at each quantity.

There are some quirks here - like how Mysterious Valentines Cards and similar items associated with site events may see an overriding boost in stock quantity. And an item will not stock if it was present in the previous stock. But by and large, the above is all you need to know!

You may have noticed that I hand-waived through assigning a probability P to each item. If we peer a bit closer, we’ll see the following equations at play:

image

Do not fear, I shall explain these as well. Imagine in your mind's eye how you’d expect items of different rarities to stock. Higher rarity = more rare, right? Rod of Rod, with its rarity of 99, should be more rare than Sparkshooter with its rarity of 50, right? But how much more rare? Twice as rare wouldn’t make much sense… if supply is inversely proportional with cost, it is hard to picture a world where Rod of Rod is only twice the price of Sparkshooter. This leads us to determining rarity exponentially. 

Now picture in your mind’s eye a scheme where an item’s probability P decays by 3% for each increase of rarity. Let’s consider Spooky Foods… Candy Peas have a rarity of 75. Bat Cookie has a rarity of 76. So we multiply Candy Peas’ probability P by 0.97 to get Bat Cookie’s probability P. If Snorkle Snout has a rarity of 80, we multiply Bat Cookie’s probability P by 0.97 four more times to get Snorkle Snout’s P.

0.97^5 = 0.859. So Bat Cookie should be 97% as common as Candy Peas, and Snorkle Snout 85.9% as common as Candy Peas. Woo-hoo, we’re exponentiating!

There are some troubles with this approach, though. For one, we sometimes want bigger jumps in rarity. For example - because of quests like Taelia and Edna, there is a much bigger demand for r89 food items than there is a demand for r90 food items. A 3% difference won’t cut it here - to get some semblance of consistency, we’d either have to make r89s way too rare or r90s way too common (and therefore disappointing to see as they turn into hard-to-sell junk that will rot in your SDB).

Second - small changes in our tuning parameters can have BIG butterfly effects. With our above system, the difference between an r50 and r99 is (0.97)^(99-50) = 0.225. Meanwhile, (0.95)^(99-50) = 0.081. A small change of 0.02 in our tuning parameter causes the relative rarity of r99s & r50s to nearly triple.

This is where our above scheme was born from. The equation determining P for an item of any rarity r is a piecewise set of functions based on four separate tuning parameters. If we want to target r100s in a shop, we change delta δ. If we want to target r98s and r99s, we can change gamma γ without simultaneously throwing low and mid rarity items into disarray.

There’s just one more rub. To account for quirky shops like magic and quest item shops where demand can jump incongruously with rarity, we employ two fudge factors. The first is a rare item minimum rarity, and the second is a rare item rate. Each time the script picks an item to stock, we roll an n-sided die. If we roll a 1, we only pick from items above the rare item minimum rarity. Otherwise, we pick from items below the rare item minimum rarity. For most shops, the rate is about 60, and the minimum rarity is about 90. In other words, each stocked item has a 1/60 chance of being r90 or higher. The specifics here vary shop by shop, though.

To ground it in an example: for Fresh Foods… 

  • alpha (α) is 1.02. So between r1 and r79, items become 2% more rare each time you increase rarity

  • beta (β) is 1.06. So between r80 and r89, items become 6% more rare each time you increase rarity

  • gamma (γ) is 1.3. So between r90 and r99, items become 30% more rare each time you increase rarity

  • delta (δ) is 20. So any given r100 is 20x more rare than any given r99

  • rare item minimum rarity is 90, and rare item odds are 75

Here's an admin view: a peek behind the curtain!

image

Congrats!!! You are now an expert in restocker math!

But wait! We still need to rebalance the shops!

6 parameters per shop… 50 active shops… nearly 9,000 stockable items? I think I need to lay down.

How we rebalance

Lately, the way that we rebalance these shops has been simple: we just don’t :’)

Through a hodgepodge of simulations and forecasts, we landed on a set of ~300 parameter values that work well enough to get by. But changing anything beyond this was frankly quite intimidating. But the suggestions asking us to revisit certain shops keep coming in, and the experience of trying to find an r99 Brightvale window continues to be less-than-fun. So we worked on a plan to get a handle on this part of the site.

By the way, massive thanks is owed here to Grundo’s Cafe user Nathan. He helped a lot with compiling & organizing information so our decisions here are data-driven.

image

Simulations were unwieldy and subject to lots of variance given the large quantity of items in each shop. Instead, we treated the game itself as our simulation and compiled month-by-month data on the restock rates of rare items. The above spreadsheet gives a glimpse of this effort. We coupled this with an analytical approach to target specific problem areas based on feedback, as well as our own perception of what could be improved.

In the interest of an exercising a light touch, we focus our changes on just gamma, delta, and the rare item odds. Changes to alpha and beta are prone to compounded effects. From here, we determine the quantity of rare items (r98-100) stocking in a shop each month, and divide by the quantity of unique items of that rarity in a shop. In the above screenshot, this is column Avg Times (the average number of times any given rare should stock in a month). We then use some conditional formatting to find outlier values (highlighted in red and orange above), and prescribe some changes in the form of tweaking parameters. These changes overlapped with general feedback we’ve been getting in the past few months, which helps improve our confidence that the tweaks are the right direction.

While the data compilation took months, the shop-by-shop analysis was much, much quicker. This makes me optimistic about being more responsive with future changes :)

So keep an eye on patch notes, and keep a closer eye on shops. We're eager to hear whether slow shops feel any less painful going forward. I do want to mention - if you notice dry streaks, before storming the suggestions channel in our Discord, do remember that these systems are subject to a lot of variance. As you can see in the Functional r99 rarity change column, most of these changes should be in the realm of a ~25% buff or nerf. I acknowledge this isn’t enough of a buff for some shops, but it’s a good jumping off point nonetheless. I’d generally prefer a step in the right direction over a leap too far.

If you’ve made it this far - thanks as always for reading, and wishing you the best. Your support means the world, even if it is just in the form of reading this 2,000 word screed.

Подобається цей допис?

Купити для Grundo's Cafe каву

2 коментарі(в)

Більше від Grundo's Cafe