modelling game economy with neo4j oscon
Post on 25-Jan-2017
1.509 Views
Preview:
TRANSCRIPT
Modelling Game Economy with Neo4j
Yan Cui (@theburningmonk)
1MILLION USERS
ACTIVEDAILY
250MILLION DAY
PERREQUEST
noSQL = MongoDB
stolefromloves loves
enemy
enemyA Good
Man Goes to War
appeared in
appeared in
appeared in
appeared in
Victory of the Daleks
appeared inappeared in
companion
companion
enemyappeared in
appeared in
planet prop
species
species
species
character
character
character
episode
episode
Graph DBs are great for modelling complex domains
Leonhard Eulerinvented Graph Theory in 1736
Leonhard Eulerinvented Graph Theory in 1736
(that’s 275 years before Edgar Codd formulated the relational model)
Find a walk through the city that would cross each bridge once and only once.
Eliminate features to leave just the land masses and the bridges.
Land masses became vertices, and bridges became edges.
location
500+ Spots
locationepisodic
Season 1 London
Season 2 Nan Jing
locationepisodicmulti-player
herebemonstersgame.com
iPad
buddies
locationepisodicmulti-playerRPG
4000 Items
800 Recipes
1500+ Quests
100+ Monsters
gamebalancing
itemPricing
itemPricing
itemPricing
itemPricing
I’ll just change this one thing…
manual game balancing is SLOW
it is REPETITIVE
ERROR-PRONE!SUBJECTIVE
there must be a better way...
Hello, Neo4j
BIG
FOO
Tca
tchi
ng
location baitattraction rate
catch rate
as a graph in Neo4j
Bigfoot
Alice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
lootscan_catch
Omar Lake
exists_in
nodes & edges can have!arbitrary properties
Bigfoot
Alice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
lootscan_catch
Omar Lake
exists_in
Strength = 502!Speed = 201!Intelligence = 184
Strength = 420!Speed = 210!Technology = 240
Bigfoot
Alice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
lootscan_catch
Omar Lake
exists_in CatchRate = 0.774
Bigfoot
Alice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
lootscan_catch
Omar Lake
exists_in
Buy Price = 20BN!Sell Price = 482 Gold!Sellable = true!…
Bigfoot
Alice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
lootscan_catch
Omar Lake
exists_inDropRate = 0.1
BigfootAlice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
loots
can_catch
Omar Lakeexists_
in
Yowie
Yetican_catch
can_catch
Apprentice’s Workshop
can_
mak
e
GoatHoney
Yeti Fur
requires
loots
mak
es
Alluring Goat Recipe
requires requires
Beeswax
loots
Bee Hiveharvests
McDonald’s Farm
sells
loots
Goat’s Milk
harvests
London
exists_in
Peryton Fawn Decoy
requires
Peryton Fawn Decoy
makes
BigfootAlice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
loots
can_catch
Omar Lakeexists_
in
Yowie
Yetican_catch
can_catch
Apprentice’s Workshop
can_
mak
e
GoatHoney
Yeti Fur
requires
loots
mak
es
Alluring Goat Recipe
requires requires
Beeswax
loots
Bee Hiveharvests
McDonald’s Farm
sells
loots
Goat’s Milk
harvests
London
exists_in
Peryton Fawn Decoy
requires
Peryton Fawn Decoy
makes
BigfootAlice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
loots
can_catch
Omar Lakeexists_
in
Yowie
Yetican_catch
can_catch
Apprentice’s Workshop
can_
mak
e
GoatHoney
Yeti Fur
requires
loots
mak
es
Alluring Goat Recipe
requires requires
Beeswax
loots
Bee Hiveharvests
McDonald’s Farm
sells
loots
Goat’s Milk
harvests
London
exists_in
Peryton Fawn Decoy
requires
Peryton Fawn Decoy
makes
BigfootAlice Lake
exists_in
Alluring Goat
can_attract
Bigfoot Toenail Clippings
Musket-teer Trap
loots
can_catch
Omar Lakeexists_
in
Yowie
Yetican_catch
can_catch
Apprentice’s Workshop
can_
mak
e
GoatHoney
Yeti Fur
requires
loots
mak
es
Alluring Goat Recipe
requires requires
Beeswax
loots
Bee Hiveharvests
McDonald’s Farm
sells
loots
Goat’s Milk
harvests
London
exists_in
Peryton Fawn Decoy
requires
Peryton Fawn Decoy
makes
gamebalancing(revisited)
impact analysis
What if I increase the price of
“White Bread”?
CRAFTS
RECIPE ITEMITEM
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)!
RETURN i, rel, wb
Node-[rel]->Node
CRAFTS
RECIPE ITEMITEM
IS_USED_IN
Node-[rel]->Node
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
RECIPE
White Bread
IS_USED_IN
ITEM
CRAFTS
MONSTERATTRACTS
RECIPE
IS_USED_IN
ITEM
CRAFTS
ITEMLOOTS
RECIPEIS_USED_IN
ITEMCRAFTS
IS_USED_IN
RECIPEIS_USED_IN
CRAFTS
RECIPE
White Bread
IS_USED_IN
ITEM
CRAFTS
MONSTERATTRACTS
RECIPE
IS_USED_IN
ITEM
CRAFTS
ITEMLOOTS
RECIPEIS_USED_IN
ITEMCRAFTS
IS_USED_IN
RECIPEIS_USED_IN
CRAFTS
MATCH!
(wb:BaseItem { Name:"White Bread"})!
-[rel:CRAFTS | IS_USED_IN*1..]!
->(i:BaseItem)!
RETURN i, rel, wb
RECIPE
White Bread
IS_USED_IN
ITEM
CRAFTS
MONSTERATTRACTS
RECIPE
IS_USED_IN
ITEM
CRAFTS
ITEMLOOTS
RECIPEIS_USED_IN
ITEMCRAFTS
IS_USED_IN
RECIPEIS_USED_IN
CRAFTS
RECIPE
White Bread
IS_USED_IN
ITEM
CRAFTS
MONSTERATTRACTS
RECIPE
IS_USED_IN
ITEM
CRAFTS
ITEMLOOTS
RECIPEIS_USED_IN
ITEMCRAFTS
IS_USED_IN
RECIPEIS_USED_IN
CRAFTS
RECIPE
White Bread
IS_USED_IN
ITEM
CRAFTS
MONSTERATTRACTS
RECIPE
IS_USED_IN
ITEM
CRAFTS
ITEMLOOTS
RECIPEIS_USED_IN
ITEMCRAFTS
IS_USED_IN
RECIPEIS_USED_IN
CRAFTS
scarcity analysis
How scarce is “Durian”
compared to “Dragonfruit”?
EXISTS_IN
FRUIT TREE SPOTFRUIT
FORAGES
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)!
WHERE! !
fruit.Name=‘Durian’ OR!
fruit.Name=‘Dragonfruit’!
RETURN fruit, tree, spot
Node<-[r1]-Node-[r2]->Node
EXISTS_IN
FRUIT TREE SPOTFRUIT
FORAGES
Node<-[r1]-Node-[r2]->Node
MATCH! !
(fruit)<-[:FORAGES]-(tree)-[:EXISTS_IN]->(spot)!
WHERE! !
fruit.Name=‘Durian’ OR!
fruit.Name=‘Dragonfruit’!
RETURN fruit, tree, spot
Durian
Dragonfruit
quest lines
AWARDS
QUEST ITEMITEM
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?
1. Price Items
2. Enrich Model
3. “Price” Quests
monster hierarchy
Catch me
No, catch ME
IS_USED_IN
CAN_ATTRACT
ITEMMONSTER
LOOTS
RECIPE
CRAFTSITEMMONSTER
MATCH! (monster1:Monster)-[:LOOTS]->(loot)! -[r:IS_USED_IN | CRAFTS*0..]->(bait)! -[:CAN_ATTRACT]->(monster2)!RETURN monster1, monster2
MATCH! (monster1:Monster)-[:LOOTS]->(loot)! -[r:IS_USED_IN | CRAFTS*0..]->(bait)! -[:CAN_ATTRACT]->(monster2)!RETURN monster1, monster2
Monster 1Monster 2
Quest 1 Quest 2
Unlocks
Unlocks
Requires
Monster 1Monster 2
Quest 1 Quest 2
Unlocks
Unlocks
Requires
successful catch = loot + gold
∑(Bait Price * Attraction Rate)
Input = Output( ∑(Loot Price * Drop Rate) + Gold ) * Success Rate
IS_USED_IN
CAN_ATTRACT
ITEMMONSTER
LOOTS
RECIPE
CRAFTSITEMMONSTER
NEW monster !
= More competitor for bait!
= Lower attraction rate for all monsters
Graph DBs are great for modelling complex domains
impact analysis
fraud detection
social networks
recommendation engine
Thank you!
@theburningmonktheburningmonk.comgithub.com/theburningmonk
top related