ホーム ブログ ページ 2

【ご案内|JRよりお越しの方へ】 渋谷駅からアピリッツ新オフィスへのアクセス方法をご紹介!

0

こんにちは!アピリッツ広報担当です。

2024年9月17日(火)より、アピリッツが新オフィスに移転いたします!

アピリッツにお越しいただくみなさまに向けて、渋谷駅JR新改札(山の手線、埼京線)からのアクセス方法をご案内いたします。

地下鉄からお越しの方はこちら

地下鉄(副都心線、半蔵門線)C2出口

|住所
〒150-6224
東京都渋谷区桜丘町1番1号
渋谷サクラステージ SHIBUYAタワー 24階
TEL:03-6684-5111
コーポレートサイト:https://appirits.com/

①JR渋谷駅 新南改札(3階)~渋谷サクラステージ

JR渋谷駅 新南改札(山手線、埼京線)

JR渋谷駅の地上3階「新南改札」から出てください。

新南改札 New South Gate

改札を出て右折し、そのまま直進してください。

新南改札 New South Gate

②渋谷サクラステージ SHIBUYAタワー(3階)

渋谷サクラステージ SHIBUYAタワー(3階)

連絡ブリッジを渡りきると、渋谷サクラステージに接続しています。

右手側の商業施設内にコスメブランド「KATE」が見えますので、

こちらを目印にSHIBUYAタワー3階の通路を直進してください。

渋谷サクラステージ SHIBUYAタワー3階

オフィスエントランスの案内表示に従って直進してください。

オフィスエントランスの案内表示

SHIBUYAタワー(3階)エントランス入り口

通路を突き当たった正面に、SHIBUYAタワー オフィスエントランスの入り口がございます。

SHIBUYAタワー オフィスエントランス入り口

③SHIBUYAタワー オフィスエリア

3階オフィスエントランス

入り口から入ってすぐ、右側に直通のエスカレーターがございますので、

こちらを利用して5階オフィスロビーまでお進みください。

直通エスカレーター

5階オフィスロビー

エスカレーターから降りたのち、大きな窓を正面に左折してください。

5階オフィスロビー

5階オフィスロビー総合受付

右手側に来訪者受付機がございますのでご利用ください。

来訪者受付機

事前にお送りしたQRコードにて、受付のご対応をお願いいたします。

来訪者受付機

通路~セキュリティゲート

受付完了後、5階通路をわたり、セキュリティゲートにお進みください。

セキュリティゲートが2つ見えてきますので、正面向かって右側のゲートよりご入館ください。

セキュリティゲート

窓側のセキュリティゲートになります。

窓側セキュリティゲート

5階エレベーターホール

18-27階行きのエレベーターを利用して24階までお越しいただき、受付機にて担当者へご連絡ください。

【ご案内|地下鉄よりお越しの方へ】 渋谷駅からアピリッツ新オフィスへのアクセス方法をご紹介!

0

こんにちは!アピリッツ広報担当です。

2024年9月17日(火)より、アピリッツが新オフィスに移転いたします!

アピリッツにお越しいただくみなさまに向けて、地下鉄(副都心線、半蔵門線)経路のオフィスまでのアクセス方法をご案内いたします。

JRからお越しの方はこちら!

JR(山手線、埼京線)新南改札

|住所
〒150-6224
東京都渋谷区桜丘町1番1号
渋谷サクラステージ SHIBUYAタワー 24階
TEL:03-6684-5111
コーポレートサイト:https://appirits.com/

①地下鉄(副都心線、半蔵門線)C2出口~渋谷ストリーム

渋谷駅C2出口エスカレーター

副都心線、半蔵門線の地下鉄渋谷駅改札(宮益坂中央改札)から、C2出口に向かってください。

渋谷駅地下通路「C2出口(渋谷ストリーム)」

渋谷ストリームの看板が見えてきましたら、エスカレーターで地上に上がります。

渋谷駅地下通路「C2出口(渋谷ストリーム)」エスカレーター

渋谷ストリーム地上1階エスカレーター

地上に出たのち、渋谷ストリームにつながるエスカレーターから2階に上がってください。

渋谷ストリーム地上1階エスカレーター

渋谷ストリーム2階エスカレーター

正面のエスカレーターから3階に上がってください。

渋谷ストリーム2階エスカレーター

②連絡ブリッジ(JR線 新南改札)

渋谷ストリーム3階~連絡ブリッジ(JR線 新南改札)

2階エスカレーターを降りると、右側に渋谷サクラステージをつなぐ連絡ブリッジがございます。

看板の案内に沿って新南改札方向へ進んでください。

渋谷サクラステージとつながる連絡ブリッジ

連絡ブリッジ入口正面の左手角に「Area Map」、右手角に「Floor Map」がございます。

連絡ブリッジ入口の右手角「Floor Map」
連絡ブリッジ入口の左手「Shibuya Station Guide」

右手側のJR新南改札を目標として、連絡ブリッジをそのまま直進してください。

連絡ブリッジ途中のJR新南改札(3階)

③渋谷サクラステージ SHIBUYAタワー(3階)

渋谷サクラステージ SHIBUYAタワー(3階)

連絡ブリッジを渡りきると、渋谷サクラステージに接続しています。

右手側の商業施設内にコスメブランド「KATE」が見えますので、

こちらを目印にSHIBUYAタワー3階の通路を直進してください。

渋谷サクラステージ SHIBUYAタワー3階

オフィスエントランスの案内表示に従って直進してください。

オフィスエントランスの案内表示

SHIBUYAタワー(3階)エントランス入り口

通路を突き当たった正面に、SHIBUYAタワー オフィスエントランスの入り口がございます。

SHIBUYAタワー オフィスエントランス入り口

④SHIBUYAタワー オフィスエリア

3階オフィスエントランス

入り口から入ってすぐ、右側に直通のエスカレーターがございますので、

こちらを利用して5階オフィスロビーまでお進みください。

直通エスカレーター

5階オフィスロビー

エスカレーターから降りたのち、大きな窓を正面に左折してください。

5階オフィスロビー

5階オフィスロビー総合受付

右手側に来訪者受付機がございますのでご利用ください。

来訪者受付機

事前にお送りしたQRコードにて、受付のご対応をお願いいたします。

来訪者受付機

通路~セキュリティゲート

受付完了後、5階通路をわたり、セキュリティゲートにお進みください。

セキュリティゲートが2つ見えてきますので、正面向かって右側のゲートよりご入館ください。

セキュリティゲート

窓側のセキュリティゲートになります。

窓側セキュリティゲート

5階エレベーターホール

18-27階行きのエレベーターを利用して24階までお越しいただき、受付機にて担当者へご連絡ください。

ゲームプランナーの仕事とは

0

今回は、アピリッツの知識共有サイト「ナレッジベース」で公開されている内容をアピスピでも紹介します。
ゲームディレクターとしても活躍されている巌光生さんの記事です。
是非最後まで読んでください!(初版:2023年2月7日)

プランナーとなって働き始めた方、まだ日の浅い方向けにゲーム制作においてプランナーの役割と求められる技能について、思い当たる部分を書かせていただきます。

はじめに

ゲームプランナーという職種は、ある意味 『何でも屋』 でなくてはいけません。
ゲーム制作の現場において、プランナーの作業は多種多様で、制作するゲームの内容によっても求められる能力が異なります。

では、行う作業について少し説明したいと思います。

企画立案

プランナーとして最初に思いつく業務かもしれませんが、実際の制作において、最初から企画を立てるという事は、最近では稀になると思います。

それは、プロジェクトとしてゲーム制作がスタートした時点で既にゲームとしての企画は成立していることが多いからです。

プロデュースやディレクション的な立場であれば、スタート時に企画立案として立ち会う、参加する場合もあります。

とは言え、企画を立てる、考える事はプランナーとして確実に必要なものです。
状況としては、制作するゲームのコンセプトに基づき、ディレクター等の指示で『遊び』となる部分の提案や立案を行い、ゲームを作っていく作業があります。

ですが、企画立案は思いついたことを提示すれば良いと言う訳ではありません。ゲームコンセプトやディレクターの意向、市場やユーザーの動向を調査しつつ考えていく必要があるでしょう。

仕様書の作成

仕様書は言わばゲームの設計図になります。基本的に仕様書は、ゲーム全体を見てプログラムやグラフィックが必要な部分を洗い出し、制作チームに必要な作業を認識してもらう役割もあります。

ですが、この時点で完全な仕様書を作ることは困難であり、先ずはゲームの流れと内容を認識できるように概要書(要件定義)としてまとめることが必要です。
この概要書の時点で各セクション(エンジニアやグラフィック)との打ち合わせを行い、プログラムやグラフィックスの発注ができるように準備しておく必要があります。

その後、各システムの流れや表示タイミング、計算式を含め仕様書を作成していきます。
各システムの仕様書が出来た時点で、初めて他セクションに発注する形になります。

プロジェクトにもよりますが、要件定義や仕様指示はディレクターからプランナーへ発注されることが多いと思います。

要件定義や指示書は「~な流れで」や「~な感じで」と言った曖昧な表現を提示される場合もあります。この場合に、分からないことや、どう表現したいのかは、必ずディレクターや発注者に質疑応答で確認してください。ただ請け負ってしまうとコンセプトのズレややり直しでタイムロスが大きくなってしまいます。
作成の前に意思疎通をしっかりと取っておきましょう。

また、仕様書は常に最新であることや改修を加えた事が一目で分かるように記載し、その都度、各セクションに修正の連絡をすることを忘れないようにして下さい。

設計と設定

ゲームを作る上で、基本となるデータの設計や設定はプランナーが担うことが多くなります。設計自体はコンセプトを如何に生かすかを考慮して行いますが、システムのロジックを含め理解していなければいけません。
仕様書作成の時点でロジックを認識していれば問題はありませんが、データ設計の上で少しでも疑問があるのであれば、エンジニアに相談し、問題を解消しておきましょう。

データ設計やデータ作成は、プランナー作成の場合、エクセルなどで作業を行い、そのエクセルをデータにコンバートしてゲームに適用する場合が多いと思います。
エクセル自体のフォーマットもコンバーターやデータ配列などを考慮するため、予めエンジニアに相談してください。

データ設定やゲームコンセプトに基づく作業には、運用するデータのバランスやゲームの遊びやすさ、継続性や配置などを考慮したレベルデザインが必要となります。これは、ディレクター指針の場合もあれば、プランナーに一任される場合もありますのであらゆる分野に目を向け、データ解析とユーザーの動向を見極められるよう学習して下さい。

スクリプトとビヘイビアツリー

プランナーとしてやらなければならない作業に、簡単な命令を用いて条件やシーンを設定するスクリプトや敵のAIやシーン呼び出しに用いるビヘイビアツリーを使用した作業が多く発生します。UnityUE等で設定していくものですが、こういった作業も多いので、各ツールの使い方は習得しておく必要があります。
その他、ツール上で設定する事項はプロジェクトによって追加され、色々と存在するので、ツールについて学習しておくことが大切です。

文章や映像の構成

ゲーム内でメッセージや説明といった文章を作成することもプランナーの作業です。文章の構成は、ユーザーに分かり易く、かつ適切でなければなりません。
時としてはシナリオの構成を求められる場合もありますので、多様な作品に触れ、読解力や作文能力も磨いておいてください。

また、映像についてはカットシーンやイベントなどより効果的に見せるため、映像分野にも視野を向け、学習しておくことを勧めます。
シーンの内容に応じて、ユーザーの心理に如何に影響するのかを知ることが映像の要です。


下手(しもて)上手(かみて)と言ったキャラクター配置やカメラのPANによるアップ、ダウンとイン、アウトと言った初歩的な内容は必ず覚えておいてください。また、多くの映像作品を意識して観るようにしてみて下さい。
時として、簡単なコンテを起こす等の作業も発生します。

データ分析と管理

ソーシャルゲーム、運営でのプランナーの役割として、今まで挙げてきた作業に加え、ユーザーの動向を量るためのデータ分析があります。KPIから得られる情報を元に、運営方針に基づき改修や改善を企画します。ここではデータが全てなので、管理も含め誤ったデータ運用をなくすことを徹底してください。(二重三重のチェック)
KPIの分析については経験者やディレクターから逐次学んでいくようにしましょう。
KPIは言わばユーザーの反応です。楽しみも苦しみも、そこから見出すことができるでしょう。

その他の作業について

上記が、プランナーとして対応できる様にしておきたい内容になりますが、実際には制作の中心として、様々な作業やコミュニケーションが必要となります。
なので、各々で何ができるか、伝えるために何をすべきかを考え実行してください。
例えば、絵が描けるのであれば絵を含めて伝える、イメージに類似する例えがあるのならば、その作品や映像を引用し伝える等、理解してもらう努力を怠らないようにして下さい。

プランナーとは

プランナーとしての心構え

最初に書いた通りプランナーとは 『何でも屋』 であるべきです。

  1. 自分の持つ引き出し(能力や知識)を限りなく増やしましょう。
  2. 作業は繊細かつ慎重に、自分の行動の影響範囲を常に意識して下さい。
  3. 分からない事、知りたい事はとことん追求し解決しましょう。
  4. ゲーム制作は、第一にユーザーを楽しませる事を考えましょう。
  5. 常にアンテナを張り、市場の動向や流行に敏感になりましょう。

ゲーム制作のすべてを賄えるプランナーを目指しましょう!


巌さんありがとうございました!

アピリッツでは自分が得た情報や技術を積極的に共有し、それらを吸収しながら各々のスキルアップを目指しています。
アピリッツに少しでも興味を持った方、エントリーお待ちしております!

アピリッツ社員寮ってどんなとこ?こんなとこ!

0

アピリッツには社員への福利厚生の一環として社員寮を設けています。でも社員寮って一概に聞いても実際どんな感じなのか、実際の本音を知りたい!!そんなあなたのために!社員寮を実際に利用している社員に話を聞いてきたので紹介します!

アピリッツ社員寮名付けて「アピトリー」

アピリッツでは、「アピリッツ」と寮を示す英単語「domitory」(ドミトリー)をかけた、「アピトリー」という名前で親しまれています!

そんな「アピトリー」、実際どんな感じなの??住むうえでの生活や節約のコツは??などのギモンにも答えながら、この「アピトリー」を紹介していきます!最後までご覧ください!

Welcome to Apitory!!

アピトリーへようこそ!アピトリーには男子寮と女子寮がそれぞれ用意されています!

それぞれ違った良さや設備があり、社員が心地よく過ごせる空間になっています。

・・・・が!!説明だけじゃわからないと思うので!早速ですが実際に住んでいる人の声を紹介しながらアピトリーを紹介していきたいと思います!

なんと○○がゼロ円!!!

早速、男子寮女子寮共通してこんな質問をしてみました。

Q, アピトリーに入寮しようと思ったきっかけはありますか?

元々入社に合わせて引っ越す予定はなかったのですが、社員寮なら会社の近くに住め、初期費用や複雑な手続きが必要なくお試し感覚で一人暮らしが出来るので入居を決めました。

東京やその周辺に関する土地勘が全くなかったこと、賃貸を探す場合の手間や初期費用など面倒な問題がいくつかあったことを考慮し、会社へのアクセスが良く安く住めるアピトリーを選択しました。特に初期費用が必要ないことが一番の要因でした。

そうなんです。アピトリーなんと、初期費用がかからないんです!!

東京で一人暮らしをするうえでかかる初期費用(敷金礼金など)は約15~20万円ほど、、                              それがかからないとなると、毎月の家賃と光熱費等のみの負担なので、手軽に一人暮らしがスタートできちゃいます!(うれしい。。!)

他にも、アピトリーは比較的会社から近いところに位置しており、慣れない東京での新生活も快適にスタートできます。さらにさらに!アピトリーには様々なサービスがあり、一人暮らしが初めてでも不安なくスタートできるんですけど、その詳細はまた後ほど。。

それぞれの寮ってこんなとこ!

男子寮、女子寮それぞれの寮の利用者に質問してみました!

男子寮編

男子寮には、大浴場や食堂などがあり食堂では朝と夜に食事がでるそう。(有料サービス)そこでこんな質問を。

Q, アピトリー(男子寮)で気に入ってるところはありますか?

大浴場があることです。大学時代に一人暮らししていた際はシャワーで済ませ湯船につかる機会がほとんどなかったのですが、今では週に何度かゆっくりと湯船につかるようにしています。お湯を張ったり掃除をしたりなど手間がかからないことが快適で気に入っています。
電気が定額なのでエアコンを気にせずつけられることです。
寮長がとても親切ですぐに対応してくれます。

大浴場を含めた水場が基本的に共用なため、面倒な水場掃除がゼロ!!これはありがたい。。。

Q, アピトリー(男子寮)の周りはどんな感じですか?

・徒歩数分の場所にコンビニやスーパーがあります。またバス停が目の前にあるので駅にもすぐに行けます(徒歩でも15分程度)。
・駅前は美味しいお店から家電量販店まであるので一通り揃えることができます。
・寮近くに大きなお寺があり、敷地が広く自然が豊かで散歩したりしています。

駅前が充実しているので、同じ寮の人とたまにご飯に行ったりしているのだとか!!

Q, アピトリーで生活するうえでのアドバイスはありますか?(節約のコツなど)

食堂を最大限利用することで月の食費は非常に安く済みます。もちろん自炊することで安く済ませられますが、手間や時間を考慮すると食堂の利用は非常に有益だと思います。
・駅から寮の途中にあるスーパーが午後7時以降お惣菜の値引きをするので、食堂を使わない場合、帰りに利用すると節約になります!

食堂のご飯が大好評。疲れた時に温かいご飯が出てくるのってうれしいですよね。。!

女子寮編

女子寮にも同じく食堂やオートロックなどうれしい設備やサービスがあります!ここでも同じくこんな質問を。。

Q, アピトリー(女子寮)で気に入っているところはありますか?

食堂で美味しいご飯が出るので自分で料理したりお皿洗いする必要がなくその分自分の時間も確保出来る。
オートロック管理人さんが常駐しているので安心感があります。
・日中に荷物を受け取ってもらえることやゴミをいつでもだせることがとても便利で助かっています。社員寮となっていますが、ほぼ一人暮らしと変わらないと感じています。

初めての一人暮らし、セキュリティ面ばっちりなアピトリーなら安心安全です!!

Q, アピトリー(女子寮)の周りはどんな感じですか?

・安いスーパーや薬局もあって暮らしやすい(少し歩けばカラオケ、本屋、家電量販店、銭湯もある)
・コンビニが徒歩10分圏内に3種類あります。畑が多く、閑静な住宅街というイメージです。
・大きい映画館にもバスですぐに行ける距離です

住宅街だからこそ病院が多くあったり、お財布にやさしいスーパーがあったりと生活しやすい環境なんだそう!

Q, アピトリーで生活するうえでのアドバイスはありますか?(節約のコツなど)

・冷蔵庫と電子レンジとケトルは共有なので、最大限活用すれば電気代の節約にはなるかと思います!
・自転車を買ったら活動範囲が広がってとても良かったのでおすすめです!
・洗濯機が共用で日によって混みあうので時間を工夫するとよいです。
・ベランダの物干し竿を置く場所が少し低いので長い衣服を干す時は工夫が必要です。

共用物を最大限に生かすのも良し!!

ちょっとの工夫でアピトリーライフがさらにより良いものに!!

ぜひともおすすめしたい!!

紹介してきましたアピトリーですが、実際の声を聞いて実際にどんな感じかイメージ沸きましたか。。!?

最後にどんな人におすすめしたいか聞いてきました。

・手続きのハードルが低く最低三ヶ月から住めるので試しに一人暮らししたい人。

・初めて一人暮らしをしたい人におすすめ。引っ越しに必要なものや費用など最低限でよいので、不安な人にもおすすめできます。

・魅力は様々だと思いますが、一番は生活費が非常に安く済むことだと思います。もちろん一人暮らしなのでそれなりにお金はかかりますが、立地やアクセスの良さを考慮すると非常にコスパの良い選択肢だと思います。節約はしたいが生活環境に妥協したくない人にはとてもオススメです。

社員寮のことが気になる方、アピリッツのことをもっと知りたい、興味がわいた方は下記ボタンからエントリーお待ちしています!

月額課金のサーバー側レシート検証の実装

0

今回は、アピリッツの知識共有サイト「ナレッジベース」で公開されている内容をアピスピでも紹介します。
エンジニアとして活躍されている鳴澤秀夫さんの記事です。
是非最後まで読んでください!(初版:2022年11月24日)

某社某案件にて課金のレシート検証を最初から実装することになったので、そのうち月額課金に関して実装時に何をしたかなどをまとめます。


課金購入の大まかな流れ

大体の流れはこの記事で理解できるかと思います。

月額課金の場合、これをベースに各工程で見るべきパラメータがが変わったり、月次更新の処理などが発生します。

この記事ではそれら月額課金特有のケースについてのみまとめていきます。

購入時

購入(月額課金加入)時のレシート検証時に通常課金と月額課金では扱う値に多少の違いがあります。

主にやることリスト

  1. (Androidのみ)レシート・署名・公開鍵を基にレシート整合性チェック
    • Googleのストアで発行された公開鍵を用いてレシートデータのsignatureが不正でないかをopensslを用いて判断する
  2. (Androidのみ)Googleのクライアント認証でアクセストークンを取得する(OAuth)
    • これをしないとストア側の検証APIを叩けない
  3. ストア側の検証APIを叩く
    • APIサーバーから詳細なレシートデータをjson形式で受け取る
  4. レシートパース
    • json形式で取得した詳細なレシートデータをパースして必要な情報を得る
  5. 重複チェック
    • 過去に扱ったレシートが不正に利用されたリクエストでないかをチェックする
  6. アイテム付与・DB保存
    • リクエストが月額課金だった場合、PJによっては専用の特典もここで別途付与する

主に月額課金でやるべき項目が変わってくるのは、上記の3〜6の範囲です。

Android編

3. GooglePlayDeveloperAPIを叩く

叩くべきURLが違います。若干違うだけでほとんど似てる文字列なので間違えないようにしましょう。
私のPJでは購入したい商品が月額課金かどうかをif文で分岐させています。

通常商品(都度購入)の場合
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/<パッケージ名>/purchases/products/<ストア側の商品ID>/tokens/<アクセストークン>

月額課金の場合
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/<パッケージ名>/purchases/subscriptions/<ストア側の商品ID>/tokens/<アクセストークン>

4. レシートパース

月額課金で特に見るべきパラメータは以下の通りです

expiryTimeMillis
  • そのレシートが月額課金である場合は上記パラメータがレシートのjson上に存在するはずなので、それの有無をまずは確認する。
  • 逆にそれが無い場合は都度課金と判断できます
paymentState
  • 決済状態がint型で表され、0なら未決済、1なら購入完了となっています。
  • 都度課金の場合、全く同じ内容なのに purchaseState という別種のパラメータから取らなければならないので面倒な仕様です
startTimeMillis
  • 月額課金のプラン開始日時がエポック秒かつミリ秒単位の数値で入っています。
    • なのでdatetime型にするためには秒数まで取れればいいので、変換前に1000で割った商を得ておきます。
expiryTimeMillis

プラン終了日時です。ソース上での扱いは上記と同じです

iOS編

3. In-AppPurchaseAPIを叩く

iOSは都度課金・月額課金共にまとめて1つのレシートデータとして返してくるので課金形態でURLは変わりませんが、本番環境か否かでURLが変わる仕様なので注意しましょう

本番
https://buy.itunes.apple.com/verifyReceipt

サンドボックス(本番以外)
https://sandbox.itunes.apple.com/verifyReceipt

4. レシートパース

月額課金で特に見るべきパラメータは以下の通りです

latest_receipt_info
  • 月額課金に関する情報はこのパラメータ下に配列で入っているため、まずはこれをまるごと取得してforeachなどで回します。
expires_date
  • そのレシートが月額課金である場合は上記パラメータがレシートのjson上に存在するはずなので、それの有無をまずは確認する。
  • 逆にそれが無い場合は都度課金と判断できます
purchase_date_ms
  • 月額課金のプラン開始日時がエポック秒かつミリ秒単位の数値で入っています。
    • なのでdatetime型にするためには秒数まで取れればいいので、変換前に1000で割った商を得ておきます。
expires_date_ms

プラン終了日時です。ソース上での扱いは上記と同じです。

5. 重複チェック

iOSの場合は過去の購入情報までまとめてレシートに入ってくるため、始めて課金をするユーザー出ない限り確実に重複が発生します。

なので、DBに保存した過去のレシートの情報と比較して重複した場合は処理をスキップさせて行きます。

もし1件も処理されず全件スキップされた場合は過去レシート使いまわしの不正レシートと判断してエラーを返すようにします。

共通

6. アイテム付与・DB保存

やるべきことは以下のとおりです

  • アイテム付与
    • これは都度課金でも同じですね。購入した時点で付与する設定のアイテムをユーザーに付与します。
  • 月額課金特典の初期化
    • 専用ログインボーナス、専用ストアの購入制限回数などのリセット処理を行います。
    • これらのデータは別途DBにテーブルがあるはずなので、値の初期化(レコードがなければ生成)をしていきます。
  • 課金状況の保存
    • DBに月額課金の状況を保存します。開始/終了日時(datetime)・プラン加入状態(bool)などです。
    • 月額課金専用の機能のAPIなどで課金状況をチェックするために使います。

更新時

更新のタイミング(契約から丸々一ヶ月後の場合) 

月額課金ということは当然ながら一定期間(大抵は1ヶ月)で更新が行われるはずです。

そのタイミングは案件によって “月末” であったり “契約時から丸々一ヶ月後” だったりする訳ですが、私が実装した際の案件では後者だったので、それを前提に進めます。

更新タイミングである”一ヶ月後”の算出方法は契約・更新した瞬間の該当月の日数となっています。つまり、次回更新は以下のとおりです。

  • 1ヶ月が31日ある月に契約・更新をした場合: 31日後に更新
  • 2月中に契約・更新した場合: 28日(閏年:29日)後に更新

更新日時は、先述の通りレシートに記載されています。

更新通知の受け取り 

ここで問題が発生します。 更新タイミングはユーザーごとにバラバラであることです。しかも分・秒単位で。
月末更新で一定であれば月次バッチ処理を仕込むなどして対応も可能ですが、そうはできない仕様となってしまいます。

しかしGoogleやAppleはWebhookを用いて月額課金購入の状態をリアルタイム通知する機能を用意してくれています。

これをサーバー側APIで受け取ってレシート検証やDB更新などをすれば、自動的に全ユーザーの更新に対応ができるようになるわけです。

購入された時、更新された時、解約された時、決済完了した時…など、月額課金の様々なアクションが発生するたびにWebhookが飛んできますが、今回は「更新」の情報のみを取得して処理をします。

購入時は別途レシート検証APIを先述の通り設けているので不要なのと、解約に関しては次回更新日まで課金特典の効力が続くため実装不要の仕様だったからです。

実装フローは以下のとおりです

  1. Webhookを受け取るためのAPIを実装
  2. Webhookを飛ばすための設定
  3. 更新の準備をする

1. Webhookを受け取るためのAPIを実装

普段の実装はクライアントとなるスマホアプリからサーバーのAPIを叩いてもらう感じですが、今回はGoogleやAppleのサーバーからゲーム側のサーバーのAPIを叩いてもらう形式となります。なので、窓口となるAPIを実装しURLを用意してあげる必要があります。

  1. 受け取ったら、それが「更新」の通知であるかをチェックする
    • iOSの場合: リクエストにnotification_typeというstring型パラメータがあるため、その中身がDID_RENEWDID_RECOVERであるかをチェックする。
    • Androidの場合: リクエストにnotificationTypeというint型パラメータがあるため、その中身が12であることをチェックする。
    • チェック対象以外の値だった場合は更新通知ではないので処理を中断させる。
  2. 各ストアから最新のレシートを取得する
  3. レシート検証をする
    • ここまでは先述のレシート検証と同じ処理を行う。
  4. 正常だったので更新準備をする
    • 後述

2. Webhookを飛ばすための設定

窓口となるAPIを実装できたら、各ストア側の設定をしてWebhookが飛んでくるようにしていきます。

こちらの説明は少々長くなるので、参考になるページへのリンクという形で割愛させてください。

3. 更新の準備をする

APIでレシート検証まで終わったら、ゲーム側での月額課金の更新処理を行います。

主にやることは以下のとおりです

  • プラン終了日時の更新
    • 最新のレシートに書かれた値にする
  • アイテム付与・特典リセットの「予約」
なぜ「予約」をするのか

Webhookの更新通知は、大体更新日時の1〜24時間前にストア側から飛んでくる仕様となっています。時間差はだいぶアバウトですが、実際の更新日時よりも前に飛んでくることは確かです。

つまり、更新時にアイテム付与などが本来の時間よりも前倒しに実行される懸念が発生してしまいます。

アイテム付与だけならまだ良くて、月額課金ユーザー限定ログインボーナスのリセットが前倒しで走ってしまった場合、最悪はユーザーが最終日のアイテムを入手できずクレーム案件につながってしまいます。

その対策として、当月分のプランが完了した後にそれらの処理を確実に実行するよう、専用のDBテーブルを用意して管理する必要があります。

ログイン時等にそのテーブルをチェックし、本来の更新日時を過ぎていればアイテム付与・特典リセットを実行する流れです。

月額課金のテスト

課金のテストに実際のお金を何度も使うことは流石にせず、開発中であれば無料で課金ができる仕様で各OSは準備がしてあります。

また、1ヶ月後の更新を動作確認でひたすら待つことが無いようにもなっており、5分経つと1ヶ月経過したとして処理されます

更新通知もだいたい1分前に飛んでくるようになっています。

ここで気をつけるべきことは、退会のテストを兼ねてか6ヶ月分更新した時点で自動的にプランが解約される仕様となっていることです。もちろん本番ではそのようなことは無いです。

ただ、やはり本番運用直前までには実際のクレジットカードを使ってちゃんとテストしたほうが(精神衛生上)良いです。

最後に

今回は月額課金の部分のみに重きを置いたため、通常課金やそもそもの課金フローに関しては別の機会にまとめられたらいいなと思ってます。


鳴澤さんありがとうございました!

アピリッツでは自分が得た情報や技術を積極的に共有し、それらを吸収しながら各々のスキルアップを目指しています。
アピリッツに少しでも興味を持った方、エントリーお待ちしております!

潜入捜査!新卒ランチ会

0

噂によるとアピリッツでは「新卒ランチ会」という謎の会が行われているらしい。。。
これは。。。特ダネの予感!!ということで、アピスピ編集部も潜入することに。

「新卒ランチ会」ってなに??

アピリッツでは、新卒社員同士の親睦を深めることを目的として毎年「新卒ランチ会」を人事主催で開催しています。ランチ会に行くメンバーは、人事側でグループを作っているそう。ち、な、み、に、その日のランチ代は全て会社負担らしいですよ。。(毎回参加しようかな)

それでは、潜入してきます!!!

ちょっと緊張してる??筋肉組
ご飯前にパシャリ!!

初任給で親孝行!?

ランチ会では新卒社員たちが快適にアピリッツでオフィスライフが送れているかなど雑談しながら聞いたりもしているんです。私たちもちょっとその会話を聞いてみたいと思います。

休みの日は何しているの?

・基本家で過ごしている。ゲームしたり、ネットフリックスを見ることが多い。
・夏季休暇を使ってディズニーに泊まる予定!ゴルフを最近やり始めました!
・友達とカフェに行ったり、10時間くらい寝てたり。1日8時間は寝たい。
・ダーツやビリヤードが趣味で、大会などに出ている。ビリヤードで元々知り合いの社員もいる。部長と二人でもビリヤードに行きました!

私も寝たい!けど遊びたい!

初任給は何に使った?

・お世話になった人にコーヒーとかジュースとか買ってあげた。
・親と飲みに行った。串カツ田中に行って、めちゃくちゃ楽しかった。
・エアジョーダンを買った。
・服とか買って、気づいたら無くなってた。学生の時と服装が違うから大変。学生時代はジャージでよかったのに…
・親にラインギフトでビール詰め合わせを送った。

私なんてゲームの課金で終わっちゃったよ。。

会社の人と飲みにいったりしてるの?

・新卒で企画してくれる人がいて、エンジニアの飲み会があった。
・前は飲み会したりしてたけど、最近はみんな忙しいからしてない。Web側の同期と飲み会とかしたいな~。
・昨日ちょうど部署の懇親会があって、初めて話した社員もいて楽しかった。
・先週は飲みではないけど、同期と秋葉原でPCの部品とか見に行ってラーメンを食べました!同期の中でラーメン屋でバイトしてた人もいたり、ラーメン好きが多かったりと、ラーメンの話題で盛り上がりました。

私もラーメン好きだから入れて~!

業務が趣味の延長線上!?

会社には慣れた?

・まだ3か月しか経ってないんだという印象。忙しかった月もあったが、今は落ち着いてる。
・既に案件に入っていて、要件定義とかもやらせてもらえてる。リモートも活用していて、その日は満員電車に乗らなくていいので楽。
・リモートもできるけど、出社の方が聞きやすいし、業務を一人でできるようになるまでは出社しようと思っています。
・上司になんでも話せているので不満や不安等はない。
・大変な業務もあるけど趣味の延長線で仕事してる感じなので、働いていて楽しい
・昨日業務でやらかしたところ・・だけど頑張ります!

大変な業務も多いと思うけど、がんばれ!!!

潜入終了!!

人事とランチ会ってなるとやっぱり少し緊張しますよね。。私が潜入した会も初めは少し緊張した空気も流れていました。でも、話していくうちにランチ会のメンバー同士も、主催の人事の方と社員のみなさんも空気が和んできて盛り上がるシーンもちらほら!

アピリッツでは社員間のコミュニケーション向上を図ったイベントが他にも多くあります。また潜入していきますので次の記事も楽しみにしていてください!

新卒1年目のエンジニア必見!AWS資格取得のコツはズバリ!:2024 Japan AWS All Certifications Engineers 受賞者インタビュー

0

「Japan AWS All Certifications Engineers」とは、AWS Partner Network (APN) に参加している会社に所属し、「AWS 認定資格を全て保持している」 AWS エンジニアの皆様を対象にした表彰プログラムです。AWS が認定する資格の種類も増え、AWS 認定資格を全て保持する事の難易度は非常に高くなっています。そんな中アピリッツでは今年、10名のエンジニアが受賞されました。
今回は表彰された内の2名のエンジニアさんに、受賞した時のお気持ちや、勉強のコツなどを聞いてきました!
これからAWS 認定資格取得を目指すエンジニアのみなさん、勉強方法で悩んでいるみなさんも是非参考にしてみてください!

きっかけはシンプル!

ー全制覇しようと思ったきっかけを教えてください。

(福留)同じチームだった伊藤さんと、どっちが先に取るか勝負しようと言っていたことがきっかけです。先に取った方がご飯をおごってもらえる約束をして、伊藤さんがいつの間にか全部取得していました(笑)勝負には負けましたが、約束したのに何もしなかったらかっこ悪いし、有効期限が切れるタイミングも重なったので全制覇しようと思いました。

(高橋)手っ取り早く給料をあげたかったからです。

ーアピリッツで導入している報奨金制度がきっかけという社員さんは多いですね!AWS JAPAN APN ブログ内で表彰されると、会社からAPN表彰手当が支給されます。その報奨金総額は100万円以上なので、モチベーションにも繋がりますよね!

AWSの資格を取得して得たものは大きい!

ー受賞したときのお気持ちを聞かせてください!

(福留)受賞が決まったときはほっとしました。実際、最後の試験に合格して、全制覇したときが一番嬉しかったです。

(高橋)改めて達成感を感じました。嬉しかったです。

ー全制覇、やっぱり大変でしたか?

(福留)2023年11月から2024年3月末にかけて9個取得しなければいけなかったので大変でした。もっと余裕を持って始めれば良かったと思います。

(高橋)新卒で入社して、3か月くらいしてから入門試験から始めました。知識0からのスタートだったので、最初は大変でした。先輩に参考書を借りてアドバイスもらったりしていましたね。

ーAWSの資格を取得して良かったことを教えてください!

(福留)お客様からの「こういうことやりたい」に対して、以前よりも頭の中でイメージが何パターンか解像度高く浮かぶようになったと感じます。お客様との話も早く進むようになりましたね。また、細かい部分を詳しくは覚えていなくても、なんとなくイメージはつくようになったので調べるのが早くなったと感じます。

(高橋)AWSのサービスを頭である程度イメージすることができるようになったことは良かったと思います。また、プロジェクトの内部構造やその動作をより深く理解できるようになり、受けた甲斐があったなと感じます。 

全制覇のコツは自分を追い込むこと

ー勉強方法を教えてください。

(福留)必要な書籍は最初に全部買って、通勤時間や帰宅してから寝るまでの間に勉強していました。仕事しながらなので、平日は1日に何時間か決めるのではなくやれる時にやるというふうにして、土日は基本ずっと勉強していましたね。youtubeで動画を倍速にして、たくさん視聴したりもしていました。

(高橋)平日は2~4時間、休日は5時間以上勉強していました。基本的には問題集で勉強して、わからないところは調べるというふうにしていました。

ー今後、AWSの資格取得を目指すエンジニアさんたちにアドバイスをお願いします!

(福留)まずは3個くらい試験を予約してしまうところからスタートして、報奨金が入る前提で先に買い物してしまって、周りにも公言して、締切効果で追い込んでやり切りましょう。自分の場合は先に家具を買って、取得できなかったらお金が無くなるリスクを追って、自分を追い込んでいました(笑)新卒の1年目である程度取った方が、時間もありますし、金銭的にも、知識的にも良いし、取って損はないため、計画的に取っていけば良いと思います。ある程度とっていれば、色んなチャンスをもらいやすくなりますしね!

(高橋)お金的にも、知識的にも2~3個取っておいたら良いんじゃないかと思います。コンスタントに勉強すれば取れる資格だと思いますので、頑張ってください。自分も、先に予約してお金も払ったしもう落ちれない、と自分を追い込んで勉強していました(笑)

これからも成長し続けます!

ー今後の目標を教えてください。

(福留)新設された試験に合格してAllCert維持することが目標です。機械学習や生成AIをどうやってクライアントの新規ビジネスに繋げるのか、企画提案できるようになりたいです。また、お客様に「福留さんに言えば何か形になる」という信頼感を持ってもらい、売り上げに繋げられるようなエンジニアになりたいです。

(高橋)新しく追加された試験は受験して、既存試験は期限が切れる前に更新して、まだまだ知識を高めていきたいと思います。

ー最後に、当時の自分に一言伝えるとしたらなんて伝えますか?

(福留)もうちょっと早めに始めた方が良いよと言いたいです。あと半年くらいは早かったら良かったです(笑)

(高橋)その頃は結構真面目に、勉強しかしてこなかったので特に言うことはないです。よく頑張ったなと伝えたいですね(笑)

ー福留さん、高橋さん、受賞された皆様、おめでとうございます!

 今後も更なるご活躍を期待しています!

編集部的!ガッツリ飯はこれだ! Sakura Stage編

0

今回は、もうすぐサクラステージに移転することもあり、アピスピ編集部員たちで、周辺ランチを調査してきました!
実はグルメが多い編集部。。選りすぐりのお店をいろんなジャンルで紹介するのでぜひ最後までご覧ください!!
飯テロしてごめんなさいっっ

これまで、vol1,2と新卒社員のオフィス周辺グルメを紹介し大好評だった「新卒のガッツリ飯はこれだ!」ですが、今回はなんとサクラステージへの移転もあり、我々編集部員たちのおすすめ、名付けて「編集部的!ガッツリ飯はこれだ! Sakura Stage編」をお送りします。

過去の記事はこちら ↓

新卒のガッツリ飯はこれだ!vol.1」

「新卒のガッツリ飯はこれだ!vol.2」

今回のアピスピ編集部的ランチマップはこちら!

タイ料理と言ったらココでしょ!

本格タイ料理 渋谷ガパオ食堂

サクラステージから徒歩4分のこのお店。

お店の前に着いた瞬間から食欲をそそる良~~い香りが・・!

京セラビルから歩いた甲斐あった~。。

  • 予算 : ¥1,000~¥1,300
  • 住所 : 東京都渋谷区桜丘町14-10 渋谷コープ1F
2種あいかけ(写真のはガパオとグリーンカレー!)¥1,230
カオマンガイ ¥1,180

お店は開放的な雰囲気で量も結構がっつりでした!麺類頼んだらライスもついてきたのはびっくりww 男性社員に食べてもらいましたw
でも味がとにかく本格的でおいしくてエスニック料理とか好きな人は絶対行くべき!

カフェでゆっくりランチはココしかない!

「Karin堂」

ここもサクラステージからは徒歩6分ほど。

外観も内装もどこか安心するようなこのカフェ。実家のような落ち着きでした。

実はここ、偶然見つけたんです!

  • 予算:¥1,000~¥1,999
  • 住所:東京都渋谷区桜丘町7-13
季節のお野菜の日替わりプレート ¥1,400
角煮と豆乳ソースのオムライス ¥1,450

落ち着いた店内ですごくよかったです!料理も野菜たっぷりでとてもヘルシーなのにがっつり感があって、大満足。
普段からジャンクフードとかを昼ごはんにしているあなた!!!健康的でおいしいご飯を求めて「Karin堂」に行ってみては!?

サクラステージは目の前!美味いイタリアンはココだ!

「Kouji&ko ITALIAN」

ここはサクラステージの目の前で徒歩約2分ほど!!

内装は白を基調としていて、席の上にはお花が飾ってあるおしゃれ空間。

入口の看板にあった「冷やしナポリタン」が魅力的で。。。

  • 予算:¥1,000~¥1,999
  • 住所:東京都渋谷区桜丘町16-13 桜丘フロントⅡビル 2F
冷やしナポリタン御膳 ¥1,320 (スープ・ドリンクバー付き)
牛肉とトマトのハヤシライス ヨーグルトソース仕立て御膳 ¥1,560 (大盛り+¥110 / スープ・ドリンクバー付き)※写真

「冷やしナポリタン」って名前だけでもうすでにおいしい。。そして味もすごくおいしいんですよ。
しかもなんと!スープバーとドリンクバーがついてくるんです。(最高)しかもしかも、内装もめっちゃ可愛くて気分も超上がるし絶対に行ってみてください!

ち!な!み!に!

アピリッツの移転先であるサクラステージや近くに建っている渋谷ストリームというビルにも数多くの飲食店が!

渋谷ストリームは現在もたまにわざわざ行くほどおいしいお店がいっぱいなのでぜひ行ってみてください。

詳しくは下記それぞれのホームページをご覧ください ↓

渋谷サクラステージ https://www.shibuya-sakura-stage.com/restaurant/

渋谷ストリーム https://shibuyastream.jp/shop/


これを見てぜひ制覇しちゃってください!

ではまたっ!

受託ゲームタイトルのリーダーが語る!コラボ企画における心構え

0

こんにちは!ゲームセグメント情報発信チームです。

当社は、オンラインゲームの受託開発および自社ゲームの企画運用における10年以上の実績を活かし、運営移管(セカンダリサービス)の事業を展開しています。

今回の記事は、とある受託ゲームタイトル(非公開)における、コラボ企画における心構えと、企画決定~リリースまでの流れについて語っていただきました!


今回インタビューしたのはこの方!

アピリッツのゲーム・コンテンツ学部で、受託運営タイトルのディレクターであり、部長を務める片木大輔さんにお話を伺いました!

過去インタビュー「ユーザー、クライアント、版元、みんなからの信頼を得る」の記事も、ぜひご覧ください!


コラボが決まった経緯

コラボ実施のきっかけを教えてください!

クライアント様から「新規コラボをやりましょう」という話がありまして、
その際にいくつかこちらから候補を出させていただきました。
総合的に判断頂いた結果、 今回のコラボ案が採用されました。


コラボが決まった後の開発は?

コラボはどういう流れで進みましたか?

まずはシナリオや世界観周りの設定から版元様とのやりとりで詰めていきました。
シナリオ概要が確定した後は、シナリオとそれを元に使用するキャラクターや設定が同時進行で進み、
最後はコラボ用の新規開発を仕上げていきました。
本当にリリース直前まで修正等を重ねていって、なんとか無事リリースする事ができました。

開発する上で問題にぶつかった事はありましたか?

いくつか壁がありまして、ある程度妥協して別の形にした方がいいのではないか、という話も出ました。
ですが、ユーザーに満足してもらうにはこれしかない!という形を目指して
最後までメンバーがあきらめずに挑戦を続けてくれたことが良かったと思います。

チームとして工夫したところはありますか?

コラボキャラクターの表現のためにかなり試行錯誤を行いました
細かいことは言えませんが、かなり広い範囲で手を加えていて、本当にギリギリまで調整をしてくれていました。
当たり前のように以前からあった機能だよね、というレベルでしれっと入ってますが、
運営メンバーの本気度はここに現れていると思います。

チーム全員でタイトル・コラボIPを尊重しつつ、制作を進めていく。

コラボでIPを扱うということについて

コラボに取り組むにあたり、大切にしている事は何ですか?

先の内容(コラボでこだわったポイント)と被ってしまうのですが、
まずコラボには当たり前ですがコラボ先のIPがあります。
運営タイトルのユーザーがどのようにコラボを楽しめるかというのと同様に、
コラボIPファンがどのようにこのタイトルを楽しめるか、という観点が必要になります。

コラボから入った新規ユーザー、またはコラボIPファンの既存ユーザーがコラボキャラを手に入れたら、
それをコラボ期間終了後もコラボIPの世界観を可能な限り損なわずに、
コラボキャラ目線で異なる世界を冒険できるような、そんなプレイ体験を与えたいです。

その場その場のコラボではなく、しっかりとその後もタイトルを遊べるようにしてあげたいですね。
なので、世界設定や体験は可能な限りコラボIPに合わせるなど、そういった部分は大切に思っています。

他社さんとのやりとりでエピソードがあれば教えてください。

過去にIPものでディレクターをさせていただいたことがありますが、
やはり全てが全て順調に進むということはなく、版元様と意見の食い違いがあったり、
場合によってはお叱りを受けることもありました。

ですがしっかりとやりたいこと、ユーザーに届けたいことを伝えて
最終的にはご理解いただけて、新しい挑戦もさせて頂くチャンスも貰うことが出来ました!


コラボ開発を終えて…

コラボで楽しかったこと、やりがいを感じたことを教えてください。

やはりリリース後のユーザーの反応ですね。
とても喜んでくれていましたし(課金ももちろんですが)
ユーザーだけではなく版元様にも、クライアント様にも喜んでもらえました。

コラボでアピリッツならではだと思ったことはありますか?

コラボIPのことを元々よく知っているメンバーも、そうではなかったメンバーも、
ユーザーに喜んでもらうために一生懸命頑張ってくれました
その想いがしっかりと形として実現して、いいものを届けることが出来たと思っています。
これはアピリッツならではだと思います。

今後何か挑戦したいことはありますか?

私自身が新しいコラボだったり、IPタイトルだったり、そういった事をやりたいというのももちろんありますが…

最近はチームメンバーがそういったゲーム作りで面白いこと、ユーザーを楽しませること、そして売り上げを上げること、
それをどんどん吸収していいものを作っていってくれてる
と実感しています。

なのでそんなチームをもっと増やして、いろんなタイトルの開発運営を実現できたら楽しいだろうと思ってます。
そんなタイトルを複数運営できるように、いろいろと挑戦していきたいと思います。

ゲーム制作について、伝えたい事をぜひお伺いしたいです!

みなさんやはりゲームをプレイして感動したことがあるのではないかと思います。
またゲームに限らずアニメや小説でも何かしら感動することって多いと思います。
そういうことがあって、ゲームを作る側に回ろうとどこかで思ったのではないかと思っています。

それってすごいステキなことだと思うんですよね。
そして今、その感動を与える側に立ってるんです。
おそらくみんなが作ったゲームで同じように感動した人が大勢いると思いますし、これからも増えていくと思います。
最初の感動を忘れないように、これからも一緒にいいゲームを作って世の中に出していきましょう!

片木さん、本日はありがとうございました!


あとがき

受託運営タイトルにおけるコラボ企画は、
受託運営タイトルの世界観を大切にしつつも、コラボ先の世界観や設定とも乖離が起きない様に、丁寧に擦り合わせていく事が非常に重要です。
ディレクター、シナリオ、プランナー、エンジニア、デザイナー…チームメンバーそれぞれ、
受託運営タイトル・コラボIP双方へリスペクトをもって、
これからも皆様に喜んで頂けるようなコラボを実現できるよう取り組んでまいります!


お読みいただきありがとうございました。

当社へのゲーム運営移管のご相談は下記URLから!

https://appirits.com/inquiry/


自転車通勤はいいぞ!(なんで?)

0

アピリッツでは健康促進運動の一環で自転車通勤を取り入れ、「自転車通勤宣言企業」に認定されました。
そこで、自転車通勤をしているアピリッツ社員の実際の声などを紹介させていただきます。
最後までどうぞご覧ください!

アピリッツは「自転車通勤宣言企業」に認定

アピリッツでは社員の健康促進として、バランスボール導入など積極的に行っています。その一環として自転車通勤をはじめ、なんと!「自転車通勤宣言企業」に認定されました!

アピリッツプレスリリースより

そこで、自転車通勤にはどんな効果があるのか?実際自転車通勤ってどんな感じ?などの疑問に実際の声なども交えてお答えしていきます!!

自転車通勤の良いところ3選

1. 通勤しているその時間がダイエット!?

平日は特に運動しようと思っても、昼間は仕事、夜は疲れて運動しにジムに行ったりするのは大変。。かと言ってお腹は空くから食べちゃうし。。そんなときの自転車通勤!自転車に乗ること自体が有酸素運動になります。なので、通勤するだけで脂肪燃焼や体力作りなどの効果が得られ、運動不足の解消や通勤しているその時間がダイエットになってしまうんです!

2 . 節約しながらエコ活動できちゃう!

普段利用している公共交通機関は排気ガスを出しています。更には毎日の通勤、毎回の出費はちょっと痛かったりもしますよね。。でも自転車通勤なら電車通勤やバス通勤よりかは出費が抑えられます!しかも、完全人力で動かすので排気ガスを出すこともなく、地球にも優しい!

3 . 自転車通勤でストレス解消!

通勤時間の公共交通機関は混雑不可避!でも自転車なら混雑からも解放!完全に自分一人でリフレッシュしながら通勤できちゃいます。しかも、夜のバスって最終バスが早かったりして終わっていないタスクをキリ悪かろうが終わらせないと。。なんてことも。でも、自転車ならそんなことを気にするストレスから解放!!

実際のところどうなの??

今回は実際に自転車通勤をしている三名の社員に自転車通勤に関して少しお話を聞いてきました!

1 . 自転車通勤に変えたきっかけってありますか?

もともと家から駅までの距離があり、バスだと最終が早いので「最終バスの時間を気にして、キリが悪いのに帰宅する」ということが度々ありました。自転車であれば、そこを気にしなくて良いので自転車通勤を申請しました。

申請すれば自転車が使えることを知り、家から駅までの通勤を自転車通勤に切り替えました。

バスが通勤時間でも1時間に3本しかなく、それもほぼ毎日かなり遅延して時間が読めないため。

2 . 自転車通勤して良かったこと、メリットはありますか?

・時間を気にして作業する必要がなくなったこと
・仕事中は基本的に座って作業するので、いい運動になること
・帰りは特に、気分転換になること

朝の時間を余裕を持って過ごせるようになったのが一番のメリットだと思います。朝がせわしないとその日1日どこか疲れた感じになってしまうので、実際に縮まった時間以上の恩恵を得られていると思います。

バスを利用した通勤に比べて通勤時間が安定しました。

3 . 自転車通勤するうえで気を付けていることを教えてください

当たり前ですが、事故を起こさないように気をつけています。
焦っていると事故を起こしやすいと思うので、時間に余裕を持って家を出るようにしています。

朝は特に急ぎがちになってしまうと思うので、車通りや人の多い駅付近の道などではより注意して運転するようにしています。

交通ルールを守るように心がけています。


アピリッツではまだまだ社員の健康促進のために様々な取り組みを行っています。

これからもアピスピを通して紹介できればと思っていますので、楽しみにしていてください!

アピ図書ってなに??

0

アピリッツには社員皆さんが快適にオフィスライフを送れるよう、様々な制度を設けています。
今回は制度の一つであるアピリッツ図書、名付けて「アピ図書」について皆さんに知ってもらうために、
アピ図書を運営している「図書委員」に話を聞いてきましたのでご紹介していきます!
アピリッツのこともっともっと詳しくなっちゃいましょう!!

「アピ図書」ってなに??

ーーアピ図書ってそもそもなんですか?

会社の「図書室」として本の貸し借りを行うことが出来る制度です。
社員の方から「欲しい!」とリクエスト頂いた本が毎月どんどん入荷されており、現在では約1,400冊の本が貯蔵されています!

ーーシステムについても教えてください!

社内の有志の方が作ってくださった書籍の貸出や在架確認ができる書籍管理システムで運営しています。
PCでもスマホでもどちらからでもログインでき、アピ図書の利用・運営にはなくてはならない存在です。
直近では、UI改善などを目的としたプチリニューアルも実施し、今後図書委員の後輩がよりよいシステムにしてくれることを期待してます。

ちなみに委員会って??

アピリッツに入社する新卒社員は、入社から1年間、業務と並行して「委員」として社内で活動します。

美化委員や衛生委員など様々な委員会があり、図書委員もその1つです!

そんな中、図書委員はどんなことをしているのでしょうか。。!?

ーー図書委員ってどんなことをしているのでしょうか?

欲しい本のリクエストの受け付けや、入荷の手配届いた本の陳列などが基本的な業務です。
社員の方々が本を探しやすいように本棚の整理整頓はもちろん、貸し出し方法を訴求するポップ設置なども行っています。
また貸し出しの際に使用する「貸出システム(本のバーコードを読み取って、貸し出し処理ができるもの)も、エンジニアやデザイナーのメンバーと協力しながら改修を行っています!
その他にも、会社で読書の習慣が広まるように社内チャットツールで「アピ図書チャンネル」を立ち上げ、お薦めの本の紹介や俳句コンテストの開催などを実施中です。

ーー本の管理以外にもいろいろなことをしているんですね!!

どんな本があるの??

さてさて、話を戻してアピ図書にはどんな本があるのでしょうか。。!

ーー入ってくる本のジャンルは主にどんなものがありますか?

業務で活かせるエンジニア向け、デザイナー向けの書籍が多いです。
ただ、購入できるジャンル自体に制限はないので、本屋大賞を受賞した今話題のアノ小説!なども毎月一定数配架されます。

ーー新しい本はどれくらいの頻度で募集・納品されるんですか?

配架希望自体は通年、googleフォームから受け付けています。
月一で集計、希望いただいた書籍の中で既に配架済みのものがないかなどを確認して、問題ないものだけ人事の方に共有、注文いただくという流れです

ーーありがとうございました!


アピリッツにはこの他にも多くの制度があります。

これからもこうしたアピリッツの制度のことも発信していくので楽しみにしていてください!

Amazon Bedrockで始める生成AI活用 vol.1 ~概要編~

0

はじめに

AIエバンジェリストの浅田です。
生成AI関連の話題は枚挙に暇がないほど日々出続けています。もはや、日常の風景になりすぎて、ブームという言葉も相応しくないほどかと思います。さて、そんな生成AIですが、どうやって活用すればいいのかよくわからないという方もいらっしゃるかと思います。

そこで、生成AI活用のポイントについて、Amazon Web Services(以後、AWS)の生成AIサービスであるAmazon Bedrock(以後、Bedrock)の利用例を交えて複数回にわたって述べていきたいと思います。なお、様々な種類の生成AIがありますが、主にテキストデータを扱う大規模言語モデルを中心として扱います。特に断りなく生成AIと表記した場合はテキスト系生成AIであるとご理解ください。

もちろん、生成AIの技術はまだまだ発展途上にあると思いますので、ここに書いたことが完全な正解とは限らないとは思いますが、活用する際のなんらかのヒントにしていただければ幸いです。

今回は概要編となります。個々の要素は今後別記事でより深掘りしていく予定です。

生成AIの先祖

生成AIの具体的な活用を考える際に、生成AIのベースとなった技術の理解が重要であると考えます。テキストにおける生成AIといえばChatGPTが有名ですが、これが有名になった2022年ぐらいに突然この技術が生まれたわけではありません。GPTはGenerative Pre-trained Transformerの略称ですが、この名前が示すようにTransformerというAIモデルがベースになっています。現在の多くのテキスト系生成AIもTransformerがベースとなっています。

Transformerは各言語に特化したPre-trained(事前学習)されたモデルを特定のタスク向けに追加学習することによって、それまでの自然言語処理(NLP)におけるベンチマークを塗り替えました。Transformerのモデルが特定のタスク向けに追加訓練を必要としていたのに対し、現在のテキスト系生成AIは追加訓練をすることなく多様なタスクを実行することができる、というのが革命的な点の一つです。

Transformerが得意とする代表的なタスク

そのようなTransformerですが、代表的なタスクに以下のようなものがあります。

  1. 翻訳
    • 与えられた文章を、別の言語に変換する
  2. テキスト要約
    • 与えられた長文から、短い文章の表現に変換する
  3. 質問応答
    • 与えられた文章情報に基づいて、ユーザの質問に対する回答を生成する
  4. テキスト分類
    • 与えられたテキストについて、あらかじめ決められた区分のどれに該当するか分類する
  5. エンティティ抽出
    • 与えられたテキストから、固有情報(名詞、数詞など)を抽出する

翻訳とテキスト要約についてはわかりやすいと思いますが、その他について少し補足します。

質問応答

参考情報となる文章、例えば特定の事実に関して書かれた文章と、それに関する質問事項をセットで入力し、答えとなる文章を生成します。

例えば以下はWikipediaの東京に関する概要部分の引用ですが、

東京は、江戸幕府が置かれていた江戸(えど)という都市が1868年9月(慶応4年7月)に名称変更されたものである。もともと江戸の地には江戸幕府すなわち政府が置かれ、徳川家の人々と老中らが政治を行っており、その一方で京都にも、江戸幕府に日本統治を委任していた朝廷があり、天皇と太政官がいるといった状態の役割分担や二重構造(「複都制的」状態)があった。1869年3月28日に、京都に「都(みやこ)」としての位置付けを残したまま、「東京」に奠都(てんと)された。こうして東京は日本の事実上の首都の役割を担ってきた。

このような文章と、「東京の元々の名称はなんですか?」といった質問をモデルに与えてあげて、「江戸(えど)」と答えさせるようなタスクになります。生成AIを利用する際の重要技術となっているRAG(後述)の仕組みと非常に似ています。

テキスト分類

与えれた文章が、あらかじめ決められた区分(クラスとも呼びます)のどれに該当するかを判定させるタスクです。

代表的な例でいえば、SNSや口コミサイトなどにおけるユーザの書き込みを「ポジティブ」、「ネガティブ」、「ニュートラル(どちらとも言えない)」のどれに該当するかを判定する「ネガポジ」判定などがあります。

例えば、

  • 東京店でタコスを2つ注文したが最高だった
    • 「ポジティブ」と判定
  • アメリカへの旅行ツアーのチケットを3人分買ったが、手数料が1000円は普通の相場よりかなり高い
    • 「ネガティブ」と判定
  • 良いか悪いかは、だいぶ天気に影響されそう
    • 「ニュートラル」と判定

といった具合です。少ない量の書き込みであれば人が目で見て判定することも可能ですが、SNSなどの大量の書き込みを分析する際にはこのような技術が役に立つでしょう。

エンティティ抽出

ここでいうエンティティというのは固有名詞や数詞などになります。Named Entitiy Recognition(NER)と呼ばれたりもします。

先ほどの例で説明すると、

  • 東京店でタコスを2つ注文したが最高だった
    • 「東京」、「タコス」、「2」がエンティティ
  • アメリカへの旅行ツアーのチケットを3人分買ったが、手数料が1000円は普通の相場よりかなり高い
    • 「アメリカ」、「3人分」、「1000円」がエンティティ

という具合です。

ここで「これが何の役に立つの?」と思われた方もいるかも知れません。エンティティ抽出はこれ単体で役に立つというより、そのほかのタスクと組み合わせて利用することで真価を発揮します。

例えば、先述の「質問応答」の例の際に「東京の元々の名称はなんですか?」という質問の参考情報として、Wikipediaの東京の情報を与えました。ですが、「参考情報をどうやって取ってくるのか?」という問題があります。そこで、「東京」というエンティティが抽出できれば、「東京」というキーワードをもとにWeb検索などで参考情報を取ってくるというアクションが可能になります。

別の例として、オンライン注文システムのチャットボットを考えたときに、「テキスト分類」と「エンティティ」抽出の組み合わせが役に立ちます。先ほどの「テキスト分類」の例ではユーザの書き込みを分類していました。これを以下のように少し変更します。

  • タコスを2つ注文したい
  • アメリカへの旅行ツアーのチケットを3人分買いたい
  • 天気を知りたい

といったユーザの発言とします。オンライン注文システムのチャットボットとしては、以下の2つの情報が必要になります。

  • ユーザの意図は何なのか?
    • 何かの情報を知りたいのか
    • 何かを注文したいのか
  • 注文するとしたら何を何個買いたいのか?
    • 料理なのか
    • 旅行チケットなのか

オンライン注文システムのチャットボットを考えたときに、「天気を知りたい」といったユーザの意図には答えないのが適切でしょう。なので、ユーザの発言が何を意図しているのかを「テキスト分類」において把握し、抽出された「エンティティ(何を、いくつ)」をもとにオンライン注文システムのAPIに対してリクエストを行うことで実際に注文を行うことができます。この仕組みは生成AIにおけるFunction Calling(後述)という仕組みと非常に似ています。

生成AIも同様のタスクが得意、かつお手軽に実行可能

これらのTransformerが得意とする代表的なタスクは、生成AIも得意とするタスクです。そして、前述のように生成AIにおいては追加学習をすることなく上記のタスクをこなすことが可能です。生成AI登場以前は、追加学習を行うプロセスや追加学習のための学習データを用意することも一つのハードルとなっていましたが、生成AIの登場によって、AIによるタスク実行の敷居が、生成AI登場以前とくらべて圧倒的に下がりました。

Transformer時代は英語用のモデル、日本語用のモデル、スペイン語のモデル…といったように各種言語用のモデルが必要でしたが、生成AIは多言語モデルのものが多いです。そのため、英語から日本語、日本語から英語への翻訳などは簡単に実行できます。さらに、既存のAIモデルは「翻訳」と「要約」とは別々のタスクでしたが、生成AIであればその二つを同時に実行できます。英語の文章を与えて、「日本語で要約して」とプロンプトに入力すれば「翻訳」と「要約」を同時に行えます。

日々の業務を分解して考えたときに、これらの生成AIが得意とするタスクを活用できる領域はないかを考えることが生成AI活用の第一歩であると考えます。そして、ビジネスのあらゆる場面で「言語」というインターフェースが使われているので、活用できる場面は必ずあるはずです。

生成AIの真価を発揮させるために

このようにテキストに対するAI利用のハードルを劇的に下げた生成AIですが、一方で生成AIだけの利用ではおのずと限界があります。生成AI単独利用時の課題点として以下のようなものが挙げられます。

  • ハルシネーションの低減
  • リアルタイムデータ、プライベートデータへの対応
  • 現実世界との連携

ハルシネーションの低減

生成AIのデメリットとして色々なところで取り上げられているので、ご存知の方も多いと思いますが、ハルシネーションとは「生成AIがもっともらしい嘘のテキストを生成すること」 です。例えば、先述の「質問応答」の例で言えば、「東京の元々の名称はなんですか?」に対し、「京都」などと回答するなどです。少し知識があれば明らかに嘘だとわかるわけですが、まったく日本のことを知らない人からすると信じてしまってもおかしくないでしょう。

これに対する有効な解決策としてよく用いられるのがRetrieval Augmented Generation(RAG) です。これは「生成AIに対して外部から取得した情報を参考情報として渡してテキストを生成させる手法の総称」です。先述のTransformerが得意とするタスクの「質問応答」と同じように回答の根拠となるべき情報を与えてあげることで、ハルシネーションをかなり低減できることが知られています。

また、RAGに使われたデータをユーザに示すことで、何を根拠とした回答であるかをユーザに示せるというのもRAGを行うメリットの一つです。それによって情報の確認がやりやすくなります。

RAG

リアルタイムデータ、プライベートデータへの対応

どんな生成AIモデルであっても、過去の時点の限られた情報で学習されています。当然のことながら、学習時に存在しなかった事柄や、学習データに含められなかった事柄に対しては正しく処理できません。そのため、リアルタイムな情報やプライベートな情報を処理するためには、その情報を生成AIに渡してあげる必要が出てきます。

例えば、最新の情報を得るためにWeb検索エンジンを使って情報を取得したり、社内のプライベートな情報を得るために社内のデータベースから情報を取得したりして、その内容に基づいて生成AIに応答を生成させる必要があります。こうすることで生成AIが学習していない最新の情報やプライベートな情報に基づいて処理をさせることが可能になります。

リアルタイムデータとプライベートデータ

現実世界との連携

生成AI自体は、テキストを入力として別のテキストを出力するツールとみなせます。すなわち、本質的には利用者とのテキスト情報のインタラクションに留まります。それだけでももちろん価値がありますが、現実世界に及ぼす影響はどうしても限定的になります。そこで、生成AIをより活用するために、生成AIにより外部APIの利用を自律的に行わせるAIエージェントという考え方があります。

AIエージェントの肝となる考え方は「どのようなアクションを、どのような情報を使って行うかを生成AI自体に判断させる」ということです。より具体的には、生成AIに対して「使用できるアクション(具体的にはプログラムにおける関数)」と「アクションに必要な情報(関数に与えるべき引数の内容)」を提示して、適切なアクションの判定とそれに付随するパラメータの抽出を行わせます。これは前述のTransformerが得意としたタスクの「テキスト分類」と「エンティティ抽出」の発展系とでもいうべきものです。

例えば、前述のRAGを行う際に、どのようにデータを検索するかという課題があります。利用者の入力に対し、Web検索すべきなのか、データベース検索すべきなのか、そもそも何かを検索すべきではないかの判断がまず必要になります。そして、Web検索やデータベース検索するにしてもどのようなキーワードを使えばいいかの判断も必要になります。このような判断を生成AI自体にやらせるのがAIエージェントの発想です。

これによって、生成AIはテキストを処理する役割を超えて、ITシステムの頭脳としての役割を果たすことができるようになります。

なお、このような機能はAmazon Bedrockで使用できるClaude3などの生成AIモデルではFunction Callingという名前で機能化されています。機能化されていないモデルであっても、プロンプトやファインチューニング(追加学習処理) によって対応することができます。

生成AI活用におけるAmazon Bedrockのメリット

生成AI活用における前述の課題を考えたときに、Amazon Bedrock自身が持つ、以下のような機能は生成AI活用におけるメリットになります。

  • 豊富な生成AIモデル
  • RAGのためのナレッジベース機能
  • AIエージェント機能
  • ファインチューニングによるモデルのカスタマイズ機能

さらに、生成AIの真価を発揮させるためには、生成AIのモデルやプロンプトだけでなく、 RAGの情報源となるデータ、連携する対象としてのシステムが重要になります。既にAWS上でビジネスにおけるシステムが稼働しているのであれば、データがAWSに既に存在することが多いでしょうし、既存のシステムと連携するという意味でも、生成AIをAWS上で稼働させることができるBedrockを利用することはメリットが多いと思います。

つまり、生成AIの活用のためのシステムインテグレーションをする上でも、Amazon Bedrockは便利なツールとなります。

さいごに

本記事で述べたことを端的に書くと、以下のようになります。

  • 現在の多くの生成AIのベースとなっているTransformerが得意としたタスクを生成AIも得意としており、そこに活用法のヒントがある
  • 生成AIの真価を発揮させるためには、データやITシステムとの連携が重要である
  • Amazon Bedrockはそのための強い武器となる

次回以降では、個々の要素について深掘りしていきたいと思います。

RPGのレベルデザイン(バトル編)の初歩について

0

今回は、アピリッツの知識共有サイト「ナレッジベース」で公開されている内容をアピスピでも紹介します。
ゲームディレクターとしても活躍されている巌光生さんの記事です。
是非最後まで読んでください!(初版:2023年2月1日)

 

先ずはゲーム全体のコンセプトを理解する。

製作するゲームのコンセプトを掴む。

例えばIPであればオリジナルのコンテンツである、

  • アニメ
  • 映画
  • コミック

などに基本のコンセプトが存在します。

特にIPの場合はゲーム化にあたり、それに独自の+αが加えられる場合もあるが、ユーザーにとってはオリジナルのイメージが反映されていることで、より没入感が生まれゲーム全体を引き立てる事ができます。

例として最近まで製作に携わったIP系のゲームを挙げてみます。このゲームのコンセプトはでした。

某海賊王のゲームですが、コミック上で仲間たちが総力戦を行うことがあまり存在しない。(主に対等か1VS多勢)本来、RPGであればパーティの職業や役割があり、パーティで敵に挑む形になるのですが、このゲームでは、コミックのイメージを元に以下のように構成しました。

  1. バトルフィードを4~6の区画に分け、各キャラクターを配置するようにした。
  2. 1区画には通常6人まで配置ができ、大きさにより存在できる体数が調整される。
  3. バトルの状況やステータスに応じてキャラクター同士の会話や演出が発生する。
  4. 各キャラクターには原作に応じたパラメーターを設定し、キャラクター性を引き立たせる。
  5. 区画間は対峙する敵がいない(倒した)場合と味方がピンチの場合に移動が可能になる。

上記のバトル設計を踏まえてパラメーターのテーブルを作成していく事になります。

データテーブルの設計

戦闘の仕様と方針が決定した時点で必要なパラメーターのテーブルを作成します。

キャラクターのイメージを具現化するように得手不得手をパラメーターに含んでいきます。パラメーターの種類や効果はかなり増えますが、後のダメージ計算などにどう結び付けるかを考慮し、数値化(比率や確率)やフラグ(有る無しによる判定)化することで扱いやすくなります。また、数値に関しては、今後の拡張も含めLONG INTEGERで幅を取っておくことが大切です。

レベルデザインとデータ作成と順序について 

ここから実際にデータを作成しレベルデザインを行っていくのですが、最終的な調整や追加を考慮して、以下の手順で設定していくことでスムーズな開発が行えます。

1)メインとなるプレイヤーキャラクターのステータスを設定する。

  • メインキャラクターの成長値や装備加算値を数値化し設定する。
  • 成長値や加算値は各ステージの難易度を仮定し増加率を定める。
  • 基本的にはゲーム全体の10%~20%まではなだらかな上昇で導入難易度を低めに設定する。
※上記は例として単一のパラメーターですが、実際には攻撃、防御、他複数の値が存在します。

2)キャラクターのステータスは ここでほぼ決定して規定値とする。

最終的に調整や追加は行えるが、全体に影響するため、第一にプレイヤーキャラクターを基準にしなければならない。

3)プレイヤーのキャラクターに対して敵のステータスを決定していく。

ここからが本当の意味でのレベルデザインとなります。プレイヤーのキャラクターに対して、強弱を決めることでバトルの難易度が決定されていきます。当たり前のことのようですが、このステータス決定の順番が大切です。

プレイヤー側のステータスがある程度固定化していれば、敵側のステータスはどのようにでも調整ができるからです。また、プレイヤーが追加された際にも、それに対応した敵を作成できるのでバランスが頭打ちになることがありません。

敵のデータはエクセルなどにダメージ計算式を仕込み、分かりやすい形でデータを算出できるようにしておくと良い。実際にどのような算出を行うかと言うと、例えば敵のHPを算出したい場合、プレイヤーの攻撃によるダメージ計算でどのくらいの値が出るかを割り出し、それに何回耐えられるかを設定するとよい。

例えばプレイヤーの与ダメージが敵の防御値を減算した場合の数値がAとした場合、3発は耐えられるとするなら、HP=A×3.2(コンマ以下は残HP)と言った簡単な算出が行える。

プレイヤーに与えるダメージにしても、プレイヤーの防御値を含めたダメージ計算でプレイヤーに対して何割くらいの与ダメージが与えられるかを計算すれば良い。プレイヤーが該当LVの時に200のHPであればHP全体の何%を減らせるかで攻撃値を算出できます。

ここまでのまとめ

  1. バトルのデータはゲームコンセプトに合わせて設計する。
  2. データの作成はプレイヤーから決定し、それを基準とする。
  3. 敵のデータはゲーム内のダメージ計算からできるだけ簡易に算出できるようにする。

上記を踏まえて、ダメージ計算式をエクセル、またはスプレッドシート上でシミュレートし、 バランスを目視できるようにすることで、全体のバランスも見えてきます。

トータルでのバランスとレベルデザインについて

ユーザーが遊びやすく継続しやすいデザイン

これは製作するゲームのコンセプトによって異なると思いますが、よりユーザーが遊びやすく継続しやすいバランスにすることが大切です。

ゲーム開始時は敵を容易く倒せる程度にする。全体ボリュームの10~20%はあまり悩まずに進めるほうが良いでしょう。デフォルトで戦って倒せる程度と言うことになります。

キャラクターを強くする、強化する事にユーザーが慣れ始めたら敵のステータスを上げていきます。この時に、ポイントとして弱点を設定し、ユーザーに強化することの意味を促します。加えて、敵のAI等に変化を加えバトルに対しての戦略性を促します。(回復や妨害などの行動を追加していく)

後半に向かってはロジック的に攻略方法を仕込んで行く工夫が必要となります。正しい行動に対して正解を導けるように敵の行動を組み立てることが必要になります。これもバトルとしてユーザーが飽きないようにするための手法です。

シナリオ、または世界観への没入を妨げないバランス

レベルデザインの要ですが、ゲーム進行の上で大切なのは物語の進展です。

ユーザーの心情に沿った敵の強さや障害は、よりバトルを引き立てます。シナリオとの親和性も十分考慮すべきでしょう。

なので、画一化したシステムでデータだけ完璧にしても、ユーザーにとってバトルは作業になってしまいます。

システム、ジャンルによる調整について

ここまで上げた例は、基本的にデータによるバランスのとり方ですが、システムによってはアクション重視のバトルもあります。ここでは簡単に手法だけ記載します。

アクション重視のRPG場合

データも無論重要ですが、ユーザーテクニックを重視する場合があります。この場合以下の方法で調整します。

  1. モーションヒットストップのタイミング(プレイヤー側)
    攻撃モーションに対してヒット時のラグタイム(次の入力許可)を制限します。
    大技ほどヒットストップが長く、 敵に対してプレイヤーの行動時間が制限されます。
    アクションの場合、ヒットストップは10f~60f程度なので、実際にはもたつきは感じません。
    また、行動のキャンセルなども行えればアクション性が高まります。
  2. AIの索敵時間(敵側)  敵の場合はヒットストップだけではなく、AI内にもウェイト(索敵)を仕込むことができます。
    行動命令が短いほど敵は強くなります。(連続行動、思考を進める)
  3. 上記に加え、モーションの長さなどにより、入力のタイミング、キャンセルをコントロールします。

巌さんありがとうございました!

アピリッツでは自分が得た情報や技術を積極的に共有し、それらを吸収しながら各々のスキルアップを目指しています。
アピリッツに少しでも興味を持った方、エントリーお待ちしております!

エントリーはこちらをチェック→〈https://recruit.appirits.com/

大好評!社内イベント開催しました!

0

こんにちは!今回は、先日当社で開催された社内イベントの様子をお届けします。競技には創造性と体力が試されるものが含まれ、社員一人一人が存分に楽しむことができました。最後までお楽しみください!

イベントの見どころを紹介!

1.誰よりも早く解き明かせ!頭脳編

脳みそフル回転!問題を解くのに、みんな真剣。ここぞとばかりに頭の回転を競いました。

そして問題を解くだけで終わらないのがアピリッツ。。

パズル問題を解く参加者はもう真剣そのもの。。

なんと、当日のサプライズルールとして回答が終わった人から採点者のいる場所までダッシュ!(は、危険なので早歩きで(笑))

採点者のところへGO!果たして正解していたのか。。!?

意外と難しくて苦戦。。(私もむっちゃ苦戦しました)そんなときの救済!名付けて「助っ人タイム」を用意し、わからないところを社員に聞いて回ったり、参加者以外とのコミュニケーションも取りながら、正解を探していました。

2. 全集中、バランス体力編

バランス力をキー――プ

片足立ちでどれだけ長く持つかを競うんですが、思った以上に盛り上がる!

白熱した戦いで見ている側もドキドキしました。。!

なんとこちらの競技にもサプライズルールが!!

片足立ちだけで終わるかと思いきや、つま先立ちまで!?

トーナメント戦で行われたこの競技。最後まで白熱していました。

3. センスを輝かせ!フォト・イラストコンテスト

事前に社員から寄せられた写真やイラスト作品を社内投票で選出。

「アニマルスピリッツ」というテーマに沿ったクリエイティブな作品がたくさん集まり、当日の結果発表の瞬間はドキドキ!

1~3位に輝いた作品たち。同じテーマでもこんなにもそれぞれの個性豊かな作品が!

イベントのハイライト

当日は社内でライブ中継もして、100名以上の社員がリアルタイムで視聴。画面越しにも応援の声が飛び交っていました。

三位おめでとうございます!配信内でも祝福の声が!!

競技ごとに豪華な景品が用意され、それがまたみんなを奮起させてました!

景品最後の一枠を見事つかみ取り喜びのピース!!

まとめ

イベントを通じて、社員同士の絆が一層深まり、互いの新たな一面を発見できたのでは。。!?終始、和やかな雰囲気の中、笑顔で終えることができたのが何よりの収穫。

またこんなイベントがあればいいなと社員みんなが思ってるはず。次回のイベントも、こんな感じで楽しめたらと思います。それでは、また更新しますね!

アピリッツのパパママ社員の働き方!

0

前回のアピスピでは、パパママリモート制度についてご紹介しました!
今回は、制度を利用せずに働くパパママ社員さんの働き方についてご紹介したいと思います!

~小学生のお子さんがいるママさん社員に聞いてみた!~

アピリッツではパパママリモート制度とは別で、週2回のリモート勤務が可能です。

週2回のリモート勤務を利用して働くママさん社員に、仕事と子育てを両立するコツをきいてみました!

リモートワークを活用して家族時間を大切に!

――仕事と子育てを両立するコツは?

どうしても時間の融通が利きにくいので、タスクの見極め、達成までのイメージはしっかり行います。イメージどおり進行していない場合に備えて、毎日ベースで細かくスケジュールを調整します。

また、急なトラブルに備えて、自分しかできないこと・知らないことを増やさないようにしたいのですが、忙しいとなかなか対応できないので、目下の目標です!

現在は、自分も主人もリモートワークができるので、子供が風邪で学校を休んだ時は主人と協力し合って仕事と子育てを両立しています

――リモートワーク時に気を付けていることはありますか?

時間を決めていないとだらだら仕事してしまうので、子供が家に帰ってきたら仕事しないっていうのを心がけています。

子供のそばで仕事をしているとセキュリティ上も良くないですし、一人っ子なので、子供を1人にして寂しい思いをさせないように家族の時間を大切にしています。

子供のいる生活は毎日が未知!だから楽しい!

――現役のパパママ社員や、将来の子育てと仕事の両立に不安を抱えている方々へひとことお願いします!

子どもがいると、時間に縛られたり突発的な事情が発生したりと全力で働けないイメージがありますが、私個人は自分の働き方を見直し、タスクを盲目的にこなすのではなく効果や達成までの道のりを見極めるようになり、仕事の質が上がったと感じています。

私も最初は思ったように仕事ができなくて葛藤することもありましたが、葛藤は誰でもあることなので、葛藤している自分に対してマイナスに思わないでほしいです。

道具や制度など仕事の両立をサポートしてくれる存在もたくさんありますので、大変そうと思わずに人生のいちイベントとして楽しんでくれたらいいなと思っています

~育休を取得したパパさん社員に聞いてみた!~

育休取りたてほやほやです!

――育休中の1日のスケジュールを教えてください!

今年の2月くらいから1か月ほど育休を取得していました!

「朝は日の光をちゃんとを浴びせる」「3時間おきにミルクとおむつ交換」「夜に眠れるように、昼は一緒に遊ぶ」など、よくある赤ちゃんのスケジュールで過ごしていました。

1人の時間と妻とのコミュニケーションを大切に。

――育児と仕事を両立するコツや逆に大変なことはありますか?

自分が家だと集中できないことと、家が少し狭いので家族と同じ空間で仕事をしなければならず、妻にも気を使わせるので利用していないです。。
機会があれば利用させていただきたいと思ってます!

アピリッツの先輩パパママ社員は子育ての強い味方!

――現役のパパママ社員や、将来の子育てと仕事の両立に不安を抱えている方々へひとことお願いします!

なんだかんだで子供は可愛いですし、今までとは違う意識で仕事に取り組めます。
良くも悪くも楽しいので、不安がらずいっそのこと楽しんでください!
あとは、一人で抱えないで同じパパママ社員と話すのが良いですよ。
アピリッツには先輩パパママ社員がたくさんいるので色々アドバイスくれると思います!

ーー貴重なお話をありがとうございました!!

アピリッツにはパパママリモート制度というものがあるらしい、、、!

0

アピリッツには多くのパパさん、ママさん社員が在籍しています。
でも子育てと仕事の両立はやっぱり大変・・・
アピリッツでは、そんなパパさん、ママさん社員を助けるべく、パパママリモート制度という制度を試験運用しています。
実際にパパママリモート制度を活用している社員さんへのインタビューをもとに、制度についてご紹介したいと思います!

パパママリモート制度とは??

アピリッツでは週2回のリモート勤務が可能です。
でも、「急に子供が体調不良になってしまった!」「子供のイベントに参加しないといけない!」「週2回のリモートだけでは足りない!」
そんなパパママ社員さんの声から生まれたのがパパママリモート制度!
子育てをするパパママを対象に、普段の週2のリモートワークに加えて、追加で取得できる制度です。


パパママリモート制度を活用している社員さんに聞いてみた!

ーー現在の働き方について教えてください。

現在はリモートと、時短でのオフィス勤務を併用しています。

ただ、子供が双子でまだ二歳ということもあり体調を崩しがちであったり、しかもそのタイミングもばらばらだったり、急な学級閉鎖などなど。。ハプニングが度々起こるのですが、そんな時にパパママリモート制度を活用させていただいています!

正直かなり助かっています。。これがなかったら有休はとっくに無くなっていました(笑)

ーーパパママリモートって実際どう?

月単位ではなく、年単位で取得上限が設けられているのはかなり助かってます。

実際、保育園などでインフルエンザ等に感染した場合に「解熱後24時間経ってから登園可能」といったルールが設けられていることがあります。

その時は、一週間ずっと家にいなければならなかったりするので、このリモート制度はめちゃめちゃ助かりましたね!

ーー現在は試験運用中ですが、パパママリモートの利用状況や課題等を確認しながら本格運用を目指していきたいと思っています!


アピリッツのパパママ社員の働き方は様々!

小学生のお子さんがいるママさん社員

「今はリモートワークが当たり前にある時代ですが、うちの子が小さかった頃はそもそもリモートワークという概念がなく、アピリッツでもリモート制度がなかったので大変でしたね。。今は子供も大きくなったので、週2回のリモート勤務を活用しています!」

育休を取得したばかりのパパさん社員

「パパママリモート制度があるなんて知らなかったです。。(笑)

うちは子供が生まれたばかりですが、今のところパパママリモート制度を利用する予定はないですね。(家だと集中できないのと、家が少し狭いため)機会があれば利用させていただきたいと思ってます!」


ーー貴重なお話をありがとうございました!!

アピリッツは働くパパママ社員さんを応援しています!!

今回はパパママリモート制度についてご紹介しました。

次回は制度を利用せずに働くパパママ社員さんの働き方についてご紹介したいと思います!

課金の実装時にサーバー側は何をやるのか

0

今回は、アピリッツの知識共有サイト「ナレッジベース」で公開されている内容をアピスピでも紹介します。
エンジニアとして活躍されている鳴澤秀夫さんの記事です。
是非最後まで読んでください!(初版:2021年12月22日)

え!!一切未経験なのに課金実装を!?

エンジニア兼デスクにフィギュアを置いてモチベを上げる者の鳴澤です。

執筆時現在はPHP/Laravelを使用してUnity製ソシャゲ(パズルゲーム)のバックエンドをやっています。

今回はその案件での体験談的なメモを残します。
注) 今回はあくまで「何をやるのかのメモ」程度ですので、詳細な手順やソースコードなどは割愛します。

サーバー側は主に”不正チェック”をする!

まず、課金処理がどのようなフローになっているかを以下のシーケンス図にまとめてみました。

サーバー側はこの中でも4〜7の工程が大事になってきます。

※ 課金APIとは、GooglePlayStoreやiTunesStoreといった課金プラットフォームが用意したAPIの意味です

これだけ見るとナンノコッチャだと思うので、以下で軽く解説してみます。

工程1〜3 アプリ(クライアント)側の処理 

ソシャゲで石を買おうとした時、AndroidやiOSのUIで「課金しますか?」みたいな確認画面が出ると思います。
そこで購入処理を行うと、アプリから課金APIへ購入処理のリクエストが送信されます。

正常に決済処理がされたら「レシート」データが返ってきます。(これが後に大事になります)

なんと、この時点で課金処理そのものは完成しているのです!

しかし大抵のソシャゲはアプリ側の処理だけでは終わらず、サーバー側と連携してアイテム付与などを行いますよね?

なのでサーバー側でAPIを実装し、アプリ側から叩いてもらいましょう。
その際、先程課金APIから返ってきた「レシート」をリクエストに含んでもらいます。

“レシート”とは何か

課金APIに決済処理をリクエストした際の取引の詳細がまとまったJSONデータです。
プラットフォームによってはbase64で暗号化された状態で返ってきたりします。

決済をして返ってくるデータなので正にレシートと言ったところですね。

このレシートには主に

  • 購入日時(エポック秒)
  • 商品のID(ストア側で設定ができる)
  • 取引ID(トランザクション番号とも。アプリ単位で一意な文字列が入る)

といった、誰がいつ何を買ったかを一発で特定可能なデータが入っています。
この”一意なデータ”であることが、今後のチェック処理で大事になってきます。

工程4〜5 レシート検証

アプリ側からサーバー側へは、決済時にストアから返ってきたレシートをリクエストに含めてAPIを叩きます。
サーバー側は、このレシートがあること(買った事実があること)を確認して石やアイテムを付与するんですね。

そこで悪い人は考えました。
偽装レシートを使ってサーバー側APIを叩きまくったら、大量に石をゲットできるんじゃね!?」

こういう悪人に”エラー表示”という正義の鉄槌を下すために実装するのが「レシート検証」です。

要するに不正防止策ですね。

実装方針

実はアプリ側に返ってきた物とは別に、ストア側にもレシートが保存されています。
ストア側の課金APIにレシートを請求することで、アプリから送られてきたレシートが偽装された物でないかチェックが可能なのです。

存在しないレシートだった場合は課金APIからエラーが返ってきますので、エラーか否かでチェックすれば間違いないので簡単ですね。

GooglePlayStoreではレシートを取得するためだけにOAuth認証をしてアクセストークンを取得する必要があるのですが、これが結構面倒でした。
この辺に関しては別の機会にまとめられたらと思います。

工程6〜7 重複チェック

ここまでの実装で、偽装レシートを用いた不正は防ぐことができましたね。

そこで悪い人は考えました。
過去のレシートを使って偽装じゃないと認識させれば、大量に石をゲットできるんじゃね!?」

こういう悪人を”わからせる”ために実装するのが「重複チェック」です。

アプリ側の問題で同じリクエストが2連続で飛んでくるケースもあるため、不正対策だけでなくバグ防止の観点でも大事な部分です。

実装方針

先程も軽く触れましたが、レシートには 「購入日時(エポック秒)」や「取引ID」といった組み合わせると完全に一意となるデータが色々入っています。

これらをゲーム側のDBに保存しておき、全く同じレコードが存在しないかを検索するのが一般的な手法です。

工程8 DBに保存 

こうして正常なレシートであることを証明できたので、DBの更新をします。

売り物のアイテムをユーザーDBに付与して保存する他、先程の重複検証で用いた”一意なデータ”も別途テーブルに保存します。

ここでレシートの値を保存することで、次回以降の重複チェックで比較対象として使われていくことになります。

他にも何かやるの?

  • 各ストアにテスト用の商品を登録(面倒)
  • 各ストアにテストプレイを許可するアカウントを登録(面倒)
  • OAuth認証やトークン周りの実装(面倒)
  • サービス用のアカウントを作成し、課金APIのアクセス権限を付与(面倒)
  • 今回の記事は通常課金のケースだけど、別途月額課金にも対応するよう実装(超面倒)

と、やることが結構多くて実装頑張ったなと自分でも思います。
この辺は今後少しずつ紹介できたらなと思っています。


鳴澤さんありがとうございました!

アピリッツでは自分が得た情報や技術を積極的に共有し、それらを吸収しながら各々のスキルアップを目指しています。
アピリッツに少しでも興味を持った方、エントリーお待ちしております!

エントリーはこちらをチェック→〈https://recruit.appirits.com/

新入社員たちのビジネスマナー研修、そのリアルな現場から

0

こんにちは!今日は、新卒社員を対象にビジネスマナー研修を行いました。どんな風に過ごしていたか、ちょっと覗いてみましょう!

緊張と真剣さが交差する講義時間

マナー研修日、新入社員たちは真新しいスーツに身を包み、何やら緊張した面持ち。講義が始まると、みんな真剣そのもの。社会人として知っておくべきことを一つひとつ学んでいきます。

筆記用具を片手に、講師の話に耳を傾ける姿はまるで大学の講義を思い起こさせるよう。でも、ここでの学びは学問だけでなく、「実際のビジネスシーン」で使う実践的なもの。それが、彼らの緊張感を一層高めているようです。

リラックスして学ぶ、グループワークの時間

講義中には、グループワークでの実践も挟み、講義で学んだ内容を元に、ロープレ形式で実践的な練習を行います。最初はぎこちない動きも、同期が助けてくれたり、互いに笑いあったりしながら、だんだんと慣れてきます。

自身の携帯を利用しての電話研修。いろんなシチュエーションで何度も挑戦!
新卒社員にとって初めての名刺交換。我々もルールを改めて聞いて再発見する面もありました(笑)
研修のグループは完全ランダムでしたが、全員初めてという共通点から仲を深めていきました。


この時間があるからこそ、新入社員たちは緊張を解きほぐし、自然体でスキルを身につけることができるんですね。お互いに「こうしたほうがいいよ」とアドバイスを交換する姿は、まるで学生時代のグループ活動を思い出させます。楽しみながら学ぶ、これが成長への近道かもしれません。

研修終わりには。。

研修が終わる頃には、朝の緊張した面持ちもどこへやら。新入社員たちは少し疲れた様子もありますが、明らかに自信に満ちた表情に変わっています。実際に研修を終えた新卒社員の声を聞いてみると。。

・現在だけでなく今後どのような社会人になりたいのかなど将来的な物事を考えるきっかけにもなりました。
・マナー・身だしなみ、所作、振る舞いはすごく周りに見られる。会社の代表として恥ずかしくない振る舞いをしたい。
・想像以上に細かいマナーが存在していてびっくりした。

一日でこんなにも変われるんだから、これから数ヶ月、数年で彼らがどれだけ成長するのか、考えるだけでわくわくします。そして、研修終わりには何か行われたそうです、、が、その様子はまた次回のアピスピで紹介します!

社会人としての一歩を踏み出した新入社員たち。彼らのこれからの成長に、私たちも大きな期待を寄せています!

UnitySentisでSpeechToTextをしよう

0

はじめに

コーヒーにこだわりたいけど豆に触れると沼だと思って手を出していません。ゲームエンジン・エンハンスメント学部 中村です。前回の記事ではUnitySentis+ML-Agentsのサンプルに触れたので、今回はもう少し踏み込んでUnitySentisを用いたSpeechToTextを実行しましょう。さらに声をコマンドにしてキャラクターを動かすちょっとしたゲームを作っていきます。

UnitySentis

前回の記事でも触れましたが、Unity Sentisはニューラルネットワークをもとに学習されたonnxファイルをインポートし、そのAIモデルをUnityがサポートするプラットフォームで直接実行することができます。これによって、音声認識や手書き文字認識などがWebを経由することがないので、ネットワークインフラに依存する必要がなくなります。

まずはサンプルから

何事もまずはサンプルから始めていきましょう。

UnitySentisでSpeechToTextを実行するためには、そのAIモデルが必要になります。SpeechToTextといえば、Web上から実行できる OpenAI 製の Whisper が有名なのでそちらを利用しましょう。WhisperはHuggingFaceにオープンソースで公開されており、その構造の詳しい説明書も含まれています。

今回はUnityから公開されているこちらのサンプルを使用していきます。このサンプルに含まれているファイルは以下のとおりです。

  • answering-machine16kHz.wav:テキストに変換したい音声ファイル
  • LogMelSepctro.sentis:音声波形をlog-melスペクトル変換するモデル
  • AudioEncoder_Tiny.sentis:log-melスペクトル変換された音声からその特徴量に変換するモデル
  • AudioDecoder_Tiny.sentis:音声特徴量とテキストトークンから次のトークンを予測するモデル
  • vocab.json:トークンと文字の組み合わせ
  • RunWhisper.cs:UnitySentisを利用してSpeechToTextを実行するコード

このサンプルではReadmeに記述されている通りの手順で実行していきました。

  1. Unity2023.2.11 で新規プロジェクトを作成し、サンプルファイル群をインポート
  2. com.unity.sentis パッケージをインポート
  3. RunWhisper.cs ファイルをMainCameraにアタッチ
  4. sentisファイルとvocab.jsonをAssets/StreamingAssetsフォルダへ移動
  5. answering-machine16kHz.wavをインスペクタから “Force Mono” と “Decompress on Load” をONにする

この状態でUnityをPlayすると、以下のようにデバッグログが出力されて音声がテキストに変換されている様子を確認できます。

音声を認識してテキストに変換していく様子

サンプルの中身を理解する

一旦 Unity 上で SpeechToText が動作していることを確認できました。ここで RunWhisper.cs がどのような動きをしているか見ていきます。私の理解でコメントを付けています。

void Start()
{
    // 推論に利用するテンソルをキャッシュ,もしくは単にメモリ割り当てを行う仕組み.
    allocator = new TensorCachingAllocator();
    // テンソル演算を実行するインスタンスを生成する(Opsはオペレーションか?).ここでbackendはSentisの実行環境を示しGPUを指定している.
    ops = WorkerFactory.CreateOps(backend, allocator);
    // 変換後の特殊文字を白埋めするのでその配列を初期化.
    SetupWhiteSpaceShifts();
    // vocab.jsonからトークンと文字の割当をロード.
    GetTokens();
    // StreamingAssetsからモデルファイルを読み込む.
    Model decoder = ModelLoader.Load(Application.streamingAssetsPath + "/AudioDecoder_Tiny.sentis");
    Model encoder = ModelLoader.Load(Application.streamingAssetsPath + "/AudioEncoder_Tiny.sentis");
    Model spectro = ModelLoader.Load(Application.streamingAssetsPath + "/LogMelSepctro.sentis");
    // 読み込んだモデルからニューラルネットワークを実行するワーカーのインスタンスを生成する.
    decoderEngine = WorkerFactory.CreateWorker(backend, decoder);
    encoderEngine = WorkerFactory.CreateWorker(backend, encoder);
    spectroEngine = WorkerFactory.CreateWorker(backend, spectro);
    // デコーダーに指定する入出力トークンを初期化する.
    // index:0 は 単に SpeechToText を開始する合図.
    // index:1 は 言語の指定.
    // index:2 は 同じ言語の文字列 に変換するか 別の言語に翻訳するか.
    // index:3 は 文字起こしにタイムスタンプを利用するか.
    outputTokens[0] = START_OF_TRANSCRIPT;
    outputTokens[1] = ENGLISH;// GERMAN;//FRENCH;//
    outputTokens[2] = TRANSCRIBE; //TRANSLATE;//
    outputTokens[3] = NO_TIME_STAMPS;// START_TIME;//
    currentToken = 3;
    // 音声をロード.
    LoadAudio();
    // ロードした音声を変換.
    EncodeAudio();
    transcribe = true;
}

まずRunWhisperのStart内では、テンソル演算に使用するオペレーションやニューラルネットワークを実行するインスタンスを生成しています。この際にAIモデルを指定すれば、内部でその演算を行ってくれます。

また、 outputTokens には SpeechToText の初期状態を設定するトークンを指定しています。このoutputTokensは音声をデコードする際に利用します。さらに LoadAudioでは単にAudioClipを浮動小数点配列として取り出し、 EncodeAudioencoderEnginespectroEngineによるエンコードを行っています。

void EncodeAudio()
{
    // 浮動小数点テンソルを 指定した TensorShapreに併せて生成.
    // ここでは data に音声データが含まれているため,音声データをテンソル化している.
    // SentisのTensorは IDisposable を持つため usingステートメントを利用する.
    using var input = new TensorFloat(new TensorShape(1, numSamples), data);
    // Whisperのエンコード/デコードに対しては30秒の音声データを入力しなければならないため,30秒に満たない場合には足りない分を0で埋める.
    // Pad out to 30 seconds at 16khz if necessary
    using var input30seconds = ops.Pad(input, new int[] { 0, 0, 0, maxSamples - numSamples });
    // 音声データをlog-melスペクトル変換して特徴量を計算する.
    spectroEngine.Execute(input30seconds);
    // 変換結果をTensorで出力する.
    var spectroOutput = spectroEngine.PeekOutput() as TensorFloat;
    // 音声データの特徴量を Whisperエンコーダーに入力する.
    encoderEngine.Execute(spectroOutput);
    // エンコード結果を受け取る.
    encodedAudio = encoderEngine.PeekOutput() as TensorFloat;
}

EncodeAudio メソッド内ではロードした音声データをWhisperエンコードしています。この処理自体は非常に簡単で、音声データからテンソルを生成して、log-melスペクトル変換、エンコード、と順に行っているだけでした。ただ、Whisperでは音声データの長さが30秒であることを基準としています。短すぎる音声ではその推論の制度が低下すると考えられているからのようです GithubDiscussion。その影響でこのサンプル内では足りない分のデータを0で埋めて処理しています。

void Update()
{
    if (transcribe && currentToken < outputTokens.Length - 1)
    {
        // outputTokensをデコーダーに入力するためにテンソルに変換する.
        using var tokensSoFar = new TensorInt(new TensorShape(1, outputTokens.Length), outputTokens);
        // デコーダーへの入力情報を作成.
        var inputs = new Dictionary<string, Tensor>;
        {
            {"encoded_audio",encodedAudio },// EncodeAudioで生成したエンコード済み音声データ.
            {"tokens" , tokensSoFar }
        };
        // デコーダーに入力して実行.
        decoderEngine.Execute(inputs);
        // 実行結果を受け取る.ここでは各トークンに対してどの程度一致しているかの数値が返される.
        var tokensOut = decoderEngine.PeekOutput() as TensorFloat;
        // 出力されたトークンの中から最も大きな数値を持つ(一致している)トークンを探す.
        using var tokensPredictions = ops.ArgMax(tokensOut, 2, false);
        tokensPredictions.MakeReadable();
        // 一致していると判断されたトークンのIDを取得.
        int ID = tokensPredictions[currentToken];
        // 出力トークンとして記憶する. 次のフレームでの推論にまた利用する.
        outputTokens[++currentToken] = ID;
        // 推論が終了したと判断されるか,IDが用意されたトークンを超えるまで繰り返す.
        if (ID == END_OF_TEXT)
        {
            transcribe = false;
        }
        else if (ID <= tokens.Length)
        {
            outputString += $"(time={(ID - START_TIME) * 0.02f})";
        }
        // tokensにはvocab.jsonからトークンと単語の組み合わせが含まれているので,その中の指定のトークンを取り出す.
        // ここで tokens[ID] は新たに推論された単語となる.
        else outputString += GetUnicodeText(tokens[ID]);

        Debug.Log(outputString);
    }
}

Updateは毎フレーム実行されるため、デコーダーによるテキストの推論を少しずつ進めて行くように処理されます。outputTokens はデコーダーへの入力とするためにテンソルに変換され、またデコーダーから推論されたトークンを新たに指定し、次のフレームでまた入力として利用されるようにループしています。デコーダーは事前にモデルを読み込まれたdecoderEngineで実行されます。通常入力された音声データと前回の結果トークンから次のトークンを推論しています。デコーダーからの出力は、vocab.jsonに含まれるすべてのトークンに対してどの程度一致しているかを数値で出力します。そのため、最も大きな数値を持つインデックスを見つければそれが推論されたトークンとなります。推論されたトークンから単語を取得し毎フレームつなぎ合わせることで結果の文章が得られます。

以上、大ざっぱですがサンプルについてその仕組みを記述しました。

今回、このSentisを利用したSpeechToTextを用いて、声で操作するミニゲームを作ってみようと思います。と考えると、音声が30秒限定というのは長くないですか?

AIモデルを出力してみる

Whisperでは短すぎる音声は推論の制度が低下するため30秒の音声ファイルを要求している、ということは理解したうえで、半分の15秒の音声ファイルを処理するモデルを作成してみようと思います。というのも「声で操作するゲーム」を考えたときに、30秒の発言で操作することはほぼないでしょう。15秒でも長いかもしれませんが、ある程度短くできればテンソルサイズが小さくなるのでメモリ節約と処理速度向上が見込めるはずです。

モデル出力スクリプトを利用する

先ほど見たサンプルに含まれる各「.sentisファイル」はonnxAIモデルファイルからUnitySentisが利用しやすいように変換されています。そのため、サンプルにonnxファイルは含まれていません。そこで、そのonnxファイルを手元で出力してみましょう。Whisperのonnxファイル出力もすでに有志によってオープンソース化していますので、こちら whisper-export をお借りします。

今回はWindows+WSL2上のPython3.10.12で実行しました。まず、任意のディレクトリに whisper-export をGitクローンします。その後、以下のコマンドで必要なライブラリをインポートできます。

$ pip install ./
$ pip install onnx

CUDAを利用してonnxを出力するため、以下のコマンドでWSL2上でCUDAが参照できているか確認します。CUDAが参照できない場合、NVIDIA Diriverが古いかインストールされていない可能性があります(1ミス)。

$ nvidia-smi
Sun Mar 24 20:50:15 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.10 Driver Version: 551.61 CUDA Version: 12.4 |
|-----------------------------------------+------------------------+----------------------+

私のWindows環境では NVIDIA Driverが551、CUDAが12.4でした。 whisper-export では torch2.2.1がインストールされるので、CUDAのバージョンを12.1以上に合わせる必要があります(1ミス)。また、CUDAのバージョンが合っていてもPythonから認識されない場合があるので、以下のコマンドで状況を確認します。認識されていない場合にはPCの再起動が必要です(1ミス)。

$ python
Python 3.10.12 (main, Mar 15 2024, 20:29:42) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> torch.cuda.is_available()
True

ここまでのコマンドで設定が確認できたら、いよいよonnxモデルを出力しましょう。以下の2つのコマンドを実行し、エンコーダーとデコーダーをそれぞれ出力します。また、この際になんでも良いので音声ファイルが1つ必要です。元になるモデルはwhisper-tinyです。

$ python cli.py audio.wav --model tiny --device cuda --export_encoder
$ python cli.py audio.wav --model tiny --device cuda --export_decoder

コマンドが正常に完了すると、export_model ディレクトリにdecoder.onnxとencoder.onnxファイルが出力されています。

また、今回の目的は音声データの認識サイズを30秒から15秒に変更することです。これはこのプロジェクト内のaudio.pyでCHUNK_LENGTHを15に変更するだけでした。

出力したモデルをSentisで使用する

手元で出力したモデルを利用するため、先ほど出力した2つのonnxファイルをサンプルプロジェクトのStreamingAssetsではないディレクトリにコピーします(1ミス)。すると、Inspectorには以下の画像のようにonnxファイルを認識した状態の情報が表示されます。ここで入出力の形も確認できるようです。

ここで、Inspectorにある[Serialize To StreamingAssets]ボタンを押すと、StreamingAssetsディレクトリにonnxをSentis用に変換した.sentisファイルが出力されます。サンプルに含まれていた.sentisファイルはこのようにして作られたものです。

これでエンコーダーとデコーダーの2つの.sentisファイルが生成されたので、サンプルに含まれていたRunWhisper.csをこのモデルを利用できるように書き換えましょう。LogMelSepctro.sentisはそのまま利用させてもらいます。

まず、以下のように単に読み込むAIモデルのファイル名を変更します。

Model decoder = ModelLoader.Load(Application.streamingAssetsPath + "/decoder.sentis");
Model encoder = ModelLoader.Load(Application.streamingAssetsPath + "/encoder.sentis");

さらに、サンプルに含まれていたデコーダーと、手元で生成したデコーダーでは入力データの数が異なります。はじめにmaxSamplesで音声の長さを指定しているので15秒とします。さらにkvCacheoffsetの2つのテンソルを用意し入力に加える必要があります。

const int maxSamples = 15 * 16000;

TensorFloat kvCache;
TensorInt offset;

void Start()
{
    ~~~~~~~~~~~~~~~~~~~~~~~
    int kvCacheFixed = 451; // whisper-exportで固定された数値.
    int beamSize = 1; // 推論探索深さ.
    int modelSize = 384; // whisperモデルごとの数値,ここではtiny用.
    kvCache = TensorFloat.Zeros(new TensorShape(8, beamSize, kvCacheFixed, modelSize));
    offset = new TensorInt(new TensorShape(1), new int[] { 0 });
}
void Update()
{
    if (transcribe && currentToken < outputTokens.Length - 1)
    {
        using var tokensSoFar = new TensorInt(new TensorShape(1, outputTokens.Length), outputTokens);
        var inputs = new Dictionary<string, Tensor>
        {
            {"audio_features",encodedAudio },
            {"tokens" , tokensSoFar },
            {"offset", offset},
            {"kv_cache", kvCache }
        };
        decoderEngine.Execute(inputs);

これで手元で出力したwhisperのAIモデルを使用する準備が整ったので、Unityをプレイします。

手元で生成したAIモデルを使用してSpeechToText

ログに出力される結果はサンプルとまったく同じです。

ここで、音声の長さを15秒としたことが正しく反映できているかは以下のログを出力すると確認できます。

Debug.Log($"encodedAudio: {encodedAudio.shape}");

このとき出力されるのは音声がエンコードされた後のテンソルの形状です。30秒のとき、15秒のときでそれぞれログは以下のようになります。

# 30秒のとき
encodedAudio: (1, 1500, 384)
# 15秒のとき
encodedAudio: (1, 750, 384)

これで手元で出力したAIモデルが利用できていることを確認できました。

音声で操作するミニゲーム

それではSpeechToTextを利用したミニゲームを作ってみましょう。

まずは音声を認識せずに、キーボードで動かす簡素なゲームを作ります。

出来上がったものがこちら

色のついた箱を指定の位置へ運ぶ

キーボードでユニットを操作し箱を指定の位置まで移動させます。画面中央にはその時ユニットに与えられた命令を表示しています。現状はキーボードからこの命令を与えていますが、ここに音声認識を組み込んでいきましょう。

音声をリアルタイムに処理する機構

これまでのサンプルでSpeechToTextする際の音声データはwavファイルになっていました。「音声で操作」するためにはマイクからの入力をリアルタイムに変換していく必要があります。この機構を作りましょう。

まず、Unityでデバイスのマイクを利用するには以下のように記述します。モバイル端末ではマイクの利用許可ダイアログの表示が必要ですが、現在Macで動作させているのでこれだけの処理でマイクを利用できます。

if (Microphone.devices.Length == 0)
{
    Debug.Log("microphone not found");
    return;
}
microphoneName = Microphone.devices[0];
Debug.Log("find microphone : " + microphoneName);
audioClip = Microphone.Start(deviceName: microphoneName, loop: true, lengthSec: audioSecondLength, frequency: audioFrequency);

このコードによってaudioClipからはマイクから入力された音声がそのままAudioClipとして参照できるので、以下のようなコードでそのデータを取得できます。

// AudioClipの現在の位置.
int position = Microphone.GetPosition(microphoneName);
if (position < 0 || position == prevSamplePosition) return;
// 全データをバッファに取得.
audioClip.GetData(dataBuffer, 0);
// 前回確認した位置と現在の位置を比較.
if (position < prevSamplePosition)
{
    // 前回の位置のほうが大きい場合はループを挟んでいるのでループを考慮してdataに格納.
    data = new float[position + (audioFrequency * audioSecondLength - prevSamplePosition)];
    Array.Copy(dataBuffer, prevSamplePosition, data, 0, audioFrequency * audioSecondLength - prevSamplePosition);
    Array.Copy(dataBuffer, 0, data, audioFrequency * audioSecondLength - prevSamplePosition, position);
}
else
{
    // 現在の位置のほうが大きいので進んだ分をdataに格納.
    data = new float[position - prevSamplePosition];
    Array.Copy(dataBuffer, prevSamplePosition, data, 0, position - prevSamplePosition);
}
prevSamplePosition = position;
// 音声がしきい値を超えているか確認.
bool isVoice = false;
for (int i = 0; i < data.Length; i++)
{
    if (Mathf.Abs(data[i]) > audioThreshold)
    {
        isVoice = true;
        break;
    }
}
// データ点の内1つでもしきい値を超えていれば音声データとして扱う.
if (isVoice)
{
    var bf = processData;
    processData = new float[bf.Length + data.Length];
    Array.Copy(bf, 0, processData, 0, bf.Length);
    Array.Copy(data, 0, processData, bf.Length, data.Length);
}
else
{
    // しきい値を超えなかったので無音と判断.
    processData = new float[0];
}

このときのAudioClipはループがONになっているので、指定の秒数を過ぎると0に戻って音声が上書きされるような動作をします。そのため、前回確認した音声の位置と現在の位置が逆転している場合にはループを挟んでいるのでそれを考慮してデータを取得しなければいけません。また、すべての音声を常にSpeechToText処理をするのも無駄なので、取得したデータがしきい値を超えているかどうかで無音の判定をする必要があります。

こうして取得した音声データをWhisperエンコーダー・デコーダーで処理することで、リアルタイムにSpeechToTextを行うことができます。その様子を録画しました。左上の白い囲いの中に、現在マイクから入力されている音声をリアルタイムにテキスト変換して表示しています。言葉が止まると途中で[BLANK_AUDIO]が認識されてしまいますが、概ね正常に変換されているようです。We'll sail ~~の部分は始めにI'll say will youなどと認識されていますが、これは認識中の音声データが短すぎるために正確な推測ができていないためで、続きの音声が順に認識され始めると一気に正確な推測ができています。

Today is the best day of my life. So I'm going to explore the world with my rabbits. We'll sail, we'll ride through the wilderness, we'll climb mountains, and we'll leave this earth one day.
音声をリアルタイムにテキストへ変換する

以上、無事に喋った言葉がテキストに変換されました。これだけでもオンラインマルチプレイなどで文字起こし機能として利用できそうですね。

変換されたテキストをコマンドとしてユニットを動かす

音声から変換されたテキストにユニットの操作コマンドが含まれていたとき、その動作を実行するようにしました。同時に変換されたテキストは右下に表示しています。これによって、音声でユニットを操作することができるようになりました。

音声から変換されたテキストでユニットを操作する

まず反省点として、とんでもなく難しいです。音声がテキストに変換されるまで1秒ほどかかってしまうので、その間にユニットは動き続けてしまい、操作しようにも間に合っていませんでした。また、ユニットを操作するコマンドが一つの単語なので、短い音声を正確に推論できないという点がネックになり、結果として短文で話しかけなければなりませんでした。声で操作するという趣旨としてはミニゲームの選定に失敗しました。

しかしながら入力した音声をリアルタイムにテキスト変換できるということは、ゲームで幅広く活用できるのではないでしょうか。大きな可能性を秘めているように感じます。

まとめ

今回はUnitySentisに触れるという目的で、まずWhisperのサンプルを動作させてそのコードをある程度理解しました。さらにwhisper-exportを利用してSentisで使用するWhisperのonnxを出力できるようになりました。このとき音声の長さを半分の15秒に変更できました。ここから音声をコマンドとしたミニゲームを作成し、マイクからの入力を常にSpeechToText変換することでゲーム内のユニットを操作できるようになりました。

このプロジェクトだけでもUnitySentisを利用することでAIモデルを気軽に扱えることが理解できるのではないでしょうか。ゲームからAIを利用する際にネットワークインフラに依存しないという点は強力だと思います。夢が広がりますね。

【生成AI】のゲーム開発への活用事例紹介

0

~ 式姫プロジェクト最新作【カクリヨ・トーキョー】の現場より ~

▼【生成AI】への取り組み

【生成AI】近年耳にしないことがないほどの単語ですので、
 ご存じの方も多いのではないでしょうか。

ChatGPTを始めとする多数のAI技術が革新した昨今
株式会社アピリッツ(以下アピリッツ)でも、
【生成AI】の活用について全社的に取り組んでいます。

この記事中におきましては、
アピリッツのゲーム開発及び運営にかかわる部門より
最新作【カクリヨ・トーキョー】を研究開発している式姫プロジェクトでの
生成AI技術(以下AI)への取り組み方の一部をご紹介します。

こんにちは~。広報担当の山田アイコです。
今回は、フィールドゲーム・テクノロジー学部で開発中の
式姫プロジェクト最新作【カクリヨ・トーキョー】
のチームにお邪魔しています!

【生成AI】って最近のトレンドですよね~。
名称はよく聞くのですが、私もまだよく解っていない所が多いと思いますので
式姫プロジェクトチームのみなさんに、【生成AI】について色々とお話を伺わせてください。

現在鋭意開発中のプロジェクトとなるため
リリース前にお伝えできる情報が限定的になってしまい、
物足りない点があるかもしれませんが頑張ります!

▼【生成AI】とは?

古今東西、人々はゲーム開発に限らず、ものづくりという分野で
【文章を書く】【絵を描く】【音楽を奏でる】【動画を撮影する】など
頭で考えて、手を動かし、匠ともいえる芸術的なコンテンツをこの世界に生み出してきています。

本や絵画、音楽に映画、そしてゲームにおいて名作と呼ばれるコンテンツが多々ありますよね。

コンピューターなどの道具は、あくまで人間が使う道具の延長線上での進化を遂げて
コンテンツ制作の速度や生産性や品質の向上に一役買っていたわけです。

最近の映画やゲームの映像で、現実と間違えてしまいそうなくらいクォリティ高いなと感じることあります!

そこへ【生成AI】は、各コンテンツのパターンや関係を大量に学習することで
道具の領域を超えて、人間の役割の一部をこなすことが期待できる
新たな技術のひとつとして登場
したものとなります。

なるほど~
だから全世界がこれほど【生成AI】に色めきだっている訳ですかぁ。

プロジェクト内での活用法を想定

さて【カクリヨ・トーキョー】はスマートフォン用のゲームとして開発を進めています。
AIを使ってゲームを開発するというと、
【自動で様々なコンテンツが制作される夢のような開発環境
を想像される所があるかと思いますが

【生成AI】は、まだまだ新しい技術なので、
「私達のゲームプロジェクトに活用するためにはどうする?」
からチーム内で考えることとなりました。

素晴らしい道具や機能も使いこなせなければ宝の持ち腐れとなってしまうからです。

たしかに最新のスマホ機能ですら、『まだまだ、私使いこなせていないなあ』と思うときありますもんね~。

そこで『式姫プロジェクト』では、

①AIでできることの調査
②各セクション内のタスク・工程を洗い出す
③洗い出した中からAIでできることと、タスクの中でマッチするものを検討
④マッチした内容でAIを使い、効率化できる箇所を想定
⑤手順化
⑥量産

までを考慮して着手しました。

セクションごとの取り組み

生成AIを役立てることができそうな項目の精査を行ったあと
現在『式姫プロジェクト』チーム内では

・2Dイラストセクション
・シナリオセクション
・3Dキャラセクション

の3つのセクションでAI技術への取り組みを進めています。

それでは各セクションの担当者にお話を伺ってみようと思います。

◾️2Dイラストセクション

- ゲーム中に表示されるスチル画像やアイテムの画像を描くセクション -

※開発中のイメージ画像です。今後ゲーム中で採用される場合がありますので、少しモザイクとなります。

2Dイラスト制作では、どのような制作項目でAIの導入を推進したのですか?

そうですね~
・アイコンラフ生成
・イメージ下絵生成
・イメージ背景生成
・アイテムスチル生成

という項目で
案出し/コンセプトパターン出し/イメージ素案/クォリティ合わせの標準化
の作業で生成AIをテストしていきました。

ゲームではたくさんの画像が使われていますもんね。
様々な絵のアイディアを出すだけでも大変な作業ですよね!

多数のポーズ案/背景イラストの構図案等を
短時間で目に見える形にする点で【生成AI】のレスポンスの良さが活かせると考えました。
それらの画像案は、そのままゲーム内で使用するのではなく
多数のアイディアを必要とする場面での効率化の為に使用しています。

なるほど。
絵のクォリティをさらにあげていく為に、
人の手をかける時間が式姫プロジェクトでは必須と考えられるので
AIの得意とする【絵のバリエーションを短時間で数多く揃える】
ところに使用しているのですね。

『式姫プロジェクト』においては
 世界観やキャラ設定を、特に大切にしていますので
その整合性について必ず人の目で確認を行ってから
ユーザーの皆様にお届けしていきたいと考えて作業を行っています。

◾️シナリオセクション

- ゲーム内の世界観や物語を描くセクション -

※開発中のイメージ画像です。今後ゲーム中で採用される場合がありますので、少しモザイクとなります。

シナリオ制作では、どのような制作項目でAIの導入を推進したのですか?

・多面的なアイディア出し
という項目ですかね。

基本的に、物語の内容や考えこむ時間の短縮化に寄与しています。
生成AI】を活用することで
思ってもみなかったシナリオアイディアのパターンがアウトプットされる事もあり、
アイディアをひねり出す時間の短縮等に活用しています。

AIというと、ChatGPTを代表としてテキスト生成では一日の長があり
多分野で使われているイメージがあるかと思いますが
シナリオ制作活用時の課題として、プロンプトの精度を上げていく必要もあり
なかなかそのまま使用できるクォリティには届かない事も多かったです。
ですのであくまでアイディア出しへの使用にとどめている現状です。

なるほど。
シナリオは、考える、まとめる、確認する
を繰り返して物語の流れを構築していかないといけないので
気づきを得るトリガーにAIを有効活用しているのですね。

【生成AI】でたくさんアイディアが出てきたとしても
どのアイディアを選択/選別して、どのように使っていくのかという場面では
人間がキャラクターやゲームの世界観に対する思い入れと
熱意をもって創作していかないと
まだまだ胸を打つ文章をお届けするのは難しい
とあらためて感じました。

■3Dキャラクターセクション

- ゲーム内キャラクターの3Dモデルを描くセクション -

※開発中のイメージ画像です。今後ゲーム中で採用される場合がありますので、少しモザイクとなります。

3Dキャラクター制作では、どのような制作項目でAIの導入を推進したのですか?

各キャラクターの動きとなる【3Dモーション】を
ダンスムービー等から式姫用モーションデータとして

生成できるかをテストしています。

3次元のキャラクターの外見を制作することをモデリングといいます。
キャラクターの外見を制作しただけでは、キャラクターは動きません。
モーションと呼ばれるキャラクターの動きのデータを制作する必要があるのです。

有名な作り方としては、モーションキャプチャーという
実際に人間が動いて、そのリアルな動作をデータ化するという技術があります。

ただこの方法が頭を悩ませる点として
モーションを撮影するスタジオと専用の機材
その動きを再現するアクター(俳優)さん
が必須となり
様々な大きめのコスト(お金や時間、小道具の準備やアクターさんの選定等)
が発生してしまうんです。

その解消法の一つとして、
動画からのモーションデータ作成に【生成AI】を活用できればと考えました。

なるほど。
特に時間のかかる制作物の納期短縮方法を模索しているのですね。
だいたいの仕事って、時間の削減がコストの削減に直結してる場合が多いですもんね。

まだテストを開始した段階なのでどこまで導入できるかは、未知数な段階です。

▼まとめ

このように【生成AI】【カクリヨ・トーキョー】にもたらす恩恵は種々様々となりますが
プレイヤーの皆様に各キャラクター達の魅力を
最大限に引き出してお届けすべく開発を進めております。
アピリッツよりリリース予定の式姫プロジェクト
【カクリヨ・トーキョー】を楽しみにお待ちいただければと思います!

【生成AI】に関する取り組みのお話ありがとうございました。
私も可愛らしい式姫ちゃん達が大好きですので
式姫プロジェクト【カクリヨ・トーキョー】のリリースを
楽しみにしています!

2024年度 アピリッツ入社式、新しい54名を迎えました

0

2024年4月1日にアピリッツは入社式を行い、今年も54名と多くの新入社員をアピリッツへ迎えることができました。
今回はその様子をお伝えいたします!(2024年4月1日取材)

Welcome to Appirits!

アピリッツでは今年、54名という多くの仲間を迎えることができました!

入社式当日は、アピリッツ社員としても社会人としても1日目でもある新入社員たち。少し緊張している様子がうかがえました。取材班も当時の入社式での自分と照らし合わせて、懐かしい気持ちになりました(笑)

ちなみに、今回は多くの仲間を迎えるために大きい会場を渋谷で借りたそう。そんな気合十分な入社式に潜入してきました!

素敵な54名の新入社員のみなさん

入社式開始直前、新入社員以上に緊張していた運営陣。

入社式の司会進行を務める人事のお姉さんに心境を聞いてみると、「名簿を読み上げる時に嚙まないかめちゃめちゃ緊張してます。と同時に、新入社員のみんなと交流できるのが楽しみです。」と、緊張しながらも新たな仲間を迎える準備はばっちり!

社長や執行役員の皆さんも、新たに迎える仲間たちにエールを送るとともに、

「卒業おめでとう」「アピリッツに入ってくれてありがとう」

と、感謝と歓迎の言葉を投げかけていました。そんな社長や執行役員のみなさんのエールをいくつか紹介させていただきます!

社長の和田からは、「ストレスが絶えない社会人へようこそ」と、ユーモアを交えた歓迎の言葉から始まり、

アピリッツ取締役社長 和田 順児

「一つひとつの物事に対してなぜ必要なのかを自分の頭でしっかりと考え、徹底して行動を心がけることが重要です。そして、こうした行動ができる人材の中から新たなリーダーが生まれてくると考えています。」と、新入社員に向けて激励の言葉を送りました。

執行役員 八木 広道

「ぜひ同期に今考えている事を聞いて、なぜなんだというのを掘り下げていきましょう。すると、自分がある物事に出くわしたときにどういう掘り下げができるのか、引き出しが増えていきます。そうなると、少なくとも人生が豊かになるんじゃないかなと思います。」

取締役 執行役員CFO 永山 亨

「今、自由な社会だからこそ何事もよく考えて自分で決める。自分のために多くの事を吸収して自分が決めれる材料を集めましょう。そして、最終的には自分の後悔しない選択ができれば一番いいかな」

名前を呼ばれて元気に挨拶をする新入社員たち

アピリッツに来た54名のフレッシュな新入社員たち。まだ緊張と社会人生活に対する不安があると思います。

これから研修や案件など多くの経験を経て成長していく彼らから目が離せません!


アピリッツではまだまだ新たな仲間を募集しています。

たくさんのご応募お待ちしています!

最近人気な記事