またろうのSteamworksブログ

Steamworks(Steam Direct)についての開発ネタを纏めています。

Steam旧正月セール続報(ゲーム購入者向け情報)



f:id:tsukinowaapp:20190205235038p:plain

前回、Steamにて旧正月セールが実施されるよって記事を書きました。
tsukinowa.hatenablog.jp
今回はゲームユーザー(購入者)向けの情報です。

3000円の購入で500円の割引セール!

カートにて3000円以上の購入で自動的に500円の割引が適用されます。
(ギフトとゲーム内購入は適用外)
ちなみにパートナー(販売者)は通常通り収益を受け取ることができます。

ポイントによる特典も

期間中にゲームを購入するとポイントが付与され、交換で様々なアイテムと交換することができます。
アイテムとはバッジ、プロフィール、割引券などです。
こちらの割引券もValveが負担するので、パートナー(販売者)は通常通り収益を受け取ることができます。

Steam旧正月セールが実施されるよって話



Steamにて2月初旬から旧正月セールが実施されます。
開発者のかたは割引の設定が可能になってますので
「アプリとパッケージ」の「セール承認」から割引率を設定してください。
(ちなみに詳しい期間については機密事項になってます)
セールについては昔の記事にも書きましたのでご確認ください。
tsukinowa.hatenablog.jp

Steam DirectとSteamworksの違いって?



Steam DirectとSteamworksの使い分けがいまいち不明瞭だったので纏めてみます。

Steam Directとは

f:id:tsukinowaapp:20181028210852p:plain
簡単に言いますと「Steamを使って自分の作ったアプリを直接販売すること」です。
Steamがアプリを販売する場所を提供してくれているということですね。

Steamで販売するまでに実施することは

  • デジタル書類の入力
  • 登録料 (後に回収可能) の支払
  • ゲームをアップロード

です。(細かく書くとやるとこは一杯ありますが。)

Steamworksとは

f:id:tsukinowaapp:20181028210719p:plain
対してSteamworksとは「Steamで配信するゲームで利用できる一連のツール群」のことを指します。
機能として

  • アカウントに紐づくイベントや実績の管理
  • アイテム課金
  • アンチチート技術
  • ユーザー生成コンテンツの管理
  • 各ユーザー用クラウドストレージ

といったところでしょうか。

実質はシームレス

実質どちらか一方がないと成立しないものなので
ほぼ同じ意味かとも思います。
あまり区別して考えなくてもいいかもしれませんね。

Steamセールス割引の適用方法


どこから入力する?

Steamは季節ごとにセールスをやってます。
でもSteamworksの管理画面でどこから設定するのか分からないかと思います。

実はセールスの時期が近づくと、開発者アカウントのメールアドレス宛にセールスの情報が届きます。
そのメールに割引を設定するためのリンクが付与してあるという訳です。

f:id:tsukinowaapp:20181024053746p:plain

割引画面の下の方に入力フォームがありまして、
「適用」ボタンの左隣から割引率を入力して「適用」ボタンを押下すると
現在予定されているセールスに対して纏めて設定できます。

後は「送信」ボタンで設定完了です。

実は機密扱い

割引画面にも書いてありますが機密扱いです。
いつ何のセールスを実施するかは割引画面に書いてありますが
公式に公開するまでイベントの詳細を書くなとありますので
黙っておいた方が良いでしょう。_(:3 」∠)_

Steam PC カフェプログラムと商用パッケージ


Steam PC カフェって何だ?

PC Café Games on Steam

SteamにはカフェPC用(サイト)ライセンスというものがあります。
(一般的には漫画喫茶のようなネットカフェですが、Steamの説明では「インターネットアクセスを提供するロケーションであればどこでも商用サイトになり得ます。」とあります。)

support.steampowered.com

これは何かというと、購入したゲームのライセンス数に応じて、ネットカフェのPC上で起動できるゲームの数を制御してくれる仕組み(サイトライセンスサーバー)を提供してくれるというものです。

サイトライセンスサーバーの仕組み

例えばネットカフェに10台のPCがあるとして、World of Warshipsのライセンスを5保有しているとします。

f:id:tsukinowaapp:20180909021122p:plain

保有しているアカウントはサイトライセンスサーバーにて管理しており、
World of Warshipsを購入していないプレイヤーはサイトライセンスサーバーが一時的にライセンスを付与することで
無料にてゲームをプレイすることができます。
(店舗が設定しているカフェの利用料は考えないものとします)

ライセンスが上限に達した状態で、World of Warshipsを購入していないプレイヤーがプレイしようとすると
「利用可能なライセンスがありません」というメッセージが表示されてリジェクトされます。
但し、World of Warshipsを購入済のプレイヤーであれば
サイトライセンスの状態に関係なくプレイすることができます。

ちなみに、支店を複数保有している場合はサイト間でSteamコンテンツを共有できるのでアカウントを一括管理できます。
(サイトライセンスサーバーは各施設に必要です)

Steamサイトライセンスを得るには

Steamworks開発者アカウントが必要です。手順はこちら。
tsukinowa.hatenablog.jp
f:id:tsukinowaapp:20180909012340p:plain
Steamworksにログインして、メインページ右下の「資格の追加」を押下します。
f:id:tsukinowaapp:20180909012457p:plain
すると「Steam サイトライセンス」の申し込みボタンがありますので、押下して
後はSteam サイトライセンス契約にサインする画面が表示されますので
所定の項目に名前を入力して手続きする流れになります。

Steamサイトライセンスの注意点

下記の「Steamゲーム開発者がすることは?」の通り、必ずしも一般ストアで購入できるゲームがサイトライセンスとして購入できる訳ではないので
「Steamの最新ゲームが遊べる!」訳ではないことに注意が必要です。
サイトライセンスとして購入できるゲームは以下のURLにあります。
PC Café Games on Steam
見る限りPUBGやDead by Daylightは配布してないっぽいですね。_(:3 」∠)_

Steamゲーム開発者がすることは?

Steamサイトライセンス用に配布するゲームは、ストアにて一般ユーザー向けに配布しているゲームとは別管理となっていまして
商用ライセンスを付与する必要があります。
(付与するまでサイトライセンス用には販売されません)

f:id:tsukinowaapp:20180909013818p:plain
Steamworksのホーム画面からゲームを選択してから「商用パッケージを作成」を押下
f:id:tsukinowaapp:20180909013916p:plain
売り切りにするか、月極にするかを選択できるのでどちらかをチェックして「商用パッケージを追加」
f:id:tsukinowaapp:20180909014245p:plain
するとアプリ管理に商用パッケージという項目が追加されます。
項目右端から2番目の$£マークを押下
f:id:tsukinowaapp:20180909014526p:plain
価格を決めたら画面下の「価格を決定」ボタンを押下します。
f:id:tsukinowaapp:20180909014651p:plain
するとステータスがViveの承認待ちになります。
1日ほど待つと承認済みになりますので、リリース可能となります。

ちなみに、ストアパッケージを無料で公開している場合は、商用パッケージも無料で固定となります。
f:id:tsukinowaapp:20180909015137p:plain

PCカフェオーナーの利点

  • 設置しているPCの台数分ライセンスを買う必要がなく、稼働率を見ながらライセンス数を調整できる。
  • サイトライセンスを一括管理できるので、ライセンスの余剰が発生しにくい
  • 人気ゲームでもライセンス購入時に在庫切れが発生しない。

ゲーム開発者の利点

  • ネットカフェに導入してもらうことで目に触れる機会を増やすことができる。
  • 人気ゲームであれば月極ライセンスで安定収入が狙える。

こんな所でしょうか。

日本でサイトライセンスサーバーを導入しているカフェは...

ググってもそれらしい情報は得られませんでした。orz
もし導入しているネットカフェがあったら教えて頂けると有難いです。

Steamで自分の開発者 & パブリッシャーホームページ(クリエイターホームページ)を持つ方法


結構イケてるクリエイターホームページ

f:id:tsukinowaapp:20180825125420p:plain

Steam開発者のアカウントがあれば
クリエイターホームページを持つことができます。
ここで自身が作成したゲームをカタログ表示したり
フォローしてもらうことで新作ゲームの通知が容易になったりします。
(ちなみにクリエイターホームページは8/25現在ベータ版です。仕様が変更になるかもしれません)

Steam Creator: Tsukinowa App

設定手順

先ずはログインして「アプリとパッケージ」タブの「クリエイターホームページ設定」を押下

f:id:tsukinowaapp:20180825132031p:plain

画面の「会社名のコミュニティグループを作成してください。」のところにリンクがありますので押下

f:id:tsukinowaapp:20180825132408p:plain

「グループ名」「省略名」「グループリンク」をそれぞれ入力します。
「使用状況の確認」ボタンを押下して入力が被っていないかチェックします。
「公開グループ」にチェックを入れて、「作成」を押下

f:id:tsukinowaapp:20180825150630p:plain

内容確認したら、「作成」を押下します。

f:id:tsukinowaapp:20180825150928p:plain

グループ管理人の詳細設定画面になります。
「略名」と「カスタムURL」は既に設定されている筈なのでそのまま
「見出し」「簡単な自己紹介」を入力
「言語」「国」を任意に設定

「グループに関連付けるゲームを検索」にてゲーム名を英文字入力すると
「ゲームを検索」フォームに近い名前のゲームリストがドロップダウン表示されます。
一覧から選択すると「関連付けられたゲーム」に自身のゲームが紐付けされます。

f:id:tsukinowaapp:20180825151901p:plain

アバター」でホームページの左上に設定するアイコンを指定します。
184pxのアイコンをアップロードすれば残りも自動的に作成されます。
「ファイルを選択」で指定して「アップロード」押下で更新されます。

自身が所有しているブログやサイトがあれば「ウェブサイト」にて設定します。

完了したら「変更を保存」を押下

ここまで入力が完了したら、一旦ホームページの設定に戻って
「ここに戻って、右側のドロップダウンからグループを選択し、」
の「ここ」がリンクになっていますので押下します。

f:id:tsukinowaapp:20180825152558p:plain

すると、「クリエイターページにリンクする」の欄がドロップダウンで選択できるようになっている筈なので
先ほど作成したグループ名を選択し、確認したら「保存」を押下します。

f:id:tsukinowaapp:20180825152852p:plain

以上のような表示が出るので暫く待ちます。
完了するとリリースしたゲームアプリのストアにある、開発者リンクがクリエイターホームページのURLへ差し変わります。

f:id:tsukinowaapp:20180825153651p:plain

リンクをクリックするとクリエイターホームページへ遷移するようになります。

Steamのランキング機能を実装する



今回はSteamのランキング機能の実装について書きます。

ランキングはSteamクライアント→コミュニティでゲームを選択して
右上のデータを表示からグローバルランキングを選択すると表示されます。

f:id:tsukinowaapp:20180817081918p:plain

また、ゲーム上に実装することも可能です。

Steamworks側の設定

ホーム→アプリ管理(アプリデータ管理)のデータ&実績タブから
「ランキング」を選択

f:id:tsukinowaapp:20180817095411p:plain

「ランキングを追加」に入力します。

名前(Name):APIから呼び出すときの名前を入力(API名)
コミュニティ名(Community Name):コミュニティに表示するときの名前を入力
並べ替え方法(Sort Method):並べ替え順を指定します。(得点が多い順なら降順)
表示タイプ(Display Type):単位を数字、秒、ミリ秒から選択します。
書き込み (Writes):「信頼済み」に設定するとクライアントから設定できなくなり、WebAPIからのアクセスのみ許可するようになります。(基本は設定しません)
読み取り (Reads):「フレンド」に設定するとゲームからはフレンドデータのみしか読み込めなくなります。(基本は設定しません)

全て設定したら右側の「作成」リンクをクリックでランキングが作成されます。
「ランキング を作成しました。このページを更新すると以下に表示されます。」と表示されたらリロードします。
画面下の「ランキング:」に黒帯で作成したランキングが表示されている筈です。

Unity側のコーディング

Google検索などで直接このページにいらしたかたは下のリンクを確認して
Steamworks.NETの設定まで済ませておいてください。

tsukinowa.hatenablog.jp

最も楽な方法

assetstore.unity.com

一番楽な方法は上記アセットを取り込んで、下記コードを追加します。
但し上記のアセットは有料($1.99)です。

using EasySteamLeaderboard;
EasySteamLeaderboards.Instance.UploadScoreToLeaderboard("XP Rank", score, (result) =>
        {
            if (result.resultCode == ESL_ResultCode.Success)
            {
                Debug.Log("Succesfully Uploaded!");
            }
            else
            {
                Debug.Log("Failed Uploading: " + result.resultCode.ToString());
            }
        });

EasySteamLeaderboards.Instance.UploadScoreToLeaderboardの
第一引数にリーダーボードのAPI
第二引数にスコアなどの設定したい値
第三引数に更新後の処理を書きます。

ゲーム上にランキングを表示する

Easy Steam Leaderboardsにはランキング表のPrefabがあるので、それを取り込むだけでOKです。
但し、見栄えを修正したり、不要な機能を取っ払ったりという修正は必要です。
(特に任意のスコアを送信できてしまう機能は必ず削除してください)

f:id:tsukinowaapp:20180817142613p:plain

自分で書こうとすると…

Statsの更新に比べると、それなりに手間です。
SteamUserStats.FindLeaderboardでリーダーボードがあるか検索し、
コールバックでSteamLeaderboard_tというインスタンスを生成してから
SteamUserStats.UploadLeaderboardScoreを呼び出す、という処理を書かないといけないのですが
結局EasySteamLeaderboardのソースを部分的にパクる感じになりますし、
抜粋して掲載するのもあまり宜しくないので
2ドル払って数行で済ました方がいいかなと思ってしまいます。

HTML5の場合は?

greenworksがリーダーボードに対応していないので、現状では方法がありません。orz

Steam用アプリをローカライズする際の注意点



Steamにて全世界にゲームを配信するのですから、
ハナから日本人向け販売しか想定していない、とか
下手にローカライズするとゲームの雰囲気が壊れる、みたいな特別な事情が無い限り
ローカライズは避けて通れないかと思います。

ローカライズとは?

簡単に言うと、使う人のネイティブに合わせてインターフェイス(ボタンや項目など)の言語を切り替えることです。
Steam上では大きく分けて3種類あります。

  • インターフェース - すべてのゲーム内テキスト (つまり、メニューやUI 等) がその言語で表示されます。
  • フル音声 - 全ての音声による会話がその言語で翻訳され利用可能なことを示します。基本的には声優による会話です。
  • 字幕 - 字幕がその言語によってすべての会話シーンで表示されることを示します。

ストアで表示する内容と、アップロードしたアプリの対応が完全に合致していないとアプリレビューで却下されてしまいます。

どの言語まで対応する?

Steamでは「Steam ハードウェア & ソフトウェア 調査」というデータを公開しています。
下の画像が2018年7月現在の言語設定データです。

f:id:tsukinowaapp:20180815153543p:plain

当然ながら英語が1位、その後に簡体字(中国語)、ロシア語と続いています。
どの国へ売り込むかにもよりますが、英語くらいは対応した方が良いかと思われます。
ulxrdの場合はアブストラクトゲームということもあって、英語の他にドイツ語対応もしました。

翻訳サービスを利用する

自身が言語に堪能でしたら苦労はないですが、
私を含めて不得手な人は多いと思います。
そんな時に利用するのが翻訳サービスです。

gengo.com

私がよく利用するサービスはGengoです。
とにかく安くて速いのが魅力です。
表向きの所要時間は翻訳前の文字数で変化しますが(概ね5~8時間)
メール文書レベルであれば、早いときは10分程度で完了することがあります。

但し、翻訳後の文書の質は翻訳担当者によってまちまちなので、
受け取ったら一旦Google翻訳などで、ケアレスミスが無いかチェックすることをお勧めします。
(結構日本語分かってない感じの翻訳が返ってくることがあります)
レビュー後の対応も、翻訳担当者によって対応の質にバラつきがあるように感じます。
(丁寧な対応をする人もいるので、そういう人は「お気に入り」に入れておくことをお勧めします)

ちなみにGengoは日本語→ドイツ語(直接翻訳)に対応していないので
trans-itを使いました。
translate-it.jp

価格が+消費税されるので若干割高なのと、翻訳に日数が掛かりますが
メールの対応は丁寧な感じです。

実装の注意点

ローカライズの実装ですが、一つ注意点があります。
それは「Steamテストチームが確認できる実装をする」ということです。
実装の仕方として、

  • 設定画面(Config)を設けて言語を選択できるようにする
  • SteamworksAPIで、Steamクライアントの言語設定を拾って切り替える
  • 言語ごとにデポを用意する

いずれかになると思いますが、
ここで「OSあるいはブラウザの言語設定を拾って切り替える」ような実装をしていると
Steamテストチームは特定の環境(おそらく英語)しか持っていないので
ローカライズされているか確認が取れず、却下されてしまいます。

スマートフォン用アプリをSteam用アプリにコンバートする際は注意が必要です。

SteamストアページのPVが驚異的だという話


SteamでPVはどのぐらい出るのか

SteamworksのストアページにはGoogle Analyticsが仕込めるのですが
アプリを公開してからの数字を晒してみます。

f:id:tsukinowaapp:20180810091141p:plain

7月20日に近日公開としてストアページを上げました。
公開直後に150PVを出したあと、ずるずると下がっていきますが
8月2日19時に本公開すると1日400PVを超えました。
その後は落ち着いて1日250~200PV程度になってます。
(8/14時点でも大体同じ数字で推移しています)

広告も一切打たないで、自前のtwitterアカウントで何度かツイートした程度でこの数字です。
Steamがどれだけ注目されているか理解してもらえると思います。

恐らくスマホアプリなどでゲームを公開したことがある人なら驚異的な数字だと分かる筈です。
GooolePlayやら、(Apple)AppStoreではこんな数字出ないです。
全く同じものを作ったとしても、個人さんのアプリだと1日どころか1週間10PV行かないです。
(最も作った人のネームバリューにもよると思いますが)

何故かというと、スマホ系ポータルには新着を優先的に取り上げる機能がないのと、
人気のあるゲームを優先的に表示する結果、人気のないゲームが表示されなくなる事象が起こるからです。
だから企業さんは初動で大量の広告を打つのですが
個人さんは投資金額が限られていますし、幾ら売れるか分からないゲームに広告打てる訳も無いので必然的に埋もれていきます。
「どうぶつタワーバトル」みたいに何かのはずみでバズって売れるケースもあるのですが
そういうのは年に1本出るか出ないかでしょう。
昔はAppBankやアンドロイダーなど無償で取り上げてくれるサイトがいくつもありましたが今は殆ど無くなっています。
当然ですが企業さんが多大な掲載料払ってくれるので
一個人のアプリを工数かけて掲載する義理なんてないのです。

Steamはどうでしょうか?
ストアを近日公開にした時点で、
特に頼んでいないのに各国にあるレビューサイトにスレッドが立ちます。
(恐らく機械的に収集して立てていると思われます)
ゲームの名前を特徴的にして、ググってみると良くわかります。

さらにリリースした時点で、新着ゲームをツイートしてくれる人がいます。
また前述の通り、新着ゲームとしてトップページの近いところから一定期間リンクしてもらえるのでPVが跳ね上がります。
後はストアページでいかに面白そうかアピールできるかですが...

ちなみに副産物として
「うちのサイトで掲載してやるからお金頂戴」とか「うちのストリームで放送するからゲームタダにして」的なメールも来るようになりますがはてさて...


Steamworks APIを導入する(Steam実績を実装する:HTML5編)



今回はHTML5にてSteamworks APIを導入する手順を書きます。
HTML5を実行ファイル化する場合、NW.jsかElectronを使うことになりますが
HTML5ベースのオーサリングツール(ツクールMVなど)も自力でJavaScriptの編集ができるなら対応可能かと思います。

f:id:tsukinowaapp:20180808225254p:plain

HTML5の場合はgreenworksを使います。

github.com

組み込み手順

上記リンクより最新のzip(NW.js用とElectron用がOSとCPU種別ごとにあります)と
後で使うことになるのでSource code (zip)をダウンロードしておきます。

また、Steamworks SDKも用意しておいてください。

用意できたら以下のパスで設置します。

Windowsの場合

|-- greenworks.js
|-- index.html
|-- lib
|   |-- greenworks-win32.node
|   |-- sdkencryptedappticket.dll
|   `-- steam_api.dll
|-- package.json
`-- steam_appid.txt

win32とwin64がありますが、win32が無難(より多くの人が遊べる)でしょう。

Macの場合

|-- greenworks.js
|-- index.html
|-- lib
|   |-- greenworks-osx64.node
|   |-- libsdkencryptedappticket.dylib
|   `-- libsteam_api.dylib
|-- package.json
`- steam_appid.txt

libというフォルダを作って、その中にnodeファイルとdll(dylib)ファイルを入れます。
dll(dylib)ファイルはそれぞれ以下の場所にあります。
sdk/redistributable_bin/
sdk/public/steam/lib/

index.htmlのあるフォルダにsteam_appid.txtを入れます。
これはUnity編同様、AppIDのみを記述しておきます。

var greenworks = require('./greenworks.js');
greenworks.init();

後はゲーム内のjsファイルにて、上記のコードを記述して初期化します。

これで動いてくれたら何の苦労もないのですが...

実際にはgreenworks.init();でエラーになると思います。
(もしエラーが出なかったら「greenworksの再コンパイル」は読み飛ばしてください)

greenworksの再コンパイル

どうも配布されているgreenworksのnodeファイルの作りが宜しくないらしく、そのままでは使えません。
なのでSource codeを使ってnodeファイルを新しく生成します。

前準備

以下の環境が必要です。

Windowsの場合

python 2.7.x(3.x系は使えません)インストールしたらPathを通しておくこと
Visual Studio 2015以降(UnityをインストールしてあるならVisual Studio 2017も一緒に入ってる筈)
node.js(最新版)

Macの場合

python 2.7.x(3.x系は使えません)インストールしたらPathを通しておくこと
Xcodeコマンドラインツールがインストールされていること)
node.js(最新版)

greenworksソースコードとSteamworks APIの統合

greenworksソースコードの中に、Steamworks APIのソースをマージする必要があります。

greenworks/srcフォルダの中にsdk/public/steamフォルダをコピー
greenworks/depsフォルダの中にsteamworks_sdkフォルダを作成
greenworks/deps/steamworks_sdkフォルダの中にsdk/redistributable_binフォルダとsdk/publicフォルダをコピー
sdk/publicフォルダで必要なのはsdk/public/steam/libフォルダなので、sdk/public/steam直下にあるhファイル等は無くてもOK)

階層的にはこうなります。

deps
|--cpplint
|--misc
|--zlib
|--steamworks_sdk
|   |--redistributable_bin
|   `--public
|         `--steam
|               `--lib
src
|-- api
|-- steam
|   |-- lib
|   |-- steam_api.h
|   |-- etc....h

ビルドコマンド

以下をコマンドプロンプト(ターミナル)から実行します。

npm install -g nw-gyp
cd (greenworks直下のパス)
nw-gyp configure --target=0.31.5(NW.jsのバージョン) --arch=(x64 または ia32)
npm install nan
nw-gyp build --target=v10.6.0(Node.jsのバージョン)

npm installは実施済みなら省略できます。
Macの場合はnpm installのところでsudo npm installとしないとエラーになる場合があります。
また、モジュール(hファイル、dllファイルなど)が足りない的なエラーが出ることもあるので
ファイルパスを見て適宜追加してください。

これでgreenworks/libフォルダの中にnodeファイルが生成されている筈です。

コーディング

初期化

var greenworks = require('./greenworks.js');
if (!greenworks) {
    log('Not support platform');
} else {
    if (!greenworks.init()) {
        log('Error on initializing steam API.');
    }
}

処理を行うjsファイルの冒頭に記述します。
greenworks.init();の処理にて正常ならtrue、エラーならfalseが返ってきますので
拾ってエラー処理を書いた方がいいでしょう。

ユーザー名の取得

var cSteamId = greenworks.getSteamId();
var userName = cSteamId.screenName;

Statの呼び出し

greenworks.storeStats(function () {
    wCount = greenworks.getStatInt("win");
}, function () {
    log("Error on connect steam.");
});

greenworks.storeStatsを呼んでからでないと取得できないようです。
第一引数で正常だった場合の処理をfunctionで記述し
第二引数でエラーだった場合の処理を書きます。

greenworks.getStatIntでInt型
greenworks.getStatFloatでFloat型が取得できます。

Statの書き込み

greenworks.setStat("win", wCount);

第一引数でAPI
第二引数で書き込む値を設定します。

実績の獲得

if (5 <= wCount) {
    greenworks.getAchievement("win_5", function (isAchieved) {
        if (!isAchieved) {
            greenworks.activateAchievement("win_5", function () { });
        }
    });
}

greenworks.getAchievementで達成フラグの状態を確認して
greenworks.activateAchievementにて更新しています。
第一引数で実績のAPI
第二引数のfunctionで後続処理を書きます。

参考文献

ここにFAQとビルド手順とAPI リファレンスがあります。

github.com


Steamworks APIを導入する(Steam実績を実装する:Unity編)



今回はUnityにSteamworks APIを導入する手順を書きます。

f:id:tsukinowaapp:20180807173441p:plain

事前作業

開発環境にもSteamクライアントをインストールして
Steamworks管理者アカウントか、「アプリのメタデータの編集」権限の付与されたアカウントを設定しておいてください。
(これをやってないとAPIの呼び出しができません)

Steamworks.NETのセットアップ

Unityの場合はSteamworks.NETを使います。
Steamworks.NETはアセットストアにもあったりしますが、
下記からunitypackageをダウンロードして
「Assets」→「Import Package」→「Custom Package」で導入した方が面倒がないです。

github.com

インポートしたらプロジェクトフォルダ直下にsteam_appid.txtを設置します。
ファイルの中にはAppID(数字)のみを記述します。

SteamManagerの導入

実はこれだけでは足りなくて、Steamworks.NET-ExampleからSteamManager.csを持ってくる必要があります。
(SteamStatsAndAchievements.csもあると便利です)

github.com

これをzipで入手・解凍したら上記csソースをプロジェクト内の分かりやすい場所に置きます。

コーディング

下記をusingに追加しておいてください。

using Steamworks;

プレイヤー名の取得

if (SteamManager.Initialized)
{
    playerName = SteamFriends.GetPersonaName();
    //Debug.Log(playerName);
}

APIを叩く前にSteamManager.Initializedを呼び出して初期化します。
正しく初期化されたらtrueが返りますので、それを拾って後続処理を行うよう記述します。
以下のソースも同様です。

Statsの呼び出し

SteamUserStats.GetStat("xp", out m_xp);

第一引数はStatsのAPI名です。
(Web側で設定した名称です)
第二引数にoutで値を設定します。

Statsの書き込み

SteamUserStats.SetStat("xp", m_xp);
bool bSuccess = SteamUserStats.StoreStats();

第一引数はStatsのAPI名です。
第二引数で書き込みたい値を設定します。
SteamUserStats.StoreStats();で実際に値を書き込む処理を行い、
成功したらtrueが返ってきます。

実績の獲得

if (m_nTotalNumWins >= 100) {
    SteamUserStats.SetAchievement("Winner");
}

実績の獲得条件が成立したら、SetAchievementを呼び出します。
引数に実績のAPI名を記述します。

SteamStatsAndAchievementsについて

SteamStatsAndAchievementsでは各処理を一纏めにして置いてあり、大変参考になります。
実績もenumを使って配列化されています。
これを改造して、インスタンス化して使うのが楽かと思います。


Steam実績を実装する(Steamworks側設定編)



今回はSteam実績(Steam Achievement)の実装について書きます。
Steamでゲームやったことがある人ならSteam実績とは何かご存知かと思います。

Steam実績とは一定の条件を満たすと付与される称号みたいなもので
プレイヤーの射幸心を煽るに便利なものです。
(Steam実績のコレクターもいるとか)

SteamAPIについては実装しなくても公開できるようになっていますが、
折角Steamで公開するのですから、Steam実績くらいは実装しておいても良いかと思います。

手始めにWeb側の設定について説明します。
※クライアント側はプラットフォーム(UnityかHTML5か)で変わってきますので別記事にします)

Webの設定

まずSteam実績を設定する前にStats(データ)を設定します。
これはゲームのスコア(キル数やレートなど)をSteamの持つ領域(クラウド的なもの)に保存できる機能で
Steamのアカウントに紐づいて保存されるため、
ログインする端末が変わっても値を引き継ぐことができます。

Stats(データ)の作成

「テクニカルツール」→「Steamworks 設定を編集」→「データ&実績」タブの「データ」を押下
f:id:tsukinowaapp:20180802145407p:plain
「新しい統計」(New Stat)を押下で値を追加します。

タイプ(Type)

型を指定します。
INT - 32ビットの符号付き整数
FLOAT - 32ビットの浮動小数点値
AVGRATE - 移動平均(一定時間内のスコアを算出するときに使用)

API 名(API Name)

データを呼び出すときの名称を設定。

設定(Set by)

データを修正できる人を設定
クライアント:アプリから更新する場合(基本はこれを選択します)
GS(ゲームサーバー):サーバーを立てて、そこから更新する場合
公式GS:Steamゲームサーバーを利用する場合

増分のみ?(Increment Only)

キル数など、加算のみで減算しない値についてはチェックをONに

最大変化(Max Change)(任意)

ゲームの仕様上あり得る上昇幅の最大値を設定(チート対策)

最小値(Min Value)(任意)

ゲームの仕様上あり得る最小値を設定(チート対策)

最大値(Max Value)(任意)

ゲームの仕様上あり得る最大値を設定(チート対策)

デフォルト値(Default Value)

最初に呼び出したときに設定する値

集計

リーダーボードの集計値として使うならチェックをONに

ディスプレイ名

Steamコミュニティで表示するときの名称を設定

入力したら「Save」で保存します。

Stats(データ)の注意

保存したら「公開」しないとアプリからの呼び出しが出来ません。

実績の作成

次は実績の設定をします。

実績には「達成」と「未達成」の2種類のアイコンが必要で
サイズは 64x64 px のJPGとなっています。
またデザインとして「獲得済みのアイコンには色を使用し、獲得済みでないアイコンには白黒を推奨」となっています。

f:id:tsukinowaapp:20180803105148p:plain
f:id:tsukinowaapp:20180803105158p:plain

API名(API Name)

データを呼び出すときの名称を設定。

進行状況(Progress Stat)

コミュニティでプログレスバーとして表示するデータを指定します。
進行状況:作成したStatsを指定。
最小値:下限(進捗0%とする値)
最大値:上限(進捗100%とする値)

ディスプレイ名(Display Name)

クライアントの通知ポップアップやコミュニティで表示される実績の名前を設定。

説明(Description)

コミュニティで表示される実績の説明。

設定(Set by)

データを修正できる人を設定
クライアント:アプリから更新する場合(基本はこれを選択します)
GS(ゲームサーバー):サーバーを立てて、そこから更新する場合
公式GS:Steamゲームサーバーを利用する場合

非表示?(Hidden)

ここにチェックを入れると、いわゆる「隠し実績」となります。
(条件を満たすまでユーザーのコミュニティに表示されません)

達成アイコン・未達成アイコン(Achieved Icon/Unachieved Icon)

それぞれ画像をアップロードします。

各項目を入力したら「保存」を押下。

実績の注意

一旦保存してからでないと画像のアップロードが行えません。
また保存したら「公開」しないとアプリからの呼び出しが出来ないのも同様です。