Skip to main content

ラグナロクオンラインの露店取引ログを返すAPIを作った

概要

ラグナロクオンライン(RO)という、2002年リリース(!)の老舗のMMORPGがあります。ドット絵のかわいさが特徴的なMMOです。

ROには露店システムというものがあります。プレイヤーはゲーム内でお店を開くことができ、自分が所有しているアイテムに自分で値段を設定して他のプレイヤーに売ることができます。

同じアイテムにはだいたいどのプレイヤーも似たような値段を付けるようになり、これが相場として形成されるわけですが、相場は時期によって大きく変動します。露店が並んでいる街を歩き回って掘り出し物を探すのも楽しいですし1、今後もっと高くなると考え、アイテムを安い時期に買って高い時期に売ることで差益を狙うというのもROの一つの醍醐味です。

何のアイテムがいついくらで売れたという露店の取引履歴は公式のツールで提供されています。このツールは各アイテムについて最新1000件の取引履歴を表示します。露店に出すときは、だいたいこのツールの履歴と他の露店が付けている値段を見ながら適当な値段を設定します。

このデータ、データ分析屋としては貯めておいて長い時期で価格変動を見てみたくなります。というわけで、取引履歴を定期的にクローリングして貯めておき、GETすると過去の履歴を返すようなAPIを作りました。(自分用なので公開はしていません)

技術構成

構成図はこちらです。

  • VPS
    • Pythonで定期的に公式ツールをクローリングし、JSONで保存してデータをCloud Storageにアップロード
      • 負荷をかけないようにするため、クローリングには十分なスリープを入れている
  • Google Cloud + Terraform
    • Cloud StorageにアップロードされたらCloud Functionsを起動してBigQueryテーブルに書き込む
      • BigQueryに直接書き込まずにCloud Storageを前段に置いているのは、クローリングしたデータの形式が変わっていてBigQueryへの書き込みでエラーになる場合にデータが消失しないようにするため
    • Cloud Functions(認証付きHTTPエンドポイント) + FastAPI(Python)でAPIエンドポイントを用意
      • GETでリクエストしたらBigQueryをクエリする

クローリングはVPS (cron), データ基盤はBigQuery + Terraformというオレオレ定番パターンです。以前に作ったニコニコ動画の再生数推移のデータ基盤と同じパターンです。

なお、公式ツールは常に最新の1000件のログを表示するため、前回のクローリングの取引ログと重複します2。こういう場合、重複を許して全件放り込むBigQueryテーブルに加え、重複を除いたユニークな取引ログを入れるBigQueryテーブルを用意して、前者にappendされるたびにスキャンして後者を全件洗い替えるのが定番です3。ですが、自分一人しか使わないアプリケーションのためにスキャンする方がかえってコストがかかるので、重複したままのBigQueryテーブルだけ作り、クエリするときにSQLで重複を取り除くようにしています。

使ってみる

月夜花カードというアイテムのレコードをAPIから取得してみます。

最初のレコードは、2024/7/18 18:16に1.3G Zeny(Zenyは通貨の名前。1G Zeny = 1000 M Zeny = 1000^2 K Zeny = 1000^3 Zeny)で1個取引が成立したというレコードです。

# 最新の3件の一部のkeyのみ抜粋
[
  {
    "datetime": "2024-07-18T18:16:00+09:00",
    "world": "Noatun",
    "item_id": "4131",
    "item_name": "月夜花カード",
    "price": 1300000000,
    "count": 1
  },
  {
    "datetime": "2024-07-10T19:38:00+09:00",
    "world": "Noatun",
    "item_id": "4131",
    "item_name": "月夜花カード",
    "price": 1000000000,
    "count": 1
  },
  {
    "datetime": "2024-06-29T15:43:00+09:00",
    "world": "Noatun",
    "item_id": "4131",
    "item_name": "月夜花カード",
    "price": 1000000000,
    "count": 1
  }
]

全部プロットしてみるとこんな感じです。価格変動が激しいですね。

APIで整形済みのデータが得られるのも分析的に楽ですね。作ったはいいものの、何に使えるかは分かりませんが…。

© Gravity Co., Ltd. & Lee MyoungJin(studio DTDS). All rights reserved.
© GungHo Online Entertainment, Inc. All Rights Reserved.
当コンテンツの再利用(再転載・配布など)は、禁止しています。


  1. プロンテラの露店街はROの華ですね。 ↩︎

  2. 例えば前のクローリングから新たに100件のログが増えていた場合、900件分のレコードが二重にカウントされることになります。 ↩︎

  3. 例えば: BigQuery にデータを差分ロード(UPSERT)する方法まとめ ↩︎