drawing

Guild Wars 2™ (GW2) is a massively multiplayer online role-playing game (MMORPG) developed by ArenaNet and published by NCSoft and ArenaNet. The game takes place in the world of Tyria, with the re-emergence of a guild dedicated to fighting dragons. The Guild Wars series is known to break some classical aspects of MMOs. For example it features a wide solo component (the storyline adapts to the player's actions), or break the Tank/DPS/Healer triptych in player vs player (PvP) and player vs monster (PvM) mode.

In this post, I will talk about the Guild Wars 2 api developped by ArenaNet for the users, more specifically the python interface by JuxhinDB. This allows anyone to access the in-game live data like items current selling price, buying prices etc.. Lot of fan-made websites uses the gw2 api to automatize their tools (like https://www.gw2bltc.com, https://www.gw2tp.com or https://www.gw2spidy.com).

TL;DR

  1. The gw2 api can be used to get live trading market data.
  2. Having the buying/selling information allows to calculate profitability for any item (given the ressources price).

Jewelvry in guild wars 2

In my gamer life, my favourite games were always RPGs style games. That's why I was always attracted, and I was able to play some mmo like dofus and Final Fantasy XIV (check this community api).
My goal was always to focus on ressources gathering and crafting, I could not therefore miss the job system of GW2 so I became a jeweler. I realized quickly that it was not easy to seel my goods and make lot of money out of it.

The process to optimize the selling price was cumbersome because I had to check some website manually like https://www.gw2bltc.com/en/item/19697-Copper-Ore. So I decided to run some automatic simulations base from grabbed data.

gw2api usage

drawing

There is a community based interface in python by JuxhinDB. The installation is quite easy with python-pip.

In [1]:

We can create a new client to the api with,

In [2]:
# we will create a client like this
gw2_client = GuildWars2Client(version='v2')

This allow us to gather information from an object id. For example the id for a copper ore can be found in the official wiki on the right.

In [3]:
# get item by its id
id_object = 19697
gw2_client.items.get(ids={"%5d" %id_object})
Out[3]:
[{'name': 'Copper Ore',
  'description': 'Refine into Copper Ingots or use Tin to refine into Bronze Ingots.',
  'type': 'CraftingMaterial',
  'level': 0,
  'rarity': 'Basic',
  'vendor_value': 1,
  'game_types': ['Activity', 'Wvw', 'Dungeon', 'Pve'],
  'flags': [],
  'restrictions': [],
  'id': 19697,
  'chat_link': '[&AgHxTAAA]',
  'icon': 'https://render.guildwars2.com/file/6E17C5A65955239640743E48B30A3425FACA5D02/65925.png'}]

A really important feature here is the possibility to get the trading market data for this item,

In [4]:
# access data from the trading market
gw2_client.commerceprices.get()
# check for a specific item
id_object = 19697
gw2_client.commerceprices.get(ids={"%5d" %id_object})
Out[4]:
[{'id': 19697,
  'whitelisted': True,
  'buys': {'quantity': 1567037, 'unit_price': 69},
  'sells': {'quantity': 842680, 'unit_price': 87}}]

Note:
Be careful to not overload the server by sending too many requests.
If so, you will get the response "HTTP 429 Limit Exceeded".

Profitability calculator

Using the trading market data, it is possible to get the optimal object to sell, given the current price of the gathered ressources. For example a copper earring (master) can be crafted using : x1 Adorned Jewel, x1 Copper Setting (x4 Copper Ores) and x1 Copper Hook (x4 Copper Ores). We can calculate the resulting price for a fine Tiger's Eye Copper Stud for example,

In [5]:
# Tiger's Eye price
id_object = 24467
tiger_eye_price = gw2_client.commerceprices.get(ids={"%5d" %id_object})[0]['sells']['unit_price']   
# copper price
id_object = 19697
copper_price = gw2_client.commerceprices.get(ids={"%5d" %id_object})[0]['sells']['unit_price'] 
# craft price
craft_price = tiger_eye_price + 8*copper_price

The rentability of this item is simply the actual price divided by the crafted price,

In [6]:
Tiger's Eye Copper Stud
Rentability is : 47.52%

Finding the id of an item manually is cumbersome. Hopefully, some good guys already created a json file with all the matching id and name : http://api.gw2tp.com/1/bulk/items-names.json.

In [7]:
# loading the json file
with open('data/guild_wars/items-names.json') as data_file:    
    data = json.load(data_file)['items']

The following object was designed to calculate the profitability of a given accessory:

In [8]:

For example to get the current profitability of a fine Amber Copper Stud,

In [9]:
t = cAccessory(gem='Amber', ore='Copper', accessory_type='Stud', mastercraft=False)
print("Rentability for %s is : %1.2f%%" %(gw2_client.items.get(ids={"%5d" %t.aId})[0]['name'], t.mRentability()))
print("Gain for %s is : %3d br" %(gw2_client.items.get(ids={"%5d" %t.aId})[0]['name'], t.mGain()))
Rentability for Amber Copper Stud is : -733.00%
Gain for Amber Copper Stud is : -733 br

The following algorithm can be used to check all jewelry profitability, by specifying from which gems/ores/accessory to choose from:

In [10]:
-------
Accessories:
Sunstone Gold Ring  , marginal gain: 1708
Sunstone Gold Earring  , marginal gain: 1426
Amethyst Gold Ring m, marginal gain: 420
Peridot Gold Ring m, marginal gain: 353
Peridot Gold Earring  , marginal gain: 246
Amethyst Gold Amulet m, marginal gain: 219
Amethyst Gold Ring  , marginal gain: 210
Carnelian Gold Earring  , marginal gain: 185
Topaz Gold Ring  , marginal gain: 184
Amethyst Gold Amulet  , marginal gain: 152
Carnelian Gold Earring m, marginal gain: 147
Sunstone Gold Amulet  , marginal gain: 7
Peridot Gold Ring  , marginal gain: -76
Topaz Gold Amulet m, marginal gain: -79
Peridot Gold Amulet  , marginal gain: -127
Lapis Gold Ring m, marginal gain: -147
Amethyst Gold Earring  , marginal gain: -195
Amethyst Gold Earring m, marginal gain: -210
Peridot Gold Amulet m, marginal gain: -220
Lapis Gold Earring  , marginal gain: -235
Spinel Gold Earring  , marginal gain: -266
Lapis Gold Ring  , marginal gain: -283
Spinel Gold Ring  , marginal gain: -285
Topaz Gold Ring m, marginal gain: -289
Lapis Gold Amulet  , marginal gain: -303
Topaz Gold Earring  , marginal gain: -324
Spinel Gold Earring m, marginal gain: -387
Peridot Gold Earring m, marginal gain: -389
Topaz Gold Amulet  , marginal gain: -395
Topaz Gold Earring m, marginal gain: -398
Spinel Gold Ring m, marginal gain: -407
Lapis Gold Earring m, marginal gain: -417
Spinel Gold Amulet  , marginal gain: -423
Sunstone Gold Ring m, marginal gain: -452
Spinel Gold Amulet m, marginal gain: -456
Lapis Gold Amulet m, marginal gain: -564
Sunstone Gold Amulet m, marginal gain: -1348
Sunstone Gold Earring m, marginal gain: -1544

The Sunstone Gold Ring seems to be the best and more profitable item. Of course, the marginal gain cannot be the only factor, the frequency of sold item is also important for example.

Conclusion

We saw that using the gw2 api allow to get the live market price of any items. The algorithm I designed allowed me to optimize my selling price, hence gaining lot of money in the game.

I think sharing ther live game data with the community is amazing, a big thumbs up to the GW2 dev team for that! It is sadly not so frequent in the video game industry, because too many are ultranationalist-centered (hello japanese games!)...

To go further

I did not discuss it here but it is of course possible to authenticate to the api. This to allow the user to access its character content like the inventory, its guild etc...

It can be done with,

client = GuildWars2Client(api_key='API_KEY_VALUE_HERE')