14
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Steamに登録されている大量のゲームから埋もれている名作を見つけ出す

Posted at

この記事はmohikanz Advent Calendar 2018 #2の18日目です。

Steamとは

Wikipediaより

Steam(スチーム)は、PCゲーム、PCソフトウェアおよびストリーミングビデオのダウンロード販売とハードウェアの通信販売、デジタル著作権管理、マルチプレイヤーゲームのサポート、ユーザの交流補助を目的としたプラットフォームである。

現在Steamで販売されているゲームは3万本以上存在し、Steam Direct(Steam Greenlight)の導入で販売するハードルも以前と比べて下がっており、販売数は年々増加しています。

プレイ可能なゲームが増えて嬉しい反面、Unityのアセットがそのまま売られるなど、いわゆる糞ゲーも多く登録されることとなっています。

今回はそれらのゲームに埋もれてしまって日の目を見ていない良ゲーを探したいと思います。

Steam APIを使用してユーザーによるレビュー情報を抜き出す

2018年12月時点でのやり方です。今後同じ方法は使えなくなる可能性があります。

概要

次の方法を用います。

  1. SteamのWebAPIで全ゲームのユーザーのレビューを取得してDBに格納
    • ユーザーはレビュー時にPositive or Negativeを付けることができるので、その情報を使います。
  2. 独自の計算式を定義して各ゲームにポイントを付けてランキング化する

環境

個人的に使い慣れているという理由で次の環境を使用します。

  • C#
  • SQLServer

全ゲームの取得

GetAppList を使用します。
これで全てのゲームのIDとタイトルがJSON形式で取得できます。

GetAppList
https://api.steampowered.com/ISteamApps/GetAppList/v2/
結果例
{  
   "applist":{  
      "apps":[  
         {  
            "appid":767330,
            "name":"Indoor Rock Climbing VR"
         },
         {  
            "appid":767340,
            "name":"Minion Forest"
         },
         {  
            "appid":767380,
            "name":"theHunter™: Call of the Wild - New Species 2018"
         }
         ...
      ]
   }
}

各ゲームの評価の取得

レビュー取得用APIを使用する

詳細は ユーザーレビュー - リストの取得

例えば次のURLのappidに10を入れればCounter-Strikeのレビューをいくつか取得できます。

URL例
https://store.steampowered.com/appreviews/{appid}?json=1&start_offset=0
結果例
{
	"success": 1,
	"query_summary": {
		"num_reviews": 1,
		"review_score": 8,
		"review_score_desc": "非常に好評",
		"total_positive": 64,
		"total_negative": 4,
		"total_reviews": 68
	},
	"reviews": [
		{
			"recommendationid": "xxxx",
			"author": {
				"steamid": "xxxxxx",
				"num_games_owned": 91,
				"num_reviews": 51,
				"playtime_forever": 25,
				"playtime_last_two_weeks": 0,
				"last_played": 1543494362
			},
			"language": "japanese",
			"review": "最高のゲームだ",
			"timestamp_created": 1537804715,
			"timestamp_updated": 1537804715,
			"voted_up": true,
			"votes_up": 1,
			"votes_funny": 0,
			"weighted_vote_score": "0.523809552192687988",
			"comment_count": 0,
			"steam_purchase": true,
			"received_for_free": false,
			"written_during_early_access": false
		}
	]
}

デフォルトだと言語や期間によって取得情報が制限されてしまうので、全て取得するには language=allday_range=9223372036854775807 のオプションが必要になります。
(参考:Steam API User Reviews Query)

ユーザーの評価であるPositive と Negative の総数が登録されているので目的は果たせそうですが、
目的を達成するのにより使い勝手が良さそうな後述のAPIが調査過程で見つかりましたので、今回はそちらを使用することとしました。

ヒストグラム取得用のAPI

Steamが「レビュー荒らし」に対策、ユーザーレビューにヒストグラム表示が追加

上記ページで紹介されていますが、2017年9月ごろからストアページでヒストグラムが表示されるようになりました。
CounterStrike_Graph.PNG

このヒストグラムを表示するためのAPIです。
以下URLでデータが取得できます。

取得用URL
https://store.steampowered.com/appreviewhistogram/{appid}
結果例
{
  "success": 1,
  "results": {
    "start_date": 1288569600,
    "end_date": 1544918400,
    "weeks": [],
    "rollups": [
      {
        "date": 1288569600,
        "recommendations_up": 21,
        "recommendations_down": 0
      },
     ...
    ],
    "rollup_type": "month",
    "recent": [
      {
        "date": 1542412800,
        "recommendations_up": 21,
        "recommendations_down": 1
      },
     ...
    ]
  },
  "count_all_reviews": false
}

必要な情報が含まれており、また期間別に分かれていてデータの取捨選択をしながら集計できるため、こちらのAPIを利用しました。

ランク付けのための計算をする

GetAppList で取得した全IDを回して appreviewhistogram にアクセスし、全ゲームのPositive, Negative情報を取得・DBに格納できました。
この情報を基に、良ゲーを探します。

なお、DBを作成したのは12月初旬であり、最近の情報は含まれていません。

試しにPositive,Negativeの総数を利用してみる

単純に考えると、「PositiveがNegativeよりも圧倒的に多いゲーム」は面白いゲームであり、「NegativeがPositiveより圧倒的に多いゲーム」はつまらないゲームと言えそうです。
ということで上記2つのゲームを試しに算出してみました。

Counter-Strike: Global Offensive は最近のアップデートで不評がかつてないほど増えていますが、リリースしてから全体的に好評が付いています。
逆にNo Man's Skyは最近は好評ですが、リリース当時かなり不評であり、それが尾を引いているようです。

上記から、アップデートによって大きく評価は変わるので最近のデータのみを使用したほうが信憑性が上がりそうではあるのですが、
今回の目的は埋もれているゲーム探しであり、最新のレビューがほとんどないものも含めて探したいため、突出したデータの除去のみを検討材料に加えます。

計算式を定義する

以下の条件を採用することとしました。

  • 基本的な計算式は Positiveの合計値 - Negativeの合計値 とする
  • 埋もれているゲームを探したいのでレビューが 100件以下 のゲームを対象とする
  • 特定期間のみに集中したレビューを弾くため、 PositiveNegativeの最大値はそれぞれ除外する

上記情報を統括したクエリが次のクエリとなります。

計算用クエリ
SELECT
        r.[AppId]
        , SUM(r.[RecommendationsUp]) - MAX(r.RecommendationsUp) - (SUM(r.RecommendationsDown) - MAX(r.RecommendationsDown)) AS point
        , a.[Name]
    FROM
        [dbo].[ReviewHistograms] AS r
        INNER JOIN [dbo].[AllGames] AS a
            ON a.[AppId] = r.[AppId]
    GROUP BY
        r.[AppId]
        , a.[Name]
    HAVING
        SUM(r.RecommendationsUp) + SUM(r.RecommendationsDown) < 100
        AND COUNT(r.[AppId]) > 10
    ORDER BY
        point DESC
;

結果

上の計算式で算出したポイントを基にランク付けしました。(DLC等は除外)

Rank タイトル ポイント 参考画像 リリース日
1 Corinne Cross's Dead & Breakfast 78 CorinneCross.jpg 2016年8月19日
2 Void Pyramid 77 VoidPyramid.jpg 2016年12月6日
3 Micron 76 Micron.jpg 2014年7月24日
3 Sword of the Samurai 76 SwordOfTheSamurai.jpg 1989年1月1日
3 Voidspire Tactics 76 VoidspireTactics.jpg 2015年11月3日
3 Higurashi When They Cry Hou - Ch.4 Himatsubushi 76 Higurashi.jpg 2016年10月14日
3 RetroMaze 76 RetroMaze.jpg 2018年5月22日
8 Zombie Bowl-O-Rama 74 ZombieBowl.jpg 2009年10月16日
8 Copy Kitty 74 CopyKitty.jpg 2018年4月20日

ひぐらし以外は聞いたことがないゲームばかりですね。
1位のグラフを見ると1箇所が大きく突出しているわけではなく、比較的理想的なグラフとなっています。
CorinneCross_Graph.PNG

終わりに

せっかくなので、1位のCorinne Cross's Dead & Breakfast を買ってプレイしてみました。(投稿時点未クリア)

あらすじを簡単に説明すると、旧友が亡くなり、その母親もショックで体調を崩して入院してしまったため、
代わりに1週間家を預かって生活する話です。
お見舞いしたり、お花を育てて売ってお金を稼いだり、料理をしたり、夜には幽霊と交流したりといった感じで、
ほのぼのADV系が好きな人には合いそうな感触です。
日本語訳はされていないですが、簡単な英語が多いので、今のところ英語ハードな私でもプレイはできています。

ウィンターセール(2018年は12/20~)も近いですし、興味のあるものがあったら購入対象として考えてみてはいかがでしょうか。
私的には1位のゲームも良かったですが、8位のCopy Kittyが「簡単に言うとカービィ+ロックマン」(レビューより抜粋)とのことであり、興味をそそられますね。

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?