Modelling game economy ! 
with Neo4j
agenda
Hi, my name is Yan Cui.
1MDAILY 
ILLION USERS 
ACTIVE
250 
MILLION DAY 
REQUEST 
PER
location
500+ Spots
location 
episodic
London 2012
Nan Jing 2013
location 
episodic 
multi-player
herebemonstersgame.com 
iPad 
buddies
location 
episodic 
multi-player 
RPG
4000 Items
800 Recipes
1500+ Quests
100+ Monsters
game 
balancing
item 
Pricing
item 
Pricing
item 
Pricing
item 
Pricing
manual game 
balancing is SLOW
it is REPETITIVE
ERROR-PRONE! 
SUBJECTIVE
there must be a 
better way...
Hello, Neo4j 
The rabbit hole sounds pretty good right about now!
catching 
BIGFOOT
catch rate 
location bait 
attraction rate
as a graph in Neo4j
Bigfoot 
Alice Lake 
exists_in 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake
Bigfoot 
Alice Lake 
exists_in 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake 
Strength = 502! 
Speed = 201! 
Intelligence = 184 
Strength = 420! 
Speed = 210! 
Technology = 240
Bigfoot 
Alice Lake 
exists_in 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake 
CatchRate = 0.774
Bigfoot 
Buy Price = 20BN! 
Sell Price = 482 Gold! 
Sellable Alice = Lake 
true! 
… 
exists_in 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake
DropRate = 0.1 
Bigfoot 
Alice Lake 
exists_in 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake
Bigfoot 
Alice Lake 
exists_in 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake
Bigfoot 
Alice Lake 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake 
exists_in 
Yowie 
Yeti 
can_catch 
can_catch 
Apprentice’s Workshop 
can_make 
Goat 
Honey 
Yeti Fur 
requires 
loots 
makes 
Alluring Goat Recipe 
requires requires 
Beeswax 
loots 
Bee Hive 
harvests 
McDonald’s Farm 
sells 
loots 
Goat’s Milk 
harvests 
London 
exists_in 
requires 
Peryton Fawn Decoy Recipe 
Peryton Fawn Decoy 
makes
Bigfoot 
Alice Lake 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake 
exists_in 
Yowie 
Yeti 
can_catch 
can_catch 
Apprentice’s Workshop 
can_make 
Goat 
Honey 
Yeti Fur 
requires 
loots 
makes 
Alluring Goat Recipe 
requires requires 
Beeswax 
loots 
Bee Hive 
harvests 
McDonald’s Farm 
sells 
loots 
Goat’s Milk 
harvests 
London 
exists_in 
requires 
Peryton Fawn Decoy Recipe 
Peryton Fawn Decoy 
makes
Bigfoot 
Alice Lake 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake 
exists_in 
Yowie 
Yeti 
can_catch 
can_catch 
Apprentice’s Workshop 
can_make 
Goat 
Honey 
Yeti Fur 
requires 
loots 
makes 
Alluring Goat Recipe 
requires requires 
Beeswax 
loots 
Bee Hive 
harvests 
McDonald’s Farm 
sells 
loots 
Goat’s Milk 
harvests 
London 
exists_in 
requires 
Peryton Fawn Decoy Recipe 
Peryton Fawn Decoy 
makes
Bigfoot 
Alice Lake 
exists_in 
can_attract 
Alluring Goat 
Bigfoot Toenail Clippings 
Musket-teer Trap 
loots 
can_catch 
Omar Lake 
exists_in 
Yowie 
Yeti 
can_catch 
can_catch 
Apprentice’s Workshop 
can_make 
Goat 
Honey 
Yeti Fur 
requires 
loots 
makes 
Alluring Goat Recipe 
requires requires 
Beeswax 
loots 
Bee Hive 
harvests 
McDonald’s Farm 
sells 
loots 
Goat’s Milk 
harvests 
London 
exists_in 
requires 
Peryton Fawn Decoy Recipe 
Peryton Fawn Decoy 
makes
8000+ Nodes
40000+ Edges
game 
balancing 
(revisited)
impact analysis
What’s the 
impact of upping 
the price of 
“White Bread”?
ITEM ITEM 
CRAFTS 
RECIPE 
IS_USED_IN
MATCH! 
(wb:BaseItem { Name:"White Bread"})! 
-[rel:CRAFTS | IS_USED_IN*1..]! 
->(i:BaseItem)! 
RETURN i, rel, wb
MATCH! 
(wb:BaseItem { Name:"White Bread"})! 
-[rel:CRAFTS | IS_USED_IN*1..]! 
->(i:BaseItem)! 
Node-[rel]->Node 
RETURN i, rel, wb
MATCH! 
(wb:BaseItem { Name:"White Bread"})! 
-[rel:CRAFTS | IS_USED_IN*1..]! 
->(i:BaseItem)! 
RETURN i, rel, wb
MATCH! 
(wb:BaseItem { Name:"White Bread"})! 
-[rel:CRAFTS | IS_USED_IN*1..]! 
->(i:BaseItem)! 
RETURN i, rel, wb
MATCH! 
(wb:BaseItem { Name:"White Bread"})! 
-[rel:CRAFTS | IS_USED_IN*1..]! 
->(i:BaseItem)! 
RETURN i, rel, wb
MATCH! 
(wb:BaseItem { Name:"White Bread"})! 
-[rel:CRAFTS | IS_USED_IN*1..]! 
->(i:BaseItem)! 
RETURN i, rel, wb
MATCH! 
(wb:BaseItem { Name:"White Bread"})! 
-[rel:CRAFTS | IS_USED_IN*1..]! 
->(i:BaseItem)! 
RETURN i, rel, wb
scarcity analysis
How scarce is 
“Durian” 
compared to 
“Dragonfruit”?
FRUIT SPOT 
EXISTS_IN 
FORAGES 
FRUIT TREE
MATCH! ! 
(fruit)<-[:FORAGES]-(tree)! 
-[:EXISTS_IN]->(spot)! 
WHERE! ! 
fruit.Name=‘Durian’ OR! 
fruit.Name=‘Dragonfruit’! 
RETURN fruit, tree, spot
MATCH! ! 
(fruit)<-[:FORAGES]-(tree)! 
-[:EXISTS_IN]->(spot)! 
Node<-[WHEREr1]-! ! 
Node-[r2]->Node 
fruit.Name=‘Durian’ OR! 
fruit.Name=‘Dragonfruit’! 
RETURN fruit, tree, spot
MATCH! ! 
(fruit)<-[:FORAGES]-(tree)! 
-[:EXISTS_IN]->(spot)! 
WHERE! ! 
fruit.Name=‘Durian’ OR! 
fruit.Name=‘Dragonfruit’! 
RETURN fruit, tree, spot
quest lines
ITEM ITEM 
AWARDS 
QUEST 
REQUIRES 
UNLOCKS
What quests 
come after “Year 
of the Horse”?
MATCH! 
(q1:Quest { Name: “Year of the Horse” })! 
-[:UNLOCKS]! 
->(q2:Quest) ! 
RETURN q1, q2
How do you 
model quest 
progression?
2. Enrich Model 
1. Price Items 
3. “Price” Quests
monster hierarchy
Catch me first. 
No, catch ME first.
MONSTER ITEM 
IS_USED_IN 
LOOTS 
RECIPE 
CRAFTS 
MONSTER ITEM 
CAN_ATTRACT
MATCH! 
(monster1:Monster)-[:LOOTS]->(loot)! 
-[r:IS_USED_IN | CRAFTS*0..]->(bait)! 
-[:CAN_ATTRACT]->(monster2)! 
RETURN monster1, monster2
Σ(Bait Price * Attraction Rate) 
Input = Output 
Σ(Loot Price * Drop Rate) + Gold
MONSTER ITEM 
IS_USED_IN 
LOOTS 
RECIPE 
CRAFTS 
MONSTER ITEM 
CAN_ATTRACT
NEW monster ! 
= More competitor for bait! 
= Lower attraction rate for 
all monsters
getting data into 
NEO4J
version control 
Game Design data
What changed! 
When did it change! 
Why did it change! 
Who changed it
allow multi-user editing
GitFlow! 
! 
- branching strategy for Git! 
- used by all our developers!
Publisher 
- Validate! 
- Localize! 
- Publish
Publisher 
Flash iOS Server Neo4j
test data changes in 
isolation
preview changes on live
Localization
more text than first three 
Harry Porter books!
Step 1. ! 
ingest gettext file
Step 2. ! 
intercept string 
property setters
Step 3. ! 
replace string
Step 4. ! 
repeat for next language
intercept string 
property setters
intercept string 
property setters
replace string
replace string
target all DTOs!
auto-tuning 
trapping stats
Monster 
strength! 
speed! 
intelligence 
Trap 
strength! 
speed! 
technology
Monster 
strength! 
speed! 
intelligence 
Trap 
strength! 
speed! 
technology 
Catch Rate %
trial-and-error
error-prone 
trial-and-error 
laborious 
sub-optimal
genetic algorithms 
(in F#)
auto-tuning baits
auto-tuning baits
LONDON 2.0 
we rewrote the entire season 1 ! 
quests to make them better.
TWICE 
THE FUN
SEASON 1 
SEASON 1! 
(POST-REWRITE) 
SEASON 2
MORE STREAMLINED
QUALITY > QUANTITY
TWICE 
THE AMOUNT 
SUPPORT TO
Neo4j to the rescue!
Thank you!
theburningmonk.com 
@theburningmonk 
github.com/theburningmonk

Modelling game economy with Neo4j