← すべての記事

誰もオンラインでなくても生きているピクセルの町:NPCとゴースト

ピクセルの町に人の気配を与えているのは、主に立ち止まっている人たちです。『ポケットモンスター エメラルド』の16の町と街では、非表示フラグを持たず、いつ訪れてもそこにいる住人100人の内訳は、持ち場に立って一方向を向くか周囲を見回す人が59人、配置された場所から1〜2セルの範囲をうろつく人が39人、その場で足踏みする人が2人です。ストーリーのフラグで消える58人(大半は悪の組織の団員、ライバル、名前のある登場人物で、そのうち54人は立っています)を加えると、内訳は158人中113人(71.5%)、43人(27.2%)、2人になります。うろつく人は16フレームで一歩進み、そのあと32、64、96、128フレームのいずれかだけ待つので、動いている時間は全体の最大でも11〜33パーセントです。1 1日の出来事は、誰も遊んでいないあいだに進む時計によってではなく、プレイヤーが戻ってきたときに、経過日数を渡して一度だけ実行される関数によって決着します。23 ほかに誰もいないとき、原典は町をほかの人の痕跡で埋めます。痕跡は小さな固定枠に収まり(エメラルドの「レコードをまぜる」は、ひみつきち20個、流行のフレーズ5つ、そして別のプレイヤーのおじいさんをあなたのゲームにコピーします)、見知らぬ人どうしが言葉を交わさずに気配だけを共有できるようにしています。45 これをすべて実測したのは、私自身の町であるKiradex Worldも、最初の静かな朝に同じ問いに答えなければならないからです。そしてサーバー自身のコードをシミュレートした時計で動かしてみると、その答えは3つの点でまずいものでした。4人のコレクターは部屋が空になると止まってしまいます。設定値の0.7秒に対して実際には1秒に1回しか歩かず、1回の歩行のうち75パーセントは立ち止まっています。さらに、アプリ自身の描画コードのモデルでは、一歩の途中で移動が届くと、ほかのコレクターが後ろ向きに跳ねて描かれます。走りでは64回の移動中45回で、40タイルの歩行ではネットワークのジッターが30 msと80 msのときにそれぞれ7フレームと16フレームで起こります。ただし、ジッターのない一定の歩行では一度も起こりません。67 本記事では、実測した原典、現代の参照先、数値つきのライブプレゼンス、子どもが入りうる世界のためのルール、そしてブリーフを順に扱います。

TL;DR

  • 町の大半は立っています。 エメラルドの町と街にいる、非表示フラグを持たない100人のうち10人に6人は、デフォルトの移動タイプが静止型です。ストーリーで消える58人を数えに入れると、158人全体の10人に7人になります(それでもストーリーのスクリプトは立っている人を歩かせることができ、トウカシティのジムの少年はプレイヤーをジムまで連れて行きます)。残りのほぼ全員は1〜2セルの範囲を、プレイヤー自身と同じペース、つまり1セル16フレーム(268 ms)でうろつき、一歩ごとに0.54〜2.14秒待ちます。ミシロタウンには6人、トウカシティには7人、キンセツシティには10人がいて、そのうち非表示フラグを持たないのはそれぞれ2人、3人、6人です。18
  • 日課はいくつかの時刻つき地点と1つのキー。記憶は1日1つのフラグ。 Stardew Valleyは村人の1日を時刻つき地点の文字列として記述し(Pierreの通常の日は7地点)、その日にどれを適用するかを3つのグループに分かれた22のキー形式から選びます。最初に一致したものが採用されます。まず全員に共通する特別なキーが1つ確認され、次に既婚の村人なら5つの結婚用形式(それ以外は使いません)、それ以外の全員なら16の通常形式が試されます。村人に1日1回話しかけると友好度が+20されます。『あつまれ どうぶつの森』では、その日最初の会話で255のうち+1、そしてリアクションを1日に1つ教わります。29101112
  • 誰もいない町をほかの人の痕跡が埋めます。痕跡は固定の枠に収まり、時とともに消えます。 エメラルドの「レコードをまぜる」は別のプレイヤーの世界を5,188バイト運びます。ジョインアベニューでは、本物の訪問者が来なかった店の枠をファンが訪問者の75%の価値で埋めます(Serebiiの説明による)。Death Strandingの建造物は「destroyed by Timefall after some time」(しばらくすると時雨によって壊される)とされます。Journeyでは一度に見知らぬ人が1人だけ現れ、名前はクレジットまで分からず、交わせるのはチャイムだけです。413145
  • ライブプレゼンスは送信レートではなくバッファの問題です。 ファンが作ったHabboのサーバーエミュレータは、すべての部屋を500 ms周期で進めます。Gaffer on Gamesは「3X the packet send rate」(パケット送信間隔の3倍)をバッファします。シリーズの毎秒3.75タイルと7.5タイルでKiradexの歩行をモデル化すると、推定サーバー時刻より350 ms遅れた時計でほかのコレクターを描けば、ジッターが80 msまでなら後ろ向きのフレームも、描くデータが尽きるフレームも0です。一方100 msでは、送り手が送信している間に描かれる600フレームのうち125〜456フレームでデータが尽きます。15167
  • 子ども向けのルールには日付がついています。 Game Centerは子どもを「to sending and receiving preset messages」(定型メッセージの送受信のみ)に制限します。Appleのドキュメントは、独自のマルチプレイヤー機能を持つゲームは、Screen Timeでマルチプレイヤーが制限されているとき「should disable it」(それを無効にすべき)としています。改正COPPA規則は2026年4月22日から遵守が求められており、削除期限を定めた書面のデータ保持方針を要求しています。171819
  • 現在のKiradexは、自らの計画と4つの点で食い違っています。 server/app/npcs.pyには「A town is never empty」(町が空になることはない)と書かれているのに、広場のコレクターは部屋に誰もいないと止まります。設定値の0.7 sに対して1.0 sごとにしか歩きません。計画の論拠は8〜10 Hzとしていたのに、アプリは1タイルにつき1回の移動を送ります(歩きで毎秒4回、走りで毎秒6.0〜6.4回)。そして計画はアイデンティティとペアレンタルコントロールをGame Centerの上に組み立てているのに、Game Centerの制限フラグを読むコードがどこにもありません。62021222324
  • これがKiradexにもたらすもの。 8人の町の人のためのブリーフです。日課はアプリ自身の時間帯をキーにし、部屋ごとに1つの時計で動き、位置はその時計から計算します。直近8人の訪問者の歩みは、サーバーが選んだ無地の姿で名前のないエコーとして再生され、7日間保持され、IDなしで送られます。1日1回のあいさつは決して減衰しません。描画バッファは350 ms。6つの分岐それぞれに8〜12の完全な文を持つセリフ帳。そして7つの安全設定。どの項目にも、スクリプト、テスト、キャプチャのいずれかで合否を判定できるチェックがついています。7119

1. 実測した町の人たち:エメラルド、Stardew Valley、どうぶつの森

小さなソーシャルワールドはどれも、最初の夜に同じ問いに直面します。プレイヤーが広場に入ったとき、ほかに誰もいなかったら何が見えるのか、という問いです。原典には3つの答えがあり、本記事はそれを順に取り上げます。1つ目は、自分の暮らしを続ける町の人たちです。これがあれば、誰かがオンラインかどうかに関係なく町はにぎわいます。2つ目は、いまはそこにいないプレイヤーが残していった、ほかの人の痕跡です。3つ目は、人がいるときにうまく描かれたライブプレゼンスで、子どもが入りうる世界のためのルールに縛られます。最も古く、最もよく実測されているのは1つ目の答えです。その名手の1人のソースが公開されているからです。

エメラルドの人たちがしていること

『ポケットモンスター エメラルド』は、pretの逆コンパイル(pokeemeraldのコミット731ad5bのシャロークローン)から読み、移動タイプの定数とすべての町と街のマップのオブジェクトイベントを読み取るスクリプトmeasure_npcs.pyで数えました。1 エメラルドには0x00から0x50まで81の移動タイプが定義されています。画面上の人物が何をするかでまとめると、24は4区間の固定ループを歩き、17は立って一方向を向き(固定、交互、または見回し)、16はその場で歩くか小走りするか走り、8はプレイヤーの真似をし、5は範囲内をランダムにうろつき、4は行ったり来たりし、4は隠れているか変装しています。残りの3つはNONE、プレイヤー、そしてきのみの木で、きのみの木は人物ではなくオブジェクトです。125

町で使われているのはそのごく一部です。16の町と街のマップにはオブジェクトイベントが172あり、そのすべてが人物というわけではありません。6つはアイテムボール、2つは引っ越しトラック、1つは船、5つは生き物です。スクリプトはこれらをgraphics_idで分類し、158人の人物だけを数えます。18 81の移動タイプのうち、人物に現れるのは11だけです。158人中113人(71.5%)は立って一方向を向き、43人(27.2%)は範囲内をうろつき、2人(1.3%)はその場で足踏みします。単独で最も多いタイプはFACE_DOWNの32、FACE_RIGHTの23、LOOK_AROUNDの20、FACE_UPの19、WANDER_AROUNDの17です。18

この158人がすべて住民というわけではありません。58人は非表示フラグ、つまりその人をマップから消すストーリーのフラグを持っています。58人のうち41人は悪の組織、ライバル、名前のある登場人物のスプライトを使っているので、58人の大半はストーリーの場面に出てくる役者です。そのうち54人は立っています。非表示フラグを持たない100人、つまり毎回マップにいる人たちの内訳は違っていて、59人が立って一方向を向き、39人が範囲内をうろつき、2人がその場で足踏みします。つまり、プレイヤーがふだん目にする住民は10人に6人が立っていて、10人に4人近くがうろついています。全体の10人に7人という数字は、ほぼ全員が立っている役者を加えた結果です。これらはデフォルトの移動タイプ、つまりスクリプトが動かしていないときにその人物がすることです。ストーリーのスクリプトは立っている人物を歩かせることもできます。トウカシティのジムの少年は、デフォルトでは周囲を見回し、非表示フラグも持っていませんが、プレイヤーをジムまで連れて歩きます。この集計が表しているのは静止状態の町であり、町のすべての場面ではありません。18

エメラルドの町のオブジェクトイベントのうち人物を、移動タイプ別に示した積み上げ棒グラフ。16の町と街すべて、158人:113人が立って一方向を向く(71.5パーセント)、43人が範囲内をうろつく(27.2パーセント)、2人がその場で足踏み。非表示フラグを持たない100人:59人が立つ(59パーセント)、39人がうろつく(39パーセント)、2人がその場で足踏み。ミシロタウン、6人:3人が立ち、3人がうろつく。トウカシティ、7人:5人が立ち、2人がうろつく。キンセツシティ、10人:8人が立ち、2人がうろつく。

エメラルドのマップにいつもいる町の人のうち10人に6人はデフォルトの移動タイプが静止型で、ストーリーで消える役者を数えに入れると10人に7人になります。うろつく人は1〜2セルの範囲にとどまります。誰でも歩かせることができるスクリプトの場面は数えていません。26

規模の違う3つの町が、同じ形を示しています。表は人物だけを数えています。除外したオブジェクトイベントは、ミシロタウンの2台のトラックと3つのアイテムボール(トウカシティに2つ、キンセツシティに1つ)です。最後の列は、非表示フラグを持たない人を、することごとに数えたものです。1

町 人数 立って一方向を向く 範囲内をうろつく うろつく範囲 (x, y) 非表示フラグあり 非表示フラグなし(立つ、うろつく)
ミシロタウン 6 3(上を向く) 3(WANDER_AROUND) (1, 2), (2, 1), (2, 1) 4 2 (0, 2)
トウカシティ 7 5(見回し2、上を向く2、下を向く1) 2(全方向1、上下1) (1, 1), (0, 1) 4 3 (2, 1)
キンセツシティ 10 8(見回し2、上を向く2、左を向く2、右を向く1、下を向く1) 2(左右) (1, 1), (1, 0) 4 6 (4, 2)

うろつく人の範囲は1セルずつ強制されます。一歩進む前に、IsCoordOutsideObjectEventMovementRangeが、配置された場所からの範囲外にある目標を拒否するので、うろつく人は遠くへ移動するのではなく、自分のホームのセルの周りを回ります。27 非表示フラグは、住民構成のもう半分を担っています。ミシロタウンの6人のうち4人、トウカシティの7人のうち4人、キンセツシティの10人のうち4人が、ストーリーが進むと自分を消すフラグを持っています。つまり町の住民構成はプレイヤーの進行度の関数であり、人が去ったり現れたりするのは何かが起きたからです。1

どれくらいの頻度で動くのか

タイミングも同じファイルにあります。うろつく町の人や見回す町の人は、次の一歩や方向転換の前に、sMovementDelaysMediumからランダムに選んだ32、64、96、128フレームのいずれかだけ待ちます。ゲームボーイアドバンスの59.7275 Hzでは0.54、1.07、1.61、2.14秒で、平均は1.34秒です。正反対の2方向を交互に向く2つのタイプ、FACE_DOWN_AND_UPとFACE_LEFT_AND_RIGHTも同じです。隣り合う2方向を交互に向くタイプや3方向を向くタイプはsMovementDelaysShort、つまり32、48、64、80フレームから選び、平均は0.94秒です。回転する2つのタイプは48フレーム固定で待ちます。3つ目のテーブルsMovementDelaysLongはソースで// Unusedと記されており、どの移動タイプもこれを読みません。127

一歩そのものはプレイヤーと同じです。PlayerWalkNormalはGetWalkNormalMovementActionを呼びます。これはうろつく人の一歩が使うのと同じアクションです。MOVE_SPEED_NORMALはsStep1Funcsに対応し、1フレームに1ピクセルずつ16フレーム動きます。16ピクセルの1セルを268 msで、毎秒3.73セルです。走りはMOVE_SPEED_FAST_1、sStep2Funcsで、1セル8フレーム、134 ms、毎秒7.47セルです。127 この2つの行を合わせると、うろつく人は「一歩と待ち時間」の0.81〜2.41秒のうち268 msだけ動いていることになります。踏み出した一歩あたりで見て、時間の11〜33パーセントです。これは上限です。うろつく人が選んだ方向が壁や範囲の端でふさがれていると、MovementType_WanderAround_Step4は動かずにもう一度向きを変えて待つように戻すので、実際に動いている時間の割合はもっと低くなります。残りの時間、その人は立っているか、向きを変えています。127

6秒間のタイムライン図。エメラルドのうろつく人を待ち時間ごとに4行で示す。待ちが32フレームなら時間の33パーセント動いており、64フレームなら20パーセント、96フレームなら14パーセント、128フレームなら11パーセント。5行目は歩行区間にいるKiradexのコレクターで、1.0 sごとに250 msだけ動き、25パーセント。

エメラルドのうろつく人は長い待ちのあいだに一歩ずつ動きます。第6節で実測するKiradexのコレクターは、歩いているはずの間、1タイル分の長さの小刻みな動きを繰り返します。26

私の読みでは、効果を生んでいるのは3つの細部です。町の中にはあなたより速く歩くものも遅く歩くものもないので、異質なものに見えるものがありません。待ちが一歩より長いので、町は静止した場面がときおり動きで区切られるものになり、だからこそ6〜10人がいても混み合って見えません。そして住民構成は非表示フラグを通じてストーリーに書き込まれているので、町が変わるのはタイマーが発火したからではなく、プレイヤーが何かをしたからです。

エメラルドの1日は到着時に決着する

エメラルドは日付を管理していますが、誰も遊んでいないあいだに進む時計によってではありません。DAILY_FLAGS_START以降に64の毎日フラグの枠を確保し、そのうち12を使っています。9つのきのみのプレゼント(コンテスト会場のロビー、きのみ名人とその妻、ルートや町でくれる5人、花屋)、ひみつきちの毎日フラグ、くじの券、そしてFLAG_DAILY_APPRENTICE_LEAVESです。228 プレイヤーが戻ってくると、DoTimeBasedEventsがUpdatePerDayを呼び、UpdatePerDayは経過日数を受け取って一度だけ実行されます(呼び出し元はDoTimeBasedEventsだけで、プレイ中も戻ってきたときも同じです)。この関数は順にClearDailyFlags、UpdateDewfordTrendPerDay、UpdateTVShowsPerDay、UpdateWeatherPerDay、UpdatePartyPokerusTime、UpdateMirageRnd、UpdateBirchState、UpdateFrontierManiac、UpdateFrontierGambler、SetShoalItemFlag、SetRandomLotteryNumberを呼びます。23 流行、テレビ、天気はすべて、戻ってきた瞬間に計算される経過日数によって進みます。3 カートリッジの電源が切れているあいだには何も起きていません。それでも町は、起きていたかのようにふるまいます。

Stardew Valley:スケジュールは文字列

暮らしを持つ町の人について、現代の参照先となるのはStardew Valleyです。wikiの「Villagers」ページには、独身男性6人、独身女性6人、結婚できない村人22人、プレゼントを渡せない村人12人が載っており、プレゼントを渡せる村人は34人です。ページには「Each villager has a daily routine, so they can be located in different sections of town depending on the in-game time of the day and weather.」(村人はそれぞれ日課を持っているので、ゲーム内の時刻と天気によって町のさまざまな場所にいる)とあります。229

日課はデータです。村人ごとにContent/Characters/schedules/の下にファイルがあり、各エントリはスラッシュで区切られた地点の文字列1本です。各地点は<time> [location] <tileX> <tileY> [facing] [animation] [dialogue]の形で、時刻はコロンなしの24時間表記、向きは0が上、1が右、2が下、3が左です。9 ページに載っているAbigailの水曜日は1000 ArchaeologyHouse 11 9 0/1800 Town 47 87 0/2200 SeedShop 1 9 3 abigail_sleepで、3つの地点、それぞれのあいだの移動、そして最後の地点でのアニメーションからなります。9 雑貨屋を営むPierreは、通常の日に7つの時刻つき地点を持ち(午前6時にカウンター、午前7時に通路、午前8時30分にカウンターに戻り、その後午後5時、午後7時、午後9時、午後11時に通路、台所、本棚、ベッドへ)、ページには彼のスケジュールの6つのバリエーションが載っています。緑の雨、春15日に修理されたバス、砂漠祭り、雨、金曜日、そして通常の日です。230

賢さはキーにあります。ある日にどのスケジュールが動くかは、3つのグループに分かれた22のキー形式で決まり、それぞれ決まった順序で試され、最初に一致したものが採用されます。特別なキーGreenRainは1つだけで、「checked first, regardless of marriage status.」(結婚の有無にかかわらず最初に確認される)とされています。既婚の村人は次に5つの結婚用形式だけを試します。marriage_<festivalID>から日付、marriageJob、曜日までです。「Married NPCs don’t use any other schedule keys. If the marriage keys don’t match, they won’t have a schedule for that day.」(既婚のNPCはほかのスケジュールキーを使わない。結婚用キーが一致しなければ、その日のスケジュールはない)。それ以外の村人は16の通常形式を試します。<festivalID>、<season>_<dayofmonth>、<dayofmonth>_<hearts>、<dayofmonth>、bus、rain2(「50% chance of applying on rainy days」、雨の日に50%の確率で適用)、rainから始まり、曜日とハートのキー、曜日を経て、<season>、spring、最後にdefaultに至ります。29 つまり、私の読みでは、1人の村人には多くの可能な1日があり、同じいくつかの地点が組み替えられて暮らしになります。そしてハートのキーがあるので、あなたを好いている村人は違う1日を送ります。ページの制約に関する注記は、1日がどう計算されるかを語っています。既存のセーブデータにNPCが追加された場合、「they generally don’t follow their schedule correctly until you’ve slept once in-game (which triggers their first day update).」(ゲーム内で一度寝るまで、たいていスケジュールどおりに動かない。寝ることで最初の1日の更新が起きるため)。9 エメラルドと同じく、Stardewの1日は連続的に進むのではなく、日の境目で計算されます。

友好度は毎日の記憶であり、コストを伴います。ハート1つは250ポイントです。wikiの友好度を上げる方法の一覧の最初の項目は「talking to them once per day (+20)」(1日1回話しかける、+20)です。村人はプレゼントを1日に1つ、週に2つまで受け取り、誕生日のプレゼントは8倍になります。そして話しかけないと毎日ポイントが減ります。ほとんどの村人では2、花束を渡したあとは10で、メーターが満タンになるか上限に達するまで続きます。配偶者では20で、こちらの減少は止まることがありません。10 台本のある場面であるハートイベントはハートのしきい値で開き、「most events can be viewed anytime (with some time restrictions) or out of order.」(ほとんどのイベントは、時間の制約はあるものの、いつでも、あるいは順不同で見られる)とされています。10 村人はあなたがいないあいだもあなたに働きかけます。ハート3つでPierreは「will send you a recipe in the mail」(郵便でレシピを送ってくる)し、ハートが0より上ならどの段階でも250g以上を送ってくることがあります。30

どうぶつの森:あなたが来たことを知っている住民

『あつまれ どうぶつの森』は、今日話しかけてくれたことを知っている住民を、たった1ポイントにまで削ぎ落としています。友好度は0から255まであり、25から始まります。Nookipediaの友好度を上げるものの一覧の最初の項目は「speaking to the villager for the first time each day」(その日初めて住民と話す)で「+1 point」です。住民はプレゼントを1日に1つ受け取ります。そして150ポイントでは、住民がプレゼントのお返しに写真をくれる確率が6%あり、1ポイントごとに0.04%上がって255では10.2%になります。11 私の読みでは、プレイヤーがその動きを目にすることはないので、これはメーターではなくフラグです。

住民の目に見える暮らしは小さく、その住民だけのものです。それぞれが6つの趣味(勉強、おしゃれ、運動、音楽、自然、遊び)のいずれかを持ち、『あつまれ どうぶつの森』では「a villager always has one hobby that doesn’t change」(住民はいつも変わらない趣味を1つ持つ)とされています。住民は虫や魚を追いかけますが「still will not catch either of them」(それでもどちらも捕まえない)。運動し、本を読み、近くの音楽プレーヤーに合わせて歌います。そして2.0アップデート以降は「invite the player to their house, ask the player for an invitation」(プレイヤーを家に招き、プレイヤーに招待を頼む)、あるいは「a random visit」(ふいの訪問)にやって来ます。3132 話す内容は8つの性格で形づくられます。男の子の住民に4つ(ぼんやり、ハキハキ、こわい、キザ)、女の子の住民に4つ(ふつう、元気、おとな、アネキ)で、そのうち「Smug and big sister were introduced in New Leaf, with the other six being present since Doubutsu no Mori.」(キザとアネキは『とびだせ どうぶつの森』で導入され、ほかの6つは『どうぶつの森』からある)とされています。33

シリーズを通じて、町は小さいままでした。32

ゲーム 最初の住民数 住民の最大数
どうぶつの森 6 15
おいでよ どうぶつの森 3 8
街へいこうよ どうぶつの森 6 10
とびだせ どうぶつの森 5 10
あつまれ どうぶつの森 2(83人の候補からハキハキとアネキが1人ずつ) 10

『おいでよ どうぶつの森』はペースも変えました。そこでは「the villagers walk at a much slower pace than the player」(住民はプレイヤーよりずっとゆっくり歩く)とされ、『街へいこうよ どうぶつの森』もそれを引き継ぎました。32 これはエメラルドのルールとは正反対ですが、私の読みでは、どちらも同じ理由でうまくいっています。のんびり歩く住民は住民らしく見え、あなたと同じペースで一歩進んでから待つ町の人もまた住民らしく見えます。効果を壊すのは、そのどちらのペースでもない動き方をする人物であり、それが第6節で扱うKiradexの問題です。

シリーズの定型の表現手段はリアクションで、これ自体が町の人たちから毎日少しずつ配られる贈り物です。『あつまれ どうぶつの森』のリアクションは1.0.0の時点で44、2.0までにさらに44増えて合計88になりました。「The player can learn one Reaction per day」(プレイヤーはリアクションを1日に1つ覚えられる)とされ、なかには特定の性格の住民からしか、あるいは友好度が高いときにしか覚えられないものもあります。212

2. ほかの人の痕跡:誰もオンラインでないとき町を埋めるもの

町の人がいれば町はにぎわいますが、毎日同じ顔ぶれです。2つ目の答えは、空っぽの世界を心配したとき、調べたすべてのゲームが手を伸ばしたものです。いまオンラインである必要のないプレイヤーが残していった、本物の人の痕跡で世界を埋めることです。エメラルドはそれを通信ケーブルで実現しました。

レコードをまぜる:固定された枠に入る、別のプレイヤーの世界

2人のエメラルドのプレイヤーが「レコードをまぜる」(record mixing)を行うと、それぞれのゲームは相手に固定の構造体PlayerRecordEmeraldを送ります。11種類のレコードからなる0x1444バイト、合計5,188バイトです。434 ほかの人がここにいたという感覚にとって重要な数は、枠の数です。ひみつきち20、テレビの枠25(通常5とさらに20)、ニュース16、流行のフレーズ5、そしてゲームが保持する4人のうち2人の弟子です。4 私の読みでは、それこそが枠の意味です。友だちのひみつきち、その番組、そのフレーズがあなたのゲームに運び込まれ、ほかの誰かが遊んだからこそ、あなたの町が変わったのです。

最も分かりやすいのは、ある1人の人物の例です。キンセツシティのポケモンセンターにはおじいさん(Old Man)が1人いて、それは5人のうちの1人です(吟遊詩人(Bard)、流行の人(Hipster)、交換したがる人(Trader)、語り部(Storyteller)、浮かれた人(Giddy))。新しいゲームでどの1人になるかは(trainerId % 10) / 2で決まり、ソース自身のコメントは「Determine man based on the last digit of the player’s trainer ID」(プレイヤーのトレーナーIDの末尾の数字で人物を決める)です。そしてレコードをまぜると、ReceiveOldManDataが相手のおじいさんをあなたのおじいさんに上書きコピーします。435 あなたの町の住人は、文字どおり別のプレイヤーの町の人なのです。

流行の人は、語彙を人との接触ごとに配給します。彼のスクリプトはFLAG_UNLOCKED_TRENDY_SAYINGSをセットし、taughtWordがfalseなら単語を1つ教えてから、それをtrueにします。これを再びfalseにする唯一の呼び出し、つまりResetMauvilleOldManFlag経由のResetHipsterFlagは、ちょうど1か所、record_mixing.cにあるReceiveOldManDataの末尾からだけ呼ばれます。35 したがって流行語(Trendy Saying)は、レコードをまぜることで流行の人が来るたびに1回、それに加えて最初から彼がいるプレイヤーなら1回解放されます。選ばれ方の規則からすると、それはトレーナーIDの末尾が2か3のプレイヤーです。このシリーズの最初の記事も、同じ規則を同じように述べています。3635 語彙は待つことでは増えず、人に会うことで増えていきます。

流行を算数で見る

流行のフレーズは、ムロタウンの町がいまの合言葉として扱う簡易会話(Easy Chat)の2語で、エメラルドが点数をつける唯一の痕跡です。ソースのコメントによれば、「boring」(退屈)なフレーズは「lose trendiness over time until it reaches 0, at which point it will stop being boring and gain trendiness until it reaches maxTrendiness (then it becomes boring again and the cycle repeats).」(時間とともに流行度を失って0になり、その時点で退屈でなくなり、maxTrendinessに達するまで流行度を得る。そしてまた退屈になり、このサイクルが繰り返される)とされています。37 フレーズのピークは、最大3回入れ子になったRandom() % 98の抽選によって30から127のあいだで決まります。各抽選がその98通りの値に対して独立かつ一様だとすると、ピークの平均は62.9で、ピークの81.3%は80以下です。開始時のスコアは30からピークまでのあいだで一様で、平均は46.5です。スコアは経過1日ごとに5ずつ動き、ほかのすべてと同じくUpdatePerDayで決着します。383 これらの数値はコードの近似であり、コードの正確な出力ではありません。Random()は16ビットを返すので、0から71の余りは65,536回中669回、72から97の余りは668回出ます。また、連続する抽選は独立したサイコロではなく1つの生成器から出てきます。余りをそのように重みづけしても(抽選は独立と仮定したまま)、どちらの数値も小数点以下1桁では変わりません。3837 連続的な速度として見ると、ピーク30のフレーズは0からピークまで上がって戻るのに12日、ピーク64では25.6日、ピーク127では50.8日かかります。ゲームはスコアを1日単位で動かし、ピークや0を越えそうなスコアは余りの分だけ跳ね返るので、日々のスコアはこの小数の周期では繰り返しません。0から上昇し始めるスコアから1日ずつ移植して計算すると、厳密な数列が初めて繰り返すのは12日、128日、254日後です。3837 流行は最大5つまで保存され、レコードをまぜると「their own trends are replaced with their mixing partner’s, unless the phrase is the same, in which case the version with a higher trendiness value is used.」(自分の流行は相手の流行に置き換えられる。ただしフレーズが同じ場合は、流行度の高いほうが使われる)。3837

エメラルドの流行スコアを60日間、1日1点で示した折れ線グラフ。3つのピークそれぞれについて、0から始まり1日5ずつ動き、ピークと0で跳ね返る。ピーク30は12日ごとに上がって下がり、厳密に繰り返す。ピーク64は約25.6日ごとに上がって下がる(連続的な近似)。日々のスコアが厳密に繰り返すのは128日後。ピーク127は約50.8日ごとに上がって下がり、日々のスコアが繰り返すのは254日後。

流行は1日1回サンプリングされるゆっくりしたジグザグです。ピークの81.3%は80以下で、上がって下がるまで約32日以内です。2638

私の読みでは、これは町を古びさせないための痕跡として正しい形です。上がり、下がり、その寿命は生まれたときに決まり、別のプレイヤーとの接触によって、より新しいものに置き換えられることがあります。

簡易会話とユニオンルーム

エメラルドには、プレイヤーどうしが何かを伝える方法が2つあり、それは本記事の安全をめぐる議論の両端にあたります。ローカル無線のロビーであるユニオンルームは、8人のグループリーダーを表示し、無線グループごとに5人(RFU_CHILD_MAXの4に1を足す)を収容し、40のスプライトを描き、30のアクティビティコードを定義しています。そのチャットはキーボード入力です。キーボードのページは4つ(UPPER、LOWER、EMOJI、REGISTER)、1メッセージ15文字(MAX_MESSAGE_LENGTH)、セーブに保存される登録フレーズは10個(UNION_ROOM_KB_ROW_COUNT)です。439 私の読みでは、そこでキーボード入力のチャットが許容できたのは、部屋にいる全員が自分の無線の届く範囲にいたからです。

プレイヤーどうしで交わされるそれ以外のことばは、すべて簡易会話を通りました。簡易会話は22のグループ、合計1,815のエントリを持っています。最初から開いているのは、トレーナー(27、うち6は無効)、ステータス(109)、バトル(63)、あいさつ(42)、人物(75)、声(63)、話し言葉(60)、語尾(69)、気持ち(69)、状態(69)、行動(78)、生活(45)、趣味(54)、時間(45)、その他(42)、形容詞(36)、それに202エントリの名前のリストです。名前はそれぞれ、プレイヤーがそのポケモンを見たときに初めて開きます。閉じているのは、ゲームをクリアするまでのイベント(29)と2つのわざのリスト(154と200)、流行の人のフラグまでの流行語(33)、そして251エントリの全国の名前のリストです。3840 どのプレイヤーも選べないトレーナーの無効な6エントリを除くと、名前を数えずに最初の1時間から開いている単語は940語です。どのグループが開くかはeasy_chat.cの1つのswitchが決め、各エントリはもう1つの判定が決めます。名前ならそのポケモンを見たかどうか、それ以外の単語ならenabledフィールドです。3840 フレーズは固定のグリッドです。プロフィールは2×2の4枠、バトル開始のことばは2×3の6枠、メールは2×5の10枠で最大9語、流行のフレーズといいことばは2×1、アンケートは2×2の4語です。3840

940語の組み合わせ可能な語彙は表現力が豊かですが、私の読みでは、やる気のある子どもならそこから何かを綴れてしまう語彙でもあります。第7節のKiradexのブリーフが拒むのは、まさにこのトレードオフです。単語ではなく、常に完全な文を使います。

ほかのゲームにおける見知らぬ人の痕跡

空っぽの世界を心配した、調べたほかのゲームはすべて、ほかのプレイヤーに手を伸ばしました。そのほとんどは、プレイヤーが残していく痕跡に向かいました。出典の強さはまちまちなので、各段落はそれぞれの出典を明記します。

Dark Souls(FromSoftware、2011年)。 Wikipediaは独自の出典を引いて次のように書いています。「The player can see ghostly images of other players, activate bloodstains that show how other players died, and leave messages using preset phrases.」(プレイヤーはほかのプレイヤーの幽霊のような姿を見たり、ほかのプレイヤーがどう死んだかを示す血痕を起動したり、定型フレーズでメッセージを残したりできる)。41 The Daily Telegraphは本作に「Best Integration of Online Features」(オンライン機能の最優秀統合)賞を贈りました。41 Bandai Namco Europeのリマスター版のページは、主な特徴に「The Way of the Multiplayer (up to 6 players with dedicated servers)」(マルチプレイヤーの道。専用サーバーで最大6人)を挙げていますが、幽霊とメッセージの層についてはそれ以上何も述べていません。FromSoftware自身の説明にはたどり着けませんでした。42 このページは、幽霊のような姿が、すでに去ったプレイヤーを再生したものなのか、その瞬間に接続しているプレイヤーを映したものなのかを述べていません。Wikipediaはそれらを、血痕やメッセージとともに、ゲームが「the single-player world」(シングルプレイヤーの世界)に「integrates」(統合する)「online features」(オンライン機能)のなかに挙げ、「Direct multiplayer」(直接のマルチプレイヤー)、つまり召喚と侵入を次の文に置いています。41

Journey(thatgamecompany、2012年)。 これもWikipediaです。「In each level, the player may come across one other player temporarily connected to their game」(各レベルで、プレイヤーは自分のゲームに一時的に接続した別のプレイヤー1人に出会うことがある)。2人は「cannot communicate via speech or text and cannot see each other’s names until after the game’s credits」(声や文字でやりとりできず、ゲームのクレジットが終わるまで互いの名前を見られない)。「The only form of communication between the two is a musical chime.」(2人のあいだの唯一のやりとりは音楽的なチャイムである)。開発者たちは「felt having text or voice communication or showing usernames would allow players’ biases and preconceptions to come between them and the other player.」(文字や声のやりとりやユーザー名の表示があると、プレイヤーの偏見や先入観が相手とのあいだに入り込んでしまうと感じた)。5 これは安全をめぐる議論をデザインの形で示したもので、大人に向けて作られたものです。

Death Stranding(Kojima Productions、2019年)。 Sonyのページにはこうあります。「Donate valuable resources to rebuild structures in your world and others’, and offer likes in support of player structures that appear in yours.」(貴重な資源を寄付して自分やほかの人の世界の建造物を再建し、自分の世界に現れたプレイヤーの建造物にいいねを送って支援しよう)。43 Wikipediaはさらに、プレイヤーは「can leave supplies, structures, and messages that can be viewed and used by other players, although structures will eventually be destroyed by Timefall after some time」(ほかのプレイヤーが見て使える物資、建造物、メッセージを残せるが、建造物はしばらくすると時雨によってやがて壊される)こと、そして「The player does not directly encounter other players in the world.」(プレイヤーが世界でほかのプレイヤーに直接出会うことはない)ことを付け加えています。14 痕跡は朽ちていくので、世界が埋もれてしまうことはありません。

Splatoon(Nintendo、2015年)。 Wikipediaによれば、出典を引いて、プレイヤーのMiiverseの投稿は「appear in-game as graffiti on various buildings」(ゲーム内でさまざまな建物の落書きとして現れる)とされています。落書きはゲームのMiiverseコミュニティへの投稿から来ていたので、私の読みでは、この痕跡はゲーム自身のオンラインプレイではなく、NintendoのMiiverseサービスに依存していました。44

後期の3つのポケモンの機能は、長く続くファンサイトSerebiiという1つの出典に頼っています。pokemon.comの『ポケットモンスター ブラック2・ホワイト2』と『ポケットモンスター サン・ムーン』のページはジョインアベニューにもフェスサークルにも触れておらず、GOのジムについてのパブリッシャーのページは保存されていません。ですから、次の3つの段落はいずれも、パブリッシャーの説明ではなくSerebiiの説明として読んでください。45

ジョインアベニュー(Join Avenue、『ポケットモンスター ブラック2・ホワイト2』、2012年)。 Serebiiによれば、アベニューは「starts off as an empty pathway」(何もない通りから始まる)もので、人が来て店を開きます。これは「is done automatically whenever you connect with someone」(誰かとつながるたびに自動的に行われる)もので、すれちがい通信、赤外線、ユニオンルーム、Wi-Fi、GTSなどを通じて起こります。店は8軒あり、「every 10th person shown to the shop, the shop will rank up」(店に案内した人が10人になるごとに店のランクが上がる)、ランク10まで上がり、「discounts of 1% for every rank up」(ランクが1つ上がるごとに1%の割引)で「a 40% discount」(40%の割引)に至ります。標準的な訪問者の価値は「from 100 to 200 points」(100から200ポイント)です。そして四天王を倒したあとは「various fans will come and visit」(さまざまなファンが訪れる)ようになり、「If you help a fan rather than another player, they will give 75% of the normal popularity points.」(ほかのプレイヤーではなくファンを手伝うと、通常の人気ポイントの75%がもらえる)。13 私の読みでは、これは原典のなかで最も明快な代替ルールの表明です。本物の人が空けた枠を代役が埋め、その価値は少しだけ低いのです。

フェスサークル(Festival Plaza、『ポケットモンスター サン・ムーン』、2016年)。 Serebiiによれば、サークルは「will propogate itself with players you will find online and locally」(オンラインやローカルで見つかるプレイヤーで自らを満たしていく。原文ママ)もので、「This is not limited to people on your friend list」(これはフレンドリストの人に限られない)とされています。何かを求めるゲストはそれを口にし、手伝うとフェスコインを払ってくれます。手伝ったゲストはVIPにでき、VIPになると「more likely to appear in your plaza in the future」(今後あなたのサークルに現れやすくなる)。サークルのランクはレベル1で6コインかかり、レベル101からは300に上がります。46 アバターを通じたプレゼンスです。あなたがやりとりするのは別のプレイヤーのアバターであり、Serebiiはその背後にいる人たちを「all players that are also playing online」(同じくオンラインで遊んでいるすべてのプレイヤー)と表現し、彼らは「when they see you」(あなたを見かけると)「challenge you to battles or request trades」(バトルを挑んだり交換を申し込んだりする)ことができるとしています。この説明に従えば、サークルの人物は自分自身もオンラインであるプレイヤーを表しています。Journeyと並んで、この一覧のなかで出典が痕跡ではなくライブプレゼンスとして描いている2つの機能のうちの1つです。46

Pokémon GOのジム(2017年のリニューアル)。 Serebiiによれば、ジムには最大6体の防衛役が置けます。バトルに負けるたびに防衛役のやる気が下がり、「Once their Motivation has dropped to 0, then they are removed from the Gym」(やる気が0まで下がると、ジムから外される)。きのみでやる気を回復でき、防衛役は10分ごとに1コインを稼ぎますが、「capped at 50 Coins earned a day.」(1日に稼げるのは50コインが上限)。47 その場所は、別のプレイヤーが不在のあいだもその相棒を見せ続け、コミュニティが餌をやらなければ朽ちていきます。

そのすべてについての私の読みでは、共通するパターンは次のとおりです。少数の固定された枠(ジョインアベニューの店8軒、ジムの防衛役6体、Journeyの相棒1体、エメラルドのひみつきち20)、朽ちていくか入れ替わる痕跡(時雨、やる気、流行のサイクル)、人より価値の低い代役、そしてフェスサークルのバトルと交換の申し込みを除けば、定型フレーズかチャイム以外に見知らぬ人どうしのライブの通信路はないことです。

3. ライブプレゼンス:レート、バッファ、すれ違う歩行

3つ目の答えは、多くの人が最初に思い浮かべるものです。ほかのプレイヤーがオンラインなら、同じ広場で動いている姿を見せる、という答えです。2つの小さな2Dソーシャルワールド、HabboとClub Penguinは、グリッド上のプレゼンスの両端を示しています。どちらの会社もレートを公表していません。私の手元にあるのは、元のクライアントと互換性があるように書かれた、オープンソースのファン製サーバー2つとファン製クライアント1つです。したがって以下の数値は、それらのクライアントが何を想定していたかの証拠であり、SulakeやDisneyが公表した数値ではありません。154849

Habbo:サーバーの1周期に1歩

Habboのサーバーをオープンソースで再実装したArcturus Morningstarは、各部屋を500 msの固定周期で動かし(scheduleAtFixedRate(this, 500, 500, TimeUnit.MILLISECONDS))、部屋の1周期ごとに、歩いている各ユニットのcycleを1回呼びます。IDLE_CYCLES = 240、つまり120秒でアバターをアイドル状態とし、IDLE_CYCLES_KICK = 480、つまり240秒で部屋の所有者以外を退出させます。15 オープンソースのHabboクライアントであるNitroは、部屋のオブジェクトを500 msの固定のDEFAULT_UPDATE_INTERVALで動かします。サーバーから更新が届くたびに新しい位置への変化量を取り、経過時間を500で割った割合で線形補間し(終点でクランプ)、そのあと変化量をゼロに戻します。49 1周期がちょうど1タイルだというのは、この2つを合わせた私の読み(500 msのサーバー周期を500 msの線形補間で描く)であり、サーバーのRoomUnitを読んで確かめたわけではありません。この読みが正しければ、描画は構造上サーバーの1周期分遅れているので、サーバーが歩調を保っているかぎりデータが尽きることはありません。

Club Penguin:ストリームではなく目的地

SoleroプロジェクトによるオープンソースのClub Penguinのサーバー、Houdiniは別の設計を示しています。移動は目的地のxとyを運ぶ1つのspメッセージで、そのまま部屋に中継され、クライアントが自分でそこまで歩きます。セーフチャットの1行は数値を運ぶ1つのssメッセージで、ほかの種類の定型の発言も同じ方法で送られます。ジョークはsj、マスコットのメッセージはsma、舞台のセリフはsl、ツアーガイドのセリフはsg、エモートはseで、それぞれIDとして中継されます。48 サーバーはエモートとアクションを1秒に1回、フレームの変更を0.5秒に1回に制限し、ハートビートのタスクが61秒ごとに接続中のクライアントを確認して、その間にハートビートを送らなかったものを切断します。48 移動はタイルごとではなくクリックした目的地へ向かう方式で、発言は相手側で引かれる番号です。私の読みでは、だからこそ単語フィルターは発言の大半を見る必要がなかったのです。

どちらの世界も、以下の物理デモのような毎秒10〜60回の更新は送っていません。16 人がタイルからタイルへ歩く世界では、一歩あるいは目的地が更新そのものです。

Gaffer on Games:遅らせて、既知の2点のあいだを描く

クライアント側を支配する方法は、Glenn Fiedlerの「Snapshot Interpolation」(Gaffer on Games、2014年11月30日)に示されています。届いたものをバッファし、遅らせた2つの更新のあいだを描きます。「In effect, we’ve traded a small amount of added latency for smoothness.」(要するに、わずかな遅延の追加と引き換えになめらかさを得たのだ)。16 遅延についての彼の目安は「enough delay so that I can lose two packets in a row and still have something to interpolate towards」(パケットを2つ続けて失っても、まだ補間する先が残っているだけの遅延)です。パケットロスが2〜5%のときに最もうまくいくのは「is 3X the packet send rate. At 10 packets per-second this is 300ms」(パケット送信間隔の3倍。毎秒10パケットなら300ms)で、これにジッターのための1〜2フレームを足すので、彼のデモは350 msで動いていました。「30 snapshots per-second」(毎秒30スナップショット)なら同じ保護に150 msかかり、「60 packets per-second needs only 85ms.」(毎秒60パケットなら85msで済む)。16 先読みして推測する外挿は「doesn’t work very well for rigid bodies because their motion is non-linear and unpredictable.」(剛体の動きは非線形で予測できないので、あまりうまくいかない)とされています。16

Kiradexの広場はWebSocketでFastAPIのサーバーにつながっています。23 WebSocketはTCPの上で動き、TCPでは何も失われませんが、再送されたパケットは遅れて届きます。私の読みでは、そのためWebSocketの世界での予算はパケットロスではなくジッターになり、グリッド上を歩く人はFiedlerの方法にとって簡単なケースになります。グリッド上を歩く人はタイルの中心どうしを直線で移動してぴたりと止まるので、外挿するものも、隠すべき非線形の動きもありません。

すれ違う歩行のモデル

Kiradexのバッファの大きさを決めるため、10月5日の時点で読んだアプリ自身のリグのロジックを使って、別のコレクターがそばを歩いて通り過ぎる様子をシミュレートしました。スクリプトmeasure_remote_walk.pyは2つのものをモデル化しています。1つは、リグ自身の算術による現在のふるまいです。一歩のprogressは32ビットのFloatで、毎フレームFloat(deltaTime)に毎秒4タイルを掛けた分だけ進みます。移動が届くたびに、歩いている人の最後の整数タイルから経路を引き直し、進行中の一歩を(一歩の途中であっても)ゼロにリセットします。6タイルより長い経路はジャンプになります。そして歩いている人は整数ピクセル上に描かれます。リグはほかのコレクターをすべて歩きの毎秒4タイルで描きます。走りとして扱われるのはプレイヤー自身の歩行だけだからです。もう1つは代替案です。一定の描画時計、つまり推定サーバー時刻から100〜350 msの遅延を引いた時計の上でスナップショット補間を行い、描画時計をはさむスタンプを持つ、受信済みの2つの更新のあいだを描きます。750 現在のリグについては、送り手は現在の実測レートで、完了したタイルごとに1回の移動を送ります。歩きの毎秒4タイルなら250 msごと、走りの毎秒6.4タイルなら156 msごとです。6.4は走りの公称レートです(このシリーズのモーション編の記事は、各タイルの行き過ぎ分が捨てられるため、60 Hzでのアプリの走りを毎秒6.0タイルとしてモデル化しています)。バッファについては、送り手はシリーズのモーション契約、つまりモーション編の記事のブリーフにある、60 Hzで歩き1タイル16ティック、走り8ティック、毎秒3.75タイルと7.5タイルでも動きます。これが第7節で目指すものです。ネットワークは0、30、80 msの一様なジッターを加え、フレームは10秒間の歩行のあいだ毎秒60回描かれます。72122

算術が重要です。32ビットでは、1/60秒のフレームを毎秒4タイルで15回足すとちょうど1.0になるので、一歩は15フレーム、つまり送り手の250 msとぴったり同じになります。64ビットの算術では同じ和が0.9999999999999999になり、一歩は16フレームかかります。そのように書いたモデルは、リグ自身の算術では起こらない、一定の歩行での引き戻しを見つけてしまいます。7

これはモデルであり、その前提こそが、数値を結果ではなく大きさの目安として扱うべき理由です。まっすぐ開けた道を前提としているので、経路の長さはマンハッタン距離です。リグでは√2倍の時間がかかる斜めの一歩はモデル化していません。ジッターは一様です。すべてのフレームのdeltaTimeはちょうど1/60秒ですが、スマートフォンでは変動します。32ビットの演算はコードの順序どおりに、積和演算の融合なしで行います。2台のデバイスからキャプチャしたものは何もありません。ですから、ジッターのない一定の歩行がスマートフォン上で一度も引き戻されないかどうかは、このモデルでは決着をつけられない問いです。1/60からわずかにずれたフレーム時間で、一歩が丸め1回分だけ1.0に届かないことがありうるからです。一歩の途中で移動が届くたびに起こるリセットそのものは、モデルの結果ではなくソースの読みです。バッファ側は、結果が依存する2つのことも前提にしています。描画側によるサーバーの時計の推定が正確であること、そして更新が届くのにジッター以外の時間がかからないことです。実際のクライアントはサーバーの時計を推定しなければならず、その推定の誤差や、考慮していない一定の片道遅延は、そのままバッファから差し引かれます。7

6つのケース(歩きと走り、それぞれジッター0、30、80 ms)にわたるグループ化された棒グラフの2つのパネル。左は現在のリグで、送り手は歩きで毎秒4タイル、走りで公称6.4:歩きでは後ろ向きに描かれるフレームが0、7、16、走りの3ケースではすべて45。右はバッファありで、モーション契約の毎秒3.75タイルと7.5タイル。600フレーム中、描く先のデータがないフレーム:歩きでは100 ms遅れで355、400、456、300 msで0、0、27、325 msで0、0、6、350 msで0。走りでは100 msで125、188、304、300 ms以上で0。バッファありの実行はすべて後ろ向きのフレームが0。

モデルでは、現在のリグは一歩の途中で移動が届くと、通り過ぎるコレクターを後ろ向きに動いているように描きます。走りではすべての実行で、歩きではジッターがあれば必ず起こります。モーション契約の速度では、350 msのバッファは一度も後ろ向きに描かず、データも尽きません。26

現在のリグは、ジッターのない歩きなら歩く人をきれいに描きます。各歩は次の移動が届く1フレーム前に終わるので、40タイルで引き戻しは0、ジャンプは0、後ろ向きのフレームも0です。ジッターがそれを壊します。30 msでは13回の移動が一歩の途中で届いてリセットを起こし、そのうち7回は一歩の後半に届くため歩く人が後ろ向きに描かれ、1回は経路が長くなってジャンプします。80 msでは25回のリセット、16の後ろ向きのフレーム、2回のジャンプです。走りでは、送り手がリグの描く毎秒4タイルを上回るので、試したどのジッターでも64回の移動のうち45回が一歩の途中で届き、そのたびに後ろ向きのフレームが描かれ、ジャンプは9回です。引き戻しが起こるとき、描かれる歩く人は送り手から最大5.9〜6.7タイル遅れ、そのあとジャンプで前に出ます。一定の歩きでは、遅れが1タイルに達することはありません(最大0.94)。7 引き戻しは、その一歩ですでに描いた分だけ歩く人を後ろへ戻して描きます。これらの実行では、16ピクセルのタイルで最大14ピクセルでした。750

バッファがあれば、歩く人は決して後ろ向きに動きません。バッファありの60回の実行(4つの速度×3つのジッター×5つの遅延)すべてで、後ろ向きのフレームは0です。問題は、描画側に描く先がなくなる頻度だけで、送り手がまだ送信している間に描かれる600フレームで数えます。モーション契約の歩きの毎秒3.75タイルでは、300 ms遅れの描画時計で、ジッター0、30、80 msのときにデータが尽きるフレームは0、0、27です。325 msでは0、0、6、350 msでは0です。100 ms遅れでは、これらの速度のすべてのケースで125〜456フレームでデータが尽きます。7.5での走りでは、300 ms以上なら試したどのジッターでも0フレームです。現在の毎秒4タイルと6.4タイルでは、同じモデルで歩きの300 msが0、0、7で、325 msと350 msでは0です。7 私の読みでは、推定サーバー時刻より350 ms遅れた描画時計こそが答えの数値で、その理由は数えた結果ではなく上界にあります。1タイルにつき1回の移動であれば、あるフレームが必要とする更新のスタンプは描画時計の最大で一歩後であり、そのスタンプから最大でも最悪のジッター分だけ遅れて届きます。毎秒3.75タイルでは一歩は1/3.75秒、266.7 msで、一歩に80 msのジッターを足すと346.7 msです。したがって時計が正確なら、350 msの遅延は80 msまでのどのジッターの抽選でもデータの尽きるフレームを生まず、3.3 msの余裕があります。7 この3 msが、時計の推定に許される余地のすべてです。推定がサーバーの時計より約3 ms以上進んでいれば保証は失われ、データの尽きるフレームが出る可能性があります。上の数値は1回のジッターの抽選(シード1)によるもので、325 msはその抽選では第7.4節が定める基準を4フレームの差で満たしましたが、すべての抽選で満たしたわけではありません。シード1〜200で再実行し、毎秒3.75タイルの歩き、80 msのジッターで調べると、325 msでは200回すべてでデータの尽きるフレームが出て、そのうち8回は10フレームを超えました。350 msではどの回でも0でした。7 350 msはFiedler自身のデモが使っていた遅延でもあります。1タイルにつき1回の移動であれば、これは歩きの一歩(毎秒3.75タイルで267 ms)より少し長い遅延であり、Fiedlerの「3X the packet send rate」(パケット送信間隔の3倍)を、パケットが一歩であり、TCPの上では失われるのではなく遅れて届く世界向けに裏返したものです。16

4. 技法を、数字つきのルールとして

以下の各ルールは、上の実測か引用した出典にさかのぼれます。ルールが複数の出典をもとにした私のまとめである場合は、出典の列にどれかを示しています。

要素 ルール 出典
誰が動くか いつもいる町の人のうち約10人に6人はデフォルトの移動タイプが静止型で、持ち場に立って一方向を向くか周囲を見回し、10人に4人近くは持ち場の周り1〜2セルの範囲をうろつく。出入りするストーリーの役者はほとんど立っているので、全体では10人に7人と4人に1人になる。 エメラルドの非表示フラグを持たない100人:59人が立ち、39人がうろつき、2人がその場で足踏み。158人全体では113人と43人。範囲は1〜2セル1
ペース 町の人はプレイヤーのペースで一歩進み、その一歩にかかった時間より長く待つ。268 msの一歩のあと、0.54、1.07、1.61、2.14 sのいずれかをランダムに。もっと遅いのんびりした歩きもうまくいく(『おいでよ どうぶつの森』)。そのどちらでもないペースはうまくいかない。 エメラルドの共通の歩行アクションと待ち時間のテーブル1、『おいでよ どうぶつの森』32
動いている割合 うろつく人が動いているのは、踏み出した一歩あたりで最大でも時間の11〜33パーセント。ふさがれた一歩では向きを変えて待つだけ。 エメラルド、上の2行についての算術。上限127
住民数 6〜10人で町になる。どうぶつの森の村全体でも最大8〜15人。 ミシロタウン6人、トウカシティ7人、キンセツシティ10人、うち非表示フラグなしは2人、3人、6人1。どうぶつの森の町は最大8〜15人32
変化 一部の町の人は、プレイヤーの進行に合わせてフラグで去ったり現れたりする。 3つの町の23人のうち12人が非表示フラグを持つ1
日課 1日は3〜7の時刻つき地点。どの1日を適用するかはキーが選び、具体性の高い順に決まった順序で試され、最初に一致したものが採用される。 Abigailの水曜日は3地点、Pierreの通常の日は7地点。キー形式は2292
1日 1日はプレイヤーが戻ってきたときに、経過日数を受け取る1回の実行で決着させる。誰も遊んでいないあいだにタイマーを動かさない。 UpdatePerDay3、Stardewの最初の1日の更新9
記憶 その日最初の会話を、町の人1人につき1つのフラグで覚える。報酬は小さく保つ。 『あつまれ どうぶつの森』で255のうち+111、Stardewでハート1つ250に対して+2010
新しいことば 新しい表現の配給は1日1つ、または出会い1回につき1つ。 リアクションは1日1つ12、流行語は流行の人が来るたびに1つ35
痕跡 ほかの人の痕跡は小さな固定枠に収まり、朽ちるか入れ替わる。 ひみつきち20と流行54、店8軒13、防衛役6体47、時雨14、流行の上昇と下降は12日から約50.8日38
代役 人が空けた枠を代役が埋め、その価値は低い。 ジョインアベニューのファンは75%、Serebiiの説明による13
見知らぬ人 見知らぬ人どうしは、ことばではなく気配を共有する。名前はなく、チャイムか定型フレーズだけ。 Journey5、Dark Souls41、子ども向けのGame Center17
発言 定型のセリフはIDとして送られ、あいさつだけでなく受け答えもする。完全な文では、単語リストで綴れるものを何も綴れない。 Club PenguinのssのID48、簡易会話の開いている940語、2〜10枠のグリッド38
更新 グリッドでは一歩につき1回の更新。リモートで歩く人は、推定サーバー時刻より歩きの一歩分を少し超えて遅れた時計で描き、進行中の一歩を決してリセットしない。 Habboの500 ms周期と線形補間(エミュレータとファン製クライアント)1549。毎秒3.75タイルと7.5タイルでのモデル、時計の同期が正確で基礎遅延なしと仮定:350 ms遅れで、ジッター80 msまで後ろ向きのフレーム0、データの尽きるフレーム07
アイドル 入力のないまま2分たったプレイヤーをアイドルとし、ハートビートに応答しなくなった接続を閉じる。 Arcturus:240周期(120 s)でアイドル、アイドル状態の所有者以外を480周期(240 s)で退出15。Houdiniは61 sの間にハートビートを送らなかったクライアントを切断48。ブリーフの「pingなしで240 s」はこの2つを合わせたもので、私による翻案
制限 Game Centerがマルチプレイヤーの制限(フレンドのみを含む)を報告したら、独自のマルチプレイヤーは外す。私の読みでは、それには本物のプレイヤーの歩行の再生も含まれ、そのプレイヤーには町の人だけが見える。 AppleのisMultiplayerGamingRestrictedのドキュメント18。エコーをマルチプレイヤーとみなすのは私の読み(第7.6節)
コミュニケーション Game Centerが個人向けコミュニケーションの制限、またはプレイヤーが未成年であることを報告したら、独自のコミュニケーションは外す。 AppleのisPersonalizedCommunicationRestrictedのドキュメント51
保持 子どものデータは、書面に記した目的に必要な期間だけ保持し、削除期限を通知に記す。 改正後の16 CFR 312.10、2026年4月22日から遵守19

5. Appleのやり方:Game Centerのフラグ、年齢層、ガイドライン、COPPA

子どもが歩いて入れる町は、Appleと米連邦取引委員会(FTC)のルールに縛られ、その多くには日付がついています。この節では、AppleとFTC自身のことばを、Appleが公開している場合は対応状況とあわせて示します。あるルールがKiradexにとって何を意味するかについて私が述べることはすべて読みであり、読みであることを明記しています。そのいずれも法的助言ではありません。

Game Centerの3つの制限フラグ

Game Centerのローカルプレイヤーは、ゲームが何かソーシャルなものを開く前に読める3つのブール値を持っています。対応状況は2026年10月4日に保存したAppleのドキュメントによるもので、それぞれの説明は原文どおりに引用しています。185152

プロパティ iOS Appleの説明
GKLocalPlayer.isMultiplayerGamingRestricted 13.0 「If this property is true, the local player can’t join multiplayer games. If your game uses a custom multiplayer feature, you should disable it.」(このプロパティがtrueなら、ローカルプレイヤーはマルチプレイヤーゲームに参加できない。ゲームが独自のマルチプレイヤー機能を使っている場合は、それを無効にすべき)
GKLocalPlayer.isPersonalizedCommunicationRestricted 14.0 「If this property or the underage property is true, the local player can’t include personalized messages on invitations or enable voice communication in multiplayer games. If your game includes any custom communication features, you should disable them.」(このプロパティまたはunderageプロパティがtrueなら、ローカルプレイヤーは招待に個人的なメッセージを含めたり、マルチプレイヤーゲームで音声通話を有効にしたりできない。ゲームに独自のコミュニケーション機能がある場合は、それらを無効にすべき)
GKLocalPlayer.isUnderage 4.1 「If this property is true, Game Center disables some features for the local player.」(このプロパティがtrueなら、Game Centerはローカルプレイヤーに対して一部の機能を無効にする)

1つ目のフラグのページは、最も重要な詳細を付け加えています。値はScreen Timeから来ており、Screen Timeでは保護者がマルチプレイヤーゲームを、全員と、フレンドのみと、誰とも不可、のいずれかで許可できます。そして「when you configure the setting to friends only, this property returns true for restricted.」(設定をフレンドのみにすると、このプロパティは制限ありとしてtrueを返す)。18 つまり、フレンドとだけ遊ぶことを許された子どもも制限ありとして読まれ、独自の広場を持つゲームはそれをオフにするよう求められます。2つ目のフラグのページには、及ぶ範囲の異なる2つの文があります。1つ目の文はGame Center自身が止めるもの、つまり招待の個人的なメッセージと音声を挙げています。2つ目の文はゲームに対して、ゲーム独自の「any custom communication features」(あらゆる独自のコミュニケーション機能)を無効にするよう求めており、定型のものについての例外はありません。私の読みでは、完全な定型文のメニューは独自のコミュニケーション機能であり、ブリーフはそれをそのように扱います。51

子どものためのGame CenterとScreen Time

AppleのGame Centerのプライバシーページは、Kiradexがすでに全員に適用しているルールを定めています。「when communicating with other players in Game Center, children cannot send or receive user-inputted text. They are restricted to sending and receiving preset messages. In-game voice chat is disabled for children.」(Game Centerでほかのプレイヤーとやりとりする際、子どもはユーザーが入力したテキストを送受信できない。定型メッセージの送受信に制限される。ゲーム内のボイスチャットは子どもには無効になる)。17 さらに「Children’s accounts never make real names visible to friends」(子どものアカウントが実名をフレンドに見せることはない)こと、そして保護者はScreen Timeを使って「multiplayer functionality, the ability to add friends, and the ability to connect with friends playing the same game」(マルチプレイヤー機能、フレンドを追加する機能、同じゲームを遊んでいるフレンドとつながる機能)をブロックできることも述べています。17 AppleのScreen Timeのサポートページは、Game Centerの制限を名前で挙げており、そのなかには「Connect with Friends」(フレンドとつながる)と「Private Messaging」(プライベートメッセージ)があり、それぞれ「Allowed or Blocked」(許可またはブロック)です。53

Declared Age Range

2025年6月11日、Appleは、子ども用アカウントが「is required for children under 13」(13歳未満の子どもに必須)となること、そして「App developers will be able to request this information through the new Declared Age Range API」(アプリ開発者は新しいDeclared Age Range APIを通じてこの情報を要求できるようになる)ことを発表しました。保護者は子どもの年齢層を「always, for each app request, or never」(常に、アプリの要求ごとに、または共有しない)のいずれかで、「in a way that does not reveal the child’s birth date」(子どもの生年月日を明かさない形で)共有するかを選びます。54 同じ発表は、年齢制限レーティングがその年の末までに「expanded to five categories」(5つのカテゴリに拡大)され、ティーン向けに13+、16+、18+が設けられるとしていました。54 Kiradexのワールド計画は、このAPIをジュニア向けルールの切り替えスイッチとして挙げ、10月2日の決定を記録しています。申告された年齢層で13歳未満なら広場はまったくなし、13〜15歳ならジュニア向けルールつきの広場、16歳以上または申告なしなら完全な広場です。23 本記事のためにこのAPI自体のリファレンスページは取得していないので、最低iOSバージョンはここでは示しません。

App Reviewガイドライン

ソーシャルな広場を縛るガイドラインは3つあります。Appleが「Last Updated: June 8, 2026」(最終更新:2026年6月8日)と日付を記した版から引用します。55

  • 1.2、ユーザー生成コンテンツ。 「with user-generated content or social networking services must include」(ユーザー生成コンテンツやソーシャルネットワーキングサービスを含むアプリは、次を備えなければならない)として、不快な素材をフィルタリングする方法、「A mechanism to report offensive content and timely responses to concerns」(不快なコンテンツを報告する仕組みと、懸念へのタイムリーな対応)、「The ability to block abusive users from the service」(悪質なユーザーをサービスからブロックする機能)、「Published contact information so users can easily reach you」(ユーザーが簡単に連絡できるよう公開された連絡先)が挙げられています。結果的に「used primarily for pornographic content, Chatroulette-style experiences, random or anonymous chat」(主にポルノコンテンツ、Chatroulette型の体験、ランダムまたは匿名のチャットに使われる)ようになったアプリなどは、「do not belong on the App Store and may be removed without notice」(App Storeにふさわしくなく、予告なく削除されることがある)とされています。55
  • 1.3、キッズカテゴリ。 このカテゴリのアプリは「must not include links out of the app, purchasing opportunities, or other distractions to kids unless reserved for a designated area behind a parental gate」(ペアレンタルゲートの奥の指定された領域に限らないかぎり、アプリ外へのリンク、購入の機会、その他子どもの気を散らすものを含めてはならない)とされ、狭い例外を除いて「should not include third-party analytics or third-party advertising」(サードパーティの分析やサードパーティの広告を含めるべきではない)とされています。55
  • 5.1.4、子ども。 「collect, transmit, or have the capability to share personal information (e.g. name, address, email, location, photos, videos, drawings, the ability to chat, other personal data, or persistent identifiers used in combination with any of the above) from a minor must include a privacy policy and must comply with all applicable children’s privacy statutes」(未成年者から個人情報(たとえば名前、住所、メール、位置情報、写真、動画、絵、チャットする能力、その他の個人データ、またはこれらのいずれかと組み合わせて使われる永続的な識別子)を収集、送信、または共有する能力を持つアプリは、プライバシーポリシーを含め、適用されるすべての児童プライバシー法を遵守しなければならない)とされ、「the parental gate requirement for the Kid’s Category is generally not the same as securing parental consent」(キッズカテゴリのペアレンタルゲートの要件は、一般に保護者の同意を得ることと同じではない)とされています。55

Kiradexの計画は、設計ドキュメントがガイドラインから引き出している2つの道のうち2つ目、つまりキッズカテゴリの外で9+または12+のレーティング(どちらにするかはまだ決まっていません)を受け、5.1.4に従う道を取っています。23 私の読みでは、5.1.4の一覧にある「the ability to chat」(チャットする能力)は、定型のセリフだけの広場でも、ほかに何を避けていようとプライバシーポリシーは必要だという意味です。

改正後のCOPPA

FTCによる改正後の児童オンラインプライバシー保護規則(Children’s Online Privacy Protection Rule)は、2025年4月22日に連邦官報(Federal Register)で公布されました(文書2025-05904、90 FR 16918)。この規則は「is effective June 23, 2025」(2025年6月23日に発効する)もので、「Except with respect to § 312.11(d)(1), (d)(4), and (g), regulated entities have until April 22, 2026 to comply.」(§ 312.11(d)(1)、(d)(4)、(g)を除き、規制対象の事業者は2026年4月22日までに遵守しなければならない)とされています。19 5対0の採決を伝えるFTCの2025年1月16日のリリースは、変更点を次のようにまとめています。「related to targeted advertising or other purposes」(ターゲティング広告やその他の目的に関連する)第三者に子どもの情報を開示するには別途検証可能な保護者の同意が必要になること、そして保持は「for as long as reasonably necessary to fulfill a specific purpose」(特定の目的を果たすのに合理的に必要な期間)に限られ、「operators cannot retain the information indefinitely」(事業者は情報を無期限に保持できない)ことです。56

規則の本文のうち3つの箇所が、何かを記憶する広場に関わってきます。

  • 保持、§ 312.10。 「Personal information collected online from a child may not be retained indefinitely. At a minimum, the operator must establish, implement, and maintain a written data retention policy that sets forth the purposes for which children’s personal information is collected, the business need for retaining such information, and a timeframe for deletion of such information.」(子どもからオンラインで収集した個人情報は無期限に保持してはならない。少なくとも事業者は、子どもの個人情報を収集する目的、その情報を保持する業務上の必要性、その情報の削除期限を定めた書面のデータ保持方針を策定、実施、維持しなければならない)。この方針はオンラインの通知に記載します。19
  • 永続的な識別子、§ 312.2。 個人情報には「A persistent identifier that can be used to recognize a user over time and across different websites or online services」(時間を超えて、また異なるウェブサイトやオンラインサービスをまたいでユーザーを認識するのに使える永続的な識別子)が含まれ、その例として「a customer number held in a cookie, an Internet Protocol (IP) address, a processor or device serial number, or unique device identifier」(Cookieに保持された顧客番号、IPアドレス、プロセッサやデバイスのシリアル番号、一意のデバイス識別子)が挙げられています。19
  • 内部運営、§ 312.5(c)(7)。 「Where an operator collects a persistent identifier and no other personal information and such identifier is used for the sole purpose of providing support for the internal operations of the website or online service」(事業者が永続的な識別子だけを収集し、ほかの個人情報を収集せず、その識別子をウェブサイトやオンラインサービスの内部運営を支援する目的にのみ使う場合)には、通知を条件として同意は不要です。19

改正後の§ 312.8は、子どものデータについて書面の情報セキュリティプログラムも求めています。19 訪問者の歩行を再生する広場にとってこれが何を意味するかについての私の読みは、読みであることを明記してブリーフに記しています。WORLD.mdの第3節は最終的な設計を弁護士に読んでもらうよう求めていますが、10月2日の決定はそれをアプリが軌道に乗るまで先送りしたので、それまではこの読みのままです。23

コスト

この節の内容は、どれもデバイス上で測定していません。認証後にGKLocalPlayerの3つのブール値を読むのにかかる時間はここでは計測していませんし、40人の部屋でほかの最大39人のコレクターのために350 msの描画バッファを持つメモリやCPUも同様です。21 私の読みでは、どちらも1フレームの描画に比べれば問題にならないはずですが、それは読みであり、ブリーフのチェックは計時ではなくふるまいを見るものです。

6. ケーススタディ:自らのコードで実測したKiradexの広場

Kiradex Worldは、私のカード収集アプリKiradexの中にあるピクセルの町です。16ピクセルのタイルで描かれた40×30の広場で、小さなFastAPIとWebSocketのサーバーが動かしています。このサーバーはプレゼンスをメモリに保持するだけで何も保存しません。ただし、そのウェブサーバーがデフォルトで記録するログは別です(第7.6節、設定6)。212357 10月5日に、作業ツリーからサーバーとアプリのワールドのコードを何も変更せずに読み、2つのスクリプトでサーバー自身のクラスをシミュレートした時計で動かしました。ですから、この節の数値は私によるコードの読みではなく、コードのふるまいです。21620 リポジトリは非公開なので、ファイルはパスで示します。以下はdocs/WORLD.mdの計画、コード自身のdocstring、そしてコードが実際にすることのあいだの食い違いです。どれも誰かが隠していた不具合ではなく、4つ目の一部は計画がすでに未実装として挙げています。

あるもの

サーバーは23の定型のセリフを持っています。プレイヤー用が14(インデックス0〜13)、町のコレクター用が9(14〜22)です。部屋の定員は40。プレイヤーごとに毎秒8回の移動と2.0秒に1回のセリフという制限があります。町の時計は0.5 sごとに刻まれます(server/app/main.pyのTICK_SECONDS)。同じコレクターにカードを見せるには60秒のクールダウンがあり、40×30の広場の到着地点はタイル(19, 13)です。2120 部屋にいる全員が同じコレクターを見られるように、4人の台本つきのコレクターがサーバー上に住んでいます。Moss、Prism、Comet、Dawnで、それぞれ4つのウェイポイントを持ち、ループの長さは18、22、30、32タイルです。それぞれ見せてほしいカードの種類(ヴィンテージ、ホロ、何でも、日本語版)と、2つか3つのセリフを持っています。server/app/npcs.pyはSTEP_SECONDS = 0.7とし、各コレクターをウェイポイントで一様分布の3〜8秒だけ立ち止まらせ、一様分布の20〜40秒ごとに(最初は8〜20秒後に)セリフを言わせます。2120

私の読みでは、これは正しい直感です。町の人は各スマートフォンではなくサーバーにいて、セリフはゆっくりした時計で発せられ、それぞれに望みがあるので、コレクションが意味を持つ場所があります。実測すると、そのうち3つが損なわれており、4つ目は計画とコードのあいだのずれです。

1. 歩行が止まったり動いたりする

measure_npc_cadence.pyはserver/app/npcs.pyとrooms.pyをインポートし、広場と4人のコレクターを組み立て、実際の0.5 sのティックでシミュレート上の1時間動かします。6 歩行区間内の歩と歩のあいだの6,253の間隔は、すべてちょうど1.0秒で、0.7秒ではありません。一歩はそのnext_move以降の最初のティックで発火するので、0.7秒は2ティックに切り上げられるのです。つまり定数が示す1.43に対して毎秒1.0タイルです。区間の前の立ち止まりは平均6.75秒(4.5〜9.0、1,202回)で、セリフは、1人のコレクターが続けて言うセリフのあいだの465の間隔で平均30.7秒おきです(1時間で469のセリフ)。6

クライアントはどの一歩も250 msで描きます。PlazaRig.swiftは101行目でtilesPerSecondを4にしています。50 ですから、毎秒1タイルで歩くコレクターは、各区間の25パーセントだけ動いているように描かれ、残りの75パーセントは、タイルとタイルのあいだごとに立ち止まっています。6 エメラルドのうろつく人はプレイヤーのペースで一歩進んでから待ちます。Kiradexのコレクターは、歩いているはずのあいだ、プレイヤーのペースで1タイル分の小刻みな動きを繰り返します。私の読みでは、これは住民ののんびりした歩きにも普通の歩行にも見えません(第1節のタイムライン図の一番下の行)。

2. そばを歩いて通り過ぎるコレクターが引き戻される

サーバーが別のコレクターの移動を中継すると、PlazaRig.move(other:to:facing:)(PlazaRig.swiftの526〜542行目)は歩いている人の最後の整数タイルから経路を計画し、その歩みをその経路にセットし、メッセージが届くたびに、一歩が半分描かれている途中であってもprogress = 0にします。6タイルより長い経路はジャンプになります。50 第3節のモデルは、リグ自身の32ビットの算術でこれに数値を与えます。ジッターのない一定の歩行では、各歩が次の移動の届く直前に終わるので、引き戻しは起きません。ジッターが30 msまたは80 msなら、40タイルの歩行は一歩の途中で13回または25回リセットされ、そのうち7回または16回が後ろ向きに描かれます。走りでは、リグは歩く人を歩きの毎秒4タイルで描くので、試したどのジッターでも64回の移動のうち45回が一歩の途中で届き、ジャンプは9回です。そして引き戻しが起こるとき、描かれる歩く人は送り手から最大5.9〜6.7タイル遅れます。7 このシリーズの以前の記事ピクセルアートの動きは、プレイヤー自身が一歩の途中で2回目のタップをしたときの同じ引き戻しをコードから読み取っています。その記事のブリーフが定めるルール、つまり進行中の一歩を決してリセットしないというルールを、このブリーフはほかのコレクターに適用します。22

3. 空になると町が止まる

server/app/npcs.pyのモジュールのdocstringは、コレクターについて「A town is never empty, and it has somewhere for a collection to matter.」(町が空になることはなく、コレクションが意味を持つ場所がある)と述べています。20 ところがserver/app/rooms.pyのRoom.tickは、自身のdocstringで「A room with nobody in it stands still」(誰もいない部屋は静止している)と逆のことを述べ、実際にそうしています。部屋にプレイヤーがいないとすぐにreturnするので、コレクターはそのときいた場所で固まります。206 スクリプトは、最初に来た人がそのとき何を見るかを測っています。新しく作ったコレクターを1回のティックでシミュレート上の10,000秒まで進めると、各コレクターから1つずつ、4つのセリフが一度に出て、全員がもといた場所に立っています。そのあいだには何も起きていません。6 そしてサーバーは何も保存しないので、静かな朝に最初に来たコレクターは同じ4人を見るだけで、ほかの誰かがそこにいた形跡は何もありません。Kiradex/とserver/app/を検索しても、訪問や毎日の会話を記録するものは見つかりません。24

4. レート、そしてGame Centerのフラグ

2つの食い違いはdocs/WORLD.mdとコードのあいだにあります。計画の第5節は、サーバーに至った論拠として、クライアントが位置と向きを8〜10 Hzで送る設計を残しています。23 アプリは代わりに、完了したタイルごとに1回のmoveを送ります。現在は歩きで毎秒4回、走りの公称レートで6.4回(モーション編の記事によるコードのモデルでは60 Hzで6.0回)で、どちらにしてもサーバーの毎秒8回の制限を下回っています。シリーズのモーション契約、つまり60 Hzで歩き1タイル16ティック、走り8ティックなら3.75と7.5になり、これも制限を下回ります(第7.4節)。2122 私の読みでは、グリッドにとってはタイルごとのほうがよい設計で、ブリーフはこれを維持します。更新すべきなのは計画のほうの記述です。

計画の第3節はアイデンティティをGame Centerの上に組み立てており、その理由は「a child’s Game Center is controlled by the parent in Screen Time (multiplayer on/off, adding friends on/off, sharing the friend list with games on/off).」(子どものGame CenterはScreen Timeで保護者が管理する(マルチプレイヤーのオン/オフ、フレンドの追加のオン/オフ、フレンドリストをゲームと共有するかのオン/オフ))からです。23 Kiradex/にもserver/app/にも、GKLocalPlayer.isMultiplayerGamingRestricted、isUnderage、isPersonalizedCommunicationRestrictedを読むものや、Declared Age Range APIを呼ぶものはありません。24 計画の第5節はすでに、未実装のものとして「junior mode by Declared Age Range」(Declared Age Rangeによるジュニアモード)を挙げています。23 挙げていないのはGame Centerのフラグのほうです。Screen Timeのマルチプレイヤーの設定はGame Center自身のマルチプレイヤーを制御し、Appleのドキュメントは「a custom multiplayer feature」(独自のマルチプレイヤー機能)を持つゲームに、自らそれを無効にするよう求めています。ですから、アプリがフラグを読むまでは、保護者の設定は広場に届きません。18

クライアントは、ソケットが切れるとmin(30, 2^attempts)秒のバックオフで再接続します(PlazaClient.swiftの165行目)。コレクターを非表示にする処理はデバイス上でIDによって行われます。215023 どちらもブリーフではそのまま残しますが、ブリーフは非表示リストの使い道を1つ加えます。広場のエコーを求める各リクエストに非表示リストを添えて送り、このプレイヤーが非表示にしたコレクターの歩行をサーバーが除外できるようにします(第7.2節)。

7. ブリーフ:Kiradexが作るものと、通るべきチェック

ブリーフは、広場にすでにあるもの(サーバー自身のコレクター、定型のセリフだけ、1タイルにつき1回の移動、メモリ上のプレゼンス)を残し、原典が示す順に3つの答えを加えます。暮らしが止まらない町の人、そこにいた人たちの痕跡、そして引き戻されずに描かれるプレゼンスです。どの項目にも、スクリプト、テスト、キャプチャのいずれかで合否を判定できるチェックがあります。タイル座標は広場のもので、xは右向き、yは下向きです。21

借用についての線引きは、このシリーズの最初の記事が特許と表現について引いたものと同じです。生き物を一切登場させず、ポケモンの地名も使わず、フランチャイズの用語を機能名に使わず、狙って投げて捕まえるもの、捕獲の可能性を示すもの、相棒を戦わせるもの、何かに乗って移動するものは一切作りません。36 以下の要素はすべて、歩き、立ち、完全な定型文を話す町の人たちと、ほかのコレクターの歩みの淡い再生です。ゲームのシステムは、上では公開された作品についての事実として名前を挙げています。Kiradexの機能には、ここでKiradex自身の名前をつけます。町の人、エコー、今日のあいさつ、セリフ帳、そして静かな広場です。docs/WORLD.mdの第3節は、フレンドでないライブのコレクターをすでにすべて「通りすがり」と呼んでいます。その呼び方はそのまま残し、再生のほうはエコーと呼んで、2つが混同されないようにします。23 法律に関する注記は読みであり、助言ではありません。

7.1 日課を持つ町の人

  • 人数。 広場自身のコレクターを4人から8人に増やし、それぞれに持ち場を与えます。21 内訳はエメラルドのいつもいる人たち、つまり100人中59人が立ち、41人がそうでない(39人がうろつき、2人がその場で足踏み)という比率に従い、8人に丸めると5人が立ち、3人が動きます。5人は持ち場に立って向きを変えます。店のカウンター、ホールのドア、噴水、そして2つの屋台です。2人は、エメラルドのうろつく人と同じように、持ち場の周り2セルの範囲をうろつきます。動く3人目はエメラルドの比率から来たものではありません。エメラルドの158人の町の人はすべて、立つか、範囲内をうろつくか、その場で足踏みするかで、決まったルートを歩く人はいないからです。3人目は、現在の4つのウェイポイントのループの1つを残したもので、持ち場のあいだを巡回します。つまり現在の4つのループは1つになります。121 新しい4人のコレクターは、現在の4人と同じく、アプリ自身のフィギュアシステムで描かれ、アプリ自身の単語リストからハンドルが与えられます。20
  • 待ち時間。 持ち場にいるコレクターは向きを変え、うろつく人は一歩進みます。その前の待ちは、サーバーの0.5 sの時計の1、2、3、4ティックからランダムに選びます。つまり0.5、1.0、1.5、2.0秒で、エメラルドの0.54、1.07、1.61、2.14をティック単位で丸めたものです。整数ティックの待ちはティックによって再び丸められることがありません。それこそが、第6節で一歩について実測した不具合です。16
  • 部屋の時計。 どの部屋も1つの時計で動きます。サーバーのUTC時刻を、部屋自身のタイムゾーン(サーバーの設定で部屋ごとに1つのIANAゾーン)で読んだものです。サーバーは到着時に、welcomeと静かな広場のレスポンス({"zone": "<IANA name>", "clock": <server ms>})でその両方を送り、広場が開いているあいだ、アプリは時間帯をスマートフォンからではなくそこから取ります。そうすれば部屋にいる全員が、同じ光のもとで同じ町の人を見ることができます。現在のDaylight.nowは、スマートフォン自身のカレンダーとゾーンであるCalendar.currentから時刻を取っており、サーバーは単調増加の時計しか持たず、どのゾーンも指定していません。50 部屋がどのゾーンを使うか、コレクターがどの部屋に送られるかは、このブリーフでは未定のままにする設定です。すべての部屋で1つのゾーンを使うのが最も単純な出発点です。広場の外では、スマートフォンの時計がそのままコレクターの時計です。
  • 日課。 町の人それぞれの1日は、サーバーのデータに1本の文字列として書かれた3〜7の時刻つき地点で、順に試されるキーで選ばれます。日付、曜日、時間帯、そしてデフォルトの順で、どれも部屋の時計で読みます。9 時間帯はアプリ自身のもので、Kiradex/World/Daylight.swiftのDaylight.Phaseから取ります。朝は6時から9時、昼は9時から17時、夕方は17時から20時、それ以外は夜です。50 部屋の時計で夜になると、持ち場にいる5人とうろつく2人は、Stardew ValleyのPierreの金曜日が酒場から(「Returns home to sleep.」、家に帰って寝る)終わるのと同じように、それぞれ自分のドアから屋内に入り、残したループを歩く人は巡回を短くします。30
  • ペース。 止まったり動いたりする歩行を、2つの変更のどちらかで直します。推奨は、サーバーが区間を一度だけ{"t": "walk", "id": ..., "path": [...], "at": <server ms>}として送り、クライアントがそれをatから、シリーズのモーション契約によるプレイヤーの歩き、つまり60 Hzで1タイル16ティック、毎秒3.75タイル(現在のリグでは4)で歩かせるものです。22 最低限の策は、サーバーの歩の間隔を整数ティックにするSTEP_SECONDS = 0.5で、クライアントは町の人の一歩を同じ0.5秒、毎秒2タイルで描きます。これはプレイヤーの歩きではなく、住民ののんびりした歩きです。632
  • 部屋が空のときの時間。 町の人のタイルは部屋の時計の純粋関数です。ルート、時間帯、シードから、問われたときに計算し、Room.tickで進めるのではありません。シードはサーバーの設定にある1つのグローバルな値で、部屋やゾーンごとのものではないので、同じゾーンの2つの部屋は同じタイルに同じ町の人を表示します。部屋の時計で07:40に最初に来たコレクターは、07:40にMossがいるはずの場所にMossを見ます。別のゾーンに設定したスマートフォンから同じ部屋に入ったコレクターも同様です。63

チェック。 (a) 設計によるペース。推奨の区間については、クライアントのテストが、町の人が立っているタイルの先に5タイル続くまっすぐな経路とatのスタンプを持つ台本どおりのwalkを与え、モーション編のブリーフの-motionLogがプレイヤーの位置を記録するのと同じように町の人の位置を毎ティック記録し、次を確認します。クライアントによる部屋の時計の推定でatにあたるティックで歩き出すこと、経路のタイルを順に通ること、毎ティックちょうど1ピクセル動き、決して後ろに戻らないこと、1タイルに16ティックかかること、そしてatの80ティック後に最後のタイルに立っていることです。サーバーのテストは、各区間がスタンプつきで、まるごと一度だけ送られることを確認します。最低限の代替策については、サーバーのテストが町の人を0.5 sのティックでシミュレート上の1時間動かし、区間内の歩の間隔がすべて設定値と等しいことを確認します。現在、measure_npc_cadence.pyは設定値の0.7 sに対して1.0 sを検出しています。どちらの場合も、サーバーのテストはすべての待ちが整数ティックであることを確認します。622 (b) テストが同じゾーンの2つの部屋を600秒ずらして開き、どちらも1つのグローバルなシードを使って、同じサーバー時刻で町の人のタイルが一致することを確認します。スマートフォンのゾーンを部屋とは別のゾーンに設定したクライアントのテストは、広場の時間帯が部屋の時計に従うことを確認します。(c) テストがサーバーの時計を、部屋のゾーンで03:00にあたるUTCの時刻に設定し、持ち場の5人とうろつく2人が広場のマップにおらず、残したループを歩く人はいることを確認します。(d) サーバーのテストが8人を種類別に数え、持ち場5人、うろつく人2人、残したループ1人であることを確認します。

7.2 エコー:直近8人の歩み

  • 仕組み。 広場は直近8回の訪問を保持します。413 1回の訪問とは、到着から最初に入ったドアまで、または60秒までのうち短いほうの、タイルと時刻の組として記録された歩いた経路です。歩いた人のフィギュアは保持しません。部屋にいるライブのコレクターが8人より少ないとき、エコーがその差を埋めます。それぞれが自分のペースで歩みを再生し、入ったドアのところで消えていきます。エコーには名札がなく、カードを掲げず、タップ対象を持たず、何も話しません。それは人ではなく、歩みです。5
  • 見た目。 エコーのフィギュアは、歩いた人のフィギュアから派生させることは決してありません。サーバーは各エコーに4つの無地のフィギュアのうち1つを与えます。マニフェストのデフォルトのパーツを4つの無地の染色で染めたもので、フォージがエコー用に作り、淡く(フォージの染色ランプの1つを固定のアルファで)描きます。4つのうちどれを選ぶかは、サーバーが保持して決して送らない秘密鍵のもとで、歩み自身のソルトの鍵つきハッシュで決めます。ですから同じコレクターの2つの歩みには、互いに無関係なフィギュアがつきます。コレクターもデフォルトのパーツを着られるので、たまたま4つのうちの1つを着ている人が、偶然エコーと一致することはあります。その一致は何も伝えません。フィギュアは誰が歩いたかについて何も語らないのです。58
  • 減衰。 エコーは7日後、または新しい訪問が8回届いたときの、どちらか早いほうで削除されます。14
  • 誰がエコーを見るか。 ライブの広場にいるコレクターで、広場にいるコレクターが8人より少ないときです。isMultiplayerGamingRestrictedがtrueの人は見ません。その人の静かな広場は町の人だけです。私の読みでは、エコーは広場のマルチプレイヤーの一部だからです(第7.6節、設定1)。18
  • 非表示。 コレクターを非表示にすると、その人のエコーも非表示になり、絞り込みはサーバーが行います。保存された各歩みは、ランダムなソルトとタグを持ちます。タグは、サーバーだけが持つ秘密鍵のもとでの、歩いた人のIDとそのソルトの鍵つきハッシュ(HMAC)なので、同じコレクターの2つの歩みには互いに無関係なタグがつきます。エコーのリクエストには、リクエストした人が非表示にしたIDが添えられます。サーバーは保存された各歩みについて、非表示の各IDのタグを計算し直し、一致した歩みを除外し、リクエストに応答した時点で、あるいはライブの接続ならソケットが閉じた時点で、そのリストを捨てます。クライアントに届くのは、無地のフィギュア、経路、そして時刻(時単位)だけです。ID、タグ、ソルトはなく、歩いた人のフィギュアから取ったものもありません。これで識別子と見た目は取り除かれます。現在この2つは、すべての到着でいっしょに送られています(server/app/rooms.pyのPlayer.public()はID、ハンドル、フィギュアを1つのオブジェクトで送り、server/app/main.pyがそれを部屋にブロードキャストします)。ただし歩みそのものは取り除かれません。経路、そのペース、その時刻は、その時間帯に広場にいた人や、友だちがいつもどこへ行くかを知っている人にとっては、あるコレクターを指し示すことがあります。また、その同じ歩みのときに部屋にいたクライアントは、各タイルを歩いた人のIDとともにmovedで受け取っています。エコーは名前がないだけで、匿名ではありません。2320
  • 何を保存するか、そしてCOPPAの読み。 ハンドル、Game CenterのID、デバイスID、歩いた人のフィギュア、地域、そして時単位より細かい時刻は保存しません。保存するのは、タイル、歩みの開始からの相対的な歩の時刻、時刻(時単位)、無地のフィギュアの選択にも使うソルト、そして非表示を適用するためのタグです。読みであり、助言ではありません。 タグは永続的な識別子から派生しているので、私はそれを永続的な識別子として扱います。タグはサーバーにとどまり、決して送られず、非表示を適用するという目的にのみ使われます。私はこれを、§ 312.5(c)(7)が通知を条件として述べる内部運営のための利用と読みます。識別子を持たず、サーバーが選んだフィギュアで送られる歩みそのものは、規則の個人情報の定義の外にあると読みます。この読みの弱点は、歩みがふるまいであり、その時間帯に広場を見ていた人がそれをあるコレクターと結びつけるかもしれないことです。時単位だけの時刻、60秒の上限、7日間という期間はその可能性を狭めますが、なくしはしません。リクエストに添えられる非表示のIDは、そのリクエストのために使われ、記録も保持もされません。プライバシー通知に記す書面の保持方針は、§ 312.10が求めるとおり7日間とします。19 これによってサーバーは、何も保存しない状態から、歩みを1週間保存する状態に変わります。そしてこの読みは、計画が軌道に乗るまで先送りしている弁護士に見てもらうべきものです。23
  • 誰を記録するか。 13歳未満は記録しません。10月2日の決定により、そもそも広場がないからです。23 isMultiplayerGamingRestrictedがtrueの人も記録しません(歩けるライブの広場がないため、設定1)。isUnderageがtrueの人(設定2がすでに子どもの信号として扱っています)も、申告された年齢層で13〜15歳の人も記録しません。後者は、計画がまだ書かれていないとしているジュニア向けルールの最初のものです。185223
  • 似せてはならないもの。 血痕、再生される死、召喚サイン、プレイヤーの投稿で埋まった壁。エコーは決して生き物ではなく、決して戦いません。4144

チェック。 (a) サーバーのテストが10回の訪問を記録し、8回が保持されて最も古いものが削除されること、そして時計を7日進めるとどれも残らないことを確認します。(b) スキーマのテストが、保存された歩みが経路、時刻、ソルト、タグのフィールドだけを持ち、ハンドル、ID、フィギュアの文字列を含まないこと、そしてクライアントが受け取るエコーがフィギュア、経路、時刻のフィールドだけを持ち、ハッシュ、タグ、ソルト、IDのフィールドを持たないことを確認します。さらに、エコーのフィギュア文字列が、歩みのソルトの鍵つきハッシュが選ぶ4つのうちの1つであり、歩いた人が何を着ていても同じであること、そして無地の4つ以外のフィギュアを着た人については、それが歩いた人のフィギュアではないことを確認します。(c) ライブのほかの人がいない状態のUIテストが、最大8つのエコーを表示し、どれもタップに反応しないことを確認します。(d) マルチプレイヤー制限フラグのテスト、isUnderageのテスト、13〜15歳の層のテストが、そのクライアントからの訪問をサーバーが記録しないことを確認します。(e) サーバーのテストが2人のコレクターの歩みを保存し、そのうち1人を非表示にしてエコーをリクエストし、そのコレクターの歩みが除外されていること、そしてその後、非表示にしたIDがサーバーの状態のどこにもないことを確認します。

7.3 今日のあいさつ

  • 仕組み。 町の人はそれぞれ、今日あなたと話したかどうかを覚えています。1110 ローカルの日付でその日最初の会話ではあいさつのセリフ(「Back again!」(また来たね!)のようなもので、Kiradexのために書き、server/app/lines.pyのインデックス22の後に追加します)が選ばれ、同じ日のそれ以降の会話では普通のセリフが選ばれます。21 同じ町の人と話した日が3日を数えるごとに、その町の人は常連の隠れたはしごを1段上がります。数えるのは最初の会話からで、決してリセットされません。そして1段上がるたびに、新しいセリフを1つ言うようになります。メーターは表示しません。
  • 減衰なし。 1日、あるいは1か月来なくても、何も失われません。Stardewの友好度は話さない日ごとに減りますが、これは決して減りません。PEGIが「daily quests, log-in streak or event-based rewards that expire after a while」(デイリークエスト、ログインの連続記録、しばらくすると期限が切れるイベント型の報酬)をPEGI 7と評価し、「players are punished by losing rewards or game status when they do not return in time」(期限内に戻らないと、報酬やゲーム内の地位を失うことでプレイヤーが罰せられる)場合はPEGI 12と評価するからです。105958
  • どこに保存するか。 デバイス上です。町の人のIDから、最後に話したローカルの日付と話した日数への辞書を1つ、コレクターのプロフィールに持ちます。これでサーバーはプレイヤーごとの保存領域を持たないままでいられます。

チェック。 (a) ユニットテストが、1人の町の人と2026-10-05に2回、2026-10-06に1回話し、その日最初のあいさつを2回、普通のセリフを1回得ることを確認します。(b) ユニットテストがデバイスの日付を前後に動かし、はしごの段が一度も取り除かれないことを確認します。(c) server/appを検索し、この機能のためにプレイヤーごとの保存領域が追加されていないことを確認します。(d) 数週間おきの3日にその日最初の会話をしたユニットテストが、その町の人がはしごを1段上がっていることを確認します。

7.4 引き戻されないプレゼンス

  • 送信。 現在と同じく、完了したタイルごとに1回のmoveを送ります。現在の基準は歩きで毎秒4回、走りで6.0〜6.4回です(60 Hzでモデル化した走りと公称レートの走り)。シリーズのモーション契約、つまりモーション編のブリーフにある60 Hzで歩き1タイル16ティック、走り8ティックでは3.75と7.5になり、このブリーフが目指すのはこの契約です。どちらも毎秒8回の制限を下回ります。2122 サーバーは、中継するすべてのmovedに自身のミリ秒のスタンプを付けます。
  • 描画。 各クライアントは受け取ったスタンプからサーバーの時計の推定を持ち、ほかのコレクターをそれぞれ、その推定より350 ms遅れた描画時計で描きます。描画時計をはさむ、受信済みの2つのスタンプのあいだを線形に描き、歩行サイクルは歩いた距離で進めます。進行中の一歩は決してリセットしません。バッファが空になったら最後のタイルで待ちます。グリッドを歩く人はぴたりと止まるので、何も外挿しません。ジャンプするのは、歩く人が6タイルより多く、または2秒より多く遅れたときだけです。716 350 msは上界から来ており、時計の推定が正確で、ジッター以外に片道遅延がないと仮定したモデルで確かめています(第3節)。モーション契約の歩きの毎秒3.75タイルでは一歩は266.7 msで、一歩に80 msのジッターを足すと346.7 msです。少なくともそれだけの遅延があれば、どのジッターの抽選でもデータの尽きるフレームは出ません。時計の推定の誤差に残る余地は約3 msです。推定がそれ以上サーバーの時計より進んでいると、データの尽きるフレームが出る可能性があります。325 msはモデルの最初のジッターの抽選ではチェック(a)に合格し、80 msでデータの尽きるフレームは6でしたが、200回の抽選のうち8回で不合格でした。350 msはどの回でも0でした。7 これはデバイス上のキャプチャで確かめるべき出発点の値であり、結果ではありません。
  • アイドル。 入力のないまま120秒たったコレクターをアイドルとし、リグに既存のdozeのアイドルサイクルで表示します。Arcturusが500 msの240周期でアバターをアイドルとするのと同じです。1550 pingのないまま240秒たったらソケットを閉じます。このルールは2つの出典を私が翻案したものです。pingの確認はHoudiniのもので、61秒の間にハートビートを送らなかったクライアントを切断します。240秒はArcturusがアイドル状態の所有者以外を退出させるまでの長さですが、Arcturusが数えるのはpingの欠落ではなく、アクションのない周期です。4815

チェック。 (a) 新しいロジックをmeasure_remote_walk.pyに移植します。描画時計は送り手自身の時計ではなく、クライアントによるサーバーの時計の推定から取ります。送り手が毎秒3.75タイルと7.5タイルのとき、6つのケースすべてで後ろ向きのフレームが0、ジッター0 msと30 msでデータの尽きるフレームが0、80 msでは送り手が送信している間に描かれる600フレームのうちデータの尽きるフレームが最大10であることを求めます。正確な時計でのモデルは、350 msで、200回のジッターの抽選のいずれでも、6つすべてでデータの尽きるフレームが0です。7 (b) 台本どおりのほかの人が広場を右へ横切って歩くUIテストで、その人のxが減るフレームが1つもキャプチャされないことを確認します。(c) サーバーのテストが、中継されるすべてのmovedにスタンプがあることを確認します。(d) サーバーのテストが時計をpingなしで241秒進め、ソケットが閉じられていることを確認します。

7.5 セリフ帳

  • 形。 6つの分岐、それぞれリリース時に8〜12のセリフ、合計48〜72で、どのセリフも2タップ(分岐、次にセリフ)で届きます。あいさつ、答え(好きな時代、コレクション歴、どのセット)、コレクション、交換(交換の段取りであり、値付けは決してしない)、応援、そしてお別れです。現在は1つのリストにプレイヤー用のセリフが14あります。21 エモートは別の列のままです。Game Centerがコミュニケーションの制限を報告するプレイヤー、または未成年のプレイヤーには、セリフ帳そのものを提供しません(第7.6節、設定2)。
  • 拡張。 プレイによって最大30のセリフが追加で解放されます。解放は1日に最大1つで、第7.3節の常連のはしごとレベルから得られます。1235 リストはサーバーが持ち、到着時にすでにリストを送っているので、1時間以内にセリフを引退させることができます。20
  • 原典との比較。 簡易会話は940語を開き、それを2〜10枠のグリッドに組み立てます。『あつまれ どうぶつの森』のリアクションは88。エメラルドのユニオンルームは15文字のキーボード入力を受け付けていました。38124 Kiradexのセリフは完全な文であり、単語から組み立てられることは決してありません。ですから、どんな選び方を重ねても、名前、数字、場所を綴ることはできません。
  • 似せてはならないもの。 簡易会話のグループ構造やその単語グリッド、流行語のリスト、あらゆるフランチャイズの用語。40

提案するセリフ帳の模式図。ルートのノードから、あいさつ、答え、コレクション、交換、応援、お別れの6つの分岐が出ており、それぞれに埋まったセリフの枠が8つと空いた枠が4つあり、分岐ごとに8〜12のセリフ。下の注記:現在は1つのリストにプレイヤー用のセリフが14。エメラルドの簡易会話は2〜10枠のグリッドで開いている940語。エメラルドのユニオンルームは15文字のキーボード入力メッセージと10の登録フレーズ。

提案するセリフ帳。本記事で唯一、実測ではなく提案を示した図です。26

チェック。 (a) lines.pyに対するテストが、リリース時に6つの分岐それぞれに8〜12のセリフがあること、そしてどのセリフもルートから2タップ以内であることを確認します。(b) テストが、数字や自由入力の枠を含むセリフがないことを確認します。(c) テストがpretの簡易会話の単語リストを読み、エントリと一致するセリフがなく、2語以上のエントリがセリフの中に含まれていないことを確認します。(d) ユニットテストが2日続けて1つずつセリフを解放し、同じ日の2回目の解放を拒否することを確認します。

7.6 安全設定、それぞれにチェックつき

  1. Game Centerの制限は、ライブでも再生でも、ほかのコレクターをオフにする。 GKLocalPlayer.local.isMultiplayerGamingRestrictedがtrueのとき(フレンドのみを含む)、広場は静かな広場として開きます。町の人だけで、エコーもWebSocketもありません。町の人と部屋の時計は、アカウントID、デバイスID、非表示のIDを含まない1回のリクエストで届きます。サーバーはリクエストのIPアドレスをそれに応答するためだけに使い、広場のサーバーはそれを記録しません。ホスト自身のエッジのリクエストログについてはここでは検証していません(設定6)。18 読み: ページには「If your game uses a custom multiplayer feature, you should disable it」(ゲームが独自のマルチプレイヤー機能を使っている場合は、それを無効にすべき)とあり、エコーは本物のコレクターの歩みの再生であり、第2節で調べた種類の、ほかのプレイヤーの痕跡であり、見る人がそれと気づくかもしれないものです(第7.2節)。WikipediaはDark Soulsのほかのプレイヤーの幽霊のような姿を、ゲームのMultiplayerの見出しのもとで説明していますが、それが記録なのか、その時点で接続しているプレイヤーなのかは述べていません。この出典はどちらとも取れます。見出しのもとの本文は、ゲームが「integrates online features into the single-player world」(オンライン機能をシングルプレイヤーの世界に統合する)と述べ、幽霊とは別に、協力の召喚と侵入を「Direct multiplayer」(直接のマルチプレイヤー)としているからです。それでもブリーフは保守的な側を取ります。私の読みでは、エコーは広場の独自のマルチプレイヤー機能の一部であり、保護者がマルチプレイヤーを制限したプレイヤーには何も見せません。1841 このプレイヤーにエコーを戻せるとすれば、App ReviewあるいはAppleが書面で、識別子のない、無地のフィギュアで再生される歩みをマルチプレイヤー以外のものと読んだ場合です。このブリーフはそれを前提にしません。チェック: フラグをtrueにスタブしたUIテストが、WebSocketが開かれないこと、エコーが描かれないこと、そして広場が静かだと表示することを確認します。サーバーのテストが静かな広場のルートを呼び、レスポンスにエコーがなく、サーバーのログにIPアドレスがないことを確認します。
  2. 独自のコミュニケーションをオフにする。 isPersonalizedCommunicationRestrictedまたはisUnderageがtrueのとき、デフォルトはエモートだけです。セリフ帳は隠され、sayは送られず、ほかのコレクターのセリフはこのプレイヤーには描かれず、音声、招待メッセージ、入力欄はどんな場合にもありません。5152 読み: ページには「If your game includes any custom communication features, you should disable them」(ゲームに独自のコミュニケーション機能がある場合は、それらを無効にすべき)とあり、定型文のセリフ帳は独自のコミュニケーション機能です。Game Centerが自身の機能のなかで子どもに定型メッセージを許していても、ゲーム独自のものが免除されるわけではありません。5117 エモートを残すのは、手を振ったりうなずいたりすることには、子どもが誰かに連絡を取るのに使えるものが何も含まれないからです。しかしエモートもある種のコミュニケーションであり(WikipediaによるJourneyの説明は、そのチャイムを「The only form of communication between the two」(2人のあいだの唯一のやりとり)と呼んでいます)、ここがこの読みで最も弱いところです。App Reviewがエモートも独自のコミュニケーション機能と読むなら、エモートも外し、このプレイヤーにとって広場はプレゼンスだけになります。5 このプレイヤーにセリフを残すのは、Appleの書面による同意が必要な例外です。このブリーフはそれを取りません。チェック: Kiradex/WorldをTextField、TextEditor、UITextFieldで検索して何も見つからないこと、そして各フラグをtrueにスタブしたUIテストが、エモートの列を表示し、セリフ帳を表示せず、sayを送らず、ほかのコレクターのセリフを描かないことを確認します。
  3. 10月2日の決定どおり、Declared Age Rangeによる年齢層。 13歳未満:広場なし、自動生成のハンドルのみ。13〜15歳:ジュニア向けルールつきの広場で、その最初のルールは歩みを決して記録しないこと。16歳以上または申告なし:完全な広場。2354 チェック: 3つの年齢層とGame Centerの3つのフラグにわたるモード表のユニットテスト。
  4. 報告と非表示はエコーにも届く。 コレクターを非表示にすると、ライブのフィギュアが非表示になり、第7.2節のとおりリクエストごとにサーバーで絞り込んで、エコーも非表示になります。報告はすべてのコレクターのパネルに残ります。55 エコーは無地のフィギュアをまとい、パネルを持たないので、プレイヤーが非表示にしたコレクターのエコーを見分けて非表示にすることはできません。それはサーバーのフィルターが行います。非表示はその前に保存された歩みにもその後の歩みにも及びますが、ほかのプレイヤーがライブで見たものや、歩みから気づいたものには及びません。チェック: 第7.2節(e)のサーバーのテスト、そして台本どおりのほかの人を非表示にし、その人の記録された歩みを再生して、それが描かれないことを確認するUIテスト。
  5. ランダムなマッチングなし、匿名のチャットなし。 見知らぬ人どうしは広場を共有するだけです。2人の見知らぬ人を組み合わせて個室に入れるものは何もありません。55 チェック: server/app/main.pyのハンドラに対するテストが、Game Centerのフレンドではない2人のコレクターのあいだに通信路を開くメッセージがないことを確認します。
  6. 書面による保持。 プライバシー通知に書面のデータ保持方針を加えます。プレゼンスはメモリ上のみ。エコーは7日間で、それぞれ歩いた人のIDの鍵つきハッシュを持ちますが、それはサーバーにとどまり、非表示の適用にのみ使われ、決して送られません。リクエストに添えられる非表示のIDは保持しません。接続のIPアドレスは、それに応答して返信を届けるためだけに使い、私はこれを§ 312.5(c)(7)のもとでの内部運営の支援と読みます。広場のサーバーはそれを記録しません。報告は理由と部屋で記録します。19 現在、サーバーはuvicorn 0.37.0をデフォルトのまま起動しており(server/Procfile、--proxy-headers)、uvicorn自身のコードを読むかぎり、そのデフォルトでは、すべてのHTTPリクエスト(アクセスログはオフにしないかぎりオン)と、受け付けたすべてのWebSocket(uvicorn.errorへのINFO行)について、クライアントの転送されたアドレスをログに書きます。ブリーフはこれを--no-access-log --log-level warningで起動します。57 チェック: 通知のURLが設定から到達できること、第7.2節(a)のサーバーのテストが7日間を守ること、そして本番の起動コマンドのもとでWebSocketを開き、静かな広場のルートを呼ぶテストが、取得したログにIPアドレスを見つけないこと。ホストのエッジのリクエストログはこのテストの範囲外で、ここでは検証していません。それがクライアントのアドレスを記録するか、記録するならどれだけの期間かは、通知を書く前にホストに確認すべきことです。
  7. ワールドにはサードパーティの分析も広告も入れない。55 チェック: アプリのターゲットの依存関係の監査で、分析や広告のSDKが1つも挙がらないこと。

拒むもの

  • 独自のプレイタイマー。 Screen Timeはすでにアプリでの時間を制限できますし、Club Penguinのサーバーはプレイヤーに許された分数をカウントダウンして0で切断していました。保護者がすでに知っているのはプラットフォームの制限のほうです。1748
  • フォロワー数、そして誰が誰を好きかを示すあらゆる数。計画はすでにこれを除外しています。23
  • 名前つきの訪問者リスト、つまり誰が来たかのページ。エコーは意図して名前を持ちません。IDを持たず、歩いた人のフィギュアから取ったものも何も持ちません。それでも匿名ではありません。その時間帯に広場にいた人や、友だちの習慣を知っている人は、歩みに気づくかもしれません。だからエコーは時刻を時単位でしか持たず、それより細かい時刻を持たないのであり、エコーを読み取れるリストもないのです。
  • タップできるエコー、話しかけたり、ついて行ったりできるエコー。
  • 今日のあいさつのメーター、あるいは戻ってこなかったことで失われるもの。59

このブリーフに含めないもの

  • 人が飾る部屋。 家具、帽子、ほかのコレクターの部屋の訪問は、このシリーズの今後の記事で扱います。
  • 新しいセリフの文言。 ブリーフはセリフ帳の形を決めます。文はKiradexのために書かれ、別途ローカライズされます。
  • グループでの遊び。 計画が未実装として挙げている交換、見せ合い、交換画面は、このブリーフの範囲外です。23
  • 実測したゲームからのもの。 Pokémon、Stardew Valley、どうぶつの森、Dark Souls、Journey、Death Stranding、Splatoon、Habbo、Club Penguinの生き物、地名、マーク、タイル、音は一切使いません。
  • デバイス上のタイミング。 チェックはふるまい、キャプチャ、モデルです。ここではフレーム時間を何も約束しません。

重要なポイント

アートを描く人へ

  • 歩いている人より立っている人を多く描きましょう。エメラルドのマップにいつもいる町の人の10人に6人は持ち場に立ち、ほとんどは一方向を向き、一部は周囲を見回しています(ストーリーの役者を数えに入れると10人に7人)。立っている各フィギュアに向きと見回しを与え、歩行サイクルは、うろつく10人に4人近くのためにとっておきましょう。1
  • 別のプレイヤーの歩みのエコーは、人ではなく痕跡として読めるようにしましょう。淡く、名前がなく、何も手にしておらず、ドアのところで消えていく。その描き方のどこにも、タップを誘うものがあってはなりません。5

エンジンを作る人へ

  • 町の1日は到着時に、経過日数を受け取る1回の実行で決着させ、町の人のタイルは、各スマートフォンの時計ではなく、部屋にいる全員が共有する1つの時計から計算しましょう。部屋が空のときにreturnするサーバーのループは、Kiradexで実測したとおり町を凍らせます。36
  • サーバーの歩の間隔を整数ティックにし、各歩を与えられた間隔で描きましょう。0.5 sのティック上の0.7 sの一歩は1.0 sごとに着地して0.25 sで描かれ、時間の75パーセントは立ち止まっている歩行になります。6
  • 1タイルにつき1回の更新を送り、サーバーでスタンプを付け、ほかの歩く人は推定サーバー時刻より350 ms遅れた時計で、進行中の一歩を決してリセットせずに描きましょう。モデルでは、シリーズの毎秒3.75タイルと7.5タイル、正確な時計の推定のもとで、ジッター80 msまで後ろ向きのフレームもデータの尽きるフレームも0です。7
  • ソケットを開く前にisMultiplayerGamingRestricted、isPersonalizedCommunicationRestricted、isUnderageを読みましょう。フレンドのみは制限ありとして読まれます。そして私の読みでは、制限されたプレイヤーにはほかのプレイヤーの再生も見せるべきではありません。185152

ゲームのループを設計する人へ

  • ほかの人の痕跡は、朽ちていく少数の固定枠に収めましょう。7日間で8つの歩みがあれば、誰かがここにいたと伝えるには十分です。非表示はサーバーで適用し、痕跡はIDなしで、歩いた人自身のフィギュアではなく無地のフィギュアで送り、歩みはそれを見た人には気づかれうることをはっきり伝えましょう。414
  • 今日のあいさつは1つのフラグで覚え、来なかった日のために何かを取り上げることは決してしないようにしましょう。PEGIは期限切れになる連続記録をレーティングの対象にしています。59
  • 見知らぬ人には、単語ではなく文を与えましょう。完全な文のセリフ帳では何も綴らせることができませんし、Game Centerはすでに子どもを定型メッセージに限っています。Game Centerがコミュニケーションの制限を伝えてきたら、セリフ帳も取り上げましょう。381751

よくある質問

ほかのプレイヤーがオンラインでないとき、ゲームの町を生きているように感じさせるには?

自分の日課を持つ町の人と、そこにいた人たちの痕跡を与えることです。『ポケットモンスター エメラルド』の16の町と街では、非表示フラグを持たない町の人100人のうち、59人が持ち場に立ち、39人が1〜2セルの範囲をうろつき、2人がその場で足踏みします(フラグで消える、ほとんど立っているストーリーの役者を数えに入れた158人全体では71.5%、27.2%、1.3%)。彼らはプレイヤーのペースで一歩進み、一歩ごとに0.54〜2.14秒待ちます。Stardew Valleyの村人は、22のキー形式で選ばれるいくつかの時刻つき地点からなる1日を送ります。そしてエメラルドの「レコードをまぜる」は、別のプレイヤーのひみつきち、流行のフレーズ、住人をあなたの町にコピーします。124

見下ろし型のピクセルゲームでは、NPCはどれくらいの頻度で動くべき?

エメラルドでは、うろつく人は16フレームの一歩(268 ms、プレイヤーの歩きと同じアクション)を進み、そのあと32、64、96、128フレーム待つので、動いているのは踏み出した一歩あたりで最大でも時間の11〜33パーセントで、選んだ一歩がふさがれていればそれより少なくなります。町の人のほとんどは一歩も踏み出さないデフォルトの移動タイプを持っていますが、ストーリーのスクリプトはそうした人を歩かせることもできます。『おいでよ どうぶつの森』は逆の方向に進み、住民をプレイヤーのペースより遅くしました。よくないのは、そのどちらでもないペースです。Kiradexのコレクターは、プレイヤーの速さで1タイルずつ小刻みに動き、タイルとタイルのあいだで0.75秒止まります。1326

『ポケットモンスター エメラルド』の「レコードをまぜる」とは?

通信ケーブルによるやりとりで、それぞれのゲームが相手に、11種類のレコードからなる5,188バイトの固定の構造体を送ります。そのなかには、ひみつきち20、テレビの枠25、ニュース16、流行のフレーズ5が含まれます。相手のキンセツシティのおじいさんがあなたのおじいさんに置き換わり、流行の人がやって来ることだけが、彼にもう1つ流行語を教えさせる唯一のきっかけになります。435

2Dのマルチプレイヤーゲームには、どれくらいの補間遅延が必要?

Glenn Fiedlerのルールは、パケットを2つ失っても持ちこたえられるだけ、つまり送信間隔の約3倍に、ジッターのための1〜2フレームを足したものです。16 TCPの上で動くWebSocketでは何も失われず、遅れたパケットは再送されるので、私の読みでは予算はパケットロスではなくジッターであり、1間隔を少し超えるバッファで足ります。1タイルにつき1回の更新を送るグリッドの世界について、シリーズの歩き毎秒3.75タイル、走り7.5タイルでKiradexの歩行をモデル化したところ、推定サーバー時刻より350 ms遅れた描画時計で、ジッター80 msまで後ろ向きのフレームもデータの尽きるフレームも0でした。1回のジッターの抽選では、80 msでの歩きで300 msは600フレーム中27フレーム、325 msは6フレームでデータが尽き、100 msはすべてのケースで125〜456フレームでデータが尽きました。200回の抽選でも、350 msはどの回でもデータが尽きませんでした。350 msの根拠は上界です。毎秒3.75タイルでの266.7 msの一歩に80 msのジッターを足すと346.7 msになります。これはまっすぐな道、一様なジッター、正確な時計の推定、基礎遅延なしを前提としたモデルであり、デバイスでのキャプチャではありません。7

iOSのゲームで子どもはチャットを使える?

Game Centerは、子どもは「cannot send or receive user-inputted text」(ユーザーが入力したテキストを送受信できない)、「restricted to sending and receiving preset messages」(定型メッセージの送受信に制限される)としており、ボイスチャットは無効です。Appleのドキュメントは、isPersonalizedCommunicationRestrictedまたはisUnderageがtrueのとき、「any custom communication features」(あらゆる独自のコミュニケーション機能)を持つゲームはそれを無効にするよう求めています。またガイドライン1.2は、ユーザー生成コンテンツについてフィルタリング、報告、ブロック、公開された連絡先を求めています。その文は定型メッセージを免除していないので、私の読みでは、Game Centerが自身の機能のなかで子どもに定型メッセージを許していても、どちらかのフラグがtrueならゲーム独自の定型のセリフは外すことになります。Kiradexのブリーフはそのプレイヤーにはエモートだけを残します。そしてこの読みはAppleの文言ではなく、私のものです。175155

COPPAは、ほかのプレイヤーの動きを保存してゴーストとして再生することを認めている?

私は弁護士ではなく、これは読みであって助言ではありません。改正後の規則は「A persistent identifier that can be used to recognize a user over time」(時間を超えてユーザーを認識するのに使える永続的な識別子)を個人情報に数え、事業者が永続的な識別子だけを「for the sole purpose of providing support for the internal operations」(内部運営を支援する目的にのみ)通知を条件として使うことを認め、2026年4月22日からは削除期限を定めた書面の保持方針を求めています。Kiradexの設計は、ハンドル、アカウントID、デバイスIDを持たず、歩いた人のフィギュアでもない歩みを保存し、それに加えて歩いた人のIDの鍵つきハッシュを保存します。このハッシュはサーバーにとどまり、ほかのプレイヤーの非表示を適用するためにのみ使われ、決して送られません。エコーはサーバーが選ぶ4つの無地のフィギュアの1つで描かれ、どちらも7日間保持され、その方針に記されます。私はハッシュを内部運営のために使われる永続的な識別子として扱い、送られる歩みは定義の外にあるものとして扱いますが、歩みはふるまいであり、その時間帯に広場を見ていた人があるコレクターと結びつけるかもしれません。ですからエコーは匿名ではなく名前がないだけであり、最終的な設計は弁護士が確認すべきです。19

このサイトの関連記事:iPhoneでつくるピクセルアートの世界はこのシリーズの最初のガイドで、本記事の町がある広場とタイルシステムを扱い、その法律に関するFAQはブリーフが従う特許の線引きを示しています。ピクセルアートの人物は、コレクターと、エコーがまとう無地のフィギュアを作るフォージを組み立て、今日のあいさつが減衰しない理由となるPEGIのルールを引用しています。ピクセルアートの建物は、町の人が夜に帰っていくドアを作りました。ピクセルアートの動きは携帯ゲーム機の歩行を実測し、アプリ自身の歩行をモデル化し、ブリーフがほかのコレクターに適用する「一歩を決してリセットしない」ルールを定めています。そして開発者のためのiPhone Duoは、広場が描かれる対象のデバイスを扱っています。

出典


  1. 著者による測定、measure_npcs.py(本記事用の著者の証拠フォルダ内)、2026年10月5日に改訂して再実行、出力はmeasure_npcs.outとして保存。入力:pretのpokeemerald逆コンパイル、コミット731ad5b(master、2026年10月1日)のシャロークローン。include/constants/event_object_movement.h(81の移動タイプ)、16の町と街のdata/maps/*/map.jsonファイル(オブジェクトイベント、グラフィックスID、移動タイプ、範囲、非表示フラグ)、src/event_object_movement.c(歩のテーブル、59.7275 Hzで換算した3つの待ち時間のテーブル、どの移動タイプがどの待ち時間を設定するか、そしてMovementType_WanderAround_Step4)。改訂版はオブジェクトイベントをgraphics_idで人物、オブジェクト(ITEM_BALL6、TRUCK2、MR_BRINEYS_BOAT1)、生き物(5)に分類し、未分類のグラフィックスIDが現れたら停止する。スプライトが変数から来るVAR_0とVAR_3のイベントは、そのすべてがライバルの非表示フラグを持っているので人物として数える。以前の版は172のオブジェクトイベントすべてを町の人として数えていた。それとその出力は.r1の接尾辞をつけて横に残してあり、改訂版の出力は以前の行を変更せずに繰り返す。最初の改訂版とその出力は.r2の接尾辞をつけて残してある。現在のスクリプトは2回目の改訂版で、158人をオブジェクトイベントにある非表示フラグで分ける。フラグを持つ58人(54人が立ち、4人がうろつく。スクリプト内のグラフィックスIDの固定リストによれば、そのうち41人が悪の組織、ライバル、名前のある登場人物のスプライトを使う)と、持たない100人(59人が立ち、39人がうろつき、2人がその場で足踏み)であり、3つの町の非表示フラグを持たない人を数え直す(ミシロタウン2、トウカシティ3、キンセツシティ6)。その出力は以前のすべての行を変更せずに繰り返す。非表示フラグを持たない人は、どのロードでもマップにいる。58人をストーリーの役者と呼ぶのは、そのスプライトとフラグ名についての私の読みであり、データのフィールドではない。動いている割合(11〜33パーセント)は歩と待ち時間の行についての算術で、16フレームを16に32〜128を足したもので割った、踏み出した一歩あたりの値である。選んだ方向がふさがれたうろつく人は、動かずにもう一度向きを変えて待つので、これは上限である。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩

  2. 著者による測定、measure_daily.py(同じフォルダ内)、2026年10月5日に再実行、出力はmeasure_daily.outと同一。入力:pretのpokeemerald 731ad5bのinclude/constants/flags.hとsrc/clock.c。保存したStardew Valley Wikiのページ「Villagers」(oldid 191346、2026年2月26日編集)、「Pierre」、「Modding:Schedule data」(22のキー形式はページの表から数えた)。Nookipediaの「Reaction」ページ(『あつまれ どうぶつの森』のバージョンごとの数)。 ↩↩↩↩↩↩↩↩↩↩↩

  3. pret、pokeemerald/src/clock.c(DoTimeBasedEventsと、最後に実行してからの日数daysSinceを受け取って一度だけ実行されるUpdatePerDay)、コミット731ad5b。DoTimeBasedEventsはsrc/overworld.cでのマップのロード時と、src/field_tasks.cの定期的なフィールドタスクからも呼ばれる。2026年10月4日閲覧、https://github.com/pret/pokeemerald/blob/master/src/clock.c ↩↩↩↩↩↩↩

  4. 著者による測定、measure_record_mixing.py(同じフォルダ内)、2026年10月5日に再実行、出力はmeasure_record_mixing.outと同一。入力:pretのpokeemerald 731ad5bのsrc/record_mixing.c(struct PlayerRecordEmerald、その11のメンバーと0x1444バイトのサイズ)、include/constants/global.hと関連ヘッダー(SECRET_BASES_COUNT、TV_SHOWS_COUNT、POKE_NEWS_COUNT、SAVED_TRENDS_COUNT、APPRENTICE_COUNT)、src/mauville_old_man.c(5人のおじいさんと選ばれ方の規則)、そしてsrc/union_room_chat.c、include/union_room.h、include/constants/global.h(ユニオンルームのリーダー、グループの人数、スプライト、アクティビティコード、キーボードのページ、MAX_MESSAGE_LENGTH、UNION_ROOM_KB_ROW_COUNT)。 ↩↩↩↩↩↩↩↩↩↩↩↩

  5. Wikipedia「Journey (2012 video game)」、GameplayとDevelopmentの節(各記述はそれぞれの出典を引く)、2026年10月4日保存、https://en.wikipedia.org/wiki/Journey_(2012_video_game) 。thatgamecompany自身のJourneyのページも保存したが、ナビゲーションしか含まれていない。 ↩↩↩↩↩↩↩

  6. 著者による測定、measure_npc_cadence.py(同じフォルダ内)、2026年10月5日に改訂して再実行、出力はmeasure_npc_cadence.outとして保存。改訂は、平均30.7秒の算出に使った、1人のコレクターが続けて言うセリフのあいだの465の間隔に加えて、すべてのsaidメッセージの数(1時間で469)を数える処理を足しただけで、ほかの行は変わっていない(以前の版は.pre-astraの接尾辞をつけて残してある)。2026年10月5日に読んだ作業ツリー(ファイルとハッシュは注20)からKiradexサーバー自身のapp.npcs(STEP_SECONDS、make_all)とapp.rooms(Plaza)をインポートし、server/app/main.pyからTICK_SECONDSを読み、シード1の4人のコレクターを理想的な0.5 sの時計でシミュレート上の3,600秒進め、すべてのmovedとsaidメッセージを記録する。連続する歩のあいだが1.5 s以下の間隔は区間内として数え、それより長い間は立ち止まりとする。空の部屋のテストは、Room.tickに早期returnがあるかを確認し、新しく作ったコレクターでadvance(10000.0)を一度呼ぶ。25パーセントと75パーセントは、クライアントの250 msの一歩(PlazaRig.tilesPerSecond = 4)を実測した1.0 sの間隔で割ったもの。この実行は、measure_kiradex.pyが定数だけから導いた0.7 sと36パーセントに取って代わる。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩

  7. 著者によるモデル、measure_remote_walk.py(同じフォルダ内)、2026年10月5日に改訂して再実行、出力はmeasure_remote_walk.outとして保存。リグの算術を64ビット浮動小数点で行っていた以前の版とその出力は、.pre-f32の接尾辞をつけて残してある。改訂版は、リグがFloatで行うすべての演算を32ビット(NumPyのfloat32)で、コードの順序どおりに行う。progressはFloat(PlazaRig.swiftの29行目)、updateはFloat(event.deltaTime)を受け取り(PlazaStage.swiftの149行目)、advance()はdt * tilesPerSecond * (running ? runPace : 1) / lengthを加算する(660行目)。runningはプレイヤーにのみ設定される(614行目)。位置は(Float(x) + 0.5) * 16(TileMap.swiftの235行目)で、from + (to - from) * progressに描かれ、整数ピクセルに丸められる(0から遠いほうへ丸める。670行目と726行目)。1/60秒のフレームを15回足すと、32ビットではちょうど1.0、64ビットでは0.9999999999999999になるという確認結果を出力する。10月5日に読んだPlazaRig.move(other:to:facing:)を再実装し(歩いている人の最後の整数タイルからの経路、メッセージごとにprogress = 0、経路が空か6歩より長いときにジャンプ)、歩みが残っていてprogressが0.05を超えているときのリセットを引き戻し、描かれたピクセル位置が前のフレームより小さいものを後ろ向きのフレームとして数え、遅れは描かれたピクセル位置から求める。これとは別に、一定の描画時計rt = now - delay(遅延は100、250、300、325、350 ms)の上でのスナップショット補間をモデル化する。nowは送り手の時計なので、モデル化しているルールは、最新の更新から遅延を引いたものではなく、推定サーバー時刻から遅延を引いたものである。この半分はリグではなく提案する描画方式であり、64ビット浮動小数点で動く。前提:すべてのフレームのdeltaTimeはちょうど1/60秒。積和演算の融合なし。送り手と描画側の時計は完全に同期。基礎の片道遅延はなく、更新はスタンプにジッターを足した時刻に届く。まっすぐ開けた道(経路の長さはマンハッタン距離。リグでは√2倍の時間がかかる斜めの一歩はモデル化しない)。送り手は完了したタイルごとに1回の移動を送り、両方の半分で現在の歩きの毎秒4タイルと走りの公称6.4、バッファについてはさらにシリーズのモーション契約の毎秒3.75タイルと7.5タイルでも送る。Jを0、30、80として0〜J msの一様なジッター。毎秒60フレーム。シード1。リグはケースごとにシミュレート上の12秒(送信10秒と落ち着くまで2秒)、バッファありの各実行は660フレーム(11秒)実行し、データの尽きるフレームは、送り手がまだ送信している間に描かれる600フレームについてのみ数える。2つ目のスクリプトmeasure_remote_walk_seeds.py(同じフォルダ内)は2026年10月5日に実行し、出力はmeasure_remote_walk_seeds.outとして保存。measure_remote_walk.pyのソースから同じ補間関数を読み込み、シード1でデータの尽きるフレームが27、6、0と再現されることを確認したうえで、毎秒3.75タイルと7.5タイルでのバッファをシード1〜200で再実行する。ジッター80 msの歩きでは、325 msは200のシードすべてでデータの尽きるフレームが出て、8つで10を超え、350 msはどのシードでも0。325 msと350 msのそれ以外のケースはすべて0。350 msの根拠となる上界も出力する。毎秒3.75タイルの一歩は266.67 ms、80 msのジッターを足すと346.67 msで、残りは3.33 ms。また、描画時計をずらして、サーバーの時計より進んだ時計の推定もモデル化する。フレームと歩が1/60 sのグリッドに揃うこのモデルでは、10 ms進んでいても200のシードでデータの尽きるフレームは0で、25 ms進むと325 msと同じふるまいになる。したがって本文の3 msは上界が保証するものであり、このモデルでデータが尽き始める点ではない。これはモデルであり、2台のデバイスからのキャプチャではない。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩

  8. pret、pokeemerald/data/maps/、16の町と街のmap.jsonファイル(LittlerootTown、PetalburgCity、MauvilleCityを含む)、およびdata/maps/PetalburgCity/scripts.inc(ジムの少年LOCALID_GYM_BOY。map.jsonではMOVEMENT_TYPE_LOOK_AROUNDで非表示フラグなし。PetalburgCity_Movement_BoyWalkToGymの移動でジムまで歩く)、コミット731ad5b、2026年10月4日閲覧、https://github.com/pret/pokeemerald/tree/master/data/maps ↩↩↩↩

  9. Stardew Valley Wiki「Modding:Schedule data」、2026年10月4日保存、https://stardewvalleywiki.com/Modding:Schedule_data 。スケジュールの形式、ゲームバージョン1.5.1時点のAbigailの生データ、キー形式とその順序、「Limitations」の注記。 ↩↩↩↩↩↩↩↩

  10. Stardew Valley Wiki「Friendship」、2026年10月4日保存、https://stardewvalleywiki.com/Friendship 。ハートあたりのポイント、友好度が上がる方法と下がる方法、減少の表、プレゼント、誕生日の倍率、ハートイベント。 ↩↩↩↩↩↩

  11. Nookipedia「Friendship」、『あつまれ どうぶつの森』の節、2026年10月4日保存、https://nookipedia.com/wiki/Friendship ↩↩↩↩

  12. Nookipedia「Reaction」、『あつまれ どうぶつの森』の節、2026年10月4日保存、https://nookipedia.com/wiki/Reaction 。バージョンごとの数はmeasure_daily.pyによる(注2)。 ↩↩↩↩↩

  13. Serebii.net「Join Avenue」、『ポケットモンスター ブラック2・ホワイト2』の節、2026年10月4日保存、https://www.serebii.net/black2white2/joinavenue.shtml 。ファンサイトであり、この機能について使った唯一の出典。 ↩↩↩↩↩

  14. Wikipedia「Death Stranding」、Gameplayの節(それぞれの出典を引く)、2026年10月4日保存、https://en.wikipedia.org/wiki/Death_Stranding ↩↩↩↩↩

  15. Krews、Arcturus Morningstar(ファンが書いた、Habboのサーバーのオープンソースのエミュレータ)、src/main/java/com/eu/habbo/habbohotel/rooms/Room.java(IDLE_CYCLES = 240、IDLE_CYCLES_KICK = 480、scheduleAtFixedRate(this, 500, 500, TimeUnit.MILLISECONDS))、2026年10月5日保存、https://git.krews.org/krews/Morningstar/-/blob/master/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java 。エミュレータの定数であり、Sulakeが公表した数値ではない。RoomUnitは読んでいない。 ↩↩↩↩↩↩↩

  16. Glenn Fiedler「Snapshot Interpolation」、Gaffer on Games、2014年11月30日、2026年10月4日保存、https://gafferongames.com/post/snapshot_interpolation/ ↩↩↩↩↩↩↩↩

  17. Apple「Game Center & Privacy」、「Children in Game Center」の節とフレンドの節、2026年10月4日保存、https://www.apple.com/legal/privacy/data/en/game-center/ ↩↩↩↩↩↩↩↩

  18. Apple Developer Documentation、GKLocalPlayer.isMultiplayerGamingRestricted(iOS 13.0+)、ドキュメントのJSONを2026年10月4日に保存、https://developer.apple.com/documentation/gamekit/gklocalplayer/ismultiplayergamingrestricted 。引用はDiscussionの本文で、trueへのインライン参照を単語として表記し、下書きフォルダ内のsources/extract_gk.pyで平文化したもの。 ↩↩↩↩↩↩↩↩↩↩↩↩

  19. 連邦取引委員会(FTC)「Children’s Online Privacy Protection Rule」、最終規則、連邦官報(Federal Register)、2025年4月22日、文書2025-05904、90 FR 16918、2026年10月4日保存、https://www.federalregister.gov/documents/2025/04/22/2025-05904/childrens-online-privacy-protection-rule 。DATESの節と、改正後の16 CFR 312.2(個人情報の定義)、312.5(c)(7)、312.8、312.10。この規則がKiradexにとって何を意味するかについての本記事の記述はすべて著者の読みであり、法的助言ではない。 ↩↩↩↩↩↩↩↩↩↩↩

  20. 著者によるKiradexリポジトリ(非公開)の読み取り、2026年10月5日時点の作業ツリー、読み取りのみでgitコマンドは実行していない。ファイルはSHA-256の先頭8桁の16進数で識別する。server/app/main.py(87c6cc9f。TICK_SECONDS = 0.5、SHOW_EVERY_SECONDS、メッセージハンドラ。その中に、歩いた人のidとタイルを運ぶ223行目のmovedの中継がある)、server/app/npcs.py(d84f12a5。モジュールのdocstring、STEP_SECONDS = 0.7、4つの定義とそのルート、望み、セリフ)、server/app/rooms.py(dcd66866。115行目のPlayer.public()は、ID、ハンドル、フィギュアを1つのオブジェクトで返し、main.pyの203行目で到着時に部屋へブロードキャストされる。CAPACITY、MOVES_PER_SECOND、SAY_EVERY_SECONDS、Plaza、そしてdocstringと早期returnを持つRoom.tick)、server/app/lines.py(391f5391。23のセリフと、サーバーが到着時にリストを送ると述べるdocstring)。 ↩↩↩↩↩↩↩↩↩↩↩

  21. 著者による測定、measure_kiradex.py(同じフォルダ内)、2026年10月5日に再実行、出力はmeasure_kiradex.outと同一。注20の作業ツリーからapp.lines、app.rooms、app.npcsをインポートし、PlazaRig.swiftとPlazaClient.swift(注50)からクライアントの定数を読む。定型のセリフの数、部屋の定員、レート制限、ティック、クールダウン、広場の大きさと到着地点、4人のコレクターのルートとループの長さ、歩きと走りの速度、6歩のジャンプのしきい値、再接続のバックオフ。これが導く0.7 sと36パーセントは注6に取って代わられている。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩

  22. Blake Crosley「Pixel-Art Motion: Walks, Cameras and Doors on iPhone」、blakecrosley.com、2026年10月5日、https://blakecrosley.com/blog/pixel-art-motion-on-iphone 。その注6は、アプリの歩行をちょうど60 Hzでモデル化している。走りは1タイル10フレーム、毎秒6.00タイルで、毎秒4タイルに走りの1.6を掛けて得られる6.4に対し、120 Hzでは6.32。現在のコードについての節は、一歩の途中での2回目のタップによる引き戻しをwalk(to:)から読み取り、そのブリーフは進行中の一歩を決してリセットしないというルールを定めている。ブリーフの項目1は、60 Hzで歩きを1タイル16ティック、走りを8ティック、毎秒3.75タイルと7.5タイルとし、これがシリーズのモーション契約である。そのチェックは-motionLog起動引数でプレイヤーの位置を毎ティック記録する。 ↩↩↩↩↩↩↩

  23. Kiradex、docs/WORLD.md(「Kiradex World: research and plan」)、2026年10月5日時点の作業ツリー(SHA-256 c7714bc1)、読み取りのみ。第2節(キッズカテゴリと5.1.4の道、レーティングは9+または12+)、第3節(Game Centerのアイデンティティ、Screen Timeの管理、フォロワー数なし、定型のセリフ、弁護士の読み)、第5節(10月2日時点で作られたサーバー:FastAPIとWebSocket、プレゼンスのみ、何も保存しない、毎秒8回の移動、デバイス上での非表示、Declared Age Rangeによるジュニアモードを含む「Not yet」(未実装)。そしてそこに至った論拠として、クライアントが位置と向きを8〜10 Hzで送る設計)、および「Decisions taken (Blake, October 2, 2026)」(決定事項、Blake、2026年10月2日)の項目6(レーティングと年齢層)と項目8(軌道に乗るまで弁護士なし)。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩

  24. 著者によるKiradexの作業ツリーのKiradex/とserver/app/の検索、2026年10月5日。isMultiplayerGamingRestricted、isUnderage、isPersonalizedCommunicationRestricted、Declared Age Range API、そして訪問や毎日の会話を保存するものを検索し、一致なし。 ↩↩↩

  25. pret、pokeemerald/include/constants/event_object_movement.h、コミット731ad5b、2026年10月4日閲覧、https://github.com/pret/pokeemerald/blob/master/include/constants/event_object_movement.h ↩

  26. 図は、記事の下書きの横に置いたfigures/make_figures.pyで2026年10月5日に描いた。入力はmeasure_npcs.py、measure_npc_cadence.py、measure_chat_trend.py、measure_record_mixing.py、measure_kiradex.py、measure_remote_walk.pyの保存済みの出力で、各値はそれらのファイルから解析し、描く前に期待値と照合して確認している。期待値はリサーチ資料のものだが、例外として町の人口の図は改訂版のmeasure_npcs.pyから人物だけをプロットし、非表示フラグを持たない100人の行を加えており、セリフ帳の開いている940語は改訂版のmeasure_chat_trend.pyによる。2つ目のエンジンによるレビューのあと、流行の図は改訂版のmeasure_chat_trend.pyからゲーム自身の整数日のスコアをプロットし(連続的な三角波ではなく、経過1日につき1点)、すれ違う歩行の図は改訂版のmeasure_remote_walk.pyをプロットしている。現在のリグはそれ自身の32ビットの算術で、バッファはモーション契約の毎秒3.75タイルと7.5タイル、遅延100、300、325、350 msで描いている。セリフ帳の図はブリーフの提案の模式図で、比較用の数値は同じ方法で解析している。ゲームのアート、スプライト、マップのレンダリングは一切使っていない。 ↩↩↩↩↩

  27. pret、pokeemerald/src/event_object_movement.c(IsCoordOutsideObjectEventMovementRange、sMovementDelaysMedium、sMovementDelaysShort、// UnusedのコメントがついたsMovementDelaysLong、回転する2つのタイプの48フレーム固定の待ち、MovementType_WanderAround_Step4、GetWalkNormalMovementAction、sStepのテーブル)、コミット731ad5b、2026年10月4日閲覧、https://github.com/pret/pokeemerald/blob/master/src/event_object_movement.c ↩↩↩↩↩

  28. pret、pokeemerald/include/constants/flags.h(DAILY_FLAGS_STARTと12の毎日フラグ)、コミット731ad5b、2026年10月4日閲覧、https://github.com/pret/pokeemerald/blob/master/include/constants/flags.h ↩

  29. Stardew Valley Wiki「Villagers」、oldid 191346、2026年2月26日編集、2026年10月4日保存、https://stardewvalleywiki.com/Villagers 。プレゼントを渡せる34人の村人は、ページのリスト(独身男性6、独身女性6、結婚候補でない22)を数えたもの。wikiの「Friendship」ページは、最初からいる28人の町の人という別の集合を数えている。 ↩

  30. Stardew Valley Wiki「Pierre」、2026年10月4日保存、https://stardewvalleywiki.com/Pierre 。通常のスケジュール、6つのスケジュールのバリエーション、どのハートの段階でも届く郵便とハート3つで届く郵便。 ↩↩↩

  31. Nookipedia「Hobby」、2026年10月4日保存、https://nookipedia.com/wiki/Hobby ↩

  32. Nookipedia「Villager」、ゲームごとの節、2026年10月4日保存、https://nookipedia.com/wiki/Villager ↩↩↩↩↩↩↩

  33. Nookipedia「Villager」、Personalitiesの節、2026年10月4日保存、https://nookipedia.com/wiki/Villager#Personalities ↩

  34. pret、pokeemerald/src/record_mixing.c(struct PlayerRecordEmerald、ReceiveOldManData、ReceiveDewfordTrendData)、コミット731ad5b、2026年10月4日閲覧、https://github.com/pret/pokeemerald/blob/master/src/record_mixing.c ↩

  35. pret、pokeemerald/src/mauville_old_man.c(選ばれ方のswitch ((trainerId % 10) / 2)とそのコメント、ResetHipsterFlag、ResetMauvilleOldManFlag、SetHipsterTaughtWord)、pokeemerald/src/record_mixing.c(ReceiveOldManDataの末尾にある、ResetMauvilleOldManFlagの唯一の呼び出し)、そしてpokeemerald/data/scripts/mauville_man.inc(setflag FLAG_UNLOCKED_TRENDY_SAYINGS、special HasHipsterTaughtWord)、pokeemerald/data/maps/MauvilleCity_PokemonCenter_1F/map.json(スクリプトがMauvilleCity_PokemonCenter_1F_EventScript_MauvilleOldManであるオブジェクトイベント)、コミット731ad5b、著者が2026年10月4日と5日に読んだ、https://github.com/pret/pokeemerald/blob/master/src/mauville_old_man.c 。トレーナーIDの末尾が2か3のゲームで最初から流行の人がいるというのは、switchについての著者の算術である。 ↩↩↩↩↩↩

  36. Blake Crosley「Pixel-Art Worlds on iPhone: What the 16-Bit Masters Knew」、blakecrosley.com、2026年10月3日(法律に関するFAQは2026年10月4日に更新)、https://blakecrosley.com/blog/pixel-art-world-on-iphone 。流行語のルールを、レコードをまぜることで流行の人が来るたびに1つと述べており、その法律に関するFAQは、Palworldの開発元に対して主張された3つの特許(捕獲アイテムを狙って投げること、捕獲の可能性を示す表示、乗れるキャラクターに乗ること)を独自の出典とともに挙げている。 ↩↩

  37. pret、pokeemerald/src/dewford_trend.c(trendinessとmaxTrendiness、および流行の保存についてのヘッダーコメント)、コミット731ad5b、2026年10月4日閲覧、https://github.com/pret/pokeemerald/blob/master/src/dewford_trend.c ↩↩↩↩

  38. 著者による測定、measure_chat_trend.py(同じフォルダ内)、2026年10月5日に改訂して再実行、出力はmeasure_chat_trend.outとして保存。改訂版は.enabled = FALSEと記されたエントリを開いている単語から差し引き(946エントリ、有効は940)、easy_chat_groups.hからトレーナーのグループのnumEnabledWordsの行(「Excludes Red, Green, Flame, Gold, Leaf, and Silver」、レッド、グリーン、フレイム、ゴールド、リーフ、シルバーを除く)を出力し、IsEasyChatIndexAndGroupUnlockedにあるエントリごとの規則を出力する。この規則のもとでは、202エントリのリストにある名前は、そのポケモンを見たときにだけ開く。以前の版とその出力は.r1の接尾辞をつけて残してある。入力:pretのpokeemerald 731ad5bのsrc/data/easy_chat/(グループの大きさ、無効なエントリ、numEnabledWords)、src/easy_chat.c(グループを開くswitch、エントリごとの規則、フレーズのグリッド)、include/constants/global.h(MAIL_WORDS_COUNT、NUM_QUESTIONNAIRE_WORDS、SAVED_TRENDS_COUNT)、src/dewford_trend.c(SeedTrendRngと毎日の一歩)。2つ目のエンジンによるレビューのあとの2回目の改訂(以前の版とその出力は.pre-astraの接尾辞をつけて残してある)では、ピークの分布を、独立かつ一様と仮定した近似と明記している。これは入れ子になった3回のRandom() % 98の抽選から、それぞれを0〜97にわたる独立な一様抽選とみなして計算したものである。さらに、16ビットの剰余の重み(src/random.cのRandom()は上位16ビットを返すので、剰余0〜71は65,536回中669回、72〜97は668回出る)を使った同じ分布を加えており、平均は62.89、80以下は81.34%で、62.90と81.33%に対応する(独立な抽選の仮定はそのまま)。また、UpdateDewfordTrendPerDayを1回の呼び出しにつき経過1日として、0から上昇するスコアから移植しており、ピーク30、64、127について、その状態に初めて戻るのは12日、128日、254日後である(到達可能などの開始状態からでも同じサイクル長)。上がって下がるまでの長さ12日、25.6日、50.8日は、ピークの2倍を5で割ったもので、連続的な近似である。 ↩↩↩↩↩↩↩↩↩↩↩↩

  39. pret、pokeemerald/src/union_room_chat.c、pokeemerald/include/union_room.h、pokeemerald/include/constants/global.h、コミット731ad5b、2026年10月4日閲覧、https://github.com/pret/pokeemerald/blob/master/src/union_room_chat.c 。そこでキーボード入力のチャットが許容できた理由についての読みは著者のもの。 ↩

  40. pret、pokeemerald/src/easy_chat.cとpokeemerald/src/data/easy_chat/、コミット731ad5b、2026年10月4日閲覧、https://github.com/pret/pokeemerald/blob/master/src/easy_chat.c および https://github.com/pret/pokeemerald/tree/master/src/data/easy_chat ↩↩↩↩

  41. Wikipedia「Dark Souls (video game)」、Multiplayer(その出典[5]を引く)とAwardsの節、2026年10月4日保存、https://en.wikipedia.org/wiki/Dark_Souls_(video_game) ↩↩↩↩↩↩

  42. Bandai Namco Entertainment Europe「Dark Souls Remastered」、Key features、2026年10月5日保存、https://en.bandainamcoent.eu/dark-souls/dark-souls-remastered 。Bandai Namco Americaのページは127バイトのテキストしかないスクリプトの外殻として保存された。FromSoftware自身の説明にはたどり着けなかった。 ↩

  43. PlayStation「Death Stranding」、「Unique social strand gameplay」の節、2026年10月4日保存、https://www.playstation.com/en-us/games/death-stranding/ ↩

  44. Wikipedia「Splatoon (video game)」、GameplayとMultiplayerの節(それぞれの出典を引く)、2026年10月4日保存、https://en.wikipedia.org/wiki/Splatoon_(video_game) 。Nintendo自身のSplatoonのページは取得していない。 ↩↩

  45. The Pokémon Company International、pokemon.comのゲームページ「Pokémon Black Version 2 and Pokémon White Version 2」と「Pokémon Sun and Pokémon Moon」、2026年10月4日保存、https://www.pokemon.com/us/pokemon-video-games/pokemon-black-version-2-and-pokemon-white-version-2 および https://www.pokemon.com/us/pokemon-video-games/pokemon-sun-and-pokemon-moon 。どちらもジョインアベニューにもフェスサークルにも触れていない。Bulbapediaは試していない。 ↩

  46. Serebii.net「Festival Plaza」、『ポケットモンスター サン・ムーン』の節、2026年10月4日保存、https://www.serebii.net/sunmoon/festivalplaza.shtml 。ファンサイトであり、この機能について使った唯一の出典。 ↩↩

  47. Serebii.net「Gyms」、Pokémon GOの節、2026年10月4日保存、https://www.serebii.net/pokemongo/gyms.shtml 。ファンサイトであり、この機能について使った唯一の出典。 ↩↩

  48. Solero、Houdini(ファンが書いた、Club Penguinのオープンソースのサーバーエミュレータ)、houdini/handlers/play/player.py(sp、ss、sj、sma、sl、sg、seのハンドラとそのクールダウン。時刻を取り、61秒眠り、最後のハートビートがその時刻より古いクライアントをすべて閉じるserver_heartbeat(if penguin.heartbeat < timer: await penguin.close()、保存したHTMLから読んだもので、保存したテキスト抽出ではこの行が崩れている)。そして、プレイヤーに許された分数を毎分カウントダウンし、7分と5分で警告し、0で切断するserver_egg_timer)、2026年10月4日保存、https://github.com/solero/houdini/blob/master/houdini/handlers/play/player.py 。元のクライアントが何を想定していたかの証拠であり、Disneyが公表したふるまいではない。 ↩↩↩↩↩↩↩

  49. billsonnn、Nitro renderer(ファンが書いた、Habboのオープンソースのクライアント)、src/nitro/room/object/logic/MovingObjectLogic.ts(DEFAULT_UPDATE_INTERVAL = 500とupdate内の線形補間)、2026年10月4日保存、https://github.com/billsonnn/nitro-renderer/blob/main/src/nitro/room/object/logic/MovingObjectLogic.ts ↩↩↩

  50. 著者によるKiradexリポジトリ(非公開)の読み取り、2026年10月5日時点の作業ツリー、読み取りのみ。Kiradex/World/PlazaRig.swift(SHA-256 819cd8d6。29行目のFloatとしてのprogress、101行目のtilesPerSecond、526〜542行目のmove(other:to:facing:)、614行目でプレイヤーにのみ設定されるrunning、652〜672行目のadvance()、722〜727行目のplace()とそのピクセルの丸め、dozeを含むidleEmotesのリスト)、Kiradex/World/TileMap.swift(db4272c2。60行目の16のtileSizeと235行目のcentre)、Kiradex/World/PlazaClient.swift(5c491933。165行目の再接続の遅延)、Kiradex/World/PlazaStage.swift(8b4850af。広場に適用される昼夜のフェーズと、149行目のrig.update(Float(event.deltaTime)))、Kiradex/World/Daylight.swift(536350dc。Daylight.Phaseとその時刻の範囲、そしてデバイス自身のカレンダーとゾーンであるCalendar.currentから時刻を取るDaylight.now)。サーバーの時計も同じ日に検索した。server/app/main.pyとserver/app/rooms.pyはtime.monotonic()を使っており、server/appのどこにもタイムゾーンを指定するものはない。 ↩↩↩↩↩↩↩↩↩

  51. Apple Developer Documentation、GKLocalPlayer.isPersonalizedCommunicationRestricted(iOS 14.0+)、ドキュメントのJSONを2026年10月4日に保存、https://developer.apple.com/documentation/gamekit/gklocalplayer/ispersonalizedcommunicationrestricted 。注18と同じく引用のために平文化。ゲーム独自の定型のセリフが、ページがゲームに無効にするよう求める「custom communication features」(独自のコミュニケーション機能)に含まれること、そしてエモートは含まれないことは、著者の読みである。 ↩↩↩↩↩↩↩↩

  52. Apple Developer Documentation、GKLocalPlayer.isUnderage(iOS 4.1+)、ドキュメントのJSONを2026年10月4日に保存、https://developer.apple.com/documentation/gamekit/gklocalplayer/isunderage 。注18と同じく引用のために平文化。 ↩↩↩↩

  53. Apple Support「Set up parental controls to manage your child’s iPhone or iPad」、「Set restrictions for Game Center」の節、2026年10月4日保存、https://support.apple.com/en-us/105121 ↩

  54. Apple Newsroom「Apple expands tools to help parents protect kids and teens online」、2025年6月11日、2026年10月4日保存、https://www.apple.com/newsroom/2025/06/apple-expands-tools-to-help-parents-protect-kids-and-teens-online/ ↩↩↩

  55. Apple「App Review Guidelines」、2026年6月8日最終更新、ガイドライン1.2、1.3、5.1.4、2026年10月4日保存、https://developer.apple.com/app-store/review/guidelines/ ↩↩↩↩↩↩↩↩

  56. 連邦取引委員会(FTC)「FTC Finalizes Changes to Children’s Privacy Rule Limiting Companies’ Ability to Monetize Kids’ Data」、プレスリリース、2025年1月16日、2026年10月4日保存、https://www.ftc.gov/news-events/news/press-releases/2025/01/ftc-finalizes-changes-childrens-privacy-rule-limiting-companies-ability-monetize-kids-data ↩

  57. 著者によるKiradexサーバーの起動コマンドと、それが動かすウェブサーバーの読み取り、2026年10月5日、読み取りのみ。server/Procfile(SHA-256 2e883a7e)とserver/railway.toml(17f8a3ba)は、uvicorn app.main:appを--proxy-headers --forwarded-allow-ips='*'付きで、ログのオプションなしで起動する。server/requirements.txt(71c30c3b)はuvicorn[standard]==0.37.0を固定している。サーバーの環境にインストールされたそのバージョンでは、uvicorn/config.py(379e9baf)がaccess_logのデフォルトをtrueにしている。uvicorn/protocols/http/httptools_impl.py(b6e4010a)とh11_impl.py(e1bf8ab3)は、それがtrueのとき各リクエストについてget_client_addr(self.scope)を記録する。そしてuvicorn/protocols/websockets/websockets_impl.py(029977b2)は、uvicorn.errorロガーのINFOでクライアントのアドレスとともに'%s - "WebSocket %s" [accepted]'を記録し、これは--log-level warningで抑止される。コードの読みであり、サーバーは実行しておらず、デプロイ先のログも見ていない。 ↩↩

  58. Blake Crosley「Pixel-Art People: Characters and a Creator on iPhone」、blakecrosley.com、2026年10月3日、第4節(PEGIのルール)と第6節、第7節(フィギュアの文字列、マニフェスト、すべてのフィギュアを描くフォージ)、https://blakecrosley.com/blog/pixel-art-characters-on-iphone ↩↩↩

  59. PEGI「What do the labels mean?」、2026年10月3日閲覧、https://pegi.info/what-do-the-labels-mean 、キャラクター編の記事(注58)での引用による。本記事のために再取得はしていない。 ↩↩↩

関連記事

Pixel-Art Structures: Houses, Halls and Interiors on iPhone

How Pokémon, the SNES RPGs and Stardew build houses, interiors and floors, measured from source, and how Kiradex's town …

80 分で読める

ピクセルアートの道:iPhoneでつくるマップ接続と地区

ポケモン、Stardew Valley、どうぶつの森は町と町のあいだの土地をどう作っているのか。道路、継ぎ目、ゲート、マップ画面をソースから測り、Kiradexのためのブリーフにまとめました。

91 分で読める

App Reviewは何を見ているのか、分かっている範囲で:2026年10月

2026年10月時点のAppleのApp Reviewを公開記録から読む。誰が審査し、どれくらいかかり、何が却下を招き、その文面はどう書かれているか。2025〜2026年のルール変更と、初回申請前にチェックリストでレッドチーム演習をかけたカ…

45 分で読める