ピクセルアートの光:昼と夜、天気と影
『ポケットモンスター クリスタル』は夜の町を描きません。時計の上に1日を3つに分けて持ち、朝6時間、昼8時間、夜10時間とし、時刻が来るとフェードなしで1フレームのうちにパレットを読み込み直します。パレットファイルのブロックでは、7つのワールドパレットが昼の明るさの0.41〜0.68、平均0.51を保ち(町が自分の水と屋根の色で表示する状態では、マップグループ別の平均が0.49〜0.54)、青くなります。一方でYELLOWというひとつのパレットだけは最も明るい色を0.90に保ち、人物のパレットは画面上で変わりません。1234 エメラルドには光のための時計がありません。代わりに18の天気の値があり、雨は1秒かけて景色のパレットを元の値の約13/16に下げますが、プレイヤーと町の人のパレットは描かれたとおりのまま残ります。エメラルドにもファイアレッドにも、ヘッダーに雨を持つ屋外マップはひとつもなく、エメラルドの雨はいくつかのマップのトリガーとスクリプトから生まれ、そのうち2つは4日周期の暦を持つ道路です。567 影はどの大きさでも1トーンで高さ5ピクセル行、暗闇は「フラッシュ」なしで半径1.5セル、ありで4.5セルの照らされた円です。85 私の町、Kiradex Worldはすでに独自の4つの時間帯を持っています。Macでソースから読むと(ここでiPhone上で測ったものは何もありません)、夜はアトラスの昼の明るさの0.588を残し、明かりのついた窓は、色合いをかけたなかで最も明るいピクセルの0.562に対して0.901にあり、切り替わりは1分に1回読まれるカットです。9 天気はなく、歩く人は地面とともに暗くなり、どの建物も地面に影を落としません。そこでブリーフは、オマージュの記事が定めた4つの時間帯を保ち、光を30分かけて変化させ、歩く人を白へ半分持ち上げ、ゾーンごとに1日1回天気を抽選し、雨はエメラルドの密度と暗さにし、建物の影を33セル地面に描き込み、現実の地元の天気、太陽とともに動く影、稲妻のフラッシュをすべて拒みます。そして各項目に、単体テスト、UIテスト、フォージのチェック、スクリプト、キャプチャのいずれかで実行できるチェックを付け、アプリに今あるもの、またはブリーフが追加を提案するものだけを名指しします。101112
TL;DR
- 1日はパレットのセットであって、2つ目の町ではありません。 クリスタルは1日を4:00、10:00、18:00で6時間、8時間、10時間に分け、背景パレットのブロックを5つ(朝、昼、夜、暗闇、屋内)持ちます。夜には、それらのブロックのなかで各ワールドパレットが昼の明るさの平均0.511を保ち(町が自分の水と屋根の色で表示する状態では0.509)、青は5ビットの単位で6.44上がります(表示される状態では7.27)。朝が変えるのは32色のうち5色だけで、どれも最も明るい色です。12134
- 明かりは暗さを拒み、人物は色を保ちます。 クリスタルのYELLOWは、ほかのワールドの色がすべて0.6を下回る夜と暗闇でも、最も明るい色をルマ0.90に保ちます。5つの人物パレットが変えるのは透明色だけです。エメラルドの雨は16の背景パレットのうち14を暗くし、プレイヤーと町の人の5つのスロットのパレットだけを、きっかり恒等写像のまま残します。114515
- 時刻はカットし、天気はフェードします。 クリスタルは時刻が変わったフレームでパレットを入れ替え、8フレームの白へのフェードはドア、ワープ、「そらをとぶ」、メニューが開く画面、一部のスクリプトの場面のためにとっておきます(黒へのフェードを呼ぶのは11のマップスクリプトだけで、白へのフェードはほかに16のマップスクリプトも呼びます)。エメラルドは20フレームの3段階、1.00秒で雨へフェードします。Stardew Valleyの夜は「gradually becomes darker over time」(時間とともにだんだん暗くなる)ものです。1516
- 天気は場所と日に属します。 エメラルド(68マップ)でもファイアレッド(76マップ)でも、ヘッダーが雨の屋外マップはありません。エメラルドの雨はいくつかのマップのトリガーとスクリプトから生まれ(5マップにある86の座標天気イベントのうち4つがRAINで、24が2つの道路の周期を始めます。スクリプトによる天気の呼び出し24のうち1つがRAIN、2つが豪雨です)、Route 119とRoute 123は4日周期を1日1段階ずつ進みます。Stardewは季節に応じて1日1回天気を抽選し、前日に予報します。571718
- 雨はまばらで速く、稲妻は短くまれです。 1画面に10粒、毎秒868ピクセル、鉛直から26.6度で、1粒18フレームと7フレームのしぶきです。稲妻は6〜8フレーム保たれ、少なくとも61フレームの暗い間隔を空け、周期どうしは6〜12秒離れます。プレイ中に雨へ変わると、雨粒は変化の約2秒後にそろい、パレットはその1秒ほど前にそろいます。54
- Kiradexの1日は機能していますが、カットします。 4つの時間帯(3、8、3、10時間)は夜のアトラスを昼の明るさの0.588にし、色合いをかけない明かりのメッシュは0.901にあり、加算のプールは決して暗くせずに光を足します。しかし光は60秒ごとに読まれるカットであり、歩く人は夜の色合いを受け、
AirのどこもReduce Motion(視差効果を減らす)を読まず、建物は地面に影を落としません。どれもMacでソースと書き出した画像から読んだもので、iPhoneで測ったものではありません。91920 - これがKiradexに与えるもの。 ブリーフです。オマージュの記事の4つの時間帯を保ち、時計から計算する30分のランプ(0.108のカットの代わりに0.0036の段階)、白へ半分持ち上げた歩く人(夜のルマは場所の0.593に対して0.796)、ゾーンごとに1日1回抽選する5つの天気の状態、ビューあたり15粒で13/16に暗くし1秒でフェードする雨、毎秒1タイルの雲の影、焼き込んだ33セルの建物の影、窓が外の時間帯を映す部屋、Reduce Motionモード、稲妻のフラッシュなし、そして11のチェックです。Kiradexの数値はMacでアプリのソースと書き出した画像から計算したもので、iPhoneで測ったものではありません。101112
Kiradexは私のiPhone向けカード収集アプリで、Kiradex Worldはそのなかにある小さなピクセルの町です。コレクターたちはそこを歩き、出会い、カードを見せ合います。町はすでに1日を持っています。Daylight.swiftはスマートフォンから時刻を読んで4つの時間帯に名前を付け、リグは照らされていないものすべてにその時間帯の色合いを掛けます。明かりのついた窓とホールの壁付け灯は、色合いをかけずに描く2つ目のメッシュです。そしてビルド29からは、街灯と窓が地面に加算のプールを落とし、昼には雲のシートが町の上を流れ、朝には公園に霧がたまり、秋には葉が落ち、夜には蛍がさまよいます。6本の煙突から煙も上がり、デザイン計画はこれをビルド28に置いています。212022239 空気を担うファイルは、それが何のためにあるかを1行で述べています。「none of it takes the day’s tint: light is light.」(どれもその日の色合いを受けない。光は光だ)22
町にないのは天気、誰もが緩やかと呼ぶような光の変化、人が夜にも読み取れるままでいられる理由、そして地面に落ちる建物の影の1つです。建物を組み立てるフォージは、その最後のものを自分のdocstringで先送りしています。「The ground shadow stays off the building: it belongs to the ground layer.」(地面の影は建物には付けない。それは地面のレイヤーに属する)24 そこでこの記事は、シリーズのこれまでの記事が建物と動きについて行ったことを、光、天気、時間について行います。クリスタルが1日をどう保つか(時刻、パレット、変化の見せ方、どのマップで起きるか)、エメラルドが天気をどう扱うか(定数、暗くする処理、雨、霧、砂、雲、雷、それぞれがどこで起きるか)、両者が暗闇と影をどう扱うか、Stardew ValleyのWikiがその1日と天気について何を記録しているか、現代のライティングされたピクセルゲームの作り手が自分たちの光について何を語っているかを測ります。そのうえでKiradex自身の光をソースから読み、出荷されているものとの差分としてブリーフを書きます。
測り方
ポケモンの数値は、pretの逆コンパイルのシャロークローンから得ています。これは各作品を定数に名前を付けたCとアセンブリから再構築するコミュニティのプロジェクトで、pokecrystalは5beda23(2026年9月29日コミット)、pokeemeraldは731ad5b(10月1日)、pokefireredは037335f(9月26日)、pokeredはd2704a6(9月22日)です。25 4つのPythonスクリプトがそれらとKiradexを測り、5つ目が正典の数値をKiradexの単位へ移し、6つ目が保存したAppleのドキュメントページを読みます。どれも出力とともにこの記事用の著者の証拠フォルダに保存してあり、どれも数秒で再実行できます。公開前にすべてを再実行しました。2つは保存した出力をバイト単位でそのまま返し、4つは途中で修正しました。それぞれの以前の版と出力は横に残してあります。提案スクリプトは、建物の影を行ごとに置くため、天気の雨の続く期間を第10節の定義どおりに数えるため、そしてKiradexの歩きを毎秒4タイルと持ち越さずにアプリのMotion.swiftから読むために直しました(ソースから読むとアプリの歩きは毎秒60ピクセルで、第2、7、10節はそれを使っています)。エメラルドのスクリプトは、雨のラベルが出現カウンターの上限を出現の周期として出力していたので直しました(第2節は修正後の数値を使っています)。クリスタルのスクリプトには、4つのフェードそれぞれを何が呼ぶかの全数調査を加えました。またマップヘッダーのパーサーが1語のフィールドしか取っておらず、音楽のフィールドが式になっているラジオ塔の5つのフロアを落としていたので直し(ヘッダーは383ではなく388で、第1節は動いたすべての数を使っています)、さらにenvironment_colors.asmと屋根の表から、マップが表示するパレットのセットを解決し、どの画面がメニューのフェードを通り、どの屋内マップが独自のパレット表を受けるかも数えるようにしました。Kiradexのスクリプトは、雲の行が同じ毎秒4タイルをラベルとして持ち越していたので直しました。それ以外のセクションは以前と同じ出力です。1215891126 7つ目は、ブリーフの2つのキャプチャでカメラがどこに落ち着くかを紙の上で再生し、8つ目のarith.pyは、フレーム時間から夜と昼の比まで本文が使う派生値をすべて出力し、9つ目はアプリの色の定数をクリスタルのパレットと比べ、10番目はエメラルドの雨の準備と雷の周期をソースの状態機械から呼び出しごとに再生し、11番目は、コレクターの枠のうちコレクター自身がどれだけを覆うかを数え、ブリーフのチェック3のために、立っている描画それぞれと、レンダラーが色合いを扱いうるそれぞれの方法について、夜の比を計算します。7つ目、9つ目、10番目も保存した出力どおりに再実行できました。274282930
ここでの明るさはルマです。保存されたチャンネルの値を0〜1にスケールし、Rec. 601の重み(赤0.299、緑0.587、青0.114)を掛けたもので、ガンマも画面のモデルも入れていません。パレットを比べるための読みの補助であって測色ではなく、ゲームボーイカラーの色は液晶がどう見せたかではなく保存された値のままです。121 セルは携帯機の16×16ピクセルのマップの升目、タイルはKiradexの1辺16テクセルの升目なので、1対1で比べられます。携帯機のレートでの秒数は毎秒59.7275フレームを使います。これはゲームボーイアドバンスでは2^24 ÷ 280,896、ゲームボーイカラーでは2^22 ÷ 70,224で、同じレートです。124
記事全体を通して1つの限界があります。iPhoneで測ったものは何もありません。Kiradexの数値はすべて、アプリのソースをテキストとして読んだか、Macでその書き出した画像から計算したものです。出荷された町のアトラスにスクリプトで色合いを適用したもの、雲の画像のアルファ、町の書き出しです。本文がKiradexの明るさを示すとき、それはこの計算であり、SpriteSheet.materialがUnlitMaterialのtintを使うように、リグの乗算の色合いがテクスチャにチャンネルごとに作用すると仮定しています。デバイス上のコストが問題になるところは、未測定と記しています。129
1. ソースから測ったクリスタルの1日
『金』『銀』『クリスタル』はリアルタイムクロックで時間を刻み、この記事が読むのはそのうちクリスタルです。2 この節の内容はすべてmeasure_gen2_daylight.pyによるものです。このスクリプトは、時計の定数と表、時刻とともに変わる3つのパレットファイル、それらを適用するルーチン、各環境のマップがファイルのどのパレットを表示するかを示す表、そしてどのマップが時計に従うかを示す388のマップヘッダーを読みます。1
1日は3つに分かれる
定数はMORN_HOUR 4、DAY_HOUR 10、NITE_HOUR 18で、時刻を1日の区分に変えるTimesOfDay表は、その要約をコメントとして持っています。「0400-0959 morn | 1000-1759 day | 1800-0359 nite」です。21 つまり朝が6時間、昼が8時間、夜が10時間で、夜が最も長く、1日の41.7%を占めます。14 このシリーズのオマージュの記事も同じ定数と同じコメントを読んでおり、両者は一致します。10
空のない場所のために4つ目の状態があります。時間帯を保持する変数wTimeOfDayはMORN、DAY、NITE、DARKNESSを取り、背景パレットのファイルbg_tiles.palは8パレットのブロックを5つ、朝、昼、夜、暗闇、屋内に1つずつ持ち、さらに屋外の水のための1組を持ちます。31131 1つのブロックの8パレットは、ジョウトのどのタイルも受ける8つの名前付きパレット、GRAY、RED、GREEN、WATER、YELLOW、BROWN、ROOF、TEXTです。132
1つの時計の上の3つの1日。クリスタルの定数、KiradexのDaylight.swift、Stardew Valley Wikiから、figures/make_figures.pyで描画。
夜は光が半分になり、青くなる
色ではなく明るさ。各パレットの4色の平均ルマを時間帯別に示したもので、ファイルの基本ブロックと、その横に町が表示する水をgen2_daylight.txtから、Kiradexのアトラスをkiradex_light.txtから取っています。後者はMacで出荷されたアトラスから計算したもので、iPhoneで測ったものではありません。パレットの色はひとつも再現していません。
パレットファイルの5つのブロックで、各パレットの4色の平均ルマとして測ると、夜のブロックは昼のブロックの明るさのうち、REDの0.406からYELLOWの0.684までを保ち、7つのワールドパレットの平均は0.511です。インターフェースのパレットであるTEXTは、どの時刻でも同一です。1 暗闇のブロックでは、ワールドパレットはルマ0.009まで落ち、YELLOWだけが0.224です。1
これはファイルが持っているとおりのブロックで、町はそれをそのまま表示するわけではありません。environment_colors.asmは、環境と時間帯ごとに、ファイルの42パレットのうちどの8つを読み込むかを名指しします。TOWNやROUTEはブロック自身のパレットを受けますが、WATERだけはファイルの屋外の組から来ます。朝と昼に1パレット、夜に1パレットです。そのあとLoadMapPalsが、マップグループの2つの屋根の色をROOFの中間の2色の上に書き込みます。INDOORやGATEのマップは、朝と昼にはファイルの屋内ブロックを受けますが、タイルセットが独自の表を読み込む場合は別です(後述)。CAVEやDUNGEONはブロックをそのまま受けます。33341 そう解決すると、町の水の平均ルマは昼0.528、夜0.248で、昼に対して0.470です(基本ブロックでは0.448)。ROOFは、町か道路を持つ25のマップグループにわたって、昼の0.369(フスベのもの)から0.688を保ちます。町が表示する状態の7つのワールドパレットは、グループ別に昼の明るさの平均0.494〜0.539を保ち、25グループでは0.509で、ブロックの0.511に対応します。14 図はブロックと、その横に表示される水を描いています。以下の数値は、どちらのセットのものかを明記しています。
夜は色相も変えます。YELLOWとTEXT以外のワールドの色について、青から赤と緑の平均を引いた値は、基本ブロックで昼が−0.73、夜が+5.71で、ゲームボーイカラーの5ビットの単位で6.44の上昇、全スケール31の約5分の1です。町の水をブロックの水の代わりに置くと−1.17と+6.10で、7.27の上昇です。14 仕組みはファイルを見れば明らかです。夜のブロックでは、YELLOWを除くすべてのワールドパレットの最も明るい色が同じ(15, 14, 24)で、ルマ0.498の青みがかった灰色です。昼のほとんどのパレットでは(27, 31, 27)、ルマ0.947です。町が表示する状態では、7つのうち5つ、GRAY、RED、GREEN、BROWN、ROOF(屋根の表は最も明るい色には手を付けません)がその色を共有します。水の夜の最も明るい色は屋外の組自身のもので(15, 13, 27)、ルマ0.490、緑で1段階、青で3段階ずれています。14 私の読みでは、最も明るい色が共有され、水がそこから1段階ずれているからこそ、夜のクリスタルの町は、6つのパレットがそれぞれ勝手に暗くなったものではなく、1つの空の下の1つの場所として読めるのです。
朝は暖かい白
朝は独自の場面ではありません。昼との違いは32のワールドの色のうち5色、15.6%で、5色すべてがGRAY、RED、YELLOW、BROWN、ROOFの色0、つまり最も明るい色です。朝は(28, 31, 16)、昼は(27, 31, 27)で、青のチャンネルが11下がります。14 各パレットのそれより暗い色はすべて昼のままです。正典の朝とは、白を暖めた昼の光であり、ほかには何も動きません。
暗さを拒むパレットが1つある
夜と暗闇では、YELLOWの色0は(30, 30, 11)、ルマ0.90です。どちらのブロックでも、町が表示するセットでも、ルマ0.6を上回るワールドの色はこれだけです。ほかのパレットの最も明るい色は、夜は0.498(町の水は0.490)、暗闇では黒に近い値です。14 ジョウトのタイルセットでは、johto_palette_map.asmがYELLOWを192タイルのうち3つ、1.6%に割り当てています。バンク0のタイル38、55、56です。GRAYは36、BROWNは99、REDは26、GREENは12、ROOFは9、WATERは7です。3514
その3つのタイルが何かを見るために、スクリプトはそれらを4倍の大きさで描画します。この描画は著作権のあるアートから派生したもので、分析のためだけに保管し、公開はしていません。1 私には、タイル38は2枚のガラスの窓に見えます。これは絵についての私の読みであって、パレットしか名指ししないソースのラベルではありません。もしそれが正しければ、クリスタルの街灯は光ではなく色です。ゲームは夜に光るべき少数のタイルに、最も明るい色が落ちない唯一のパレットを与えて印を付け、まわりの町が青くなるあいだも窓はともったままなのです。
照らされたものは明るいまま。クリスタルのYELLOWとほかの夜の色、そしてKiradexの明かりのセルとプールと色合いをかけた町を、gen2_daylight.txt、kiradex_light.txt、arith.txtから。Kiradexの値はMacで書き出した画像から計算したもので、iPhoneで測ったものではありません。
人物は暗くならない
npc_sprites.palにあるオブジェクトパレットも時間帯に従いますが、背景とは違うやり方です。5つの人物パレット(赤、青、緑、茶、ピンク)は、昼と夜、昼と暗闇のあいだで色0しか変えません。そしてオブジェクトパレットの色0はゲームボーイカラーでは透明なので、画面上ではまったく変わりません。SILVERはどの色も変えません。4色すべてを変えるのは、景色であるオブジェクトのパレット、TREEとROCKだけです。141 クリスタルの夜、町は青くなり、そこを歩く人々は正午とまったく同じに描かれます。
屋根は自分の夜を持つ
屋根には専用の表があります。roofs.palは27のエントリを持ち、最初のものは未使用で、マップグループごとに1つずつです。各エントリは朝と昼のための色の組と、夜のための組を持ちます。グループ全体で、夜の組のルマを昼の組のルマで割った値は0.247から1.000まで、平均0.556です。361 このシリーズの構造編の記事は同じ表と、1つのタイルセットがどうやってジョウトのどの町にも独自の色を与えるかを説明しました。23
読み込み直しが読み込むもの
LoadMapPalsは、マップが読み込まれるときや時刻が変わるときにそのすべてを適用します。時間帯のための8バイトの背景パレットを8つ、environment_colors.asmがマップの環境に名指しする8つをコピーします。ただし6つの屋内と洞窟のタイルセット(TILESET_POKECOM_CENTER、TILESET_BATTLE_TOWER_INSIDE、殿堂入りの外でのTILESET_ICE_PATH、TILESET_HOUSE、TILESET_RADIO_TOWER、TILESET_MANSION)は例外で、それらの背景パレットはLoadSpecialMapPaletteが先に独自の表から読み込むので、このコピーは飛ばされます。次に時間帯のための8つのオブジェクトパレットを、すべてのマップでコピーします。そしてTOWNかROUTEに限り、マップグループの2つの屋根の色、4バイトをROOFパレットに入れます。341 TOWNやROUTEのマップで6つのタイルセットのどれかを使うものはありません(使うのはINDOORマップ75とCAVEマップ5で、そのINDOORマップのうちTILESET_ICE_PATH上の殿堂入りを除くすべて、74が独自の表を受けます)。したがって屋外では、背景パレット64バイト、オブジェクトパレット64バイト、屋根4バイトの合計132バイトです。14
これはこのシリーズの1文を訂正します。ワールドについての最初の記事は「time of day in Johto is a 64-byte palette reload」(ジョウトの時間帯は64バイトのパレットの読み込み直しだ)と書きました。32 背景パレットについては正しい記述です。LoadMapPalsと照らし合わせると、読み込み直しはオブジェクトパレット64バイトもコピーし、屋外では屋根の色4バイトもコピーします。人物のパレットは透明色しか変わらないので見た目は同じですが、バイトは読み込み直されています。341 これはこの記事の発見です。以前の記事は編集していません。
変化はカット
フィールドのループは、マップのイベントが有効なあいだ、毎回UpdateTime、GetJoypad、TimeOfDayPalsを呼びます。HandleMapTimeAndJoypadは、wMapEventStatusがMAPEVENTS_OFFのときは最初に戻ります。371 _TimeOfDayPalsは、強制されたパレットのセットが有効なとき(FORCED_PALSET_F)や時間帯が変わっていないときはすぐに戻ります。変わっていれば、パレットのセットを入れ替え、_UpdateTimePalsを1回呼び(これはld c, $9 ; normalのあとにDmgToCgbTimePalsが続くものです)、1フレーム待ちます。朝と昼、昼と夜、夜と朝のあいだに段階的なフェードはなく、パレットのセットは1フレームで変わります。31
ゲームにはフェードがあり、それを別のことのためにとってあります。FadeInFromBlack、FadeOutToBlack、FadeInFromWhite、FadeOutToWhiteは、それぞれ4つのパレットを1段階2フレームで進み、8フレーム、134ミリ秒です。314 マップの準備スクリプトが使うのは白の組です。プレイヤーが踏むワープ、つまりドアや洞窟の入口は、Doorスクリプトでマップを読み込みます。これは白へフェードアウトし、Trainスクリプトへ流れ込んで白からフェードインします。スクリプトによるワープが実行するWarpスクリプトは、終わりの2コマンド前で白からフェードインします。「そらをとぶ」のスクリプトは白へフェードアウトし、Warpスクリプトへ流れ込みます。そしてFadeToMenuを通って開きFinishExitMenuを通って戻る画面は、白へフェードアウトして戻ってきます。スタートメニューの項目のうち6つ(StartMenu_Pokedex、StartMenu_Pokemon、StartMenu_Pack、StartMenu_Status、StartMenu_Option、StartMenu_Pokegear)がそうで、ほかの7つのファイルにさらに15の呼び出しがあり、そのなかにはショップ、パソコン、セレクトボタンの道具のものが含まれます。スタートメニュー自体にはフェードがありません。StartMenuはマップの上に描画し、開くときと閉じるときに、現在の時刻のパレットを適用するUpdateTimePalsを呼びます。黒の組を名指しする準備スクリプトはありません。黒の組に至るのは11のマップスクリプトのspecialだけで、どれもフェードアウトとフェードバックを1回ずつ持ち、そのなかにはマダツボミのとうの3階、Route 24、ロケット団アジトの地下2階があります。381 マップスクリプトは白の組も呼び、しかもより頻繁です。16のマップスクリプトで、specialによる白へのフェードアウトが27、フェードインが12あり、そのなかには誰もどこにも行かない場面、グリーンの家でナナミがポケモンの毛づくろいをする場面や、灯台の6階の場面があります。そして黒の組の11のうちの1つ、Route 26の休憩所は、移動ではなく休息と回復です。1 したがって、全数調査が示す正典の文法はこうです。フェードは場面の変化、移動、メニュー、スクリプトの瞬間を示し、時刻はそのどれでもありません。
プレイヤーがカットを見たかどうかは、4:00、10:00、18:00にどこにいたかで決まりました。時計に従うマップの屋外にいれば、それはそのフレームで画面に出ました。フィールドのループは、プレイヤーが歩いているあいだにパレットを適用するからです。屋内では、変わったパレットは表示されているものではありませんでした。FadeToMenuを通って開く画面では、戻るときに白からのフェードインの前に時間帯のパレットを読み込み直すので、新しいセットはフェードのもとで到着しました。スタートメニュー自体では、メニューが閉じるときにUpdateTimePalsがそれを適用しました。37381 それぞれがどれくらいの頻度で起きたかは、ソースからはわかりません。広場に開いたまま置かれたスマートフォンは別の状況で、第7節でそこに戻ります。
時間を刻むのは屋外だけ
各マップヘッダーは環境とパレットのモードを名指しします。388のヘッダーのうち、23のTOWNマップと54のROUTEマップはすべて、時計に従うモードであるPALETTE_AUTOで、CAVEマップの1つもそうです。388マップのうち78、20.1%です。3914 屋内では時計が止まります。208のINDOORマップのうち207と、25のGATEマップのうち24はPALETTE_DAYで、時刻にかかわらず昼の光に固定されています。それらのINDOORマップのうち133が見せる昼の光はファイルの屋内ブロックで、残りの74はHOUSE、RADIO_TOWER、MANSION、BATTLE_TOWER_INSIDE、POKECOM_CENTERのタイルセット上にあり、LoadSpecialMapPaletteがそれらのタイルセットのために読み込む表を見せます(上の「読み込み直しが読み込むもの」)。13334 13のマップがPALETTE_DARKです。うずまき島の8マップ、シロガネやまの最初の部屋、くらやみのほらあなの2つの入口、イワヤマトンネルの2つのフロアです。27のマップがPALETTE_NITE、つまり永遠の夜です。そのうち24はCAVEマップで、ウバメのもりとトージョウのたきが含まれます。残りの3つはやけたとうの1階(DUNGEONマップ)、りゅうのほこら(INDOOR)、地下通路(GATE)です。1394
つまりクリスタルでは、時間帯は野外の性質です。22:00の家は正午の家と同じように照らされ、木々の天蓋の下の森はいつも夜で、暗闇はまた別の第3のものです。1
フラッシュはパレット、赤の暗闇はオフセット
クリスタルの「フラッシュ」は円を描きません。PALETTE_DARKのマップでは、ReplaceTimeOfDayPalsはDARKNESSのセットを使いますが、ステータスフラグSTATUSFLAGS_FLASH_Fが立っていればすべての時間帯にNITEのセットを使います。3 「フラッシュ」で洞窟を照らすと、洞窟は黒から夜へ、18:00以降に町がまとうのと同じ青いパレットへ変わります。
1世代前の赤には暗い場所が1つあり、それを1行で扱います。ワープの行き先がROCK_TUNNEL_1Fのとき、ワープのコードはwMapPalOffsetを6にし、LoadGBPalはそのオフセットをFadePal4から引いてFadePal2に着地します。その背景のエントリはdc 3,3,3,2で、ほとんど真っ黒です。4041 屋外のマップからのそのワープは、pokeredがオフセットを0か、戦闘が保存して戻す値以外に設定する唯一の場所です。2つの屋内マップのあいだのワープはオフセットをそのままにし、下のフロアのROCK_TUNNEL_B1Fは4つのワープを持ち、そのすべてが1階へ通じています。したがってそこへは1階からしか行けず、同じように暗いままです。「フラッシュ」、全滅、「そらをとぶ」かダンジョンからのワープ、外へ戻るワープは、どれもオフセットを0にします。4042 赤には時計がなく、イワヤマトンネルの2つのフロアが唯一の暗い場所です。
2. ソースから測ったエメラルドの天気
光のための時計はない
ゲームボーイアドバンスの作品は逆の道を進みました。エメラルドにもファイアレッドにも光のための時間帯のシステムはありません。どちらの逆コンパイルでも、src/*.cやinclude/**/*.hのどのファイルも「timeofday」や「time_of_day」に一致しません。5 エメラルドはリアルタイムクロックを持っており、オマージュの記事はそれが動かすものを測りました。現実の時間で育つきのみと、日付が変わるときに実行される11の日次更新で、天気もそのひとつです(生きている町の記事がその関数UpdateWeatherPerDayを名指ししています)。1043 そのどれも、時刻によってパレットに触れることはありません。クリスタルが色を時間に使ったところで、エメラルドは色を空に使ったのです。
18の天気、3つの種類
include/constants/weather.hは18のWEATHER_*の値を名指しします。NONE、SUNNY_CLOUDS、SUNNY、RAIN、SNOW、RAIN_THUNDERSTORM、FOG_HORIZONTAL、VOLCANIC_ASH、SANDSTORM、FOG_DIAGONAL、UNDERWATER、SHADE、DROUGHT、DOWNPOUR、UNDERWATER_BUBBLES、ABNORMAL、そして2つの道路の周期です。ヘッダーはそのうち3つ(SNOW、FOG_DIAGONAL、UNDERWATER)に「// Unused」(未使用)と記し、SHADEには独自のコメント「Original name was closer to WEATHER_CLOUDY/OVERCAST」(元の名前はWEATHER_CLOUDY/OVERCASTに近かった)が付いています。マップのトリガーのために、さらに13のCOORD_EVENT_WEATHER_*の値があります。445
- パレットを暗くする天気。 使われている4つ、RAIN、RAIN_THUNDERSTORM、DOWNPOUR、SHADEは、パレットをカラーマップ3にします。未使用のSNOWもそうです。どれも
InitVarsでtargetColorMapIndexを3に、colorMapStepDelayを20フレームに設定します。5 - 独自の表を持つ天気。 DROUGHTは、
src/field_weather.cで負のマップ番号(フェードイン後は−6)を通じて参照する、あらかじめ計算された独自の色の表を使います。612 - パレットに手を付けない天気。 SUNNY_CLOUDS、FOG_HORIZONTAL、FOG_DIAGONAL、VOLCANIC_ASH、SANDSTORMはカラーマップ0のままで、代わりにスプライトのレイヤーを場面の上にハードウェアのアルファブレンド、チャンネルごとの
(eva × target1 + evb × target2) / 16で重ねます。雲は12と8へ、横の霧は12と8へ、のちに4と16へ、灰と砂は16と0です。5
雨は場所を13/16に暗くする
暗くする処理はBuildColorMapsから来ており、スクリプトはそれをPythonで再生します。19のマップを作り、それぞれが5ビットのチャンネルの値を別の値へ変える表です。最初の3つは、値を16で割ったものを1段階ずつ引いていくので、雨と日陰が使うマップ3は、チャンネルの値vを約0.81 vに写します。31は25に、16は13に、8は6になります。1〜31の値で、出力を入力で割った値は0.8125を超えることがなく、16でそこに達します。65 雨は20フレームの3段階、60フレーム、1.00秒でそこへ達します。54
そこで13/16、つまり0.8125が、正典の雨の数値になります。暗くなるすべてのパレットのすべてのチャンネルがおよそ5分の4です。光を半分残すクリスタルの夜と比べると、穏やかな暗さです。14
エメラルドの雨と稲妻のマップ。BuildColorMapsからfigures/make_figures.pyで再生し、measure_gen3_weather.pyが出力した点をアサートしています。アートではなく曲線です。
雨は人物に手を付けない
どのパレットが暗くしたマップを受けるかも表になっていて、sBasePaletteColorMapTypesは32のエントリ、ハードウェアのパレットごとに1つです。6 背景パレット0〜13は暗くしたマップを受け、インターフェースである14と15は何も受けません。16のオブジェクトパレットのうち、10が暗くしたマップを受け、6が普通の「contrast」のマップを受けます。そのマップ3は恒等写像で、描かれたものはきっかり描かれたままです。5
include/event_object_movement.hで名前の付いたパレットのスロットと照らし合わせると、その6つはオブジェクトパレット0、2、3、4、5、10で、PALSLOT_PLAYER、PALSLOT_NPC_1〜PALSLOT_NPC_4、PALSLOT_NPC_SPECIAL、つまりプレイヤーと町の人の5つのスロットです。反射のスロットは、プレイヤーのものも町の人それぞれのものも、すべて暗くしたマップを受けます。155 雨のなかで、エメラルドの地面、建物、水、そしてその水に映る反射までもが13/16になり、そこを歩く人々は自分の色を保ちます。
2つの世代、2つの仕組み、そして1つの規則です。クリスタルの人物パレットは夜に透明色しか変えず、エメラルドの人物パレットは雨のなかで恒等写像の上にあります。光は場所に属し、人物はそのなかで読み取れるままです。15 ソースは対応を述べるだけで、理由は述べていません。私の読みでは、それは小さく暗い画面での読みやすさです。そこでは暗くしたスプライトが最初に輪郭を失います。いずれにせよ効果として、目を凝らさなければならないものが人物になることは決してありません。
稲妻は同じ表の反対の端
同じ表の反対の端が閃光です。最後のマップ19は、12以上のチャンネルの値をすべて31に送り、12未満の値はほぼ元のところに残します。0は1に、4は4のまま、8は8のまま、11は10になります。56 これは白い画面ではなく、高コントラストの閃光です。すべてのパレットの明るい半分が白くなり、暗い半分は暗いままです。
雨を測る
雨は10個の雨粒スプライトで、雷雨は16個、豪雨は24個、これが上限でもあります。各雨粒は16×32のスプライトです。UpdateVisibleRainSpritesは++rainSpriteVisibleCounter > rainSpriteVisibleDelayのときに雨粒を1つ有効にします。これは遅延の次のフレームで発火するカウンターで、遅延は雨で8、重い2種類で4なので、新しい雨粒は雨では9フレームごと、雷雨と豪雨では5フレームごとに加わり、数が満たされるまで続きます。有効化の段階だけで、有効な雨粒0個から数えて、雨は90フレーム、1.51秒、雷雨は80フレーム、1.34秒、豪雨は120フレーム、2.01秒です。754 これが変化のすべてではありません。状態機械から呼び出しごとに再生すると、晴れた空(終了処理がすぐに戻るSUNNY)からのプレイ中の天気の変化は、Task_WeatherMainが天気を入れ替えるフレームに始まります。次のフレームから、Rain_Mainは最初の呼び出しで雨粒のシートを読み込み、続く24回で1回に1つずつ24個すべての雨粒スプライトを作り、そのあとでようやく有効化を始めます。したがって雨の最後の雨粒が有効になるのは入れ替えから115フレーム後、1.93秒で、雷雨は105フレーム、1.76秒、豪雨は145フレーム、2.43秒です。パレットのほうが先に終わります。20フレームの3段階でフレーム59にマップ3に達し、どの種類の最後の雨粒よりも前です。雷雨の最初の稲妻はフレーム109に落ちることがあります。2つの雨の種類のあいだでは、スプライトは保たれて数だけが変わり、5か9フレームごとに1粒です。雨から雷雨へは、32回目の呼び出しまでに追加の6粒を有効にします。すでに雨が降っている状態でマップが読み込まれると、Rain_InitAllが同じ手順を1フレームのなかのループで実行し(雨で116回の呼び出し)、画面は満ちた状態で始まります。雨がやむときは、同じ呼び出しが9か5フレームごとに1粒を退かせます。29764
各雨粒は、16が1ピクセルにあたるQ28.4の固定小数点で保存された一定の速度で動きます。雨は1フレームに(−6.5, +13.0)ピクセル、14.5ピクセル、毎秒868ピクセル、鉛直から26.6度で18フレーム、262ピクセル落ちてからしぶきになります。豪雨の雨粒は1フレームに(−10, +20)ピクセル、22.4ピクセル、毎秒1,336ピクセルで同じ角度に12フレーム、268ピクセル落ちます。57 どちらも着地するまでに約16セル分の距離を、0.301秒と0.201秒で落ちます。4 しぶきのアニメーションは3 + 2 + 2 = 7フレーム、0.117秒で、重いしぶきは3 + 3 + 4 = 10フレーム、0.167秒です。54
つまり正典の雨はまばらで速いのです。240×160の画面に10本の筋があり、約5分の1秒で画面を横切り、それぞれが上端からしぶきの終わりまで25フレーム、0.42秒生きます。4 雨として読めるのは、密度ではなく、角度、速さ、しぶきのおかげです。
霧、砂、雲
- 横の霧は4フレームごとに1ピクセル、毎秒14.9ピクセル、歩く速さの4分の1でスクロールし、8/16の上に12/16へブレンドされます。54
- 斜めの霧は未使用で、横に3フレームごと、下に5フレームごとに1ピクセル動きます。毎秒19.9ピクセルと11.9ピクセルです。5
- 砂あらしはレイヤーを1フレームに
gSineTable[index] × 4 / 256ピクセル動かし、インデックスは6フレームごとに0x20から0x5Fまで進みます。src/trig.cのサイン表で6,000フレーム再生すると、1フレームに2.83〜4.00ピクセル、平均で左へ3.59(毎秒215ピクセル)、上へ0.90です。歩く速さの3.6倍で、プレイヤーより速い唯一の天気のレイヤーです。454 - SUNNY_CLOUDSは64×64の雲のスプライト3つで、ソースが「for the lower half of Route 120」(Route 120の下半分のため)と述べるマップのセルに置かれ、12と8へブレンドされ、
UpdateCloudSpriteで動かされます。そのコメントは「Move 1 pixel left every 2 frames.」(2フレームごとに1ピクセル左へ動かす)です。毎秒29.9ピクセル、歩きの59.7の半分です。7511
歩きに対する空気。エメラルドのレイヤーはgen3_weather.txtから、Kiradexの今日の雲と提案する雲はkiradex_proposals.txtとarith.txtから、Kiradexの歩きはそのMotion.swiftから読んでいます。Kiradexの速さはMacでソースから読んだもので、iPhoneで測ったものではありません。
雷:短く、まれで、閃光と同時かその後に聞こえる
雷雨は小さな状態機械を実行し、ソースはそれをパターンとして要約しています。「(SHORT_BOLT){1,2}(LONG_BOLT)?」です。7 測定結果は次のとおりです。54
- 最初の周期のあとの各周期は、360〜719フレームのタイマーを待ち、それが切れた2フレーム後に落ちます(次の呼び出しで稲妻を準備し、その次の呼び出しで落ちます)。周期の始まりから361〜720フレーム、6.04〜12.05秒です。最初の周期は待ちません。嵐へのフェードが終わると、
THUNDER_STATE_WAIT_CHANGEが待ちを飛び越えてTHUNDER_STATE_INIT_CYCLE_1へ進みます。5297 - 短い稲妻が1回か2回落ち、それぞれがマップ19を6〜8フレーム、0.10〜0.13秒保ってから雨のマップに戻ります。57
- 稲妻のあいだのタイマーは60〜75フレームで、1つの稲妻の終わりから次の落雷までの暗い間隔はそれより1フレーム長く、61〜76フレーム、1.02〜1.27秒です。長い稲妻の間隔も同じです。5294
- 周期の半分では長い稲妻が続き、30〜45フレーム、0.50〜0.75秒保たれ、そのあとカットではなく徐々に雨のマップへフェードして戻ります。57
- 雷の音は、周期の最後の稲妻が落ちるフレームでキューに入ります。長い稲妻が続かないときは最後の短い稲妻が落ちるときに
EnqueueThunder(20)、長い稲妻が落ちるときにEnqueueThunder(100)です。EnqueueThunderはタイマーをRandom() % waitFramesに設定し、各フレームのThunderstorm_Mainの先頭で呼ばれるUpdateThunderSoundがそれを数え下げ、0に達してほかの効果音が鳴っていなければ音を鳴らします。タイマーが切れたときにほかに何も鳴っていなければ、落雷の1〜20フレーム後、最大0.33秒、長い稲妻では1〜100フレーム後、最大1.67秒です。そのときほかの効果音が鳴っていれば、UpdateThunderSoundは戻って次のフレームでもう一度試すので、雷はその音が終わるのを待ち、これらの範囲は上限ではありません。短い稲妻は6〜8フレーム保たれるので、音は稲妻がまだ光っているうちに始まることがあります。ソースには「Thunder only plays on the final bolt of the cycle.」(雷鳴は周期の最後の稲妻でだけ鳴る)とあります。74
最初のあと(最初は待ちを飛ばします)の、待ちが最小の3本の稲妻の周期を、gen3_replay.txtの状態遷移から再生したもの。各間隔は、そのタイマーに次の状態が動くまでの1フレームを足したものです。1秒の定規はarith.pyのものです。
これを真似る人にとって、この算術は重要です。2つの稲妻のあいだの暗い間隔は少なくとも61フレームで、毎秒59.7275フレームでは1.0213秒、1秒より長くなります。したがってエメラルドの嵐のどの1秒の窓にも、1つの稲妻の終わりと別の稲妻の始まりの両方が入ることはなく、どの1秒にも閃光は多くて1回です。4 これはW3Cの達成基準2.3.1の範囲内です。これはレベルAの要件で、コンテンツが「anything that flashes more than three times in any one second period」(どの1秒間にも3回より多く閃光を放つもの)を含まないことを求めます。46 それでも第10節はKiradexのために閃光を拒み、その理由はそこで述べます。
3. 天気のありか:マップ、トリガー、暦
天気はマップの性質
第3世代のすべてのマップのmap.jsonは、ヘッダーで天気を1つ名指しします。スクリプトはエメラルドの518、ファイアレッドの425のすべてを読み、マップの種類ごとにまとめます。547
エメラルドの68の屋外マップ(シティ9、タウン7、道路41、海の道路11)は、SUNNYを51回、NONEを13回、SHADEを2回、FOG_HORIZONTALを1回、VOLCANIC_ASHを1回持ちます。ファイアレッドの76の屋外マップは、SUNNYが66、NONEが8、SHADEが2です。54 どちらの作品でも屋外マップの4分の3以上がデフォルトで晴れ(75.0%と86.8%)で、ヘッダーが雨の屋外マップはありません。4
マップ別のヘッダーの天気。gen3_weather.txtのセクションGから。
雨はトリガー、スクリプト、暦から来る
エメラルドの雨は抽選されるのではなく、置かれています。マップには86の座標天気イベント、つまりプレイヤーが踏むと天気を変えるセルがあり、5つのマップ、デコボコさんどうとRoute 113、119、120、123にあります。種類別では、SUNNYが34、SUNNY_CLOUDSが12、VOLCANIC_ASHが12、RAINが4、2つの道路の周期がそれぞれ12です。54 スクリプトは24のsetweatherの呼び出しを加えます。NONEが5、SUNNYが4、ABNORMALが3、DOWNPOURが2、SANDSTORMが2(どちらもRoute 111)、SUNNY_CLOUDSが2、VOLCANIC_ASHが2、FOG_HORIZONTALが2、RAINが1回(Route 120)、DROUGHTが1回です。5 ファイアレッドには座標天気イベントがまったくありません。5
2つの道路が暦を持っています。Route 119はSUNNY、RAIN、RAIN_THUNDERSTORM、RAINを、Route 123はSUNNY、SUNNY、RAIN、SUNNYを、1日1段階ずつ巡り、UpdateWeatherPerDayが進めます。75 Route 119では4日のうち3日が雨で、Route 123では1日です。4 段階は1日に1回しか動かないので、同じ日にRoute 119を2回歩くプレイヤーは同じ天気に2回出会い、ある日の天気は誰かが着く前に決まっています。
屋内も天気
ヘッダーのフィールドは空のためだけのものではありません。エメラルドは2つの屋内マップに横の霧を、1つの屋内マップに日陰を与え、地下では11のマップが日陰、7つが霧です。ファイアレッドは5つの屋内マップに霧を、4つに日陰を与え、14の地下マップに霧を、1つに日陰を与えます。エメラルドの14の海中マップはすべてUNDERWATER_BUBBLESを持ちます。548 元の名前が曇りやどんよりを意味していたとコメントにあるSHADEは、部屋や洞窟が薄暗いことを表す正典の方法です。
これが天気について語ること
まとめると、測定は天気を世界の予定された状態として描き出します。天気は場所(道路、洞窟、部屋)に属し、一歩か1日で変わり、以前にその道路を歩いたことのある人には前もってわかり、そこにいる全員にとって同じです。5 第5節は、Stardew Valleyが別の仕組みで同じことをしているのを示します。谷全体で毎日1回の抽選をし、前日に告知するのです。17 どちらのゲームもプレイヤーの現実の天気を見せません。私の読みでは、それはハードウェアの制約ではなく設計です。世界の天気は世界が持っているものであって、プレイヤーが持ち込むものではないのです。
4. 第3世代の暗闇と影
暗い洞窟は照らされた円
エメラルドは暗闇を幾何として描きます。src/field_screen_effect.cのsFlashLevelToRadiusは{200, 72, 64, 56, 48, 40, 32, 24, 0}ピクセルで、完全に明るい状態から完全に黒い状態までの9段階です。495 マップのヘッダーがrequires_flashを設定すると(マップのツールはこれを、CのコードがgMapHeader.caveとして読むヘッダーのバイトに書き込みます)、SetDefaultFlashLevelはレベル7、gMaxFlashLevel - 1、半径24ピクセル、1.5セルから始めます。「フラッシュ」を使ったあとはレベル1、72ピクセル、4.5セルから始めます。それ以外のすべてのマップは、洞窟であってもなくても、レベル0、完全に明るい状態から始まります。505 照らされた範囲はゲームボーイアドバンスのウィンドウで、その水平方向の境界はDMAによって走査線ごとに書き換えられ、プレイヤーではなく画面の幅と高さの半分、つまり画面の中央に置かれます。5
240×160の画面で、「フラッシュ」なしの円は画面の4.7%を、ありの円は42.4%を覆い、面積は9倍です。4 レベル1からレベル7まで、各レベルは半径を8ピクセル、半セルずつ削り、レベル8は黒です。4
セル単位の半径としての暗闇。gen3_weather.txtに出力されたsFlashLevelToRadiusからの模式図です。マップは描いていません。
エメラルドの7つのマップがrequires_flashを設定しているので、518のうち7つが暗い状態で始まります。そのうち3つはルビー・サファイアから残った未使用のマップ(CaveOfOrigin_UnusedRubySapphireMap1〜3)で、残りはいしのどうくつの下の2フロアとチャンピオンロードの2つです。ファイアレッドには2つ、イワヤマトンネルのフロアがあります。5 クリスタルと並べると、3つの世代は暗い場所を3通りに描いています。赤はパレットのオフセットで、クリスタルは「フラッシュ」が夜と入れ替えるパレットのセットで、エメラルドは「フラッシュ」が半径を3倍にする光の円で描くのです。4035
影は1トーンで高さ5行
エメラルドは影を4つのフィールドエフェクトのスプライトで描き、measure_shadows.pyがそれを読みます。小は8×8ピクセル、中は16×8、大は32×8、特大は64×32です。どれも1つの色のインデックスで、どれもフレームの下5行にある平たい楕円です。不透明なピクセルは、小が64のうち24、中が128のうち64、大が256のうち144、特大が2,048のうち304です。8514 歩く人の大きさがどうであれ、影は高さ5行で1トーンです。このシリーズの高さの記事は規則のもう半分を測りました。歩く人が段差を跳ぶとき、影は地面に残るのです。52
Kiradexの歩く人の影、shadow.pngも同じ設計に従っています。12×4ピクセル、1トーンで、(18, 17, 23)にアルファ153、48ピクセルのうち40が不透明です。これはMacで出荷された画像から読んだもので、iPhoneで測ったものではありません。89 アルファ153は60%の被覆で、トーンはルマ0.071、青に寄った黒に近い色です。4
5. Stardew Valleyの1日と天気
Stardew Valleyは、暦で動く町を求めてこのシリーズが繰り返し立ち返る現代のゲームで、そのWikiは1日と天気を詳しく記録しています。ここにあるのは2026年10月5日に保存したWikiの言葉と数値です。この記事のためにゲームのコードは読んでいないので、読んだページが示していない夜の色合いの値や暗くなる速さは、ここにはありません。12
止めなければ14分の1日
1日は午前6時から午前2時まで、ゲーム内の20時間で、「Time passes at 0.7 real seconds per in-game minute」(ゲーム内の1分につき現実の0.7秒が過ぎる)ので、1日全体は現実の840秒、14分になります。ただしWiki自身の2つの条件のもとでの話です。1つは、1分が0.9秒かかるドクロの洞窟の外であること(「except the Skull Cavern where it’s 0.9」)、もう1つは「Ignoring pauses」(一時停止を除く)で、シングルプレイではカットシーン、メニュー、会話のあいだ時計が止まるからです。164 日暮れは季節とともに動きます。「In Spring and Summer , it is 8pm, while in Fall it is at 7pm and Winter is 6pm.」(春と夏は午後8時、秋は午後7時、冬は午後6時)とあります(コンマの前の空白はWikiのものです)。日暮れには「indoors the windows turn dark and lamps and sconces light up」(屋内では窓が暗くなり、ランプと壁付け灯がともる)、屋外では「it does not immediately become full dark, but gradually becomes darker over time.」(すぐに真っ暗になるのではなく、時間とともにだんだん暗くなる)のです。16 午前6時から数えると、日暮れは春の日では現実の約9.8分後、冬の日では8.4分後に来ます。4
つまりStardewは、クリスタルがしないことをしています。暗さはグラデーションとして訪れ、始まる時刻は季節に従います。屋内も暗くします。クリスタルは208の屋内マップのうち207を昼に固定していますが、Stardewでは、Wikiが記録する例外が1つあります。「if nightfall happens while you are indoors it stays light until you exit and re-enter.」(屋内にいるあいだに日暮れが来ると、出て入り直すまで明るいままになる)161
明かりはマップの性質
Wikiのマップのモッディングのページは、ライティングをマップが持つプロパティとして挙げています。53
AmbientLightは「Sets the RGB color that is subtracted from white (255,255,255)」(白(255,255,255)から引くRGBの色を設定する)もので、マップの暗さは掛け合わせる色ではなく、取り除く色です。53Lightは9種類の光のうち1つを置きます。ランタン、窓、壁付け灯、大釜、屋内の窓、プロジェクター、水槽、冬の町の木の電飾、ピンポイントです。53WindowLightは「only lit during the day when it is not raining」(雨が降っていない昼のあいだだけともる)光を加えます。外から窓を通って入ってくる光です。53NightTilesは「Changes the tile after 7pm」(午後7時以降にタイルを変える)もので、ページは、それが「is mostly used for lamps in the game.」(ゲームでは主に街灯に使われる)と付け加えています。53
構造編の記事は、Kiradexの明かりのついた窓のモデルとしてNightTilesを使いました。23 WindowLightはもう半分で、Kiradexがまだ持っていないほうです。窓が外の光を映す部屋です。
天気は日ごとに、前日に告知される
Stardewの天気は1日に1回抽選され、告知されます。Wikiの天気のページは「Weather changes daily and with the seasons」(天気は毎日、季節とともに変わる)と述べ、翌日の天気は「can be checked by viewing the TV screen」(テレビの画面を見て確かめられる)としています。テレビの天気予報です。17 天気が強制されない日付について、モッディングのページの確率は次のとおりです。18
- 春:「an 18.3% base chance of rain」(雨の基本確率18.3%)、そして「in spring there’s a 66.4% chance of sunny weather.」(春は66.4%の確率で晴れ)18
- 夏:「The chance of sunny weather diminishes steadily per day from 87.4% on summer 1 to 79.9% on summer 28」(晴れの確率は夏の1日の87.4%から夏の28日の79.9%まで、日ごとに着実に下がる)、そして「There’s an 85% chance that rain becomes storms.」(雨が嵐になる確率は85%)18
- 冬:「a 63% chance of precipitation」(降水確率63%)、そして雨そのものについては「Winter: never rains.」(冬:雨は降らない)18
- **風に舞うもの(風):**春は「approximately 16.6% chance of debris weather」(風に舞う天気の確率は約16.6%)、秋は「approximately 49.8%」(約49.8%)です。18
嵐のあいだは「There is a chance for a lightning strike to occur every 10 minutes」(10分ごとに落雷が起きる可能性がある)とあり、ゲームはプレイヤーに雪を弱めさせることもできます。「Snow transparency can be changed in the Options Menu」(雪の透明度はオプションメニューで変えられる)17 この最後の1行は天気についての小さなアクセシビリティの設定で、第10節はこのヒントを受け取ります。
6. 現代のライティングされたピクセルゲームを、作り手の言葉で
このシリーズの最初の記事は、ピクセルアートのライティングの段階表を示しました。ここで要約すると、いちばん下にMoonlighterの重ねたスプライト、Celesteのライトマスク、Eastwardの手描きのバンプマップ、そしていちばん上にSea of StarsとHD-2Dのライティングされた3Dの場面です。Animal WellとDead Cellsも位置づけています。32 この節は作り手のもとへ戻り、それぞれが自分の光は何のためにあると言っているかを確かめます。昼夜の周期や天気の数値を示す作り手はいません。数値があるのはCelesteのテクスチャと光の予算だけで、ライティングの数値を含むEastwardやSea of Starsの発言は見つかりませんでした。12
Moonlighter:明かりはまったくない
Digital Sunは80.lvに「There is no dynamic lighting」(動的ライティングはない)と述べ、「we use the superposition of sprites to give the impression of light (for example in Rynoka during the night).」(スプライトを重ねて光の印象を与えている。たとえば夜のRynokaで)と語りました。54 その町の夜は計算されるのではなく、描かれています。
Celeste:壁に当たる光
2017年9月25日の、Celesteのライティングを作り直したNoel Berryの記録は、1つの要件から始まります。単純なスポットライトでは「wouldn’t cut it」(通用しない)、なぜなら「the lights needed to actually hit walls.」(光は実際に壁に当たる必要があった)からです。彼の方法は、まず各ライトのスポットライトをマスクに描き、そのうえですべての壁の面が「their shadow projection (each just a single quad)」(影の投影、それぞれただ1枚の四角形)を上に描いて、スポットライトから影を切り抜くというものです。各ライトは2048×2048のテクスチャを256×256のスロットに分けたものの1つの色チャンネルを使い、4チャンネルのスロットが64あるので、「we can have a total of 256 lights on a single, big texture.」(大きなテクスチャ1枚に合計256個のライトを持てる)のです。554
Eastward:2Dに見える3Dのゲーム
PixpilのTommo Zhouは2021年10月11日にGame Developerに語りました。「Interestingly Eastward is a 3D game with a 2D perspective!」(面白いことに、Eastwardは2Dの視点を持つ3Dのゲームなんだ)。スタジオは「shader textures and lighting systems in our custom engine (Maoi) to help convey atmosphere, and things like the weather and the time」(雰囲気や天気や時間のようなものを伝えるために、独自エンジン(Maoi)でシェーダーのテクスチャとライティングのシステム)を使い、「intricate fog layers and sunlight beams breaking through the landscape during dawn and dusk」(夜明けと夕暮れに風景を割って差す複雑な霧のレイヤーと日差し)を持ち、アセットは3Dで作り直され「hand painted in the bump map one by one」(1つずつバンプマップに手で描かれる)のです。56
Octopath TravelerとHD-2D:影の落ち方
Nintendo Everythingが2018年11月3日に翻訳したNintendo Dreamのインタビューで、Octopath TravelerのShizuka Morimoto氏はこう語りました。「At first, I started using some techniques to add dramatic lighting to the 2D art, but Asano told me that wasn’t enough.」(最初は2Dのアートに劇的なライティングを加える技法を使い始めたが、浅野にそれでは足りないと言われた)。Tomoya Asano氏はこうです。「I wanted to make use of lighting mixed with pixels in a way that emphasized how light shines on objects and how shadows fall.」(光が物にどう当たり、影がどう落ちるかを強調するやり方で、ピクセルと混ざったライティングを活かしたかった)57 二次資料であるWikipediaは、このシリーズが知られるようになった技法、HD-2Dを説明しています。「Typically, a point light source is placed into the scene to make characters and objects cast shadows」(通常は、キャラクターと物に影を落とさせるために点光源が場面に置かれる)とあり、その上にティルトシフト、被写界深度、ブルーム、ボリュメトリックライティング、霧が加えられます。58 コストについてのAsano氏自身の評価は、2022年5月にNintendo Lifeが報じた4Gamerのインタビューから、記事の見出しの下の1行にあります。「It costs more than you’d think」(思っているより費用がかかる)59 Unreal EngineのOctopath Travelerの2つのページは、フェッチャーにもcurlにもHTTP 403を返したので、Nintendo Dreamの翻訳がその代わりを務めます。12
Sea of Stars:機能としてのライティング、そして遊びのなかの時計
SabotageのSea of Starsのプレスキットは「Full-on dynamic lighting. Our custom-made render pipeline allows the creation of a breathtaking world coming to life by pushing the limits of 2D pixel-art games.」(本格的な動的ライティング。独自のレンダーパイプラインが2Dのピクセルアートゲームの限界を押し広げ、息をのむような世界に命を吹き込む)と挙げています。60 ゲームプレイの映像についてのTechRaptorの記事は、昼と夜の変化が遊びを動かすことを示しています。それは「influences gameplay as well, specifically some interesting little puzzles that materialize bridges at the right time of day.」(ゲームプレイにも影響し、特に正しい時間帯に橋が現れる面白い小さなパズルがある)のです。61 Sabotage StudioのThierry Boulangerは2023年8月にScreen Rantに、このシリーズの高さの記事が引用するとおり、レベルが「to all read well with different levels of height, with the light and everything」(異なる高さで、光やすべてとともに、どれもよく読めるように)する必要があったと語りました。52
手で描く影
2人の画家が、エンジンをまったく必要としない影の規則を示しています。1人は3つの記事で、もう1人は1行で。
Raymond Schlitterは、見下ろし型のオブジェクトについてのPixelblogで、落ち影についてこう書いています。「It’s best to keep them subtle and not cast out long in any particular direction」(控えめに保ち、どの方向にも長く伸ばさないのがいちばんだ)、そして「in most cases I make the shadows on separate tiles and place them on a different layer than the sprites.」(たいていの場合、影は別のタイルに作り、スプライトとは別のレイヤーに置く)。62 見下ろし型のタイルの記事の第2部では、壁の下の落ち影についてこうです。「it’s best to limit them to one or two wall faces, minding light source, and they should not exceed a tile in length. No matter how tall the rock wall all shadows are the same length.」(光源を意識して壁の1面か2面に限るのがいちばんで、長さは1タイルを超えるべきではない。岩壁がどれほど高くても、影はすべて同じ長さだ)63 そして見下ろし型の木の記事では、木の影をどこに置くかについてこうです。「It’s most practical for game design to center the shadow directly under the tree, so that it doesn’t run into other assets」(ほかのアセットにぶつからないよう、影を木の真下の中央に置くのがゲームデザインとして最も実用的だ)64
石井浩一氏は、聖剣伝説3について、Shmuplationsの翻訳でこう語っています。「for shadows and the like, we’re using deep blues and purples instead of shades of black, to impart a sense of softness.」(影などには、柔らかさを出すために、黒の濃淡ではなく深い青や紫を使っている)65
段階表を、スマートフォンのために読む
作り手の言葉は、段階表に1つのことを付け加えます。Moonlighterより上のすべての段階は、光を何かと相互作用させるためにあります。Celesteの光は壁に当たり、Eastwardの光はバンプマップの面に落ち、Octopathは「how shadows fall.」(影がどう落ちるか)を見せます。555657 足すだけの光、遮られることも、落ちた先のものに形作られることもない光は、どうブレンドされていてもMoonlighterの段階です。
Kiradexのプールはまさにそれです。本物の加算ブレンドで地面に足された光で、何とも相互作用しません(第7節)。6622 私の読みでは、それは欠点ではありません。スマートフォンの町に払える段階であり、上の手描きの規則が、エンジンなしでどこまで持っていけるかを教えてくれます。影は独自のレイヤーに、短く、1面か2面に、高さにかかわらず同じ長さで、黒ではなく青に寄せた色で。626365
7. Kiradexの今日の光を、Macでソースから読む
この節の内容はすべて、2026年10月5日の16:51から18:19にかけて、Kiradexリポジトリの作業ツリーから、コミットcf3beb1eから66c116b0の時点で読んだものです。ツリーはその日編集されている最中で、gitもフォージも実行しておらず、各注がどの読み取りかを名指ししています。読んだもののなかには、Kiradex/World/Daylight.swift、Motion.swift、Air.swift、Glow.metal、PlazaStage.swift、PlazaRig.swift、HallView.swift、フォージのscripts/forge/air.py、town.py、buildings.py、そして書き出した町Kiradex/Resources/World/town.json(40×30タイル、ファイルの日付は2026年10月3日21:34)とそのアトラスと空気の画像があります。912 measure_kiradex_light.pyはSwiftとPythonをテキストとして読み、Pillowで出荷された画像に色合いを適用します。iPhone上で実行したものはなく、ここにある数値はどれもキャプチャではありません。本文が町の夜は昼の0.588だと言うとき、それは出荷されたアトラスに出荷された色合いをMacで掛けたものです。9
スマートフォンの暦の上の4つの時間帯
Daylight.Phaseは時刻を、6時から9時を朝、9時から17時を昼、17時から20時を夕方、それ以外を夜に対応させます。3、8、3、10時間です。219 街灯は夕方と夜にともり、lampsOnはself == .evening || self == .nightで、1日13時間、その54.2%です。214 これらはクリスタルの時刻ではなく、それは意図したものです。オマージュの記事はKiradexの時間帯をクリスタルの4、10、18と並べ、Kiradex独自のままにすると決めました。この記事はその決定を保ちます。10
各時間帯は色合い、つまり「a multiplier on the art’s own colours」(アート自身の色への乗数)で、ファイルは4つをアートの面、「four fixed lights for a pixel world」(ピクセルの世界のための4つの固定された光)として宣言しています。21 ルマとともに示します。9
| 時間帯 | 色合い(赤、緑、青) | ルマ | 青から赤と緑の平均を引いた値 |
|---|---|---|---|
| 朝 | 1, 0.96, 0.86 | 0.961 | −0.12 |
| 昼 | 1, 1, 1 | 1.000 | 0.00 |
| 夕方 | 1, 0.78, 0.6 | 0.825 | −0.29 |
| 夜 | 0.5, 0.58, 0.9 | 0.593 | +0.36 |
季節はそこに掛け合わせる色味を加えます。春(0.97, 1, 0.95)、ルマ0.985。夏は白、1.000。秋(1, 0.93, 0.84)、0.941。冬(0.9, 0.94, 1)、0.935です。時間帯と季節の16の組み合わせのうち、最も暗い光は秋の夜で(0.5, 0.539, 0.756)、ルマ0.552、最も明るいのは夏の昼で1.000です。921 季節は月で選ばれ、ファイル自身の言葉では「in the north; the south is a setting for later」(北半球で。南半球はあとで設定にする)です。21
形は正典と一致しています。夜はクリスタルでもKiradexでも最も長い時間帯で、24時間のうち10時間です。Kiradexの朝は暖めた昼の光で、すべての色にルマ0.961の色合いを掛けますが、クリスタルは白だけを暖めます。そしてKiradexの夜はクリスタルと同じく青に寄っています。194 Kiradexは、クリスタルにはない、暖かく街灯のともる夕方を加えています。
色合いが町にすること
出荷されたアトラスtown.png(256×352ピクセル、そのうち81,926ピクセルが不透明)に適用すると、4つの色合いは平均ルマを朝0.432、昼0.449、夕方0.372、夜0.264にします。昼に対して0.962、1.000、0.829、0.588です。94 Kiradexの夜はクリスタルの平均より少し多くの光を残し(0.511に対して0.588)、夜の色合い自身のルマ0.593より少し少なくなります。アトラスの色が、夜の色合いが削る暖色のチャンネルに寄っているからです。4 私の読みでは、腕を伸ばして持つスマートフォンにとって、誤るならこちら側が正しいのです。
明かりは色合いを拒む
Kiradexは別の道を通ってクリスタルの答えにたどり着きました。明かりのついた窓とホールの壁付け灯は、マテリアルをlight: .whiteで、色合いをかけずに描く2つ目のメッシュで、街灯がともると有効になります。フォージは明かりのセルごとに、ともったときに変わるピクセルだけを書き出します。2023 書き出しでは、それは3つのアトラスインデックスにある24セルです。窓が20(インデックス200、それぞれ54の不透明ピクセル)、切妻の窓が2(インデックス201、同じく54。buildings.pyが切妻の三角形の中央に置く窓で、house-mineとホールにあります。ドーマーは明かりの変種を持たない屋根のピースです)、そしてホールの壁付け灯が2(インデックス257、12ピクセル、セル(21, 5)と(23, 5))です。9
それらの最も明るいピクセルは、色合いをかけずに描かれてルマ0.901です。夜の色合いのもとでは、アトラスのどこであれ最も明るいピクセルは0.562です。明かりのセルは、夜の色合いをかけたアトラスで最も明るいピクセルの1.60倍です。ここには加算のプールを含めていません。プールの街灯の中心は0.785〜0.806に達します(後述)。94 クリスタルのYELLOWが、ほかのパレットの夜の最も明るい色0.498(町の水はそこから1段階ずれた0.490)に対して0.90にあるのは、同じ考えをパレットで表したものです。照らされたものは明るさを保ち、そのまわりの町が落ちていくのです。14
この数はこのシリーズの別の記事を訂正します。構造編の記事は「nineteen windows and the hall’s two sconces」(19の窓とホールの2つの壁付け灯)と述べ、「21 lit cells dedupe to two」(21の明かりのセルは重複をまとめると2つになる)と言っています。23 10月3日21:34の書き出しには、3つのアトラスインデックスにある24の明かりのセル、窓20、切妻の窓2、壁付け灯2があります。94 その記事が書かれたあとで町が変わったか、記事の数え方が違ったかのどちらかです。出荷された書き出しに照らすと、3セルと1つのアトラスインデックスぶん古くなっています。これはこの記事の発見で、以前の記事は編集していません。
足すだけの光のプール
ビルド29から、街灯と明かりのついた窓は夜に地面へ光のプールを落とします。Glow.metalはRealityKitのサーフェスシェーダーで、画像の色に色合いを掛けたものをベースの色と発光の色の両方として、不透明度1で書き出し、マテリアルは加算でブレンドします。コメントがその理由を述べています。「black adds nothing, and a pool of light never darkens what it lies on, which an alpha halo did.」(黒は何も足さない。光のプールは自分が載っているものを決して暗くしない。アルファのハローはそうしていた)6622 Air.swiftでは、プログラムのディスクリプタがblendMode = .addを設定しています。22
- 街灯のプール。 56×56ピクセル、3.5タイルで、町の7つの明かり(街灯の頭とキオスク)それぞれの下にあり、色合いは(0.7, 0.52, 0.24)です。922
- 窓のプール。 40×28ピクセル、2.5×1.75タイルで、明かりのついた1階の窓か壁付け灯の前にあり、色合いは(0.5, 0.38, 0.17)です。プールを落とすのは建物の基部の行かその上の行にある明かりのセルだけなので、24の明かりのセルのうち17がそうで、プールは全部で24です。4
- 画像。
glow.pngは64×64の放射状のプールで、中心が0.961、ピクセルの0.713でゼロを上回ります。967
プールが地面に何をするかは計算できます。夜のアトラスの平均色は(0.228, 0.264, 0.358)、ルマ0.264です。中心で街灯の色合いを丸ごと足すと(0.928, 0.784, 0.598)、ルマ0.806に上がり、昼の0.449を上回ります。9 スクリプトは色合いを丸ごと足しています。画像自身のピーク0.961で重み付けすると、中心は0.785になります。4 いずれにせよ、夜の街灯は足もとの地面を正午より明るくします。それは街灯が足もとの地面にすることです。
歩く人は夜を受ける
歩く人は自分の色を保ちません。PlazaRig.light(_:lampsOn:)は新しい光を地面、周囲、オブジェクトに設定し、すべての歩く人に「redrawn in the new light on the next frame」(次のフレームで新しい光のもとで描き直す)と印を付けます。各歩く人のフレームのマテリアルは、同じlightを使うsheet.material(column:row:light:)、つまり地面と同じ乗算です。20 夜には、歩く人は夜の色合い、3つのチャンネルの乗数(0.5, 0.58, 0.9)で描かれます。その色合い自身のルマは0.593で、保存された値ではコレクターの人物のルマ(idle_aで保ったときのマスク)の0.575を残します。30 ちょうどクリスタルとエメラルドが人物に手を付けないところです。915
1つの例外は、コレクターが持っているカードです。リグは「For the card alone: nothing else in the world is lit.」(カードのためだけ。世界のほかのものは何も照らされない)というコメントとともにDirectionalLightを加えています。20
これが2つ目の訂正です。世界の記事のチェックリストにはこうあります。「Dusk and night as one multiply tint over the world plus hand-drawn emissive variants for lamps, windows and the kiosk sign.」(夕暮れと夜は世界全体に1つの乗算の色合いとし、街灯、窓、キオスクの看板には手描きの発光の変種を加える)32 コードはそのとおりにしており、コードについての記述としては正確です。この記事のブリーフはそれを歩く人について変えます。歩く人は色合いを丸ごと受けるべきではありません(第10節、項目2)。正典と照らし合わせると、歩く人を含むすべてに1つの乗算を掛けることは、クリスタルとエメラルドがどちらも採らない規則です。これはこの記事の発見で、世界の記事は編集していません。
カット、1分に1回
光はclock、つまりステージが持つ日付の関数です。タスクが60秒ごとにそれを読み直し、そのコメントは「The light follows the clock, a minute at a time.」(光は時計に、1分ずつ従う)です。そしてonChange(of: clock)がrelight()を呼び、時間帯と季節を計算して新しいマテリアルを一度に割り当てます。199 光と光のあいだにアニメーションはなく、World/のどこにもsignificantTimeChangeNotificationのオブザーバーはありません。時刻はスマートフォン自身のタイムゾーン、Calendar.currentからDaylight.nowを通じて来ます。起動引数-plazaHourは時刻を1つ強制し、UIテストはそれを使って夜の広場を見ます。92168 ステージはTimelineView(.animation(minimumInterval: 0.1))を実行していますが、それはbubbles(of:in:)にある吹き出しの時計で、言ったばかりのことを言った人の頭の上に数秒保つためのものです。光の時計ではなく、歩きの時計でもありません。歩きはrig.updateがシーンの更新イベントから進めます。199
したがって時間帯の変化はカットで、境界から最大60秒遅れて来ることがあります。アトラスの平均ルマでのカットは、arith.pyによると次のとおりです。411
- 06:00、夜から朝: 0.168の段差、1日で最大です。4
- 09:00、朝から昼: 0.017です。4
- 17:00、昼から夕方: 0.077です。11
- 20:00、夕方から夜: 0.108です。11
クリスタルもカットしており、18:00に屋外にいたプレイヤーは、それが起きたフレームで見ました(第1節)。誰かがどれくらいの頻度で見ていたかは、ソースからはわかりません。1 私の読みでは、Kiradexの広場は開きっぱなしの画面です。誰かが机の上に開いたまま置いておき、20:00に顔を上げると、町の平均ルマが1フレームで0.372から0.264へ、明るさの4分の1以上落ちるのを見るかもしれません。見られている画面の上のカットは出来事であり、正典はそれを解決する必要がありませんでした。
部屋とホールはスマートフォンの時計を保つ
PlazaStage.swiftにあるRoomViewは独自のPlazaStageを作り、HallViewも1つ作ります。したがって部屋とホールは、広場と同じコードで、同じ時計、つまりスマートフォンの時計から、街灯も含めて照らし直されます。1969 どちらも黒いベールを通って入り、それぞれのコメントでは「A room is entered through the veil」(部屋にはベールを通って入る)、「The show is entered through the veil」(ショーにはベールを通って入る)とあり、どちらも広場を置き換えるのではなく広場の上に重ねられます。1969 これはコードについての私の読みで、キャプチャではありません。これはクリスタルではなくStardewの選択です。Stardewは日暮れに屋内を暗くしてランプをともし、クリスタルは208の屋内マップのうち207を昼に固定しています。161 どちらも正典です。Kiradexはすでに一方を選んでおり、さらにその一歩先へ進んでいます。Stardewは日暮れにプレイヤーがいる部屋を、出て戻ってくるまで明るいままにしますが、Kiradexの部屋はプレイヤーがなかにいても1分ごとに照らし直されます。これはKiradex自身の選択であって、正典の選択ではありません。1619
空気
Air.swiftは、デザイン計画の第4節に従った、ビルド29の「Light and air over a place」(場所の上の光と空気)のレイヤーです。2270 コードとフォージの画像から測ります。9
- 雲の影。 どのビューよりも幅の広いシートで、カメラに従い、その画像
cloud.png(256×256)はワールドの384ピクセルごとに繰り返します。テクスチャのオフセットは毎秒(0.004, 0.0015)進み、384ピクセルにわたっては毎秒(1.536, 0.576)ピクセル、合わせて毎秒1.64ピクセルです。229 この換算は、RealityKitがオフセットをスケールのあとに足し、オフセット1が画像のちょうど1回の繰り返しになると仮定しています。この記事のために保存したAppleのページは、このプロパティが「A two-dimensional transformation to apply to the entity’s primary texture coordinates」(エンティティの主テクスチャ座標に適用する2次元の変換)だと述べるだけで、順序には触れていません。71 アプリ自身のスプライトシートも同じ順序に頼っています。SpriteSheet.swiftは、列を列数で割ったオフセットと、1を列数で割ったスケールでフレームを選びますが、これはオフセットがスケールのあとに来る場合にだけフレームに当たり、そのコメントはシミュレーターでオフセットの規約を測ったことを記録しています。72 したがって1.64と、第2節のチャートにある雲の棒は、その順序に依存しています。オフセットには毎フレーム、カメラの位置を384で割ったものも足されるので、画面上でのシートの動きは、流れに加えて、ビューが動くときにその項がすることになります。私はそれをキャプチャしていません。229 雲は夜以外のすべての時間帯に表示されます。 - 雲の陰。
cloud.pngは「a tileable mask of cloud shadow: alpha where a cloud passes」(タイル状に並べられる雲の影のマスク。雲が通るところにアルファがある)で、面積の0.499を覆い、アルファは最大110で、マテリアルの不透明度0.55で描かれます。最も暗い陰は地面に0.763を掛け、画像の平均は0.950を掛けます。679 - 霧。 公園の池の上、セル(5, 24)、(9, 26)、(4, 27)に3つのかたまりがあり、それぞれ128×64ピクセル、アルファは最大93で不透明度0.7、朝だけです。922
- 葉と蛍。 秋には夜以外のすべての時間帯に14枚の葉、夜には公園の長方形のなかに10匹の蛍です。922
- 煙。 フォージが記録した6本の煙突それぞれの上に3つの煙のかたまり。UIテストは空気のレポートが
smoke 18と言うのを待ちます。2268
正典と比べると、雲は遅く、その陰は穏やかです。毎秒1.64ピクセルではKiradexの歩きの0.027で、1タイルを横切るのに9.8秒かかります。エメラルドの雲は歩きの半分で動きます。スマートフォンでは、私の読みでは、止まって見えるほど遅いのです。114 比べる歩きは毎秒60ピクセルです。Motion.swiftのティックの時計は毎秒60ティックで動き、Stride.ticksは16ピクセルのまっすぐな歩きの一歩に16ティックを与え、PlazaRig.update(_:)はティックをtick()に通し、それがプレイヤーを進めます。732011 雲の最も暗い陰0.763は、エメラルドの雨のマップ(すべてのチャンネルの約0.81)より暗いのですが、画像の半分しか覆いません。95
影
3つの影が規則によって描かれ(敷石の上の街灯の柱も独自の影を持ちます)、1つが欠けています。9874
- 歩く人の影。
shadow.png、第4節の12×4の1トーンのかたまりで、すべての歩く人の下に12×4で描かれます。98 - 壁の影。 フォージは、壁のセルの足もとにあるものの上の4ピクセル行を、それ自身のランプで1段階暗くします。コメントは参照先を名指ししています。「the way the light falls at Leene.」(Leeneでの光の落ち方)74
- 軒の影。 屋根の下の建物の壁にある3ピクセル行の影で、
buildings.pyが建物を仕上げるときに描きます。24 - 地面の影、欠けているもの。 どの建物からも地面に影が落ちません。それを先送りするdocstringはこの記事の冒頭で引用したとおりで、フォージの
paintはそれを決して描きません。249
壁の影はすでにSchlitterの規則(1面、1タイル未満の長さ、上に何があっても同じ長さ)に従っており、歩く人の影はエメラルドの規則(1トーン、数行)に従っています。638 欠けているのは建物です。
動きとシステムの設定
accessibilityReduceMotionは、World/のなかでちょうど1つのファイル、FigurePreview.swiftでしか読まれていません。Air.swiftはそれを読まないので、雲の流れ、霧、葉、蛍、煙はどれも設定にかかわらず動きます。975 ステージはrenderingEffects.depthOfField = .disabledを設定しています。デザイン計画のビルド29は「a vignette and tilt-shift depth of field as the camera’s rendering effects」(カメラのレンダリング効果としてビネットとティルトシフトの被写界深度)を求めていましたが、ビネットは作られ、被写界深度はオフになっています。1970
シリーズの各記事が言っていることを確かめる
このシリーズの以前の記事にある3つの記述が、この記事の測定と一致しません。それぞれ上で測定とともに述べました。構造編の記事の21の明かりのセルに対して書き出しの24、世界の記事の64バイトの読み込み直しに対して屋外でのLoadMapPalsの132バイト、そして世界の記事の世界全体に1つの乗算の色合いで、このブリーフはそれを歩く人について変えます。2332934 一致したものは次のとおりです。オマージュの記事のクリスタルとKiradexの時刻。生きている町の記事の今日の時計についての説明、つまりスマートフォンの暦と、ゾーンを名指ししないサーバー、そしてそれと並ぶ、部屋のゾーンと時計を運ぶwelcomeと静かな広場の応答の契約。第10節はこれを土台にしており、クライアントは10月5日の時点でそれを読んでいませんでした。構造編の記事のNightTilesとroofs.palについての説明。そして高さの記事の、ジャンプの下で地面に残る影です。1043762352 キャラクター編、モーション、部屋、ルートの各記事は、この記事が否定することを何も言っておらず、モーションの記事の、毎秒60ティックで1タイル16ティックの歩きは、アプリが今実行しているものです。127773
8. 技法を、数値付きの規則として
以下の各規則は、第1〜7節で測った事実に、私がそこから受け取るデザイン上の読みを添えたものです。数値は正典とアプリのものです。Kiradexの数値はどれもMacでソースから読んだか、書き出した画像から計算したもので、iPhoneで測ったものではありません。読みは私のものです。
| 要素 | 規則 | 出典 |
|---|---|---|
| 1日の区分 | 1日は3つか4つに分かれ、夜が最も長い。クリスタル:6 + 8 + 10時間。Kiradex:3 + 8 + 3 + 10。 | 第1節と第7節19 |
| 夜 | 夜は光がおよそ半分になり、より青くなる。クリスタルのワールドパレットは、パレットファイルのブロックで昼のルマの0.41〜0.68、平均0.51を保ち(町が自分の水と屋根の色で表示する状態では、マップグループ別に0.49〜0.54)、青への偏りは5ビットの単位で約6〜7上がる。Kiradexの夜はアトラスのルマの0.59を保つ(Macで読んだもの)。 | 第1節と第7節19 |
| 朝 | 朝は暖かい白であって、別の場面ではない。クリスタルの32のワールドの色のうち朝に変わるのは5色で、どれも最も明るい色。 | 第1節1 |
| 明かり | 明かりは色合いを拒む。クリスタルのYELLOWは夜もルマ0.90のまま。Kiradexの明かりのセルは色合いをかけず0.901で、最も明るいピクセルが0.562の夜の町に対している(Macで読んだもの)。 | 第1節と第7節19 |
| 人物 | 場所は暗くなり、人物は暗くならない。クリスタルの人物パレットと、エメラルドのプレイヤーと町の人のパレットは、夜にも雨にも手を付けられない。 | 第1節と第2節15 |
| 変化 | 時刻はカットし、天気はフェードする。クリスタル:時刻ちょうどに1フレームで、8フレームの白へのフェードはドア、ワープ、「そらをとぶ」、メニューが開く画面、一部のスクリプトの場面のためのもの。エメラルドの雨:20フレームの3段階、1.00秒で、雨粒はその約1秒後にそろう。町の上に開いたまま置かれたスマートフォンは、カットのあいだも見られているので、Kiradexはランプにする(第10節)。 | 第1節、第2節、第7節15 |
| 雨の光 | 雨は場所を13/16にする。エメラルドのマップ3、すべてのチャンネルの約0.81。 | 第2節5 |
| 雨粒 | 雨はまばらで速い。240×160の画面に10粒、鉛直から26.6度で毎秒868ピクセル、1粒18フレームと7フレームのしぶき。豪雨は24粒で毎秒1,336ピクセル。 | 第2節5 |
| 空気 | 雲と霧は歩くより遅く動く。エメラルドの雲は歩きの0.50、霧は0.25。それより速いのは3.6の砂あらしだけ。 | 第2節511 |
| 天気の予定 | 天気は場所と日によって予定され、前もってわかる。エメラルドにもファイアレッドにも、ヘッダーが雨の屋外マップはない。Route 119と123は4日周期を持つ。Stardewは1日1回抽選し、翌日を予報する。 | 第3節と第5節517 |
| 稲妻 | 稲妻は短くまれ。1本6〜8フレーム、短い稲妻は多くて2本で少なくとも61フレームの暗さを挟み、周期どうしは6〜12秒離れる。2本の稲妻を含む1秒はなく、W3Cの1秒に3回の閃光を下回る。 | 第2節5446 |
| 屋内 | 屋内は昼を保つか、昼に従う。どちらか1つを選ぶ。クリスタルは208の屋内マップのうち207を昼に固定する。Stardewは日暮れに屋内を暗くしてランプをともすが、日暮れにプレイヤーがいる部屋は、出て戻るまで明るいまま。KiradexはすでにStardewに従っており、プレイヤーがなかにいる部屋も照らし直す。 | 第1節、第5節、第7節11619 |
| 暗闇 | 暗闇はセル単位の半径。エメラルド:「フラッシュ」なしで1.5セル、ありで4.5セル。 | 第4節5 |
| 落ち影 | 落ち影は1トーンで、1タイル未満の長さで、1面か2面に落ち、高さにかかわらず同じ長さ。エメラルドの影のスプライト、Schlitterの規則、Kiradexの壁。 | 第4節、第6節、第7節86374 |
| 加算の光 | 加算の光は決して暗くしない。影にはアルファかアートが要る。RealityKitのプログラムのブレンドモードはaddとalphaで、unlitのマテリアルは透明度でブレンドする。 |
第7節と第9節7866 |
9. Appleのやり方:ブレンドモード、跳ぶ時計、Reduce Motion
Kiradex Worldの下にあるエンジンは、このシリーズの最初の記事が示したものです。2Dのレンダラーとして使うRealityKitのシーン、1テクセルあたり整数のデバイスピクセルに置いた正投影カメラ、そしてunlitのスプライトのマテリアルだけです。32 光、天気、時間に新しいフレームワークは要りません。必要なのは加算とアルファのブレンドで、アプリはすでにどちらも使っています(前者はプールのBlendMode.addとして、後者はUnlitMaterialの透明のブレンドとして)。そしてまだ監視していない2つの通知と、1つのファイルでしか読んでいない1つの環境値です。以下の対応状況は、2026年10月5日に各ドキュメントページが挙げていたもので、保存したページからparse_apple.pyが読みました。26
2つのブレンドモードと、それぞれが描けるもの
MaterialParameterTypes.BlendModeは「Modes that describe how materials should be blended with content behind them」(マテリアルを背後のコンテンツとどうブレンドするかを表すモード)と説明されており、そのページはちょうど2つの列挙ケース、addとalphaを挙げています。784 addについて、Appleはこう書いています。「Blend by adding the material’s color to the background color, ignoring alpha」(アルファを無視し、マテリアルの色を背景の色に足してブレンドする)、「also known as additive blending or linear dodge.」(加算ブレンドやリニアドッジとしても知られる)79 どちらもiOS 18.0以降、iPadOS 18.0、Mac Catalyst 18.0、macOS 15.0、tvOS 26.0、visionOS 2.0として挙げられています。7879
ブレンドモードはマテリアルのプログラムに属し、そのプログラムはCustomMaterial、「A material that works with custom Metal shader functions」(カスタムのMetalシェーダー関数とともに動くマテリアル)で、iOS 15.0とmacOS 12.0から使えます。80 町のほかのものはすべてUnlitMaterial、「A material that doesn’t respond to lights in the scene」(シーンの光に反応しないマテリアル)で、iOS 13.0とmacOS 10.15からです。71 Kiradexはまさにそのとおりに両方を使っています。プールは、プログラムのディスクリプタがblendMode = .addを設定するCustomMaterialです(保っておく価値のあるコメント付きです。「The program says how to blend; the material says that it blends at all.」(どうブレンドするかはプログラムが言い、そもそもブレンドするかどうかはマテリアルが言う))。雲のシートと霧は、不透明度0.55と0.7で.transparentのブレンドを持つUnlitMaterialです。229
影についての帰結は、このリストから導かれます。加算の光は明るくすることしかできません。Glow.metalの言葉では「black adds nothing」(黒は何も足さない)です。66 プログラムのブレンドモードが挙げるケースがaddとalphaだけで、unlitのマテリアルが透明度でブレンドする以上、このエンジンで影を描く方法は2つに1つです。背後にあるものの上に暗い色をアルファブレンドする方法で、雲のシートがすでにしていることです。あるいはアートに焼き込む方法で、壁の影がしていることです。782274 影の色で暗くする乗算のブレンドはありません。したがって動く影はアルファのシートであり、固定された影はアトラスに属します。
どちらもスマートフォン上でのコストは測っていません。構造編の記事は、その2つの新しいメッシュのGPUでのコストがプロファイルされていないと記しており、その後加わった24の加算のプール、雲のシート、霧もプロファイルされていません。2312 ブリーフは雨のスプライト、しぶき、雪、雲のための2つ目のアルファの強さを加えます。それらのコストも測っていません。項目4は雨についてそう述べ、項目5と6の雪、曇り、雲の新しい速さもプロファイルされていません。
時計と、それが跳ぶとき
ステージは眠るタスクで60秒ごとに時計を読み直します。19 SwiftUIには、時間とともに変わるビューのための文書化された代替があります。TimelineView、「A view that updates according to a schedule that you provide」(指定したスケジュールに従って更新されるビュー)で、スケジュールeveryMinuteは「A schedule for updating a timeline view at the start of every minute」(毎分の始めにタイムラインビューを更新するスケジュール)と説明されています。どちらもiOS 15.0から使えます。8182 私の読みでは、ステージのタスクが時計が跳んだこと(真夜中を越えた、夏時間に入った、別のゾーンに入った)を知るのは、次に目覚めたとき、最大1分後です。時刻が跳ぶときは、システムがそれを伝えます。
UIApplication.significantTimeChangeNotificationは、Appleの言葉では「when, for example, there’s a change to a new day (midnight), a carrier time update, or a change to, or from, daylight savings time.」(たとえば新しい日への変化(真夜中)、通信事業者による時刻の更新、夏時間への、または夏時間からの変化があったとき)に送られます。そのページはiOS、iPadOS、Mac Catalyst、tvOS、visionOSを、バージョンなしで挙げています。8326 NSSystemTimeZoneDidChangeは「A notification posted when the time zone changes」(タイムゾーンが変わったときに送られる通知)で、iOS 2.0から使えます。84 EnvironmentValues.timeZoneは「The current time zone that views should use when handling dates」(ビューが日付を扱うときに使うべき現在のタイムゾーン)で、iOS 13.0からあり、ビューの木にゾーンを運ぶためのSwiftUIの方法です。85
このシリーズの生きている町の記事は、部屋ごとの時計の契約を定めています。どの部屋もUTCのサーバー時刻で動き、それを部屋自身のゾーンで読み、サーバーはwelcomeと静かな広場の応答で、その両方をzoneとclockとして送ります。そうすれば部屋のなかの全員が、スマートフォンの時計が何と言おうと同じ時間帯を見ます。43 広場が開いているあいだ、光はスマートフォンの時計ではなくその時計に従わなければなりません。そして上の通知が扱うのはスマートフォンの暦であって、部屋の暦ではありません。Appleのページは、1つ目が送られるときとしてデバイス上の新しい日を挙げていますが、別のゾーンの真夜中については何も言っていません。ブリーフの項目1が、その2つをどう組み合わせるかを述べます。10月5日の時点では、部屋の時計も、時刻の跳びのオブザーバーも、アプリにはありませんでした。第10節は、その後変わったことから始めます。983
Reduce Motion
accessibilityReduceMotionは「Whether the system preference for Reduce Motion is enabled」(Reduce Motionのシステム設定が有効かどうか)を表す環境値で、iOS 13.0から使えます。ページの説明は率直です。「If this property’s value is true, UI should avoid large animations, especially those that simulate the third dimension.」(このプロパティの値がtrueなら、UIは大きなアニメーション、特に3次元を模したものを避けるべきだ)86 KiradexはそれをFigurePreview.swiftで読み、世界のコードのほかの場所では読んでいません。9 すべてが動きである空気は、今日それを読んでいません。
現実の天気と閃光
Appleはプレイヤーの現実の天気のためのフレームワークを提供しています。WeatherKitは「Deliver weather conditions and alerts to your users」(ユーザーに気象状況と警報を届ける)と説明されており、iOS 16.0から使えます。87 第10節はそれを拒み、その理由をそこで述べます。
閃光には公表されたしきい値があります。WCAG 2.2の達成基準2.3.1「Three Flashes or Below Threshold」(3回の閃光、またはしきい値以下)、レベルAの基準についてのW3CのUnderstandingのページは、ウェブページが「do not contain anything that flashes more than three times in any one second period, or the flash is below the general flash and red flash thresholds」(どの1秒間にも3回より多く閃光を放つものを含まないか、閃光が一般閃光と赤色閃光のしきい値を下回る)と述べ、理由を挙げています。「Flashing content can cause migraines, dizziness, nausea, and seizures.」(閃光を放つコンテンツは片頭痛、めまい、吐き気、発作を引き起こすことがある)46 Kiradexはウェブページではなくアプリであり、私はこの基準を最も近い公表された基準として使っているのであって、法的に適用されると主張しているのではありません。
10. ブリーフ:Kiradexが作るものと、通るべきチェック
著者による統合。 以下は私の提案で、第1〜9節から導き、2026年10月5日16:51から18:19に、コミットcf3beb1eから66c116b0の時点で、ツリーが編集されている最中に読んだアプリとの差分として書いています。各注が依拠する読み取りを名指ししており、読んだもののなかにはDaylight.swift、Motion.swift、Air.swift、Glow.metal、PlazaStage.swift、PlazaRig.swift、PlazaClient.swift、HallView.swift、CollectorComposer.swift、フォージのair.py、town.py、buildings.py、interiors.py、10月3日のtown.json、そして人物のシートとそのcharacters.jsonがあります。1297388 どのポケモン作品からも名前を付けず、何も描きません。そのパレット、スプライト、天気の名前、音はひとつも使いません。仕組みを借りるところでは、第8節の規則がどこからかを述べ、見た目はフォージのものです。オマージュの記事の決定は変わりません。Kiradexは独自の4つの時間帯と独自の時刻を保ちます。10 どれもまだ作られておらず、どの数値もiPhoneで測ったものではありません。Kiradexの数値はどれもMacでソースから読んだか、書き出した画像から計算したもので、デバイス上のコストは全体を通して未測定であり、チェックはビルドがそれを測れるように書いています。チェックが名指しする型、メソッド、ファイル、起動引数はどれも、今日存在してここでシンボルを、注で行を引用しているか、項目のなかで提案する追加として挙げているかのどちらかです。チェック2〜8、10、11は、ドシエのものを私が改訂したものです。最初に書かれたままでは、アプリ自身のプロセスにしかできないことをUIテストに求めたり、アプリの実行中に起動引数を変えたり、値を運ばない場所から値を読んだり、アプリにないリストに頼ったりするものがありました。UIテストは独自のプロセスで動き、アプリをアクセシビリティの値、ラベル、スクリーンショットを通して見ます。-plazaHourは起動引数から読まれるので、起動のあいだは固定されます。そしてステージがテストに与える唯一の値、アクセシビリティの値は、プレイヤーの最後の一歩か、-airProbeのもとでは空気のレポートを運びます。UIテストはそれを読みます。ステージ自身のコメントによれば「since nothing else the simulator logs reaches them」(シミュレーターが記録するほかのものは何もそこへ届かないから)です。192168 改訂した各チェックは、何を必要とするかを述べています。
アプリは10月5日から動いています。 2026年10月15日23:53に、リポジトリのmainが名指しするコミットfc9d4876(その日の17:45にコミット)から読み直しました。gitを実行せずにリポジトリ自身のオブジェクトから各ファイルを取り出し、作業ツリーのそれぞれのコピーも同じバイトでした。サーバーは今、すべてのwelcomeでzoneとclockを送ります。世界全体で1つのゾーンで、設定しなければUTCです。そしてPlazaClientがそれを保ち、項目1が提案するとおり、サーバーのミリ秒をスマートフォンの稼働時間と組にして、部屋の時刻をroomDateとして与えます。89 光はまだそれを読んでいません。PlazaStageは今も1分ごとにスマートフォンから読み直すclockを保ち、そこから1日を取っています。静かな広場は今もどの部屋にも参加しません。そして作業ツリーのSwiftを検索しても、時刻の跳びのオブザーバーは見つかりません。拒否リストが今は存在し、scripts/forge/protected_names.txtで、server/tests/test_names.pyがそれを世界のエリア名、プリセットの台詞、町の人のハンドルに照らして読みます。89 以下はすべて10月5日の読み取りに対して書いたもので、その「今日」はその日のことです。項目1とチェック2は今ならクライアントの部屋の時計から、項目10とチェック11はそのリストから始めることになります。
1. 1日の時計:時刻を保ち、光をランプにし、部屋の時計を読む
- 時刻は変えない。 6時から9時が朝、9時から17時が昼、17時から20時が夕方、それ以外が夜です(第8節「1日の区分」)。1021
- 時計から計算するランプ。 新しい
Daylight.light(at:calendar:)は、Daylight.now(_:calendar:)がすでにそうしているように、日付と、既定値がCalendar.currentの暦を受け取り、各境界のあとの最初の30分にわたって、前の時間帯の色合いから新しい色合いへ線形に補間した色合いに、季節の色味を掛けたものを返します。ステージはすでに毎分照らし直しているので、ランプは30段階です。アトラスの平均ルマでは、夕方の変化は0.077の1段階の代わりに0.0026の30段階に、夜の変化は0.108の1段階の代わりに0.0036の30段階になります。11 今日最大のカット0.168である朝の変化は、最大0.0056の30段階に、昼の0.017は最大0.0006の段階になります。4 - ランプにアニメーションも新しいタイマーも要らない。 1日の光は時刻の純粋な関数なので、同じ時計を読む2台のスマートフォンは同じ光を見せ、17:12に目覚めたスマートフォンは、ランプを見ていなくても17:12の光を見せます。クリスタルのカットが残るのは、テストが時間帯を直接見るために使う強制された
-plazaHourのときだけで、そのもとではrelight()は今日のDaylight.light(phase:season:)を呼び続けます(第8節「変化」)。2168 天気の1秒のフェード(項目4)が唯一アニメーションする変化で、独自のタイマーではなく、リグの既存のフレームごとの更新に乗ります。 - 部屋の時計。 次の項目で提案する小さな型
LightClockが、光が読む唯一の時計で、広場では生きている町の記事の契約が定めるとおり部屋の時刻で動きます。UTCのサーバー時刻を部屋自身のゾーンで読み、その両方をwelcomeと静かな広場の応答でzoneとclockとして送るものです。静かな広場の応答は、その記事がマルチプレイが制限されたプレイヤー、つまりWebSocketを開かないプレイヤーに与える唯一のリクエストです。2つのうち届いたほうが、それをLightClockに渡します。welcomeではPlazaClientが、応答では静かな広場のリクエストが渡します。時計は、サーバーのスタンプを、それが届いた瞬間のスマートフォンの単調な稼働時間と組にして保つので、そのnowはサーバー時刻にそれ以後の稼働時間を足したものを部屋の暦で表したものになります。壁時計が何時間もずれているスマートフォンも、部屋のほかのどのスマートフォンとも同じ光を見せ、Daylight.light(at:calendar:)とWeather.today(zone:date:)(項目3)は時計の暦とゾーンを受け取ります。スマートフォン自身の壁時計とゾーンが読まれるのは、広場の最初のwelcomeか静かな応答が届く前と、広場の外、つまり部屋やホールだけです。そこでは生きている町の記事がコレクターを自分の時計のまま置いています(項目8が、その入口でそれが何を意味するかを述べます)。LightClockは次の応答が届くまで最後の応答のゾーンとスタンプを保ち、その状態はどれで動いているかを名指しします。welcomeによる部屋の時計、静かな応答による部屋の時計、またはスマートフォンの時計です。10月5日の時点では、サーバーのwelcomeはゾーンも時計も運ばず、PlazaClientのハンドラーもどちらも読んでいませんでした(その後変わったことは、この節の冒頭が述べています)。静かな広場の応答は、その記事の提案です。応答がそれらを運ぶまで、LightClockはスマートフォンの時計で動き、状態でそう述べます。432176 - 1分遅れではなく、境界で変える。 新しい
Kiradex/World/LightClock.swiftにあるLightClockは、時刻の供給源(単調な稼働時間と壁時計、どちらも差し替え可能)、NotificationCenter、そしてステージの照らし直しを与えられます。その暦から、光が変わらなければならない次の瞬間、つまり次の時間帯の境界と、項目1のその境界の30分のランプの終わり、そして項目3の、そのゾーンでの次の真夜中を計算し、それぞれについて明示的に目覚めを予約します。ランプに必要な1分に1回の目覚めとは別です。目覚めは、読んだ時刻で照らし直しを呼びます。さらに自分のセンターでUIApplication.significantTimeChangeNotificationとNSSystemTimeZoneDidChangeを監視し、どちらでも照らし直します。Appleのページが名指しするもの、つまりスマートフォン自身の時計での新しい日、通信事業者による時刻の更新、夏時間への、または夏時間からの変化、そしてスマートフォンのゾーンの変化のためです。それらが扱うのはスマートフォンの暦で、ページは1つ目が別のゾーンの真夜中に送られるとは言っていないので、部屋の境界がそれに任されることは決してありません。PlazaStageは、自分のclockの状態と、それを毎分読み直す眠るタスクの代わりに、システムの時刻の供給源とNotificationCenter.defaultで作った1つを持ちます。そうすれば、部屋のゾーンでの真夜中、時間帯の境界、夏時間の変化、ゾーンの変化が最大60秒待つことはありません。時計、センター、時刻の供給源はパラメーターなので、テストがそれらを動かせます。この設計は私のものです。838419 - 強制した時刻は起動引数のまま。
Daylight.forcedHourはプロセスの起動引数から-plazaHourを読むので、実行全体を通して保たれ、アプリの実行中に変えることはできません。以下のどのチェックもそれを求めません。21 - コスト。 地面、周囲、オブジェクト、各歩く人に、今日と同じく1分に1回マテリアルを割り当てます。これはプロファイルされていません。ランプは、2色のブレンドを計算する以上の仕事を加えません。20
提案と今日の比較。各分の光のもとでのアトラスの平均ルマを、出荷されたtown.pngとDaylight.swiftの色合いからfigures/make_figures.pyで計算したもの。Macで読んだもので、スマートフォンでキャプチャしたものではありません。
受け入れチェック1、ランプ。 Daylight.light(at:calendar:)の単体テストで、固定したゾーンの暦を与え、16:59、17:00、17:15、17:29、17:30、そして20:00から20:30までの毎分を調べます。ルマはサンプルした時刻を通じて単調であること、1分離れた任意の2つのサンプルのあいだ(16:59と17:00、17:29と17:30、そして20:00から20:30の各分)で、アトラスの平均について0.004を超える段差がないこと(スクリプトの値は0.0036。テストはアプリのバンドルからtown.pngの不透明ピクセルの平均を取ります)、そして:30以降は今日の色合いと等しいことを確かめます。1211 06:00から06:30の同じテストは0.006の上限を使います。朝のランプは1分に最大0.0056進むからです。4
受け入れチェック2、部屋の時計と時刻の跳び。 プロセス内で、新しいKiradexTests/LightClockTests.swiftで行います。UIテストはアプリのなかで通知を送れず、スマートフォンの時計を設定できず、-plazaHourはアプリの実行中に変えられないからです。各テストは、独自のNotificationCenter、自分で制御する時刻の供給源(手で進める稼働時間と壁時計)、そして呼び出しを記録する照らし直しでLightClockを作り、本物のタイマーは使いません。テストが自分で稼働時間を進め、その瞬間までに予約されたものを発火するよう時計に求めます。(a) ずれたスマートフォン:部屋のゾーンでclockが20:35:00のwelcomeを、供給源の稼働時間でスタンプして時計に与え、壁時計は3時間ずらしておきます。照らし直しは部屋の暦で20:35を受けて呼ばれ、Daylight.now(_:calendar:)はそれをnightと読み、Daylight.light(at:calendar:)は夜の光を返します。項目1のランプは20:30に終わっているからです(ランプのなかの時刻、たとえば20:05なら、夕方の光から夜の光へ6分の1進んだ光になり、正しいビルドでもそれを夜の光と一致させることはできません)。そして壁時計をもう一度動かしても何も変わりません。(b) 2つのゾーン:スマートフォンの暦を部屋より10時間進んだゾーンに置き、どちらも固定オフセットにして、夏時間の変化がどちらも動かさないようにします。部屋のゾーンで20:35にあたるサーバーの瞬間は、スマートフォンでは翌日の06:35で、Daylight.Phase(hour:)はそれを朝、項目1のランプを過ぎたものと読みます。一方、部屋の20:35は夜で、夕方のランプを過ぎています。照らし直しは、スマートフォンの光、つまり朝の色合いに季節の色味を掛けたもの(夏で0.961)ではなく、部屋の光、つまり夜の色合いに季節の色味を掛けたもの(夏でルマ0.593)を受けます。そしてWeather.today(zone:date:)は部屋のゾーンと部屋の日付、スマートフォンの日付の前日で問い合わされます。スマートフォンの時計を読むビルドは、光でも日付でも失敗します。(c) 境界、通知をまったく送らずに:部屋の時計で19:59:30から、テストは稼働時間を60秒進め、予約された目覚めが、その分の終わりではなく部屋の暦の20:00:00に1回発火したことをアサートします。23:59:30から60秒進め、部屋のゾーンで翌日の00:00:00に目覚めがあり、その時刻のWeather.today(zone:date:)が新しい日の抽選であることをアサートします。(d) オブザーバー、配線だけとして:部屋の時計を与えずに、テストのセンターにsignificantTimeChangeNotificationを送ると壁時計の時刻で照らし直し、NSSystemTimeZoneDidChangeでも同じです。テストがアサートするのは呼び出しであって、システムがそれを送るということではありません。それはどのテストにもできません。(e) 通知も、期限の来た目覚めも、welcomeもなければ、照らし直しは呼ばれません。(f) 静かな広場、プロセス内で:welcomeの代わりに静かな広場の応答を、同じ20:35:00と3時間ずれた壁時計で時計に与えると、照らし直しは(a)と同じく部屋の暦の20:35と夜の光を受け、その状態は静かな応答を名指しします。そしてアプリでは、UIテストを、生きている町の記事の最初の安全チェックがスタブするようにマルチプレイの制限をスタブしてオンにし、-airProbeを付け、静かな広場のリクエストに固定のzoneとシミュレーターから3時間ずれたclockで答えるローカルのテストサーバーとともに起動します。サーバーにはアプリの既存の-plazaServer引数(PlazaClient.endpointで、そのコメントはローカルのサーバー用に-plazaServer ws://127.0.0.1:8300/v1/plazaを挙げています)を通じて届きます。静かなリクエストはWebSocketを開かないので、そのURLをHTTPの形、wsをhttpに、wssをhttpsにし、静かなルート自身のパスを付けて受け取ります。この対応づけは私の提案です。ステージの値はLightClockの状態をプローブのレポートに加えて静かな応答を名指しし、テストは、その記事のチェックと同じく、WebSocketが開かれないことをアサートします。これにはサーバーのフィクスチャとプローブの行が必要で、どちらも私の提案です。ファイル:LightClock.swift(新規)、LightClockを持つPlazaStage.swift、welcomeのハンドラーがzoneとclockをそれに渡すことになるPlazaClient.swift(サーバーは10月5日にはそれを送っていませんでした)、答えで同じことをする静かな広場のリクエスト、そして新しいテストファイルです。7643 テストに見えないのは、PlazaStageがNotificationCenter.defaultと本物の時刻の供給源を渡すことで、それはソースで読む2行です。最初に書かれたままでは、チェックは-plazaHourを変えたあとでUIテストに通知を送らせていましたが、それはどのUIテストにもできません。スマートフォンの壁時計の上に作り、手で送った真夜中の通知を部屋のものの代わりにする時計も、役に立ちません。生きている町の記事の契約が前者を退け、Appleのページは後者を約束していないからです。だからこそチェックは、サーバーのスタンプ、明示的に予約した境界、そして2つのゾーンの場合に依拠しています。1221194383
2. 人物は色を保つ
- 持ち上げ。 歩く人は、白へ半分持ち上げた光、チャンネルごとに
(1 + tint) / 2を受けます。夜には(0.75, 0.79, 0.95)、ルマ0.796で、場所の0.593に対して1.34倍の明るさです。夕方は0.913、朝は0.980です。114 - どこに置くか。 新しい
Kiradex/World/PlaceLight.swiftにある新しい値型PlaceLightが、1日の光(項目1から)と天気の係数(項目4)を持ち、2つの色を与えます。placeは1日の光に係数を掛けたもの、walkersは1日の光を白へ半分持ち上げたもので、天気の係数を受けません。PlazaRigは自分の1つのlightの代わりにこれを1つ持ちます。場所のマテリアルはplaceを受けます。build(tiles:collector:arrival:)が最初に作る地面、周囲、オブジェクトで、light(_:lampsOn:)のなかと波紋のフレームの更新のなか、そしてshowDoor(at:sheet:column:)のドアの描画です。歩く人はwalkersを受けます。add(other:figure:tile:facing:)での到着のマテリアルと、animate(_:)での各フレームのマテリアルです。20 純粋な値なので、単体テストがRealityKitなしで動かせます。この型は私の提案です。 - なぜ半分か。 第8節の規則は「手を付けない」と言っています。半分を提案するのは、Kiradexの歩く人がハードウェアのパレットの上ではなく、加算のプールとビネットのあるブレンドされた場面に立っているからで、まったく色合いをかけない人物は、私の読みでは、夜に貼り付けたように見えるでしょう。これはデバイスの上で下すべき判断で、下のチェックはそれを下す余地を残しています。1219
- 持っているカード。 すでに独自の光、カードのためだけの
DirectionalLightを持っています。変更なしです。20 - プローブ上のコレクターの枠、人物、描画。
-airProbeのもとでは、ステージの値はさらに、プレイヤーのスプライトの四隅にPlazaRig.viewPoint(of:in:displayScale:)を適用した、ビューのポイントでのコレクターの枠と、コレクターの人物のマスクを運びます。マスクは32×40のセルのピクセルのうち、立っているコレクターが見せるすべての描画、つまり息づかいの待機、まばたき、PlazaRig.animate(_:)が選ぶ待機のエモート(チック、見回し、肩をすくめる、考える、うたた寝)のどれでも不透明なものです。人物の合成されたインデックスの面、CollectorComposer.indexPlane(for:)から取り、ピクセルは透明でも消しゴムでもないときに不透明とし、各行に沿ったランとして書きます。どちらも、空気が準備されたあとでステージの.taskが今日そこに書くレポートに加えます。マニフェストの既定の人物が下を向いているとき、マスクはセルの1,280ピクセルのうち290です。20198830 値はさらに、コレクターのマテリアルが見せるフレーム、歩く人のshown(向きの行にシートの43列を掛け、描画の列を足したもの。したがって0は下向きのidle_a)を、変わるたびに書き直して運び、完全にビューに入っている明かりのセルのビューでの枠を、town.jsonでのセルごとに運びます。デバッグ引数-plazaHoldStill(私の命名)は、-plazaHourと同じく起動引数から読まれて起動のあいだ固定され、立っているコレクターをidle_aに保ちます。息づかいもまばたきも待機のエモートもなしです。animate(_:)はそうでなければそれらを6〜14秒おきにランダムに始め、プレイヤーの最初のエモートは7秒、最初のまばたきは2.5秒です。20 同じ引数のもとで、Air.set(phase:season:)は歩く人の上を動くレイヤー、つまり雲、霧(朝だけ、2.41)、葉、蛍、煙突の煙を描かずにおきます。どれも歩く人の1〜1.5より上の、深さ2.4〜2.45に描かれています。街灯のプールは夜の光なので残ります。プローブの値は、どれかのプールの面がコレクターの枠と重なるかどうかも述べ、-airProbeのもとでステージはチェック3のパイプラインの見本を描いてその枠を報告します。2230 これらはすべて、チェック3のために提案する追加です。
Daylight.swiftのKiradexの色合いと、提案する歩く人の光。見本はfigures/make_figures.pyで描画。これらはアプリ自身の値で、Macでソースから読んだものです。ルマはそこで計算したもので、iPhoneで測ったものではありません。
受け入れチェック3、人物。 iPhone 18 Pro Maxのシミュレーターで2つのキャプチャを取り、それぞれを別の起動にします。1つは-plazaHour 12、もう1つは-plazaHour 22で、どちらも-plazaWeather clear(項目3)を付けてその日の抽選が光を変えないようにし、-plazaHoldStill(項目2)を付けて両方が同じ描画を見せ、その上に何も描かれないようにし、-airProbeを付け、UIテストのsaveで保存します。ステージの値はコレクターの枠、人物のマスク、描画、そして明かりのセルの枠(項目2で提案する追加)を運ぶので、テストはどのピクセルがコレクターで、どれが明かりのついた窓かを知っています。各キャプチャの直前と直後に描画を読み、4回ともフレーム0、つまり下向きのidle_aであることを求めます。4回の読み取りのどれかがフレーム0でなければ保持が破れており、チェックは失敗します。さらに夜のキャプチャで、コレクターの枠の上にプールがないとプローブが報告することも求めます。フィクスチャは、どのキャプチャを判定するよりも前に凍結します。4つの起動引数のセット、見本の画像、色合い、位置、キャプチャを作る対象の町の書き出し(10月3日のtown.jsonをハッシュで指定し、そのアトラスとともに)、切り抜き(プローブからのコレクターのマスクで、その各ピクセルを枠のなかの対応する升目の中心でサンプルする。地面はビューからコレクターの枠とステータス行を除いたもの。明かりのピクセルは下記)、パイプライン、そして下記の許容値はテストのなかの定数であり、そのどれを変えることもチェックを変えることで、公開の場で行い、決してキャプチャから取った読みにはしません。12206819
ルマはキャプチャの保存された色の値で取ります。RealityKitが色合いと画像をどうその値に変えるかは、この記事のために保存したAppleのページには書かれていません。UnlitMaterialのページはinit(applyPostProcessToneMap:)、「Creates an UnlitMaterial with the given tone mapping setting」(指定したトーンマッピングの設定でUnlitMaterialを作る)を挙げていますが、SpriteSheet.material(light:)が作る素のUnlitMaterial()が何をするかも、色合いと.colorのセマンティックで作ったテクスチャがそれぞれどう変換されるかも述べていません。7172 そこで帯はパイプラインごとに、すべてどのキャプチャよりも前に、被覆の計算のセクションEから設定します。30
- 較正。 明かりのついた窓と壁付け灯は色合いをかけずに描かれるので、夜のキャプチャは自分自身の固定された基準を運びます。以下の各パイプラインで、色合いをかけない色は保存されたとおりに出てきます。24の明かりのセルのうち7つは、チェック8の紙の上の再生で到着時のビューに完全に入り、明かりのピクセルは294で、そのすべてがどのプールの面からも外れ、ビューの中心から450ポイント以内、つまりビネットの900ポイントの半径のうち透明な内側の半分にあります。それぞれを、走査線の行が覆わない升目の点でサンプルし、それらのピクセルにわたって、アトラスの保存された値からのチャンネルごとの差の最大値の中央値が0.02以下、255段階で5段階以下でなければなりません。そうでなければ、トーンマップか色の変換が経路にあり、以下のどのパイプラインも当てはまりません。チェックはそこで、帯を読む前に失敗し、窓が見せるものの帯を、これまでと同じくアトラスから計算して、ペアをもう一度判定する前にテストに書き込みます。201930
- 色合いを保存されたとおりに掛ける、または色合いと画像の両方をリニアで扱う。 地面の夜と昼の比は、保存されたとおりでは0.588、画像と色合いをsRGBからデコードして掛け合わせ、エンコードし直すと0.562になります。チャンネルごと、赤、緑、青では(0.500, 0.580, 0.900)と(0.469, 0.554, 0.892)です。帯は0.46〜0.69です。
idle_aで保ったコレクターのマスクは、持ち上げのもとで0.788と0.764、夜の色合いを丸ごと受けると0.575と0.531になり、0.67に達しなければなりません。これは2つの正しい値の低いほうと、2つの壊れた値の高いほうの中間です。 - 色合いの数値をリニアとして扱う。 画像をデコードし、色合いをデコードしない場合、地面は0.774、チャンネルごとに(0.719, 0.772, 0.951)になり、帯は0.67〜0.87です。マスクは持ち上げのもとで0.889、色合いを丸ごと受けると0.756になり、その中間の0.82に達しなければなりません。
-
どれなのか。 パイプラインを名指しするのは地面ではなく見本です。
-airProbeのもとで、ステージは保存値51と102(255のうち)の2つの灰色の固定画像を、すべてのチャンネルに0.25の固定の色合いのもとで描きます。これはSpriteSheet.material(light:)に直接与え、決してPlaceLightや1日の光を通しません。プールの上の四角形に、ビューの固定した位置に描き、Pro Maxの440×956ポイントのx 24〜56、y 462〜478に、16ポイントの2つのパッチを横に並べます。左端の高さの中央で、最も遠い隅は中心から197ポイントなので、ビネットの透明な半分のなかにあります。プローブはその枠を報告し、地面の切り抜きはそれを除外し、位置はほかのフィクスチャとともに凍結します。プローブの枠から、テストはそれがコレクターの枠とも、7つの基準の窓のどれとも重ならないことをアサートします。到着時の計算では重なりは0で、最も近い窓から267ポイント離れています。窓と同じく走査線の行を外してサンプルし、その保存された値は両方の時刻で同じです。保存されたとおりに掛けると13と26、画像と色合いをリニアにすると6と20、色合いの数値をリニアとして扱うと22と51になり、どちらのパッチでも2つのパイプラインが6段階より近づくことはありません。各キャプチャの見本は、1つのパイプラインの2つの値から2段階以内になければならず、すべてのキャプチャで同じパイプラインでなければなりません。そしてそのパイプラインの帯としきい値が適用されます。パイプラインを名指しするのは地面ではなく見本なので、たまたま別のパイプラインの帯に合う地面がそのもとで通ることはありません。テストは名指ししたパイプラインを、それを名指ししたSDKとともに記録もし、あとの実行が別のものを名指しすれば、記録を公開の場で変えるまで失敗します。見本とその画像は私の提案です。30 -
合格の条件。 較正が成り立つこと。地面の夜と昼の比が、名指ししたパイプラインの帯のなかにあること。見本がすべてのキャプチャで1つのパイプライン、テストが記録したものを名指しすること。マスクの比がそのパイプラインのしきい値に達し、地面の比より上にあること(これが項目2の持ち上げの表れです)。地面のチャンネルの比が下の2つのアサーションを通ること。両方の対照が失敗すること。描画の4回の読み取りがすべてフレーム0であること。そして夜のキャプチャが、コレクターの上にプールがないと報告することです。それ以外はすべてチェックの失敗です。
- 帯。 各帯は、そのパイプラインの計算した比の前後0.1を丸めたもので、それは計算から設定した目標であって、測定ではありません。計算した比はアトラスだけのものです。キャプチャには街灯のプールも入っており、それは夜を明るくすることしかできず、0.1はそのために残した余地で、最初のキャプチャの前に選んだものです。走査線とビネットは両方の時刻で同じに描かれるので、私の読みでは、2つのキャプチャを同じように縮めます。1291922
- なぜ同じ描画か。 しきい値が成り立つのは、両方のキャプチャで同じ描画のとき、そしてそのときだけです。保存されたとおりに掛けると、持ち上げの最も小さいチャンネルは0.75なので、そのもとでどの色も昼のルマの0.75未満しか保たないことはなく、同じ描画ならマスクの平均もそうなりえません。2つの描画にまたがるとそうなりえます。マスクが固定するのはどのピクセルをサンプルするかであって、それが持つ色ではないからです。マスクの昼のルマは
doze_bの0.2989からthinkの0.3161まであり、昼はthinkで、夜はdoze_bでキャプチャした正しいビルドは0.746になり、11の描画の121の順序付きペアにわたって、歩く人に色合いをかけるビルドは0.610に達します。だからこそ保持するのです。リニアでは、sRGBの曲線のまっすぐな足もとが最も暗い色に0.75未満しか保たせないので、各しきい値はその下限ではなく計算した平均になっています。3011 - 空気がすること。 空気が描くものはすべて、どの歩く人よりも上にあります。雲は深さ2.4、霧(朝だけ)は2.41、葉、蛍、煙は2.45、プールは2.5で、歩く人の1〜1.5に対しています。そして雲は夜以外のすべての時間帯に表示されます。その最も暗い陰は下にあるものに0.763を掛け、昼のマスクの上では、歩く人に色合いをかけるビルドを、陰がエンコードされた値を暗くするなら、保存されたとおりで0.754、リニアで0.696、色合いの数値をリニアとして扱うと0.991に持ち上げます。エンコードの前にリニアの光で暗くするなら、リニアで0.608、色合いの数値をリニアとして扱うと0.865です。レンダラーがどちらをするかは、保存したページには書かれておらず、0.608の場合を除くすべての場合で、壊れたビルドがしきい値を通ってしまいます。2230
- なぜ保持か。 保持は空気をコレクターから遠ざけ、このチェックはそれなしでは成り立ちません。コレクターが陰から外れるまで撮り直すプローブのフラグでも役に立ちますが、雲は横に毎秒1.536ピクセル、上か下に0.576ピクセル流れます(どちらの軸でどちらへ向かうかはコードが決めていません。スプライトシートの測定した規約、つまりテクスチャの左上から数えるオフセットは、それら自身の手作りの四角形のためのもので、雲は生成された平面です)。そのため、コレクターの枠を横切る陰は、流れがそれを枠の幅である32ピクセル運ぶのにかかる21秒(20.8秒)のあいだ、その一部にとどまり、陰が広ければもっと長くとどまります。しかも画像は約半分が覆われています。一方、保持はどのキャプチャでもそれを解決します。私は保持を選びました。プールは遠ざけられません。それは試験している光そのものだからです。そしてプールは動きません。到着時、コレクターの32×40ピクセルの枠は最も近いプールの面から52ピクセル離れているので、プローブのプールのフラグはその計算の見張りであり、それが立てばチェックは撮り直さずに失敗します。22930
- なぜ枠全体ではないか。 コレクターの枠全体は切り抜きとして使えません。ほとんどが地面だからです。既定の人物は、最初の立っている描画で1,280ピクセルのうち408を覆い(体のシートだけで377、書き出しのすべての人物のシートを一度に重ねると581)、残りをアトラスの平均色として保存されたとおりに掛けると、正しいビルドの枠全体は0.638になります。マスクが達しなければならない0.67を下回り、地面よりわずか0.049上で、歩く人に色合いを丸ごとかけるビルドは0.584になります。30
- さらに2つのアサーション。 ペアが似ていることで通るのを防ぎます。地面の夜と昼の比をチャンネルごとに取ると、夜の色合い(0.5, 0.58, 0.9)が並べるとおり、青が緑より上、緑が赤より上の順に並ぶこと、そしてそれぞれが、名指ししたパイプラインの計算したチャンネルから0.15以内にあること(最初のものでは、どちらのセットでもよい)です。
- 対照。
-plazaHour 22で、提案するデバッグ引数-plazaNoTintを付けた3つ目の起動は、-plazaHourと同じく起動のあいだ固定され、そのもとでPlaceLight.placeはすべての時刻に1日の光を返します。これは帯に失敗しなければならず、その地面の比は1の近くに来ます。これは帯が色合いのない出力を退けることを示します。PlaceLightを無視するレンダラーは両方の時刻で同じ画像を出し、このチェックに対しては、地面の比が約1なのでどちらの帯にも失敗し、平らなチャンネルの比が順序に失敗します。2つ目の対照、-plazaHour 22で別の提案するデバッグ引数-plazaLiftAgain(私の命名)を付けた4つ目の起動では、SpriteSheet.material(light:)が与えられたすべての色合いをもう一度白へ半分持ち上げ、これも失敗しなければなりません。これはPlaceLightは正しい値を与えるのに、マテリアルがそうしないビルドです。保存されたとおりに掛けると、地面は昼の0.794、チャンネルは(0.750, 0.790, 0.950)、マスクは0.894になり、白い窓は変わらず、色合いのない対照は1のままです。地面だけなら、0.794で赤の比0.750は、色合いの数値をリニアとして扱う場合の帯0.67〜0.87のなかにあり、地面について行うすべてのアサーションを通ってしまいます。だからこそ見本が決めるのです。見本はそれを失敗させます。その色合いは0.625に達し、32と64と読まれ、最も近いパイプラインの値から13段階離れています。30 - 帯は動かさない。 最初の本物のペアがそのパイプラインの帯の外に落ちたら、チェックは失敗し、原因をレンダラーか計算のなかに探します。それに合わせて帯を動かすことはしません。最初のペアから帯を取れば、色合いを無効にしたレンダラーを通してしまいます。だからこそフィクスチャと帯は前もって固定され、最初のペアはすでに書かれた帯のどれかを選ぶだけなのです。
- 単体テスト。
PlaceLightの単体テストが正確な部分を加えます。夜の色合いで、夏の晴れた天気のとき、walkersは(0.75, 0.79, 0.95)で、placeは色合いそのものです。11 - 最初に書かれたまま。 チェックは夜のキャプチャを1つ持ち、地面が0.55〜0.65のあいだに、コレクターの平均ルマが昼のキャプチャの少なくとも0.75であることを求め、切り抜きも、フィクスチャも、描画も、パイプラインも、対照も名指ししていませんでした。上のすべては私の改訂です。12
3. 天気:5つの状態、1日1回の抽選
- 状態。
clear、overcast、rain、heavy rain、そして冬だけのsnowです。朝の霧、秋の葉、夜の蛍は今のままで、上に重なります。天気は屋外だけです。Airが空を見つけないところ(そのoutdoors)、つまり部屋とホールは雨粒も天気の係数も受けません。この選択は私のものです。1222 - 1日1回の抽選、ゾーンの全員に同じ。
Weather.today(zone:date:)は、ゾーンの識別子とそのゾーンでの日付"zone|yyyy-mm-dd"のSHA-256を取り、ダイジェストの最初の4バイトを1つの符号なしビッグエンディアンの数として読み、100で割った余りを取ります。その抽選の値を季節の表に累積的に照らします。状態を挙げた順に取り、各状態の重みを累計に足していき、累計が抽選の値を最初に超えた状態がその日の状態です。春なら、抽選の値0〜54が晴れ、55〜79が曇り、80〜99が雨です。11 表は私のものです。春は晴れ55、曇り25、雨20。夏は晴れ65、曇り20、雨10、大雨5。秋は晴れ45、曇り30、雨20、大雨5。冬は晴れ40、曇り30、雪30です。12 その形はStardewの季節の確率に従い(雨の多い春、雨が激しくなる乾いた夏、雨の降らない冬)、数値はKiradexのものです(第8節「天気の予定」)。18 - 1年分。 1つのゾーンで2027年について実行すると、抽選は次のようになります。春92日、晴れ53(58%)、曇り22(24%)、雨17(18%)。夏92日、晴れ61(66%)、雨13(14%)、曇り12(13%)、大雨6(7%)。秋91日、晴れ40(44%)、曇り30(33%)、雨17(19%)、大雨4(4%)。冬90日、晴れ36(40%)、曇り29(32%)、雪25(28%)。1年の82日の湿った日、つまり雨、大雨、雪の日のうち、ここでの湿った期間とは、3つをどう混ぜてもよい連続した湿った日の並びで、雨の日のあとに大雨の日が続けば2日の1つの期間です。湿った期間は65あり、1日のものが50、2日のものが13、3日のものが2で、最長は3日です。2つのゾーンは1月の30日のうち8日で一致します。各ゾーンは独自に抽選するからです。そして同じゾーンと日付は常に同じ状態を与えます。114 春の雨18%は、Stardewの基本確率18.3%に一致します。184
- 変化がステージに届くとき。 抽選の日付は部屋のゾーンで読むので、その日の状態はそのゾーンの真夜中に変わります。ステージは照らし直すたびにそれを読み、項目1の
LightClockは自分の暦から部屋の真夜中に目覚めを予約するので、新しい日の状態は最大1分遅れではなく時間どおりに届き、Appleのページがスマートフォン自身の日についてしか約束していないシステムの通知にも頼りません。現れたステージは、最初の照らし直しでその日の状態を読み、フェードなしで見せます。したがって項目4のフェードを見るのは、部屋の真夜中に広場を開いている人だけで、それはKiradexの夜のなかに来ます。832143 - 前もってわかる。 Stardewのテレビがそうするように、クエストボードは明日の天気をKiradex自身の言葉で1行に載せます。17
- ファイル。 状態、各状態の光の係数とステータスの言葉、抽選、ボードの行(
Weather.boardLine(zone:date:)、同じゾーンの翌日の状態を名指しする)、雲の速度(項目6)、強制した状態のための新しいKiradex/World/Weather.swift。雨、しぶき、雪、曇りのためのAir.swift(項目4)。rain.png、splash.png、snow.pngを8×8〜8×16のセルで描くフォージのair.py。relight()が状態を読んで係数をリグに、状態をAirに渡し、PlazaView.wordsが状態の言葉をステータス行に加えるPlazaStage.swift。そしてボードの行のためのQuestBoardView.swiftで、これは広場のビュー(PlazaView)とMeタブがシートとして表示します。129019Daylight.swiftは天気を受けません。その光は時刻だけの関数のままで、天気の係数はPlaceLightで適用します。ドシエは天気の係数をDaylightに、ボードの行をPlazaStage.swiftに置いていました。フェードは時刻の関数のなかには住めず、ボードは独自のビューなので、どちらの訂正も私のものです。 - テストのための強制した天気。 状態の名前を付けた
-plazaWeatherは、1回の起動のあいだその日の状態を強制します。起動引数から読まれ、-plazaHourと同じく起動のあいだ固定されます。以下のチェックがこれを使います。これは私の追加です。
提案:毎日の抽選の1年分。kiradex_proposals.txtのセクション6から、Macで計算したもの。
受け入れチェック4、抽選。 単体テストが、ゾーンAmerica/Los_Angelesで2027年の365日についてWeather.todayを計算し、measure_kiradex_proposals.pyのセクション6が出力するものと照合します。各季節の各状態の数、上で定義した65の湿った期間にある82の湿った日、最長3日、そしてEurope/Londonが一致する1月の30日のうちの8日です。1211 さらに、テストがデバイスのゾーンとしてどのゾーンを設定しても、同じゾーンと日付が同じ状態を与えることをアサートします。日付は名指ししたゾーンで読むからです。ボードの行は私のものです。同じテストが、Weather.boardLine(zone:date:)が同じゾーンの翌日についてWeather.todayが返す状態を名指しすること、そして5つの状態のステータスの言葉がそれぞれ異なり、どれも空でないことをアサートします。最初に書かれたままでは、チェックは1年を日ごとにスクリプトの出力と比べていましたが、スクリプトが出力するのは日ではなく数です。そしてサーバーのテストに、サーバーが行わない抽選を確かめさせていました。さらにドシエの湿った並び(そのセクション4.3)は1つの状態の並びを数えていたので、雨のあとの大雨は2つになり、67という数になっていましたが、スクリプトはもうそれを出力しません。
4. 雨
- 雨粒。 iPhone 18 Pro Maxのビューに15粒です。ビューはワールドの165×358ピクセルを見せます(キャラクター編の記事の数値で、ここでは測り直していません)。エメラルドの10,000平方ピクセルあたり2.60粒という密度を持ち越したものです。大雨は37粒です。1191
- 落下。 雨粒はフォージが描くKiradex独自の形の筋で、毎秒約868ピクセル、鉛直から26.6度で0.301秒(エメラルドの18フレーム)落ち、そのあと地面で0.117秒(その7フレーム)のしぶきになります。11 位置は整数のピクセルです(第8節「雨粒」)。毎秒120フレームでは1フレームに7.2ピクセルで、筋の長さが隙間を覆います。114
- 雨粒のありか。
AirにRainFieldを加えます。これはビューの大きさとその日の状態に対する雨粒の位置を持ち、フレームの時間で進めて整数のピクセルに丸める値です。Air.update(_:camera:view:)がそれを進め、雨粒ごとに1つのエンティティを置きます。そしてAir.set(phase:season:weather:reduceMotion:)が今日のset(phase:season:)を置き換えて、雨粒、雪片、曇りのシートをオンとオフにします。雨粒はAirのもので、ヘッダーの言葉ではAirのどれもその日の色合いを受けないので、夜の雨粒はフォージが描いたとおりに描かれます。それが夜になじむかどうかは、デバイスの上での判断です。Airは雨粒の数もレポートに保ち、-airProbeのもとでは、ステージは空気を準備する.taskのなかで、プレイヤーの最初の一歩まで、レポートを1回ではなく1秒に1回自分の値にコピーします。そこから先は、今日と同じくrig.onStepが一歩のトレースをそこに書きます。歩きのテストはそこでそれを読むからです。レポートを読むチェック5と10は、一歩も踏みません。これはすべて提案です。2219 - 光。 場所の光に13/16を掛けます(第8節「雨の光」)。アトラスの昼のルマは0.449から0.365へ、雨の夜は0.214になります。11 歩く人は項目2の持ち上げを保ち、天気の係数を受けません。明かりのセルとプールは変わりません。
- 1秒のフェードと、誰がそれを動かすか。 雨に入るときと出るとき、場所の光は1秒かけてフェードします(第8節「変化」)。12
PlaceLight(項目2)は、天気の係数、フェードしていく先の係数、変化からの時間を持ちます。フェード付きで新しい係数を告げられると、進められる時間の1.0秒にわたって、持っていた係数から新しい係数へ線形に動きます。すでに世界のティック(歩く人、カメラ、カード)を実行し、そのあと毎フレーム、ショーケースを回し、波紋を進め、空気を更新しているPlazaRig.update(_:)がそれを進め、placeが変わったフレームでは、照らし直しのたびにlight(_:lampsOn:)がするように3つの場所のマテリアルを割り当て、ドアが表示されているあいだはドアのものも割り当てます。ステージのrelight()は各状態の係数(晴れ1、曇り0.9、雨13/16、大雨0.75、雪1)をフェード付きで渡しますが、ステージの最初の照らし直しだけは例外で、すぐに設定します。ほかに光をアニメーションさせるものはなく、タイマーも加えません。2019 - 仮定。 持ち越した数値は60ヘルツを仮定しています。携帯機と異なるフレームレートは、1フレームあたりの進みを変えるだけで、速さは変えません。12
- コスト。 15〜37のスプライトのエンティティとそのしぶきで、プロファイルしていません。11 フェードのあいだ、リグは1秒間毎フレーム3つの場所のマテリアルを割り当て、ドアが表示されていればそのぶんも割り当てます。60ヘルツで180回、120ヘルツで360回(ドアありで240回と480回)で、照らし直しが1分に3回(ドアの表示中は4回)、水のあるところでは波紋が1秒に12回であるのと比べてです。これはコードから数えたもので、デバイス上のコストは測っていません。420
受け入れチェック5、雨。 2つの部分があります。アプリでは、Pro Maxのシミュレーターで-plazaHour 12、-plazaWeather rain、-airProbeを付けて起動したUIテストが、testTheChimneysSmokeがsmoke 18を待つように、ステージの値にある空気のレポートが15 ± 1の雨粒の数を示すのを待ちます。これには項目4で提案するレポートとその1秒に1回のコピーが必要で、テストは一歩も踏まないので、コピーが値を保ちます。6819 プロセス内では、単体テストが、Pro MaxのビューのRainFieldを毎秒120フレームで10秒ぶんのシミュレートした雨で進め、すべての雨粒の位置が整数で、数が15であることをアサートします。1日の光にあるPlaceLightを、フェード付きで雨を告げて進め、placeが1.0秒の印の1フレーム前にはまだ1日の光の13/16より上にあり、その1フレーム後以内に13/16にあることをアサートします。そしてwalkersが天気の係数のあるなしで同じであることをアサートします。配線、つまりPlazaRig.updateが自分のPlaceLightを進め、placeが変わったときにマテリアルを割り当てることは、ソースで読む数行です。最初に書かれたままでは、チェックは4つすべてをリグのログから読んでいましたが、そのログが届くのはMacのコンソールで、テストではありません。12
5. 曇り、雪、稲妻のない大雨
- 曇り。 雲のシートの不透明度は0.55から0.8に上がり、光は0.9の灰色を受けます。12 出荷された
cloud.pngでは、最も暗い陰は0.763から0.655へ、画像の平均は0.950から0.927へ、その灰色のもとでのアトラスの昼のルマは0.404になります。4 灰色は雨と同じくPlaceLightを通してフェードします。シートの不透明度はAir.set(phase:season:weather:reduceMotion:)がすぐに設定します。状態が変わるのは真夜中だけで、そのときシートは隠れているからです(Air.setは夜に雲を隠します)。22 - 雪。 冬だけで、フォージが描きます。葉の揺れを持つゆっくりした雪片で、
Airが葉と同じように保ち、地面は冬の色味を保ちます。雪は天気の係数を受けず、これは私の選択です。1222 - 大雨。 光はさらに0.75まで暗くなります。アトラスの昼のルマは0.337、大雨の夜は0.198です。124
RainFieldは37粒を持ちます。11 - 稲妻のフラッシュなし。 大雨は閃光を出しません。第2節で測ったエメラルドの嵐は、どの1秒にも多くて1本の稲妻しか持たず、W3Cの1秒に3回の閃光という上限を下回るので、正典は基準を通るでしょう。446 拒むのは通るかどうかの話ではありません。W3Cの言葉では、閃光を放つコンテンツは「can cause migraines, dizziness, nausea, and seizures」(片頭痛、めまい、吐き気、発作を引き起こすことがある)からで、私の前提は、子どもたちが長い時間この町を使うかもしれないということです。そう使われる世界に、それは要りません。4612
受け入れチェック6、閃光なし。 プロセス内で、単体テストが1日の光にあるPlaceLightを毎秒120フレームで10秒ぶんのシミュレートした時間で進め、2秒目にフェード付きで大雨を、6秒目に晴れを告げ、placeがアトラスの平均でのルマとして、1つのフレームから次のフレームへ0.02より大きく変わることが決してなく、1日の光の0.75に達して戻ることをアサートします。大雨へのフェードは昼の0.449を1秒かけて0.337にし、60ヘルツで1フレームに0.0019、120ヘルツで0.0009なので、上限は余裕を持って成り立ちます。カットなら0.112の段差になるでしょう。4 PlaceLightはReduce Motionの入力を受けないので、フェードは構造上、設定がオンでもオフでも同じです(項目9)。設定が何を変えるかは、チェック10がアサートします。Macから行うシミュレーターの画面収録でクロスチェックはできますが、収録がアプリの描くすべてのフレームを持つとは限らず、雨粒自身の動きもフレームの平均を動かすので、チェックは単体テストです。最初に書かれたままでは、チェックはすべてのフレームのキャプチャを求めていましたが、UIテストにはそれが取れません。12
6. 動く雲の影
- 速さ。 雲は毎秒1.64ピクセルではなく、固定の毎秒16ピクセル、1秒に1タイルで流れます。今日の歩き、毎秒60ピクセルの0.27で、アプリのティックの時計は、モーションの記事のブリーフが定めたとおりにこの歩きを与えます(1ティックに1ピクセル、1タイルに16ティック、毎秒60ティック)。固定した数値が提案で、第2節のチャートはそれをその歩きと並べています。エメラルドの霧の比0.25に近く、その雲の0.50より遅いのです(第8節「空気」)。その速さで、雲はPro Maxのビューの高さ358ピクセルに等しい距離を22.4秒で進みます。ビューを横切るのにかかる時間は下記のその日の向きによります。2027年1月1日には東から215.16度に向かい、垂直成分は毎秒9.21ピクセル、水平成分は13.08ピクセルなので、ビューの高さを38.9秒で、幅を12.6秒で横切ります。1147773 これは今日の流れの9.75倍です。4
- 陰。 シートの最も暗い陰0.763と、画像の約半分という被覆はそのままにします。9
- 向き。 その日の向きは、ダイジェストの5バイト目、つまり抽選が読まない最初のバイトで固定し、そのバイトに360/256度を掛けた角度を東から反時計回りに取ります。そうすればゾーンの全員が、雲が同じ方向へ行くのを見ます。2027年の1月の30日について、スクリプトは30の異なる向きを見つけます。11 ドシエは抽選の「second byte」(2バイト目)と書いていましたが、それは抽選が読む4バイトの1つです。5バイト目は私の訂正です。12
- ファイル。
Weather.swiftのWeather.cloudVelocity(zone:date:)が、その日の速度を毎秒のピクセルで与えます。Air.updateは、今日の固定の毎秒SIMD2(0.004, 0.0015)の代わりに、それを384で割って雲のオフセットに足し、流れを毎秒のピクセルでレポートに保ちます。どちらも提案です。22
受け入れチェック7、雲。 プロセス内で、単体テストが、Weather.cloudVelocity(zone:date:)の大きさが毎秒16ピクセルであること、同じゾーンと日付で同じであること、そしてある日付のあとの29日のうち少なくとも1日で異なることをアサートします(スクリプトは、2027年1月2日から30日の29日すべてが1月1日と異なることを見つけます)。画面上では、-plazaHour 12、-plazaWeather clear、コレクターが立ち止まった状態で5秒離して取った2つのキャプチャを、雲の陰を最もよく揃えるずらしで重ね、80 ± 3ワールドピクセルの流れを示します。これは同時に、第7節が仮定するとおりRealityKitがオフセットをスケールのあとに適用するかどうか、そして項目6が言うとおりAir.updateが速度を足すかどうかも測ります。最初に書かれたままでは、チェックはリグのログを読み、2台のシミュレーターに日付を共有させていましたが、起動ではそれを設定できません。122211
7. 地面に落ちる建物の影
- パス。
town.pyのpaintのなかの、壁の影のあとに置くフォージのパスです。各建物について、最上段の行から基部の行まで1行ずつ、その行の最も東にある建物のセルのすぐ東のセルが、壁の足もとと同じ扱い、つまり建物に最も近い4ピクセルの列で、それ自身のランプで1段階暗くなる扱いを受けます。セルが影を受けるのは、町の文字で地面、芝生、道、敷石のときだけです。小道具、木、キオスク、別の建物、柵、水があれば、その行は影を受けず、パスはそれを越えてさらに東のセルへ進むことは決してありません。したがってどの帯も自分の壁に接します。光は左上から来ます。影は1つの面に落ち、1タイル未満の長さで、1階建てでも2階建てでも同じ幅です(第8節「落ち影」)。126311 行と小道具についての規則は私のものです。ドシエはパスを各建物の列で定義しており、そのスクリプトは列を建物のバウンディングボックスから取っていたので、屋根や基部の行が狭いと、帯が壁から3セル離れていました。 - どこに落ちるか。 7つの建物には合わせて39の行があります。33の行では東のセルが地面で、芝生が28、道が5で、影を受けます。6の行では小道具があり(通行をふさぐものが5つ、
house-mineの基部の行の横にある花壇が1つ)、自分のアートを保ちます。11 1セル16行の4列で、影になるピクセルは2,112です。4 - 基部の下には落とさない。 各列の最も下の建物のセルの下にあるセルは、さらに40を加えることになり、そのうち35が地面です(道が22、芝生が8、敷石が5)。ブリーフはそれらを影にしません。114 正面はビューの光の側を向いており、私のSchlitterの「one or two wall faces」(壁の1面か2面)の読みでは、そこに帯があると建物が浮いているように見えるでしょう。1163
- 実行時に描かず、焼き込む。 影は地面のアトラスに入ります。時刻とともに動かず(ここで測ったどのゲームも影を動かしません)、夜には何のコストもかかりません。12
- docstringが本当になる。
buildings.pyの行「The ground shadow stays off the building: it belongs to the ground layer.」(地面の影は建物には付けない。それは地面のレイヤーに属する)は、そのとき存在するものを説明するようになります。24
提案:建物の影が落ちるところ。town.jsonとkiradex_proposals.txtのセクション3から。描画ではなく計画です。
受け入れチェック8、影。 フォージのチェックが33の影のセルを数え、西隣が同じ行の同じ建物のセルでない影のセル、芝生、道、敷石でないセルの上の影、そして4ピクセルより広い帯を拒みます。1211 Pro Maxのシミュレーターで、到着時、どのタップよりも前に、-plazaHour 12、-plazaWeather clear、-airProbeを付けて起動したキャプチャは、house-dawnの5つの行すべての東、列18の道の上の帯と、house-mossの行3と4の帯を見せ、小道具の立つ行5の東には何も見せません。その枠は、リグ自身の幾何を使った紙の上のカメラの再生から来ています。コレクターは(19, 13)に到着し、カメラはワールドピクセルで(312, 278)に落ち着き、ビューは横に229.5から394.5にわたるので、それらの帯はどれも25ピクセル以上の余裕を持って枠に入ります。プローブのビューとワールドの大きさが、キャプチャを判定する前に再生の165×358を確かめ、プローブの枠が、-airProbeのもとで描かれるチェック3のパイプラインの見本が、ここで名指しした帯のどれとも重ならないことを確かめます。到着時、帯は見本から144ポイント以上離れています。276830 代わりにtestTheChimneysSmokeの歩きに従ってhouse-mineへ行くのはうまくいきません。同じように再生すると、その歩きのタップは書き出しが小道具と記すセルに落ちるのでコレクターは動かず、到着時の枠からテストが行えるどのタップも、house-mineの帯のすべてを幅10.3タイルのビューに入れません。隣接の規則と到着時の枠は、ドシエのチェックを私が改訂したものです。
8. 屋内
KiradexはすでにStardewに従っています。部屋とホールは、広場と同じコードで同じ時計から、ランプとともに照らし直され、その時計は今日はスマートフォンのものです(第7節)。それを保ちます(第8節「屋内」)。ただし第7節が名指しする違いがあります。Stardewはプレイヤーのいる部屋の光を、プレイヤーが出て戻ってくるまで保ち、Kiradexはそれを1分ごとに照らし直し、これはKiradexの選択です。16 広場が部屋の時計に移っても(項目1)、部屋とホールはスマートフォンの時計のままです。広場の外では、生きている町の記事の契約のとおりコレクターの時計はその人自身のもので、ホールはそのコメントでは「off the plaza」(広場の外)の場所であり、クライアントなしで作られます。スマートフォンのゾーンと部屋のゾーンが異なるところでは、光が戸口で変わることがあり、コードはすでにどちらの通り抜けも黒いベールのもとに置いています。部屋とホールにはそれを通って入り、広場は「out of the door gone in by, the veil lifting」(入ったドアから出て、ベールが上がる)で戻ります。広場は上に重ねられた場所の下にとどまり、そのLightClockも一緒なので、戻る途中でも最後のwelcomeか静かな応答のゾーンとスタンプを保っています。この規則は私のものです。436919 そのうえで、Stardewの1つの洗練、そのWindowLightを加えます。部屋の窓が外の時間帯を見せるので、夜の部屋は窓が暗いから暗いのです。125369 フォージのinteriors.pyは今日、部屋の窓を2つ描いています。普通の窓とカーテン付きの窓(windowとcurtained_windowで、部屋のグリッドの文字NとKで置かれます)です。それぞれのガラスについて昼、夕方、夜の変種を描き、各窓のセルを部屋とともに書き出すことになります。リグは、棚や机をそのセルの上に重ねるように(addQuad)、時間帯の変種を各窓のセルの上に重ね、ステージのrelight()がそれに時間帯を渡します。これはすべて提案です。9220
受け入れチェック9、部屋。 フォージのチェックが、部屋のアトラスに各ガラスの3つの変種を見つけ、部屋のグリッドのすべてのNとKについて窓のセルを見つけます。Pro Maxのシミュレーターで、それぞれを別の起動にし、-plazaHour 22と-plazaHour 12で取る2つのキャプチャが、サーバーを必要としないMeタブのme-roomボタンでプレイヤー自身の部屋に入り、1階のセル(3, 1)のカーテン付きの窓に夜のガラスと昼のガラスを見せます。同じ紙の上の再生では、部屋の到着地点(7, 10)から、ビューは横にタイル2.34から12.66にわたり、部屋の高さ全体を覆うので、その窓は枠に入り、(12, 1)の普通の窓は端で切れます。9227 このチェックは私のもので、すべての項目がチェックを持つように加えました。
9. Reduce Motion
PlazaStageは環境からaccessibilityReduceMotionを読み、-plazaHourと同じく起動のあいだ固定されるデバッグ用の起動引数-plazaReduceMotionとの論理和を取り、その結果を照らし直しのたびと、環境の値が変わるたびにAir.set(phase:season:weather:reduceMotion:)へ渡します。引数もパラメーターも提案です。オンのとき、雨と雪は数が3分の1になって半分の速さで落ち(ビューのなかに雨で5粒、大雨で12粒、毎秒434ピクセル)、葉、蛍、霧、煙は止まり、雲は速度をゼロとして止まります。光はカットしません。色合いは30分のランプを保ち、天気は1秒のフェードを保ち、PlaceLightはReduce Motionの入力なしでそれを動かします。私の読みでは、明るさのゆっくりした変化は、この設定が対象とする動きではなく、それをカットすればゆっくりした変化を突然の変化と引き換えにすることになります。雨へのフェードはアトラスの昼の平均を0.449から0.365にし、60ヘルツで1フレームに0.0014ですが、カットは0.084の1段階で、チェック6の上限である1フレーム0.02の4倍を超えます。12864 ドシエはReduce Motionのもとで天気をフェードさせずカットさせており、名指ししていたのは雨、雪、葉、蛍、雲だけでした。この項目とチェック6が一致するようにフェードを保ったこと、そして第7節が設定にかかわらず動いていると見つけた霧と煙を止めたことが、私の変更です。Stardewの雪の透明度の設定が、プレイヤーに天気を弱めさせる前例です。17
受け入れチェック10、Reduce Motion。 SwiftUIの環境値は読み取り専用で、var accessibilityReduceMotion: Bool { get }と宣言されているので、アプリもテストもそれを設定できません。変えられるのはシステムの設定だけです。86 そこで項目9は-plazaReduceMotionを加えます。-plazaHour 12、-plazaWeather rain、-plazaReduceMotion、-airProbeを付けて起動したUIテストが、雨粒の数(項目4)と雲の流れ(項目6)を運ぶ空気のレポートが、5 ± 1の雨粒の数と0の流れを示すのを待ちます。チェック6の単体テストが、フェードが上限のもとに保たれることを示します。フェードにはそれを変えるReduce Motionの入力がないからです。一度だけ手で、シミュレーターの設定でReduce Motionをオンにすると、同じレポートが引数なしで同じ数を示します。最初に書かれたままでは、チェックは雨のログを読んでいましたが、テストのなかのどれも設定をオンにしません。1219
10. 名前とアート
10月5日の時点で、アプリには拒否リストがありませんでした。この項目のドシエの版は、天気の画像が「the deny list」(拒否リスト)を通ると言い、それを求めるルートの記事は「The deny list does not exist yet」(拒否リストはまだ存在しない)と言って、それを作ることを自分のブリーフの一部にしています。10月5日にKiradexリポジトリを検索しても、そのようなリストは見つかりませんでした。1293 そこでこの項目は、10月5日にできたことと、そのリストを待っていたことを述べます。リストはその後追加されました(この節の冒頭)。
- 文字列。 新しい文字列は、5つの状態のステータスの言葉とボードの行です。それらはルートのブリーフが求める拒否リストを通ります。それは10月5日には存在せず、今はリポジトリが
scripts/forge/protected_names.txtとして持っています。さらに公開されている1つのリスト、オマージュの記事の「Never」のリストとも照合します。その2つ目の項目は、どの機能も使ってはならないフランチャイズの語彙を名指ししています。10 - 画像。
rain.png、splash.png、snow.png、そして窓のガラスはフォージが描き、同じリストの1つ目の項目に照らしてレビューします。それは「taken, traced or redrawn from any Pokémon game」(どのポケモン作品からであれ、取ったり、なぞったり、描き直したりした)タイル、スプライト、パレットを拒みます。10 - パレット。
DaylightやWeatherのどの色の値も、0〜1にスケールしたpokecrystalのパレットの色と等しくなりません。ただし純粋な白は例外です。白はアートを描かれたとおりに残す乗算であって、誰かから取った色ではありません。今日の昼の色合いと夏の色味は白で(Daylight.swiftのなか)、白はクリスタルの背景と人物のパレットにもあるので、ドシエが書いたままの規則では、出荷されたままのアプリが失敗してしまいます。例外は私の訂正です。122821
受け入れチェック11、名前とアート。 新しい単体テストKiradexTests/NamesTests.swiftが、オマージュの記事の「Never」の項目2の語をテストターゲットのなかのリストとして持ち、どの状態のステータスの言葉にも、どのボードの行にも、大文字小文字を無視してそれが含まれないことをアサートします。その項目が「Poké-anything」(Pokéで始まるあらゆるもの)を拒むように、「Poké」で始まるどの語も拒みます。同じテストは、10月5日には存在しなかったリポジトリの拒否リストも読みます。これはその日には実行できなかったチェックの半分で、今はscripts/forge/protected_names.txtです。ファイルはKiradexTestsにテストのリソースとしてバンドルし、そのエントリ(1行に1つ、#の行は飛ばす)を、ファイルのヘッダーが言うとおり(「matched without regard to case as a whole word or phrase」(大文字小文字にかかわらず、語や句の全体として照合する))、大文字小文字にかかわらず語や句の全体として照合します。バンドルは私の提案です。89 スクリプトが、Daylight.swiftとWeather.swiftのすべての色の定数を、0〜1にスケールしたbg_tiles.pal、npc_sprites.pal、roofs.palのすべての色と比べ、純粋な白以外に一致がないことを見つけます。スクリプトは著者の証拠フォルダのなかで、逆コンパイルのクローンの横で実行するので、同じ「Never」のリストの4つ目の項目が求めるとおり、逆コンパイルのデータはアプリにもフォージにも入りません。10月5日に出荷されたDaylight.swiftに対して実行すると、その8つの色の定数と3つのファイルの404色のあいだに、2つの一致を見つけます。どちらも純粋な白で、昼の色合いと夏の色味であり、ほかにはありません。それ以外で最も近い組は、1つのチャンネルで5ビットのちょうど1段階離れています。画像のレビューは、それぞれのキャプチャとともに記録します。121028 最初に書かれたままでは、チェックは画像に、10月5日にはアプリが持っていなかった拒否リストを通させていました。
このブリーフに含めないもの
- プレイヤーの現実の天気。 WeatherKitは広場を天気アプリにしてしまい、プレイヤーの位置情報を必要とします。正典の天気は世界のもので、予定され、共有されています(第8節「天気の予定」)。8712
- 太陽とともに動く影、スプライトへの点光源、被写界深度。 HD-2Dの段階は、自身のプロデューサーの言葉で「costs more than you’d think」(思っているより費用がかかる)もので、世界の記事が記録したとおり、そのプレイヤーはぼかしをオフにします。5932 ここで測ったどのゲームも時刻とともに影を動かさず、ステージはすでに被写界深度を無効にしています。19
- 稲妻のフラッシュ(項目5)と、すべての街灯のちらつき。ただし、ちらつきがチェック6を通り、Reduce Motionのもとで止まるなら別です。12
- クリスタルのパレット、エメラルドの雨、霧、しぶきのスプライト、そしてその天気の名前。 仕組みだけです。1210
- 時刻ちょうどのカット。ただし強制した
-plazaHourのもとでは別です。12
重要なポイント
アートを描くなら
- 夜は2つ目のタイルのセットではなく、パレットとして描きましょう。クリスタルは光をおよそ半分残し(パレットのブロックでは各パレットの昼のルマの0.41〜0.68、町が表示する状態ではマップグループ別に平均0.49〜0.54)、夜には7つのワールドパレットのうち5つで青みがかった灰色の最も明るい色を1つ共有し、町の水はそこから1段階ずれています。1
- 朝は暖かい白にし、それ以上はしないでください。クリスタルが朝のために変えるのは32色のうち5色で、どれも最も明るい色です。1
- 明かりには暗さを拒む色を与えましょう。クリスタルのYELLOWは、ほかのすべてが0.6を下回るときも0.90のままです。Kiradexの明かりのセルは、色合いをかけたなかで最も明るいピクセル0.562に対して0.901にあります(Macで読んだもので、iPhoneで測ったものではありません)。19
- 落ち影は短く、1トーンで、1面か2面に置き、高さにかかわらず同じ長さにしましょう。黒ではなく青に寄せた色にします。86365
エンジンを作るなら
- 人物を色合いから外すか、ほとんど外しましょう。クリスタルとエメラルドはどちらもそうしており、2つの異なる仕組みによっています。15
- 光は時計から計算してランプにし、人が開いたままにする画面の上でカットしないでください。30分のランプは、Kiradexの0.108のカットを0.0036の段階に変えます(アトラスの平均ルマで、Macで読んだもの)。11
- 光を部屋の時計で動かし、自分の境界を予約し、スマートフォンの境界のためにはシステムの時刻の跳びの通知を監視しましょう。次の1分を待たないでください。438384
- 加算の光は暗くできません。RealityKitの2つのブレンドモードでは、動く影はアルファのシートで、固定された影はアトラスに属します。7866
- 空気を動かすすべてのファイルでReduce Motionを読みましょう。869
ループを設計するなら
- 天気は、プレイヤーの現実の空ではなく、世界の予定された性質にし、1日1回抽選して前もって知らせましょう。エメラルドにもファイアレッドにも、雨で生まれる屋外マップはありません。517
- 天気は約1秒かけてフェードインさせ、穏やかに保ちましょう。エメラルドの雨は光の13/16です。5
- 稲妻のフラッシュは入れないでおきましょう。正典の嵐はW3Cのしきい値を通ります。子どもたちがこの町で長い時間を過ごすかもしれないという私の前提では、それを試す必要はありません。446
- 屋内が1日に従うかどうかを決めましょう。クリスタルは208のうち207で「いいえ」と言い、Stardewは「はい」と言います。1つを選んで、それを保ってください。116
よくある質問
『ポケットモンスター 金・銀・クリスタル』の昼夜の周期はどういう仕組みですか?
この記事が読む3作のうちのクリスタルでは、リアルタイムクロックが1日を、4:00からの朝、10:00からの昼、18:00からの夜、6時間、8時間、10時間に分けます。各区分は、8つの背景パレット、8つのオブジェクトパレット、そして屋外では屋根の色の独自のセットを持ち、区分が変わるとゲームはそれらをフェードなしで1フレームのうちに読み込み直します。時計に従うのは町、道路、1つの洞窟だけです。208の屋内マップのうち207は昼に固定され、27のマップ(そのうち24がCAVEマップ)は永遠の夜です。2134
『ポケットモンスター エメラルド』に昼夜の周期はありましたか?
光についてはありません。エメラルドにもファイアレッドにも、ソースに時間帯のシステムはありません。エメラルドの時計はきのみと日々のイベントを動かします。エメラルドにあるのは18の天気の値で、マップごとに、またトリガーによって設定されます。雨、雷雨、豪雨、日陰、霧、灰、砂あらし、日照りなどがあり、雨は景色を約13/16に暗くし、人物は自分の色を保ちます。510
『ポケットモンスター エメラルド』の雨はどういう仕組みですか?
雨は10個の雨粒スプライトで、雷雨は16個です。それぞれが毎秒868ピクセル、鉛直から26.6度で18フレーム落ちてから、7フレームのしぶきになります。豪雨の24粒は毎秒1,336ピクセルで12フレーム落ちてから、10フレームのしぶきになります。パレットは1.00秒かけて元の値の約0.81のカラーマップへフェードしますが、プレイヤーと町の人のパレットは例外です。晴れた空からプレイ中に雨に入ると、シートと24の雨粒スプライトを準備し、9フレームに1粒ずつ雨粒を有効にしたあと、雨の場合は変化の115フレーム後、1.9秒で雨粒がすべてそろいます。ヘッダーが雨の屋外マップはありません。雨は5つのマップの座標トリガー、いくつかのスクリプト、そしてRoute 119と123の4日周期から来ます。57
タイルを描き直さずに、ピクセルアートのゲームで昼と夜を作るにはどうすればいいですか?
1日の区分ごとに場面へ色合いを掛けるか、パレットを入れ替え、明かりはそこから外しましょう。クリスタルの夜は光をおよそ半分残して青くなります。Kiradexは4つの色合いを掛け、明かりのついた窓を色合いをかけない2つ目のメッシュとして描き、地面には加算の光のプールを置きます。色合いのあいだはカットせずにランプでつなぎ、キャラクターを場所より明るく残しましょう。196611
見下ろし型のピクセルアートで影はどう描けばいいですか?
短く、1トーンで、独自のレイヤーに描きます。エメラルドの影のスプライトは、どの大きさでも5行の単色です。Raymond Schlitterは落ち影を控えめに、別のタイルに、1面か2面に、壁がどれほど高くても同じ長さに保ちます。石井浩一氏は黒の代わりに深い青や紫を使いました。加算とアルファのブレンドしかないエンジンでは、固定された影はアートに属します。862636578
ピクセルアートのゲームはプレイヤーの現実の天気を使うべきですか?
正典の答えは「いいえ」です。エメラルドの天気はそのマップと日々に属し、Stardewは谷全体で1日に1つの天気を抽選し、前日にテレビで告知します。現実の天気はプレイヤーの位置情報を必要とし、共有された世界を個人的な予報に変えてしまいます。ゾーンと日付をキーにした毎日の抽選なら、ある場所の全員に同じ空を、前もってわかる形で与えられます。5178711
ゲームの稲妻は発作のリスクになりますか?
閃光はなりえます。W3Cの達成基準2.3.1は、閃光が一般閃光と赤色閃光のしきい値を下回る場合を除き、どの1秒にも3回以下という基準を定め、閃光を放つコンテンツは片頭痛、めまい、吐き気、発作を引き起こすことがあると述べています。測ったエメラルドの嵐は、1秒に2本の稲妻を持つことが決してありません。Kiradexのブリーフは閃光を完全に除いています。464
この記事の作り方。 背後にある調査ドシエは2026年10月5日にまとめたもので、4つのpretの逆コンパイルのシャロークローンを、出力とともに保存した5つのPythonスクリプトで測り、さらに保存したStardew Valley Wikiの1日、天気、マップのページ、現代のライティングされたピクセルゲームについての8つのページ(インタビュー、開発者の投稿、プレスキット、ニュース記事、WikipediaのHD-2Dの記事)、3つのPixelblog、聖剣伝説3についての翻訳されたインタビュー1本、閃光についてのW3Cのページ、そして6つ目のスクリプトで読んだ11のAppleのドキュメントページから作りました。公開前に、そのすべてを再実行しました。2つは保存した出力を変わらずに返しました。提案スクリプトは、建物の影を行ごとに置くため、湿った期間を第10節の定義どおりに数えるため、そしてKiradexの歩きを毎秒4タイルと持ち越さずにアプリのソースから読むために修正しました。エメラルドのスクリプトの雨のラベルは、出現カウンターの上限を周期として出力していたので修正しました。クリスタルのスクリプトにはフェードのルーチンの呼び出し元の全数調査を加え、マップヘッダーのパーサーは、音楽のフィールドが式になっている5つのヘッダーを落としていたので修正し、今では各環境が表示するパレットのセットも解決します。そしてKiradexのスクリプトの雲の行から、同じ持ち越した歩きを外しました。変更した各スクリプトの以前の版と出力は横に残してあります。7つ目は、ブリーフのキャプチャのチェックが町と部屋をどう枠に収めるかを紙の上で再生し、8つ目のarith.pyは派生値をすべて出力し、9つ目はアプリの色の定数をクリスタルのパレットと比べ、10番目はエメラルドの雨の準備と雷の周期をソースから呼び出しごとに再生し、11番目はコレクターの枠のうちコレクター自身がどれだけを覆うかを数えます。本文のポケモンの数値はどれもスクリプトの出力で、各注がそのスクリプトを名指ししています。Kiradexの数値はどれもMacでソースから読んだか書き出した画像から計算したもので、iPhoneでキャプチャしたものはありません。第10節の提案は私のもので、そう明記しています。そのどれもまだ作られていません。
このサイトの関連記事:iPhoneでつくるピクセルアートの世界:16ビットの巨匠たちが知っていたことはこのシリーズの最初の記事で、RealityKitのレシピ、ライティングの段階表、法的な線引きを扱っています。ピクセルアートの建物:iPhoneでつくる家、ホール、室内は明かりのついた窓を作り、roofs.palとNightTilesを読みました。昔のポケモンを、何も借りずに讃えるは、Kiradexの4つの時間帯をクリスタルの時刻と照らして定めました。ピクセルアートの人物:iPhoneのキャラクターとクリエイターは、雨の大きさの基準になるビューを測りました。ピクセルアートの動き:iPhoneでの歩行、カメラ、ドアには、空気を測る基準になる歩きがあります。誰もオンラインでなくても生きているピクセルの町:NPCとゴーストは、光が従うことになる部屋の時計を提案しています。ピクセルアートの部屋:家具のグリッド、上限、採点は、項目8がその窓を時刻で照らすことになる部屋です。ピクセルアートの道:iPhoneでつくるマップ接続と地区は、作られるなら毎日の天気が覆うことにもなる、広場の先の世界です。そしてピクセルアートの段差・階段・橋:タイルでつくる世界の高さは、地面に残るジャンプの影を測り、光のなかで高さを読むことについてのSabotage StudioのThierry Boulangerの言葉を引用しています。
出典
-
著者による測定、2026年10月5日:
measure_gen2_daylight.py(本記事用の著者の証拠フォルダ内)、出力gen2_daylight.txt(およびgen2_yellow_tiles.png。著作権のあるアートから派生した3つのタイルの4倍の描画で、分析のために保管し、公開していない)。セクション:A、時刻(constants/misc_constants.asmとengine/rtc/rtc.asmのTimesOfDay表)。B、gfx/tilesets/bg_tiles.palの時刻別の背景パレット、ファイルのブロックをそのまま(朝、昼、夜、暗闇、屋内での各パレットの4色の平均ルマ。夜と昼の比。時刻別の色0。朝が変える色。青から赤と緑の平均を引いた値。夜か暗闇でルマ0.6を上回る色)。B2、マップが表示するパレットのセット:data/maps/environment_colors.asmの、環境と時刻ごとの、ファイルの42パレットへの8つのインデックス(屋外のセットのWATERは屋外の組から取る)と、マップグループごとのgfx/tilesets/roofs.palからのLoadMapPalsの屋根のコピー(屋外のセットのルマと夜と昼の比。表示される水、その夜の最も明るい色とその比。(15, 14, 24)を共有する5つのパレット。朝と昼の比較。青への偏り。0.6を上回る色。町か道路を持つ25のマップグループ、それらにわたる表示されるROOFの比、そしてグループ別の7つのワールドパレットの平均の比。屋内のセット)。C、gfx/overworld/npc_sprites.palのオブジェクトパレット(昼から夜と暗闇でどの色が変わるか)。D、gfx/tilesets/roofs.pal(27のエントリ、マップグループ別の夜と昼の比)。E、engine/tilesets/timeofday_pals.asmの_TimeOfDayPals、_UpdateTimePals、4つのフェード、フィールドのループ、各フェードを何が呼ぶかの全数調査(data/maps/setup_scripts.asmの各マップ準備スクリプトのフェード。db -1のないスクリプトは次のスクリプトへたどる。踏んだワープ、「そらをとぶ」、スクリプトのコマンドwarpがどの準備の定数で読み込むか。home/map.asmのメニューのフェード。timeofday_pals.asmの外のすべての.asmにあるフェードのspecial、farcall、mapsetupをファイル別に数えたもの。黒の組の11のマップスクリプトとその行番号)、背景パレットをLoadSpecialMapPaletteがLoadMapPalsから引き取る6つのタイルセット(マップヘッダーから環境別に数えたもの)、そしてそのパレットを実際に読み込むマップ(TILESET_ICE_PATH上のINDOORマップである殿堂入りを除く。INDOORマップ74、どれもPALETTE_DAYで、そのうち57がTILESET_HOUSE上、そしてCAVE 5)、スタートメニュー自身の行(StartMenu、その.Exit、そのUpdateTimePalsの呼び出し、その項目のどれがFadeToMenuを呼ぶか)、そしてmobile/とhome/map.asmの外のすべてのcall FadeToMenuをファイル別に。F、data/maps/maps.asmの388のマップヘッダーを環境とパレットのモード別に。各mapディレクティブをコンマで分割し、すべてのディレクティブが消費されたことをアサートする(以前のパーサーは1語のフィールド8つに一致させており、音楽のフィールドが式になっている5つのラジオ塔のヘッダーを落としていたので、383のヘッダー、203のINDOORマップのうち202が昼、383のうち78が時計に従う、20.4%と出力していた。今は388、208のうち207、388のうち78、20.1%)。G、ジョウトのタイルセットのパレットマップ、gfx/tilesets/johto_palette_map.asm。ルマは0〜1にスケールした5ビットの値にRec. 601を適用したもので、ガンマなし。入力:pretpokecrystal、5beda23。公開前に再実行:セクションA〜DとG、そしてタイルの描画は以前と同じ出力。セクションEはフェードの全数調査、メニューの全数調査、特別な表を受けるマップの数を加え、B2とFの修正したパーサーは、以前のスクリプトと出力を横に残したあとの改訂で追加した。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
pret、
pokecrystal/constants/misc_constants.asm、5beda23(MORN_HOUR EQU 4、DAY_HOUR EQU 10、NITE_HOUR EQU 18、36〜38行目)とpokecrystal/engine/rtc/rtc.asm(TimesOfDay、48行目、50行目にコメント「0400-0959 morn | 1000-1759 day | 1800-0359 nite」)、2026年10月5日閲覧、https://github.com/pret/pokecrystal/blob/master/engine/rtc/rtc.asm ↩↩↩↩↩ -
pret、
pokecrystal/engine/tilesets/timeofday_pals.asm、5beda23、2026年10月5日閲覧:_TimeOfDayPals(13行目)、_UpdateTimePals(109行目、ld c, $9 ; normal、続いてGetTimePalFadeとDmgToCgbTimePals)、FadeInFromWhite(115)、FadeOutToWhite(122)、FadeInFromBlack(146)、FadeOutToBlack(153)、ReplaceTimeOfDayPals(189、206行目でSTATUSFLAGS_FLASH_Fを判定)、https://github.com/pret/pokecrystal/blob/master/engine/tilesets/timeofday_pals.asm ↩↩↩↩↩ -
本文の測定値からの著者の算術:
arith.py(本記事用の著者の作業フォルダ内)、出力arith.txt。本記事用の著者の証拠フォルダにある出力を読み、さらに読み取り専用で、Kiradexの書き出したtown.pngとglow.pngを読む。出力するのは次のとおり。フレームレート(2^24 ÷ 280,896と2^22 ÷ 70,224、どちらも59.7275ヘルツ)。時刻と1日に占める割合(夜は24のうち10、41.7%。Kiradexの街灯は13時間、54.2%)。Stardewの1日(20 × 60 × 0.7 = 840秒、14分。日暮れは午前6時から現実の9.8、9.1、8.4分後)。クリスタルのパレットごとの夜と昼の比とその平均(0.511)、青への偏りの変化(6.44、31の0.208)、色(15, 14, 24)のルマ0.498、(30, 30, 11)の0.898、(27, 31, 27)の0.947、(28, 31, 16)の0.916、gen2_daylight.txtのセクションB2からの表示される屋外の水(昼0.528、夜0.248、0.470。その夜の最も明るい色(15, 13, 27)、0.490)、町が表示する状態での7つのワールドパレットのマップグループ別の夜と昼の比(0.494〜0.539、25グループで平均0.509)、表示されるROOFの比(0.369〜0.688、平均0.477)と表示される青への偏り(−1.17〜+6.10、7.27の上昇)、朝の32のうち5(15.6%)、YELLOWの192タイルのうち3(1.6%)、読み込み直しの64 + 64 + 4 = 132バイト、フェードの8フレーム(134ミリ秒)、セクションFからパースしたマップヘッダー(388。時計に従うマップは388のうち78、20.1%。昼に固定の屋内は208のうち207。永遠の夜の27マップを環境別に、CAVE 24、DUNGEON 1、GATE 1、INDOOR 1。以前の383、383のうち78、203のうち202を横に記す)。エメラルドの13/16(0.8125)、31、16、8でのマップ3、雨のフェード(60フレーム、1.005秒)、雨と豪雨の速さ、落下、しぶき(262と268ピクセル、0.301と0.201秒、7と10フレーム、0.117と0.167秒、雨粒の寿命は25フレーム、0.419秒)、出現の周期(遅延 + 1:9と5フレーム)、有効な雨粒0個からの有効化の段階(90、80、120フレーム、1.51、1.34、2.01秒)、そしてgen3_replay.txtからの、プレイ中の晴れた空からの完全な遷移(準備の呼び出し25回 + 有効化:115、105、145フレーム、1.93、1.76、2.43秒。フレーム59でマップ3にあるパレット。フレーム109の雷雨の最初の稲妻。雨から雨への数)、毎秒59.73ピクセルの歩きに対する雲、霧、砂あらし(0.500、0.250、3.60)、雷の待ち、保持、間隔を秒で、間隔のタイマーに1を足した暗い間隔(61〜76フレーム、1.021〜1.272秒。61フレームを1.0213秒として、稲妻の始まりは少なくとも67フレーム離れる)、周期の最初の落雷までの待ち(361〜720フレーム)、雷の図のタイムライン、そして落雷のあとの雷の音の遅れ(1〜20フレーム、最大0.335秒。1〜100、最大1.674)。屋外のヘッダーの割合(68のうち51、75.0%。76のうち66、86.8%)と86の座標イベント。フラッシュの円(1,810と16,286平方ピクセル、38,400の4.7%と42.4%、面積は9倍)。影のスプライトの不透明な割合とKiradexのもの(48のうち40、アルファ153 = 0.60、ルマ0.071)。各色合いのもとでのKiradexのアトラス(0.4318、0.4488、0.3719、0.2639)、色合いをかけたなかで最も明るいピクセルに対する明かりのセル(1.60)、4つのカット(0.0170、0.0769、0.1079、0.1678)と、各境界での30分のランプの1分あたりの最大の段差(0.0006、0.0026、0.0036、0.0056)。色合いを丸ごと足した街灯のプールの中心(0.806)と、画像のピーク0.961で重み付けしたもの(0.785)。7 + 17 = 24のプール。Motion.swiftから読んだ今日の歩き(毎秒60で16ティックに16ピクセル、毎秒60ピクセル。走りは120)、雲の毎秒1.640ピクセル(歩きの0.0273、1タイルに9.8秒、16の9.75分の1の遅さ)、歩きに対する提案の毎秒16ピクセル(0.2667)、ビューの高さに等しい距離を22.4秒、そしてダイジェストの5バイト目から計算し直した2027年1月1日の向き(153、215.15625度。垂直成分は毎秒9.21293ピクセルで358ピクセルの高さを38.86秒で横切り、水平成分は13.08136で165ピクセルの幅を12.61秒で横切る)、不透明度0.55と0.8でのその陰(最も暗いもので0.763と0.655、平均で0.950と0.927)と曇りの日(0.404)。59,070平方ピクセル(1.538画面)のビューとそのなかの雨粒。アトラス上の雨と大雨(0.365、0.214。0.337、0.198)。時間帯ごとの歩く人の持ち上げた光(0.980、1.000、0.913、0.796。夜は場所の1.34倍)。天気の1年の湿った割合。Reduce Motionの3分の1と半分(5粒、12.3、毎秒434ピクセル)。建物の影の33 × 4 × 16 = 2,112ピクセル(芝生28、道5、小道具のために飛ばした行6)と基部の下の40セル、そのうち35が地面。雨と大雨へのフェードのフレームあたりの値(カットとして0.084と0.112。60ヘルツで1フレーム0.0014と0.0019、120ヘルツで0.0007と0.0009)。1秒のフェードが割り当てる場所のマテリアルをコードから数えたもの(照らし直しで3、波紋で1秒に12、フェードのあいだ60ヘルツで180、120ヘルツで360。ドアを表示していると照らし直しで4、フェードのあいだ240と480。この行は2026年10月16日に追加)。天気の1年の湿った日と期間(82日、17 + 19 + 21 + 25。65の期間、最長3)。Celesteの(2048 ÷ 256)^2 = 64スロット × 4 = 256。そして保存したMaterialParameterTypes.BlendModeのページの2つの列挙ケースで、トピックのリストから読んだもの(parse_apple.pyはこれを出力しない)。ヘッダーの数を持ち越さずにスクリプトから読むため、表示されるパレット、雨の完全な遷移、雷の間隔、雲の比と横切る時間を加えるため、そして今日の歩きを毎秒64ピクセルと持ち越さずにアプリのMotion.swiftから読むために改訂した。以前のスクリプトと出力は横に残してある。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
著者による測定、2026年10月5日:
measure_gen3_weather.py(本記事用の著者の証拠フォルダ内)、出力gen3_weather.txt。セクション:A、include/constants/weather.hの定数。B、src/field_weather_effect.cの各天気のInitVarsとブレンドの目標。C、src/field_weather.cのBuildColorMapsをPythonで再生したもの、sBasePaletteColorMapTypes、include/event_object_movement.hのパレットのスロット。D、雨のQ28.4の速度、落下の時間、しぶきのフレーム、出現の周期(UpdateVisibleRainSpritesの++rainSpriteVisibleCounter > rainSpriteVisibleDelay、遅延 + 1フレームごとに1粒、そして1フレームのなかでのRain_InitAllのループ)。E、雲、霧、砂あらしの流れ(砂あらしはsrc/trig.cのgSineTableで6,000フレーム再生)。F、雷のタイミング。G、エメラルドとファイアレッドのすべてのdata/maps/*/map.jsonのヘッダーの天気をマップの種類別に、座標天気イベント、2つの道路の周期、data/**/*.incのスクリプトによるsetweatherの呼び出し、そしてrequires_flashのマップ。H、sFlashLevelToRadiusと既定のフラッシュのレベル。I、src/*.cとinclude/**/*.hでの「timeofday」と「time_of_day」の大文字小文字を区別しない名前検索。入力:pretpokeemerald、731ad5bとpokefirered、037335f。公開前に再実行:Dの最後の行を除き、すべてのセクションが以前と同じ出力。その行のラベルはrainSpriteVisibleDelayそのものを出現の周期として出力していた(8と4フレームごと)が、今は遅延 + 1(9と5フレームごと)を満ちるまでの時間とともに出力する。以前のスクリプトと出力は横に残してある。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
pret、
pokeemerald/src/field_weather.c、731ad5b、2026年10月5日閲覧:sWeatherFuncs(85行目、各天気のinitVars、main、initAll、finish)、sBasePaletteColorMapTypes[32](114行目)、StartWeather(154)、SetNextWeather(183)、Task_WeatherInit(216、画面の準備ができると222行目で天気のinitAllを呼ぶ)、Task_WeatherMain(227:現在の天気と次の天気が異なるあいだ、古い天気のfinish()を毎フレーム、falseを返すまで呼び(231行目)、そのあと新しい天気のinitVars()(235行目)、colorMapStepCounter = 0(236行目)、WEATHER_PAL_STATE_CHANGING_WEATHER(237行目)。そうでなければ天気のmain()(244行目)。どちらのあとにもパレットの状態の関数(247行目))、BuildColorMaps(271)、UpdateWeatherColorMap(344、354行目で++colorMapStepCounter >= colorMapStepDelayのときにカラーマップを進める)、ApplyColorMap(459)。そしてinclude/constants/field_weather.hの4行目、MAX_RAIN_SPRITES 24、https://github.com/pret/pokeemerald/blob/master/src/field_weather.c ↩↩↩↩↩↩ -
pret、
pokeemerald/src/field_weather_effect.c、731ad5b、2026年10月5日閲覧:雲の座標のコメント「These coordinates are for the lower half of Route 120.」(この座標はRoute 120の下半分のためのもの)(41行目)、Clouds_InitVars(95)、UpdateCloudSpriteのコメント「Move 1 pixel left every 2 frames.」(2フレームごとに1ピクセル左へ動かす)(222)、sRainSpriteSplashAnimCmd(414)、sRainSpriteMovement(449)、sRainSpriteFallingDurations(458)、Rain_InitVars(471)、Rain_InitAll(484、weatherGfxLoadedまでのループ)、Rain_Main(491:その3つの状態、496行目のシート、500行目でfalseを返すまでのCreateRainSprite、504行目でfalseを返すまでのUpdateVisibleRainSprites)、Rain_Finish(513、次の天気が雨の種類のときはすぐにfalseを返してスプライトを保つ、518〜524)、CreateRainSprite(665:24個あるときはfalseを返す、670〜671、1回の呼び出しで1つのスプライトを作り、24個目を作る呼び出しでfalseを返す、694〜709)、UpdateVisibleRainSprites(714、有効な数が目標に達するとfalseを返す、716〜717、そして++rainSpriteVisibleCounter > rainSpriteVisibleDelayのときに雨粒を有効にする、719行目)、Sunny_Finish(168、falseを返す)、雷の状態のenum(1014〜1035)、Thunderstorm_InitVars(1037)、Downpour_InitVars(1066)、雷雨のパターンのコメント「(SHORT_BOLT){1,2}(LONG_BOLT)?」(1089)と「Thunder only plays on the final bolt of the cycle.」(雷鳴は周期の最後の稲妻でだけ鳴る)(1091)、Thunderstorm_Main(1092)とその最初のUpdateThunderSound()(1094)、その準備の状態(1097〜1111)とそのTHUNDER_STATE_WAIT_CHANGEのケース(1112)、これは待ちを飛び越えてTHUNDER_STATE_INIT_CYCLE_1(1114)へ進む、THUNDER_STATE_NEW_CYCLE(1116、1118行目のタイマー(Random() % 360) + 360が1121行目のTHUNDER_STATE_NEW_CYCLE_WAITへ流れ込み、その--thunderTimer == 0は1123行目)、THUNDER_STATE_INIT_CYCLE_1と_2(1126と1131、1135行目のTHUNDER_STATE_SHORT_BOLTへ流れ込み、落雷は1137行目、保持(Random() % 3) + 6は1142行目)、THUNDER_STATE_TRY_NEW_BOLT(1145、1149行目で稲妻の終わり、1154行目で間隔のタイマー(Random() % 16) + 60)、THUNDER_STATE_WAIT_BOLT_SHORT(1169)、THUNDER_STATE_INIT_BOLT_LONG(1173、1174行目で同じ間隔のタイマー)、THUNDER_STATE_WAIT_BOLT_LONG(1177、1181行目でEnqueueThunder(100)、1182行目で落雷、1183行目で保持(Random() & 0xF) + 30)、THUNDER_STATE_FADE_BOLT_LONG(1187、1191行目で徐々にフェード)、EnqueueThunder(1242、1246行目でタイマーRandom() % waitFrames)とUpdateThunderSound(1251)、FogHorizontal_Main(1392)、Sandstorm_Main(1975)、Shade_InitVars(2247)、sWeatherCycleRoute119(2581)、sWeatherCycleRoute123(2588)、UpdateWeatherPerDay(2622)、https://github.com/pret/pokeemerald/blob/master/src/field_weather_effect.c ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
著者による測定、2026年10月5日:
measure_shadows.py(本記事用の著者の証拠フォルダ内)、出力shadows.txt:エメラルドのshadow_small.png、shadow_medium.png、shadow_large.png、shadow_extra_large.png(pretpokeemerald、731ad5b、graphics/field_effects/pics/)と、KiradexのKiradex/Resources/World/shadow.pngの大きさ、不透明なピクセル、異なるトーンの数。それぞれを不透明なピクセルのテキストのマスクとして描く。公開前に再実行し、同一の出力を得た。 ↩↩↩↩↩↩↩↩↩↩ -
著者による測定、2026年10月5日、iPhoneではなくMacで:
measure_kiradex_light.py(本記事用の著者の証拠フォルダ内)、出力kiradex_light.txt。テキストとして、KiradexリポジトリのKiradex/World/Daylight.swift、PlazaStage.swift、Air.swift、Kiradex/World/のすべてのSwiftファイル、そしてscripts/forge/town.pyとbuildings.pyを読み、Pillowで、書き出したKiradex/Resources/World/town.png(その不透明なピクセルに色合いをチャンネルごとに適用)、cloud.png、mist.png、glow.png、shadow.png、town.json(40×30、日付は2026年10月3日21:34)を読む。セクション:A、Daylightの時間帯、色合い、季節の色味、街灯。B、アトラス上の色合いと明かりのセル。C、時計、そのオブザーバー、Reduce Motion。D、空気。E、町の明かり、明かりのセル、プール、煙突、建物。F、影。ルマは0〜1の値にRec. 601を適用したもので、ガンマなし。非公開リポジトリで、gitもフォージも実行せずに、10月5日16:54にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから読んだ。公開前に、18:11にコミット66c116b0の時点で再実行:Dの1行を除き、すべての行が以前と同じ出力。その行のラベルは毎秒4タイルの歩く速さを持ち越していたが、行の数値、つまり雲が1タイルを横切るのにかかる9.8秒はそれを使っていない。以前のスクリプトと出力は横に残してある。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Blake Crosley「Honoring the Old Pokémon Games Without Borrowing Them」、blakecrosley.com、2026年10月5日:第3節(クリスタルの
MORN_HOUR 4、DAY_HOUR 10、NITE_HOUR 18とTimesOfDayのコメント。KiradexのDaylight.Phase、「morning from 6 to 9, day from 9 to 17, evening from 17 to 20 and night otherwise」(6時から9時が朝、9時から17時が昼、17時から20時が夕方、それ以外が夜)と、「the brief in section 14 keeps it that way」(第14節のブリーフはそれをそのまま保つ)という記述。リアルタイムクロック上のエメラルドのきのみと、エメラルドの11の日次更新のリスト、そのなかの「the weather」(天気)、関数は名指ししていない)と第14節(ブリーフ。Kiradexの時間帯を保ち、それは「which are already not Crystal’s 4, 10 and 18 and stay that way」(すでにクリスタルの4、10、18ではなく、そのままである)。そしてその「Never」のリストで、項目1は「tile, sprite, palette or screen layout taken, traced or redrawn from any Pokémon game」(どのポケモン作品からであれ、取ったり、なぞったり、描き直したりしたタイル、スプライト、パレット、画面レイアウト)を拒み、項目2はどの機能も使ってはならないフランチャイズの語彙を、Pokédexや「Poké-anything」(Pokéで始まるあらゆるもの)からFrontierまで名指しし、項目4はアプリやフォージのなかの「code or data from the decompilations」(逆コンパイルのコードやデータ)を拒む)、https://blakecrosley.com/blog/honoring-the-old-pokemon-games ↩↩↩↩↩↩↩↩↩↩↩↩↩ -
著者による測定と提案の算術、2026年10月5日、Macで:
measure_kiradex_proposals.py(本記事用の著者の証拠フォルダ内)、出力kiradex_proposals.txt。セクション:1、エメラルドの雨をワールド165×358ピクセルのiPhone 18 Pro Maxのビューへ持ち越したもの(10,000平方ピクセルあたりの密度、ビューのなかの雨粒、60と120ヘルツでのフレームあたりの速さ、落下としぶきの時間)。2、17:18のコピーのMotion.swiftから読んだKiradexの歩き(毎秒60ティックで16ティックに16ピクセル、毎秒60ピクセル。走りは120。斜めの歩きの一歩は対角線に沿って59.0)、各ゲームの歩きに対する流れの速さ(エメラルドの毎秒59.7ピクセル、Kiradexの60)、そして毎秒16ピクセルと歩きの半分での提案の雲。3、town.jsonでの建物の影のセル:7つの建物それぞれの各行について、その行の最も東の建物のセルのすぐ東のセルを文字別に、芝生、道、敷石のところだけ影にする(39のうち33)。比較のために、各列の最も下の建物のセルの下のセル(40、そのうち35が地面)。4、昼から夕方と夕方から夜について、アトラスの平均ルマでのカットと30分のランプ。5、アトラス上の雨の13/16と、白へ半分持ち上げた歩く人の光。6、1つのゾーンでの提案する毎日の天気の抽選の1年分(2027年)、sha256("zone|yyyy-mm-dd")、最初の4バイトをビッグエンディアン、100で割った余り、提案の季節の表を挙げた順に累積的にたどる(各季節について状態ごとの抽選の値の範囲を出力する)、湿った日と湿った期間(雨、大雨、雪の日がどう混ざってもよい、連続した日の極大の並び:82日、65の期間、最長3)、1月の30日にわたる2つのゾーンの一致、そしてダイジェストの5バイト目からの提案の雲の向き。出力でPROPOSALと記されたものはすべて著者のもの。セクション3は、各建物のバウンディングボックスから、上の行ごとの規則に改訂した。セクション6は改訂した:1つの湿った状態の並びを数えており(67、最長3)、1年の最後の日で終わる並びを落としていた。今は上で定義した湿った期間を数え、抽選の範囲と雲の向きを出力する。18:11にコミット66c116b0の時点で、作業ツリーの町の書き出しと画像を読んで再実行。セクション2は歩きをMotion.swiftから読むように改訂した:毎秒4タイル、毎秒64ピクセルを持ち越しており、今日の雲を歩きの0.026、提案を0.25としていた。以前のスクリプトと出力は横に残してあり、セクション1、3、4、5とセクション6の季節の数は以前と同じ出力。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
この記事のための著者の調査ドシエ「Light, weather and time: how pixel worlds keep a day, and what Kiradex should」(光、天気、時間:ピクセルの世界はどう1日を保つか、そしてKiradexはどうすべきか)、2026年10月5日にまとめたもの。Kiradexリポジトリの
docs/research/light/01-light.md(非公開。その日の07:25の日付で、16:51にコミットcf3beb1eの時点で読んだ)、著者の証拠フォルダにあるコピーと同一。第1節(主要な事実)、第2節(事例研究)、第3節(数値付きの規則)、第4節(Kiradexのためのブリーフ。第10節の状態、表、係数、ファイル、受け入れチェック1〜8と、この記事の10と11(ドシエの9と10)は、最初に書かれたままのものとしてここから来ている。この記事はチェック2〜8、10、11を改訂し、それぞれでそう述べている。そのチェック10は天気の画像が「the deny list」(拒否リスト)を通ると言い、その雲の向きは「the weather roll’s second byte」(天気の抽選の2バイト目)から来ている)、第5節(測ったものと測っていないもの:近似、届かなかったページ、提案、公開済みの記事に対するチェック)。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
pret、
pokecrystal/gfx/tilesets/bg_tiles.pal、5beda23、2026年10月5日閲覧:8つの背景パレットの5つのブロック(朝、昼、夜、暗闇、屋内)と屋外の水の組(51〜53行目:RGB 23,23,31, 18,19,31, 13,12,31, 07,07,07 ; morn/dayとRGB 15,13,27, 10,09,20, 04,03,18, 00,00,00 ; nite)、https://github.com/pret/pokecrystal/blob/master/gfx/tilesets/bg_tiles.pal ↩↩ -
pret、
pokecrystal/gfx/overworld/npc_sprites.pal、5beda23、2026年10月5日閲覧:時間帯ごとのオブジェクトパレット、https://github.com/pret/pokecrystal/blob/master/gfx/overworld/npc_sprites.pal ↩↩ -
pret、
pokeemerald/include/event_object_movement.h、731ad5b、2026年10月5日閲覧:PALSLOT_PLAYER(12行目)からPALSLOT_NPC_SPECIAL(22行目)までのオブジェクトパレットのスロットと、その反射のスロット、https://github.com/pret/pokeemerald/blob/master/include/event_object_movement.h ↩↩ -
Stardew Valley Wiki「Day Cycle」、2026年10月5日に本記事用の著者の証拠フォルダに
sdv-day-cycle.htmlとsdv-day-cycle.txtとして保存(「Time passes at 0.7 real seconds per in-game minute」(ゲーム内の1分につき現実の0.7秒が過ぎる)。日暮れは「In Spring and Summer , it is 8pm, while in Fall it is at 7pm and Winter is 6pm」(春と夏は午後8時、秋は午後7時、冬は午後6時)。「indoors the windows turn dark and lamps and sconces light up」(屋内では窓が暗くなり、ランプと壁付け灯がともる)。屋外では「it does not immediately become full dark, but gradually becomes darker over time」(すぐに真っ暗になるのではなく、時間とともにだんだん暗くなる))、https://stardewvalleywiki.com/Day_Cycle ↩↩↩↩↩↩↩↩↩ -
Stardew Valley Wiki「Weather」、2026年10月5日に本記事用の著者の証拠フォルダに
sdv-weather.htmlとsdv-weather.txtとして保存(「Weather changes daily and with the seasons」(天気は毎日、季節とともに変わる)。翌日の天気は「can be checked by viewing the TV screen」(テレビの画面を見て確かめられる)。「There is a chance for a lightning strike to occur every 10 minutes」(10分ごとに落雷が起きる可能性がある)。「Snow transparency can be changed in the Options Menu」(雪の透明度はオプションメニューで変えられる))、https://stardewvalleywiki.com/Weather ↩↩↩↩↩↩↩↩↩ -
Stardew Valley Wiki「Modding:Weather data」、2026年10月5日に本記事用の著者の証拠フォルダに
sdv-weather-data.htmlとsdv-weather-data.txtとして保存(天気が強制されない日付についての、季節ごとの各天気の種類の確率)、https://stardewvalleywiki.com/Modding:Weather_data ↩↩↩↩↩↩↩↩ -
Kiradexのソース、
Kiradex/World/PlazaStage.swift、2026年10月5日閲覧、最後は17:42にコミット5a344e3fの時点で、アプリ自身のエージェントがその日編集していた作業ツリーから(非公開リポジトリ。ファイルの日付はその日の17:22で、行番号はその読み取りのもの。16:51、コミットcf3beb1eの時点での読み取りでは、469行目以降が4〜8行少なかった。ファイルがその後アクセシビリティの表現を得たため):daylight(at:)(69行目、設定されていればDaylight.forcedHourを使う)、relight()(77〜81、152行目の構築のあとと、194行目の空気の準備のあとに呼ばれる)、stepTrace、プレイヤーの最後の一歩か空気のレポートで、「as the stage’s accessibility value」(ステージのアクセシビリティの値として)(60〜63、361行目でStageAccessibilityがステージのアクセシビリティの要素に与える)、content.renderingEffects.depthOfField = .disabled(133)、ビューの.taskのなかで、rig.air.prepare()のあとに1回、ステージの値に書かれる-airProbeのレポート(190〜193)、relight()を呼ぶonChange(of: clock)(248〜250)、60秒眠るタスク「The light follows the clock, a minute at a time.」(光は時計に、1分ずつ従う)(251〜257)、走査線、3ポイントごとに1本の影の線(344〜349)、ビネット、透明から透明を経て不透明度0.28の黒へ至る、半径900ポイントの放射状のグラデーション(353〜355)、RoomView(911行目で宣言、946行目でPlazaStageを作り、975行目でfitsWhole: false)。時計の@State(57)。PlazaView.words、ステータス行の言葉(819)。毎フレームrig.updateを進めるSceneEvents.Updateの購読(176〜182)。stepTraceをプレイヤーの一歩に設定するrig.onStep(156〜160)。bubbles(of:in:)、TimelineView(.animation(minimumInterval: 0.1))のもとでの頭の上の吹き出し(447〜463)。そしてPlazaView(536)、これはQuestBoardViewをシートとして表示し(690)、部屋かホールを広場の上に重ねる、「laid over it, not pushed」(プッシュせず上に重ねる)、広場はその場所の下にとどまる(719〜724)。RoomViewの「A room is entered through the veil, and its floors change under it.」(部屋にはベールを通って入り、その床はその下で変わる)(936)、そしてそのclient: nilのPlazaStage(947)。そして部屋、ショー、訪問からの広場の戻り、「out of the door gone in by, the veil lifting.」(入ったドアから出て、ベールが上がる)(678〜679)。その読み取りの時点で、Kiradex/World/にsignificantTimeChangeNotificationやNSSystemTimeZoneDidChangeのオブザーバーはなかった。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Kiradexのソース、
Kiradex/World/PlazaRig.swift、2026年10月5日16:51にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ。ファイルの日付は15:22で、行番号はその読み取りのもの):コメント「For the card alone: nothing else in the world is lit.」(カードのためだけ。世界のほかのものは何も照らされない)のもとでのカードのDirectionalLight(161行目と162行目)、リグのlight(211)、light(_:lampsOn:)(254)と、歩く人が「redrawn in the new light on the next frame」(次のフレームで新しい光のもとで描き直す)というそのコメント(262)、material(light: .white)を持つ明かりのついた窓のメッシュ(383)、そしてリグのlightを使うsheet.material(column:row:light:)からの各歩く人のフレームのマテリアル(512、508行目のadd(other:figure:tile:facing:)のなか、そして1081、animate(_:)のなか)。animate(_:)そのもの(1038)、そこでは立っている歩く人が息づかいの待機、まばたき、そして時おりidleEmotesのどれか、チック、見回し、肩をすくめる、考える、うたた寝を見せ(136)、次のものは6〜14秒後(1062)で、マテリアルが見せるフレームを歩く人のshownに記録する(1078〜1080)、つまり向きの行にシートの列数を掛け、描画の列を足したもの。プレイヤーの最初の待機のエモートは7秒、最初のまばたきは2.5秒(Walker、33〜35)。light(_:lampsOn:)でmaterial(light:)を与えられる地面、周囲、オブジェクト(257〜259)、そして波紋のなかでも、そのフレームが変わるたびに、水のあるところでは1秒に4回(231、240〜250)。showDoor(at:sheet:column:)での、リグの光を使うドアの描画(617。マテリアルは627と634)。build(tiles:collector:arrival:)(362)、これは最初に地面、周囲、オブジェクトにリグの光でmaterial(light:)を与える(363、370、376)。addQuad、いくつかのタイルの上に平らに置いた画像(346)。worldPoint(at:in:displayScale:)(459)。viewPoint(of:in:displayScale:)、ワールドの点がビューのどこに来るか(471)。update(_:)、フレームごとの更新で、ティックの時計を通して世界のティックを実行し、そのあとショーケースを回し、波紋を進め、空気を更新する(952〜966)、tick()(969)が歩く人とカメラを進める。place(_:)、歩く人の足を、そのタイルの中心から0.3タイル下に、整数のピクセルで立たせる(1088〜1097)。そしてlockCamera()(1171〜1200)、これはカメラをプレイヤーの上に、CameraLock.bounds(Kiradex/World/Motion.swift、258〜262行目、日付は12:36)がマップの端へ内側に丸める境界のなかで設定する。以前のファイルの読み取りがカメラについて引用したfollow(_:)は、もうファイルにない。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Kiradexのソース、
Kiradex/World/Daylight.swift、日付は2026年10月2日、10月5日16:51にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ。行番号はそのコピーのもの):Phase.init(hour:)(13行目)、tint(26行目、「a multiplier on the art’s own colours」(アート自身の色への乗数)、「ART SURFACE: four fixed lights for a pixel world」(アートの面:ピクセルの世界のための4つの固定された光)と宣言)、lampsOn(36行目)、Season.init(month:)(54行目、「By the month, in the north; the south is a setting for later.」(月で、北半球で。南半球はあとで設定にする))、cast(75行目)、calendar: Calendar = .currentを持つnow(_:calendar:)(86行目)、light(phase:season:)(92行目)、そして-plazaHourから読むforcedHour(101行目)。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Kiradexのソース、
Kiradex/World/Air.swift、日付は2026年10月3日、10月5日16:51にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ。行番号はそのコピーのもの):ヘッダー、「Light and air over a place, build 29 of the design plan」(場所の上の光と空気、デザイン計画のビルド29)、最後は「none of it takes the day’s tint: light is light.」(どれもその日の色合いを受けない。光は光だ)(6〜12行目)。lightingModel = .unlitとblendMode = .addを持つglowプログラムのディスクリプタと、コメント「The program says how to blend; the material says that it blends at all.」(どうブレンドするかはプログラムが言い、そもそもブレンドするかどうかはマテリアルが言う)(88〜96行目)。プール(144〜153行目)。set(phase:season:)(160行目から:夜に隠れる雲、朝の霧、秋の夜以外のすべての時間帯の葉、168行目、updateの276行目に同じ判定、夜の蛍)。makeCloud(175行目、不透明度0.55、「repeats every 384 world pixels」(ワールドの384ピクセルごとに繰り返す))。makeMist(192行目、不透明度0.7、3つのかたまり)。14枚の葉(209行目)。10匹の蛍(248行目)。-airProbeが見せるレポート(105行目と114行目で組み立てる)。そしてフレームごとの雲のオフセット、cloudOffset += SIMD2(0.004, 0.0015) * dtにcamera / 384を足したもの(266〜268行目)。深さ、cloudDepth2.4、driftDepth2.45、poolDepth2.5(19〜21行目)、葉、蛍、煙はdriftDepth(237、251、287、314)。TileMap.depth(atWorldY:)、1にマップの下へ向かって最大0.5を足したもの(Kiradex/World/TileMap.swift、122行目)。outdoors、場所が空を持つかどうか(27行目と71行目)。夜に隠れる雲(163行目)。漂うものとしての葉(207〜215行目)。そしてupdate(_:camera:view:)(262行目)。 ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Blake Crosley「Pixel-Art Structures: Houses, Halls and Interiors on iPhone」、blakecrosley.com、2026年10月3日:TL;DRの「nineteen windows and the hall’s two sconces」(19の窓とホールの2つの壁付け灯)。街灯がともると有効になる、色合いをかけない2つ目のメッシュとしての明かりのついた窓の節。アトラスの段落、「the 21 lit cells dedupe to two」(21の明かりのセルは重複をまとめると2つになる)と、2つの新しいメッシュのGPUのコストは「is not profiled yet」(まだプロファイルされていない)という注記。クリスタルの
roofs.pal。そしてStardewのNightTilesとWindowLight、https://blakecrosley.com/blog/pixel-art-structures-on-iphone ↩↩↩↩↩↩↩↩ -
Kiradexのフォージ、
scripts/forge/buildings.py、日付は2026年10月3日、10月5日16:51にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ。行番号はそのコピーのもの):モジュールのdocstring、「The ground shadow stays off the building: it belongs to the ground layer.」(地面の影は建物には付けない。それは地面のレイヤーに属する)(13〜16行目)。切妻の三角形に置く窓、形がgableで幅が少なくとも5のとき屋根のブロックの中央に置くK.window(lit=night)(91〜93行目)、建物の窓のなかに記録され(112と113)、切妻屋根の2つの建物が持つ。dormer、明かりの変種なしで描かれ、窓として記録されない屋根のピース(133行目と134行目)。そしてfinishのなかの、屋根の下3行の軒の影(195〜198行目)。 ↩↩↩↩ -
pretの逆コンパイル、シリーズ用の著者の証拠フォルダにあるシャロークローン:
pokecrystal、5beda23(2026年9月29日コミット)、pokeemerald、731ad5b(10月1日)、pokefirered、037335f(9月26日)、pokered、d2704a6(9月22日)、https://github.com/pret ↩ -
著者による読み取り、2026年10月5日:
parse_apple.py(本記事用の著者の証拠フォルダ内)、出力apple_pages.txt。その日保存した11のAppleのドキュメントのJSONページ(apple-*.html)それぞれのタイトル、要約、宣言、プラットフォームを出力する。公開前に再実行し、同一の出力を得た。 ↩↩↩ -
著者による測定、2026年10月5日、Macで:
measure_capture_walk.py(本記事用の著者の証拠フォルダ内)、出力capture_walk.txt。Pro Maxのカメラがどこに落ち着くかを、Kiradexのソースから読んだリグ自身の幾何で、シミュレーターでの実行ではなく紙の上で再生したもの(10月5日16:51、コミットcf3beb1e、その日編集されていた作業ツリー。行番号はその読み取りのもの):3倍、1テクセル8デバイスピクセルでの440×956ポイントのビュー、ワールドの165×358.5ピクセル(PlazaRig.fit、433〜456行目)。タイルの中心と点の下のタイル(TileMap.swift、234〜241行目)。タップのワールドの点(PlazaRig.worldPoint、459〜463行目)。歩ける文字(TileMap.swift、35〜53行目)、アプリはそれを書き出しの行から取る(WorldMap.swift、99〜110行目)。歩く人の足(PlazaRig.place、1088〜1097行目、シートの32×40のセルと足の下の2行はcharacters.jsonから)。そしてプレイヤーの上に設定してマップにクランプしたカメラ(PlazaRig.lockCamera、1171〜1200行目、Motion.swiftのCameraLock.bounds、258〜262行目は境界を整数のピクセルへ内側に丸める。再生が見つけるどちらの落ち着く点も境界上にないので、丸めは何も動かさない)。スクリプトのdocstringはのちにそれらの行に合わせ、以前の読み取りの数値は横のコピーに残してある。その出力は変わっていない。見つけたこと:testTheChimneysSmokeのタップは書き出しの小道具である(18, 8)に落ちるので、コレクターは(19, 13)にとどまり、カメラは(312, 278)にある。そこからhouse-dawnの帯(列18、行16〜20)とhouse-mossの行3と4の帯が25.2ピクセル以上の余裕を持ってビューに入り、小道具であるその行5も入る。横に0.02〜0.98、縦に0.05〜0.95の正規化した点のグリッド上のどのタップも、house-mineの帯をビューに入れない。そしてプレイヤーの1階の部屋では、その到着地点(7, 10)から、ビューは横にタイル2.34〜12.66にわたり、部屋の高さ全体を覆い、(3, 1)のカーテン付きの窓は完全にビューに入り、(12, 1)の窓は入らない。 ↩↩↩ -
著者による測定、2026年10月5日、Macで:
measure_palette_match.py(本記事用の著者の証拠フォルダ内)、出力palette_match.txt。5beda23のpretpokecrystalのgfx/tilesets/bg_tiles.pal(168色、うち57が異なる)、gfx/overworld/npc_sprites.pal(128、うち23が異なる)、gfx/tilesets/roofs.pal(108、うち91が異なる)のすべての色を読み、5ビットの各チャンネルを1/31でスケールし、KiradexのDaylight.swiftの8つの色の定数(テキストとして読む、28〜31行目と77〜80行目)と比べる:完全一致は2つ、どちらも純粋な白(31, 31, 31)で、29行目と78行目。ほかにはない。それ以外で最も近い組、79行目の(1, 0.93, 0.84)と(30, 28, 26)は、1つのチャンネルで0.0323、5ビットの1段階異なる。 ↩↩↩ -
著者による再生、2026年10月5日:
replay_gen3_rain_thunder.py(本記事用の著者の証拠フォルダ内)、出力gen3_replay.txt。まず、731ad5bのpretpokeemeraldのテキストに対して、依拠する慣用をアサートする:Rain_Mainの3つの状態、1回の呼び出しで1つのスプライトを作り、24個目を作る呼び出しでfalseを返すCreateRainSprite、UpdateVisibleRainSpritesの++rainSpriteVisibleCounter > rainSpriteVisibleDelay、次の天気が雨の種類のときにスプライトを保つRain_Finish、すぐにfalseを返すSunny_Finish、Task_WeatherMainの入れ替え(古い天気のfinish()をfalseまで、そのあとinitVars()、段階のカウンターのリセット、パレットの状態を変化中に設定、src/field_weather.cのなか)とUpdateWeatherColorMapの++colorMapStepCounter >= colorMapStepDelay、雷雨の準備の状態とTHUNDER_STATE_WAIT_CHANGE、そしてThunderstorm_Mainの周期のすべてのタイマーと遷移。そのうえで、それらを呼び出しごとに再生する。セクション:A、雨のスプライトがない状態からプレイ中に入る雨の種類、Task_WeatherMainが天気を入れ替えるフレームから数える(呼び出し1でシート、呼び出し2〜25で24のスプライト、最初の雨粒が有効になるのは雨で呼び出し34、重い種類で30、最後は呼び出し115、105、145。フレーム59でマップ3にあるパレット。フレーム109の雷雨の最初の稲妻。マップの読み込み時にRain_InitAllがループする呼び出し、116、106、146)。B、別の雨の種類から入る雨の種類、スプライトを保ち、数を5か9回の呼び出しごとに1粒動かす。C、THUNDER_STATE_NEW_CYCLEからの雷雨の周期を、最小の抽選、最大の抽選、そして短い稲妻1本だけで(周期の呼び出しから361〜720フレーム後の最初の落雷。6〜8フレーム光る稲妻。61〜76フレームの暗い間隔、間隔のタイマーに次の状態が要する1回の呼び出しを足したもの。30〜45フレーム最大の長い稲妻。落雷から1〜20か1〜100フレーム後の音)。 ↩↩↩↩ -
著者による測定、2026年10月5日、Macで:
measure_collector_coverage.py(本記事用の著者の証拠フォルダ内)、出力collector_coverage.txt。コミット66c116b0の時点の18:07のコピーの人物のシートとcharacters.jsonを読み、読んだとおりのCollectorComposerに従う。A、下向きのフレーム0の32×40のセル、1,280ピクセル:体のシートだけで377が不透明、123のシートすべてを一度に重ねると581(消しゴムのピクセルを不透明と数えると705)。B、立っているコレクターが見せる11の描画(PlazaRig.animate(_:))それぞれについて合成したマニフェストの既定の人物:最初の描画で408の不透明なピクセル、描画全体で374〜408、11すべてで不透明なものが290。C、保存された色の値での、チャンネルごとの夜と昼の比:既定の人物のピクセルは持ち上げた光のもとで0.787(290では0.788)、夜の色合いを丸ごと受けると0.573(0.575)、持ち上げの最も小さいチャンネルは0.75。アトラスの平均色での地面、0.588。人物の408ピクセルと地面の872ピクセルの枠全体、正しいビルドで0.638、歩く人に色合いを丸ごとかけるビルドで0.584、体の被覆で0.633、すべてのシートの被覆で0.662。セクションDとEは2026年10月15日に追加し、A〜Cはそのまま。D、各描画自身の色での290ピクセルのマスク:昼のルマは0.2989(doze_b)〜0.3161(think)。両方のキャプチャで同じ描画なら、持ち上げのもとで0.7875〜0.7884、色合いを丸ごと受けると0.5750〜0.5768。描画の121の順序付きペアにわたっては、持ち上げのもとで0.7456(昼はthink、夜はdoze_b、0.75を下回る唯一のペア)〜0.8336、色合いを丸ごと受けると最大0.6099。idle_aで保つと0.7876と0.5752。E、町のアトラスのすべての不透明なピクセル(コミットcf3beb1eの時点の16:51のコピー)での地面と、idle_aで保ったマスクを、3つのパイプラインのもとで:保存されたとおりに掛けると、地面0.5880、チャンネル(0.500, 0.580, 0.900)、マスクは持ち上げのもとで0.7876、色合いを丸ごと受けると0.5752。画像と色合いをsRGBからデコードし、掛け合わせてエンコードすると、0.5623、(0.469, 0.554, 0.892)、0.7643と0.5312。画像をデコードし、色合いの数値をリニアとして扱うと、0.7742、(0.719, 0.772, 0.951)、0.8885と0.7557。そして窓の基準、capture_walk.txtのPro Maxの到着時のビューに完全に入る24の明かりのセルのうち7つ、明かりのピクセル294、すべてが24のプールの面(Air.lightPools)の外にあり、ビューの中心から450ポイント以内。セクションF、同じ日に追加:空気の深さ、雲2.4、漂うもの2.45、プール2.5、歩く人の1〜1.5に対して(TileMap.depth)。雲の最も暗い陰、1からその最大のアルファ(255のうち110)に不透明度0.55を掛けたものを引いて、0.7627。歩く人に色合いをかけるビルドで、その陰が昼のマスクの上にあると、保存されたとおりで0.7541、リニアで0.6964、色合いの数値をリニアとして扱うと0.9908。そして到着時、(19, 13)で、コレクターの枠はワールドピクセルでx 296〜328、y 258〜298で、24のプールの面のどれとも重ならず、最も近いものから52ピクセル離れている。そして雲の陰をエンコードの前にリニアの光で取る場合、リニアで0.6076、色合いの数値をリニアとして扱うと0.8645。セクションG、同じ日に追加:パイプラインの見本、保存値51と102の2つの灰色を0.25の固定の色合いのもとで描いたもの、3つのパイプラインはそれを13と26、6と20、22と51にし、どの2つも6段階より近づかない。そしてマテリアルがすべての色合いをもう一度半分持ち上げるビルドで、その見本は32と64と読まれ、最も近いものから13段階離れ、その夜は保存されたとおりで、地面0.794024、チャンネル(0.750, 0.790, 0.950)、マスク0.893804を与える。セクションH、そのあとに追加:見本の位置、Pro Maxのビューのポイントでx 24〜56、y 462〜478、その最も遠い隅は中心から196.7ポイント。到着時、ビューのポイントで、コレクターの枠はx 177.3〜262.7、y 424.7〜531.3で、見本と重ならず、7つの基準の窓は見本から266.7ポイント以上、チェック8の7つの帯は144.0以上離れている。出荷された画像からの計算であって、キャプチャではない。 ↩↩↩↩↩↩↩↩↩↩↩↩↩ -
pret、
pokecrystal/constants/ram_constants.asm、5beda23、2026年10月5日閲覧:wTimeOfDayとその値MORN、DAY、NITE、DARKNESS(142〜147行目)、https://github.com/pret/pokecrystal/blob/master/constants/ram_constants.asm ↩ -
Blake Crosley「Pixel-Art Worlds on iPhone: What the 16-Bit Masters Knew」、blakecrosley.com、2026年10月3日:第2世代の段落(「time of day in Johto is a 64-byte palette reload」(ジョウトの時間帯は64バイトのパレットの読み込み直しだ)。8つの名前付きパレット)、ライティングの段階表(Moonlighter、Celeste、Eastward、HD-2D。HD-2Dは「costs more than you’d think」(思っているより費用がかかる)。Octopath Traveler IIのプレイヤーは被写界深度をオフにする)、RealityKitのレシピ、そしてチェックリストの「Dusk and night as one multiply tint over the world plus hand-drawn emissive variants for lamps, windows and the kiosk sign」(夕暮れと夜は世界全体に1つの乗算の色合いとし、街灯、窓、キオスクの看板には手描きの発光の変種を加える)、https://blakecrosley.com/blog/pixel-art-world-on-iphone ↩↩↩↩↩↩↩
-
pret、
pokecrystal/data/maps/environment_colors.asm、5beda23、2026年10月5日閲覧:EnvironmentColorsPointers(1〜12行目:TOWNとROUTEは.OutdoorColorsへ、INDOORとGATEは.IndoorColorsへ、CAVEとDUNGEONは.DungeonColorsへ、ENVIRONMENT_5は.Env5Colorsへ)、各表は時間帯ごとに8つのパレットのインデックスの1行。.OutdoorColors(15〜19)、そのWATERのインデックスは朝と昼が$28、夜が$29で、ファイルの屋外の水の組であり、ほかの7つはブロック自身のもの。.IndoorColors(21〜25)、朝と昼は屋内ブロック$20〜$26とTEXT$07、そのあとに夜と暗闇のブロック。.DungeonColorsと.Env5Colors(27〜37)、ブロックをそのまま、https://github.com/pret/pokecrystal/blob/master/data/maps/environment_colors.asm ↩↩ -
pret、
pokecrystal/engine/gfx/color.asm、5beda23、2026年10月5日閲覧:LoadMapPals(1197行目から:まず1198行目でfarcall LoadSpecialMapPalette、1199行目でjr c, .got_pals、これはそのルーチンがキャリーを立てたときに背景のコピーを飛ばす。そうでなければ8バイトの背景パレット8つ。1257行目の.got_palsから、1261行目のMapObjectPalsからの8つのオブジェクトパレット。そして1269行目のcp TOWNのあと、TOWNかROUTEでは1280行目のRoofPalsからのマップグループの屋根の色、1284行目のcp NITE_FでNITEとDARKNESSには夜の組、1290〜1291行目でwBGPals1 palette PAL_BG_ROOF color 1へ4バイト、つまりROOFの色1と2。8つの背景のインデックスは1206行目のEnvironmentColorsPointersから、環境と時間帯ごとに来る)、そしてpokecrystal/engine/tilesets/tileset_palettes.asm、LoadSpecialMapPalette(1〜53行目:TILESET_POKECOM_CENTER、TILESET_BATTLE_TOWER_INSIDE、環境がINDOORでない限りのTILESET_ICE_PATH(殿堂入り)、TILESET_HOUSE、TILESET_RADIO_TOWER、TILESET_MANSIONについて独自の表を読み込んだあとにキャリーを立てる。51行目の.do_nothingがそれをクリアする)、https://github.com/pret/pokecrystal/blob/master/engine/gfx/color.asm ↩↩↩↩↩↩ -
pret、
pokecrystal/gfx/tilesets/johto_palette_map.asm、5beda23、2026年10月5日閲覧:ジョウトのタイルセットの192タイルそれぞれのパレット、https://github.com/pret/pokecrystal/blob/master/gfx/tilesets/johto_palette_map.asm ↩ -
pret、
pokecrystal/gfx/tilesets/roofs.pal、5beda23、2026年10月5日閲覧:27のエントリ、マップグループごとに朝と昼の組と夜の組、https://github.com/pret/pokecrystal/blob/master/gfx/tilesets/roofs.pal ↩ -
pret、
pokecrystal/engine/overworld/events.asm、5beda23、2026年10月5日閲覧:HandleMapTimeAndJoypad(193行目)、これはwMapEventStatusがMAPEVENTS_OFFのときに戻り(194〜196行目)、そうでなければUpdateTime、GetJoypad、TimeOfDayPalsを呼ぶ(198〜200行目)、https://github.com/pret/pokecrystal/blob/master/engine/overworld/events.asm ↩↩ -
pret、
pokecrystal/data/maps/setup_scripts.asm、5beda23、2026年10月5日閲覧:12のマップ準備スクリプト(4〜15行目の表)。MapSetupScript_Fly(29行目、30行目にmapsetup FadeOutToWhite、32行目のMapSetupScript_Warpへ流れ込み、そのmapsetup FadeInFromWhiteは52行目で、終わりの2コマンド前)。MapSetupScript_Door(102、103行目にmapsetup FadeOutToWhite、104行目のMapSetupScript_Trainへ流れ込み、そのmapsetup FadeInFromWhiteは121行目)。MapSetupScript_Connection(81)にはフェードがなく、FadeInFromBlackやFadeOutToBlackを名指しするスクリプトはない。さらにengine/overworld/events.asmの1005行目、WarpToNewMapScriptのnewloadmap MAPSETUP_DOOR、プレイヤーが踏むワープが実行する準備。engine/events/overworld.asmの619行目、newloadmap MAPSETUP_FLY。engine/overworld/scripting.asmの2074行目、スクリプトのコマンドwarpのためのMAPSETUP_WARP。home/map.asm、FadeToMenu(1910、1914行目にfarcall FadeOutToWhite)、CloseSubmenu(1919)とExitAllMenus(1927)、これらはReloadTilesetAndPalettes(1966、そのfarcall UpdateTimeOfDayPalは1979行目)を呼び、FinishExitMenu(1933、1938行目にfarcall FadeInFromWhite)で終わる。スタートメニュー、engine/menus/start_menu.asm:StartMenu(13行目)、独自のFadeの呼び出しはなく、39、44、92行目にcall UpdateTimePals(home/time_palettes.asmの20行目、UpdateTimePalsが_UpdateTimePalsを呼ぶ)、その.Exit(80)、そしてcall FadeToMenuする6つの項目、StartMenu_Option(447)、StartMenu_Status(455)、StartMenu_Pokedex(466)、StartMenu_Pokegear(475)、StartMenu_Pack(482)、StartMenu_Pokemon(501)、これらはCloseSubmenu、ExitAllMenus、またはメニューの.Clear(155行目にcall FinishExitMenu)を通って戻る。FadeToMenuはmobile/とhome/map.asmの外の8つのファイルで21回呼ばれ、そのうち6回がスタートメニューで、ほかはengine/events/specials.asm(8)、engine/pokemon/mail.asm(2)、そしてengine/items/mart.asm、engine/events/pokecenter_pc.asm、engine/overworld/select_menu.asm、engine/events/move_tutor.asm、engine/events/battle_tower/battle_tower.asmにそれぞれ1回で、gen2_daylight.txtのセクションEが数えた。そして黒の組をspecialで呼ぶ11のマップスクリプト、それぞれ出ると入るが1回ずつ:本文が名指しする3つ、maps/SproutTower3F.asm(55行目と59行目)、Route24(29、33)、TeamRocketBaseB2F(110、118)、そしてさらに8つで、それぞれ2つの行とともにgen2_daylight.txtのセクションEに挙げてある、https://github.com/pret/pokecrystal/blob/master/data/maps/setup_scripts.asm ↩↩ -
pret、
pokecrystal/data/maps/maps.asm、5beda23、2026年10月5日閲覧:mapマクロ(1〜15行目、8つのフィールド:マップ、そのタイルセット、環境、ランドマーク、音楽、電話のフラグ、パレットのモード、釣りのグループ)、26のマップグループのポインター(17〜46)、そして388のマップヘッダー、それぞれが環境とパレットのモードを持ち、そのなかには5つのラジオ塔のフロア(95〜99)があり、その音楽のフィールドは式RADIO_TOWER_MUSIC | MUSIC_GOLDENROD_CITY。27のPALETTE_NITEのマップのうち、IlexForest(130行目)とTohjoFalls(161行目)はCAVE、BurnedTower1FはDUNGEON(91行目)、DragonShrineはINDOOR(160行目)、UndergroundPathはGATE(164行目)、https://github.com/pret/pokecrystal/blob/master/data/maps/maps.asm ↩↩ -
pret、
pokered/home/overworld.asm、d2704a6、2026年10月5日閲覧:ワープのコードのROCK_TUNNEL_1Fの判定とld [wMapPalOffset], a(497〜500行目)、https://github.com/pret/pokered/blob/master/home/overworld.asm ↩↩↩ -
pret、
pokered/home/fade.asm、d2704a6、2026年10月5日閲覧:オフセットを引いたFadePal4から読むLoadGBPalと、FadePal2:: dc 3,3,3,2, 3,3,3,2, 3,3,2,0(66行目)、https://github.com/pret/pokered/blob/master/home/fade.asm ↩ -
pret、
pokered、d2704a6、2026年10月5日閲覧:wMapPalOffsetへのすべての書き込み。home/overworld.asmの500行目(6、屋外のマップからROCK_TUNNEL_1Fへのワープで)、535行目(0、外へ戻るワープで。屋内の分岐、508行目の.indoorMapsはそれを書かない)、790行目(0、HandleFlyWarpOrDungeonWarpのなか)。engine/menus/start_sub_menus.asmの187行目(0、「フラッシュ」)。engine/events/black_out.asmの7行目(0)。engine/battle/init_battle_variables.asmの18行目(戦闘のための0)、engine/battle/core.asmが6667行目でプッシュし6768行目でポップする値から戻される。そしてdata/maps/objects/RockTunnelB1F.asm、その4つのwarp_eventの行(15〜18)はすべてROCK_TUNNEL_1Fへ通じる、https://github.com/pret/pokered ↩ -
Blake Crosley「A Pixel Town Alive When Nobody Is Online: NPCs and Ghosts」、blakecrosley.com、2026年10月5日:エメラルドの
UpdatePerDayとそれが呼ぶ関数、そのなかのUpdateWeatherPerDay。そしてその第7.1節の、ブリーフの部屋の時計:「Every room runs on one clock: the server’s time in UTC, read in the room’s own time zone, one IANA zone per room in the server’s configuration」(どの部屋も1つの時計で動く。UTCのサーバー時刻を、部屋自身のタイムゾーンで読む。サーバーの設定で部屋ごとに1つのIANAゾーン)、welcomeと静かな広場の応答で{"zone": "<IANA name>", "clock": <server ms>}として送られ、「and while the plaza is open the app takes its day-part from them rather than from the phone, so everyone in a room sees the same townspeople under the same light」(広場が開いているあいだ、アプリは時間帯をスマートフォンではなくそこから取るので、部屋の全員が同じ光のもとで同じ町の人を見る)、「Outside the plaza the phone’s clock stays the collector’s」(広場の外では、スマートフォンの時計がコレクターのものであり続ける)、Calendar.currentを読む今日のDaylight.now、そしてそのチェック(b)、「a client test with the phone’s zone set to a different one from the room’s asserts that the plaza’s day-part follows the room’s clock」(スマートフォンのゾーンを部屋と異なるものに設定したクライアントのテストが、広場の時間帯が部屋の時計に従うことをアサートする)、https://blakecrosley.com/blog/pixel-art-town-alive-when-nobody-is-online ↩↩↩↩↩↩↩↩↩ -
pret、
pokeemerald/include/constants/weather.h、731ad5b、2026年10月5日閲覧:WEATHER_NONE(4行目)からWEATHER_ROUTE123_CYCLE(21行目)までの18のWEATHER_*の値、SNOW、FOG_DIAGONAL、UNDERWATERを未使用と記すコメントとSHADEの「Original name was closer to WEATHER_CLOUDY/OVERCAST」(元の名前はWEATHER_CLOUDY/OVERCASTに近かった)、そして13のCOORD_EVENT_WEATHER_*の値、https://github.com/pret/pokeemerald/blob/master/include/constants/weather.h ↩ -
pret、
pokeemerald/src/trig.c、731ad5b、2026年10月5日閲覧:gSineTable(5行目)、https://github.com/pret/pokeemerald/blob/master/src/trig.c ↩ -
W3C Web Accessibility Initiative「Understanding Success Criterion 2.3.1: Three Flashes or Below Threshold」、WCAG 2.2 Understanding Docs、2026年10月5日に本記事用の著者の証拠フォルダに
wcag-three-flashes.htmlと.txtとして保存(レベルA。「Web pages do not contain anything that flashes more than three times in any one second period, or the flash is below the general flash and red flash thresholds」(ウェブページは、どの1秒間にも3回より多く閃光を放つものを含まないか、閃光が一般閃光と赤色閃光のしきい値を下回る)。「Flashing content can cause migraines, dizziness, nausea, and seizures」(閃光を放つコンテンツは片頭痛、めまい、吐き気、発作を引き起こすことがある))、https://www.w3.org/WAI/WCAG22/Understanding/three-flashes-or-below-threshold.html ↩↩↩↩↩↩↩ -
pret、
pokeemerald/data/maps/*/map.json、731ad5b、2026年10月5日にmeasure_gen3_weather.pyで閲覧:518のマップ、各ヘッダーのweather、map_type、requires_flash、coord_events。例:https://github.com/pret/pokeemerald/blob/master/data/maps/Route119/map.json ↩ -
pret、
pokefirered/data/maps/*/map.json、037335f、2026年10月5日にmeasure_gen3_weather.pyで閲覧:425のマップ、https://github.com/pret/pokefirered/tree/master/data/maps ↩ -
pret、
pokeemerald/src/field_screen_effect.c、731ad5b、2026年10月5日閲覧:sFlashLevelToRadiusとgMaxFlashLevel(53行目と54行目)、そしてDISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2を中心とするフラッシュの効果(980行目)、https://github.com/pret/pokeemerald/blob/master/src/field_screen_effect.c ↩ -
pret、
pokeemerald/src/overworld.c、731ad5b、2026年10月5日閲覧:SetDefaultFlashLevel(971〜979行目:gMapHeader.caveが設定されていなければレベル0、FLAG_SYS_USE_FLASHがあれば1、そうでなければgMaxFlashLevel - 1)、そしてinclude/global.fieldmap.hの180行目、ヘッダーのu8 cave、これはtools/mapjson/mapjson.cppの164行目が各マップのrequires_flashから書き込む、https://github.com/pret/pokeemerald/blob/master/src/overworld.c ↩ -
pret、
pokeemerald/graphics/field_effects/pics/、731ad5b(shadow_small.png、shadow_medium.png、shadow_large.png、shadow_extra_large.png)、2026年10月5日にmeasure_shadows.pyで閲覧。再現していない、https://github.com/pret/pokeemerald/tree/master/graphics/field_effects/pics ↩ -
Blake Crosley「Pixel-Art Ledges, Stairs and Bridges in a Tile World」、blakecrosley.com、2026年10月5日:その第3節「The shadow stays on the ground」(影は地面に残る)、赤、クリスタル、エメラルドで地面に残るジャンプの影。そして2023年8月29日のScreen Rantのインタビューからの、Sabotage StudioのThierry Boulangerの引用、レベルが「to all read well with different levels of height, with the light and everything」(異なる高さで、光やすべてとともに、どれもよく読めるように)する必要があった(https://screenrant.com/sea-stars-interview-thierry-boulanger/)、https://blakecrosley.com/blog/pixel-art-elevation-ledges-bridges ↩↩↩
-
Stardew Valley Wiki「Modding:Maps」、2026年10月5日に本記事用の著者の証拠フォルダに
sdv-modding-maps.htmlと.txtとして保存(ライティングのプロパティAmbientLight、9種類の光を持つLight、WindowLight。そしてNightTiles、「Changes the tile after 7pm」(午後7時以降にタイルを変える)、「mostly used for lamps in the game」(ゲームでは主に街灯に使われる))、https://stardewvalleywiki.com/Modding:Maps ↩↩↩↩↩↩ -
80.lv「Moonlighter: Building Pixel Art & Preparing for Switch」、Digital Sunへのインタビュー、2026年10月5日に本記事用の著者の証拠フォルダに
moonlighter-80lv.htmlと.txtとして保存、https://80.lv/articles/moonlighter-building-pixel-art-preparing-for-switch ↩ -
Noel Berry「Remaking Celeste’s Lighting」、2017年9月25日、2026年10月5日に本記事用の著者の証拠フォルダに
celeste-lighting.htmlと.txtとして保存、https://noelberry.ca/posts/celeste_lighting/ ↩↩ -
Game Developer「Eastward’s creators share insights on making pixel art adventures」、PixpilのTommo Zhouへのインタビュー、2021年10月11日、2026年10月5日に本記事用の著者の証拠フォルダに
eastward-gamedev.htmlと.txtとして保存、https://www.gamedeveloper.com/art/eastward-s-creators-share-insights-on-making-pixel-art-adventures ↩↩ -
Nintendo Everything、Octopath Travelerの開発者へのNintendo Dreamのインタビューの翻訳、2018年11月3日、2026年10月5日に本記事用の著者の証拠フォルダに
octopath-ne.htmlと.txtとして保存(ライティングについてのShizuka MorimotoとTomoya Asano)、https://nintendoeverything.com/octopath-traveler-devs-on-character-origins-visual-style-initial-hd-rumble-plans-much-more/ なお、Unreal EngineのOctopath Travelerの2つのページは、フェッチャーにもcurlにもHTTP 403を返した(octopath-ue.htmlはその403のページ)。 ↩↩ -
Wikipedia「HD-2D」、2026年10月5日に本記事用の著者の証拠フォルダに
hd2d-wiki.htmlと.txtとして保存。二次資料(「Typically, a point light source is placed into the scene to make characters and objects cast shadows」(通常は、キャラクターと物に影を落とさせるために点光源が場面に置かれる))、https://en.wikipedia.org/wiki/HD-2D ↩ -
Alana Hagues「Triangle Strategy Producers Talk HD-2D And Why Other Devs Haven’t Used it」、Nintendo Life、2022年5月30日、Tomoya Asano氏とYasuaki Arai氏の4Gamerのインタビューを報じたもので、リードは「It costs more than you’d think」(思っているより費用がかかる)、2026年10月5日に本記事用の著者の証拠フォルダに
triangle-nlife.htmlと.txtとして保存、https://www.nintendolife.com/news/2022/05/triangle-strategy-producers-talk-hd-2d-and-why-other-devs-havent-used-it ↩↩ -
Sabotage Studio、Sea of Starsのプレスキット、2026年10月5日に本記事用の著者の証拠フォルダに
sos-presskit.htmlと.txtとして保存、https://sabotagestudio.com/presskits/sea-of-stars/ ↩ -
TechRaptor「Sea of Stars Gameplay Clip Shows Day & Night Cycle」、2026年10月5日に本記事用の著者の証拠フォルダに
sos-techraptor.htmlと.txtとして保存、https://techraptor.net/gaming/news/sea-of-stars-gameplay-clip-shows-day-night-cycle ↩ -
Raymond Schlitter「Pixelblog 21: Top Down Objects」、SLYNYRD、2026年10月5日に本記事用の著者の証拠フォルダに
slynyrd-objects.htmlと.txtとして保存、https://www.slynyrd.com/blog/2019/9/18/pixelblog-21-top-down-objects ↩↩↩ -
Raymond Schlitter「Pixelblog 43: Top Down Tiles Part 2」、SLYNYRD、2026年10月5日に本記事用の著者の証拠フォルダに
slynyrd-tiles2.htmlと.txtとして保存、https://www.slynyrd.com/blog/2023/3/26/pixelblog-43-top-down-tiles-part-2 ↩↩↩↩↩↩↩↩ -
Raymond Schlitter「Pixelblog 44: Top Down Trees」、SLYNYRD、2026年10月5日に本記事用の著者の証拠フォルダに
slynyrd-trees.htmlと.txtとして保存、https://www.slynyrd.com/blog/2023/5/22/pixelblog-44-top-down-trees ↩ -
Shmuplations、聖剣伝説3についての石井浩一氏への翻訳インタビュー、2026年10月5日に本記事用の著者の証拠フォルダに
sd3-shmuplations.htmlと.txtとして保存、https://shmuplations.com/seikendensetsu3/ ↩↩↩↩ -
Kiradexのソース、
Kiradex/World/Glow.metal、日付は2026年10月3日、10月5日16:51にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ):glowSurface、画像の色に色合いを掛けたものをベースの色と発光の色の両方として不透明度1で設定する。コメント「Light that adds, as light does」(光がするように、足す光)と、その行「black adds nothing, and a pool of light never darkens what it lies on, which an alpha halo did.」(黒は何も足さない。光のプールは自分が載っているものを決して暗くしない。アルファのハローはそうしていた)のもとにある(6〜10行目)。 ↩↩↩↩↩↩ -
Kiradexのフォージ、
scripts/forge/air.py、日付は2026年10月3日、10月5日16:51にコミットcf3beb1eの時点で閲覧(非公開リポジトリ):docstringの画像、glow.png(「a radial pool, white at the centre falling to black」(中心が白く、黒へ落ちていく放射状のプール))とcloud.png(「a tileable mask of cloud shadow: alpha where a cloud passes」(タイル状に並べられる雲の影のマスク。雲が通るところにアルファがある))、9〜13行目。 ↩↩ -
Kiradexのテスト、
KiradexUITests/KiradexUITests.swift、2026年10月5日16:51にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ):testThePlazaKeepsTime(502行目)、-plazaHour 21と-airProbeで起動(503)。そしてtestTheChimneysSmoke(523)、-plazaHour 12で起動し(524)、空気のレポートがsmoke 18を含むのを待ち(531行目と532行目)、そのあと歩きが「Up the grand stair onto the terrace, left of the fountain」(大階段を上ってテラスへ、噴水の左へ)向かうというコメントのもとで(534〜537行目)、広場の正規化した(0.38, 0.3)をタップする(538)。ヘルパーのwait(for:toRead:)(1171行目)、launch(1179行目、app.launch()の前にlaunchArgumentsを設定する)、save(1212行目、画面のスクリーンショット)。ファイルの日付は2026年10月5日10:32で、行番号はそのコピーのもの。 ↩↩↩↩↩↩↩ -
Kiradexのソース、
Kiradex/World/HallView.swift、2026年10月5日16:51にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ。ファイルの日付はその日の14:59):ファイルを開くコメント「The show hall: off the plaza」(ショーのホール:広場の外)(5行目)、そしてホールは「is not networked」(ネットワークにつながっていない)こと、広場が入るときに部屋を離れること(9〜11)。「The show is entered through the veil.」(ショーにはベールを通って入る)(34)。そしてそれが作るPlazaStage(57)、client: nil付き(58)。コミットが66c116b0だった18:07にも、ファイルは同じバイトだった。 ↩↩↩↩ -
Kiradexのデザイン計画、
docs/research/design/01-art-direction-v2.md、日付は2026年10月3日、10月5日16:51にコミットcf3beb1eの時点で閲覧(非公開リポジトリ):第4節「The plan, by build,」(ビルドごとの計画)、そのビルド29は光のプール、雲の影、霧、葉、蛍、そして「a vignette and tilt-shift depth of field as the camera’s rendering effects」(カメラのレンダリング効果としてビネットとティルトシフトの被写界深度)を挙げている。 ↩↩ -
Apple Developer Documentation、
UnlitMaterial(RealityKit)、2026年10月5日に本記事用の著者の証拠フォルダにapple-unlitmaterial.htmlとして保存したページのJSON:「A material that doesn’t respond to lights in the scene」(シーンの光に反応しないマテリアル)。iOS 13.0以降、macOS 10.15以降。そしてそのトピックのリストのなかのtextureCoordinateTransform、「A two-dimensional transformation to apply to the entity’s primary texture coordinates」(エンティティの主テクスチャ座標に適用する2次元の変換)、オフセットとスケールの順序についての記述はない。そしてinit(applyPostProcessToneMap:)、「Creates an UnlitMaterial with the given tone mapping setting」(指定したトーンマッピングの設定でUnlitMaterialを作る)、素のイニシャライザがトーンマッピングについて何をするかの記述はない、https://developer.apple.com/documentation/realitykit/unlitmaterial ↩↩↩ -
Kiradexのソース、
Kiradex/World/SpriteSheet.swift、日付は2026年10月3日、10月5日16:51にコミットcf3beb1eの時点で閲覧(非公開リポジトリ。行番号はそのコピーのもの):オフセット(列 ÷ 列数、行 ÷ 行数)とスケール(1 ÷ 列数、1 ÷ 行数)を持つフレームのマテリアルのtextureCoordinateTransform(65行目)、オフセットはテクスチャの左上から測ると記録するコメント、「measured on the simulator」(シミュレーターで測った)のもとにある。semantic: .colorで作ったシートのテクスチャ(37)。そして素のUnlitMaterial()を作るmaterial(light:)(75と76)。さらにAir.swiftの223行目、煙のフレームも同じように設定されている。 ↩↩ -
Kiradexのソース、
Kiradex/World/Motion.swift、2026年10月5日17:18にコミットcf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ。ファイルの日付はその日の12:36で、コミットが66c116b0だった18:07にも同じバイト):そのヘッダー、モーションの記事のブリーフを出典として名指しする(3〜6行目)。TickClock、ディスプレイのレートにかかわらず世界に整数の60分の1秒を渡す、ticksPerSecond = 60(14〜52、定数は17)。Stride.pixels、16(57)、そしてStride.ticks(diagonal:running:)(67〜74):まっすぐな歩きの一歩に16ティック、走りで8、斜めで23と12。そしてStepping.tick()(215)、ティックの数がストライドのものに達すると一歩を終える。measure_kiradex_proposals.pyとarith.pyは3つの数値をこのコピーから読む。 ↩↩↩↩ -
Kiradexのフォージ、
scripts/forge/town.py、日付は2026年10月3日、10月5日16:51にコミットcf3beb1eの時点で閲覧(非公開リポジトリ。行番号はそのコピーのもの):凡例の「a lamp post on paving (as l, with its shadow in the stone’s shade)」(敷石の上の街灯の柱(lと同じで、その影は石の陰の色))(29行目)。paintのなか(403行目から)の壁の影、「the top four rows of whatever stands at its foot」(その足もとにあるものの上の4行)、1段階暗く、「the way the light falls at Leene.」(Leeneでの光の落ち方)(426〜436行目)。 ↩↩↩↩ -
Kiradexのソース、
Kiradex/World/FigurePreview.swift、日付は2026年10月4日、10月5日16:51にコミットcf3beb1eの時点で閲覧(非公開リポジトリ):25行目の@Environment(\.accessibilityReduceMotion)、Kiradex/World/でこの設定を読む唯一の箇所。 ↩ -
Kiradexのソース、
Kiradex/World/PlazaClient.swift、日付は2026年10月3日、10月5日17:42にコミット5a344e3fの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ):handle(_:)のcase "welcome":(214行目)、これはサーバーのwelcomeからyou、room、lines、playersを取り、ほかには何も取らない。endpoint(87〜91行目)、これは起動引数から-plazaServerを読み、そのコメントの例ws://127.0.0.1:8300/v1/plazaでは「points a run at a local」(実行をローカルのものに向ける)サーバーで、そうでなければ本番のwss://のエンドポイントを使う。ファイルのどこでもzoneやclockは読まれていない。18:19にコミット66c116b0の時点で読み直した:同じバイト。 ↩↩↩ -
Blake Crosley「Pixel-Art Motion: Walks, Cameras and Doors on iPhone」、blakecrosley.com、2026年10月5日:ブリーフの項目1、「The walk is 1 pixel a tick, 16 ticks a tile; the run is 2 pixels a tick, 8 ticks」(歩きは1ティックに1ピクセル、1タイルに16ティック。走りは1ティックに2ピクセル、8ティック)、60ヘルツのティックで、歩きは毎秒60ピクセル。アプリは今日そのティックとストライドを
Motion.swiftで実行している(第7節)、https://blakecrosley.com/blog/pixel-art-motion-on-iphone ↩↩ -
Apple Developer Documentation、
MaterialParameterTypes.BlendMode(RealityKit)、2026年10月5日に本記事用の著者の証拠フォルダにapple-mpt-blendmode.htmlとして保存したページのJSON:「Modes that describe how materials should be blended with content behind them」(マテリアルを背後のコンテンツとどうブレンドするかを表すモード)。列挙ケースaddとalpha。iOS 18.0以降、iPadOS 18.0以降、Mac Catalyst 18.0以降、macOS 15.0以降、tvOS 26.0以降、visionOS 2.0以降、https://developer.apple.com/documentation/realitykit/materialparametertypes/blendmode ↩↩↩↩↩↩ -
Apple Developer Documentation、
MaterialParameterTypes.BlendMode.add、2026年10月5日に本記事用の著者の証拠フォルダにapple-blendmode-add.htmlとして保存したページのJSON:「Blend by adding the material’s color to the background color, ignoring alpha」(アルファを無視し、マテリアルの色を背景の色に足してブレンドする)。「also known as additive blending or linear dodge」(加算ブレンドやリニアドッジとしても知られる)。同じ対応状況、https://developer.apple.com/documentation/realitykit/materialparametertypes/blendmode/add ↩↩ -
Apple Developer Documentation、
CustomMaterial(RealityKit)、2026年10月5日に本記事用の著者の証拠フォルダにapple-custommaterial.htmlとして保存したページのJSON:「A material that works with custom Metal shader functions」(カスタムのMetalシェーダー関数とともに動くマテリアル)。iOS 15.0以降、iPadOS 15.0以降、Mac Catalyst 15.0以降、macOS 12.0以降、tvOS 26.0以降、https://developer.apple.com/documentation/realitykit/custommaterial ↩ -
Apple Developer Documentation、
TimelineView(SwiftUI)、2026年10月5日に本記事用の著者の証拠フォルダにapple-timelineview.htmlとして保存したページのJSON:「A view that updates according to a schedule that you provide」(指定したスケジュールに従って更新されるビュー)。iOS 15.0以降、https://developer.apple.com/documentation/swiftui/timelineview ↩ -
Apple Developer Documentation、
TimelineSchedule.everyMinute(SwiftUI)、2026年10月5日に本記事用の著者の証拠フォルダにapple-everyminute.htmlとして保存したページのJSON:「A schedule for updating a timeline view at the start of every minute」(毎分の始めにタイムラインビューを更新するスケジュール)。iOS 15.0以降、https://developer.apple.com/documentation/swiftui/timelineschedule/everyminute ↩ -
Apple Developer Documentation、
UIApplication.significantTimeChangeNotification(UIKit)、2026年10月5日に本記事用の著者の証拠フォルダにapple-significanttime.htmlとして保存したページのJSON:「when, for example, there’s a change to a new day (midnight), a carrier time update, or a change to, or from, daylight savings time」(たとえば新しい日への変化(真夜中)、通信事業者による時刻の更新、夏時間への、または夏時間からの変化があったとき)に送られる。ページはiOS、iPadOS、Mac Catalyst、tvOS、visionOSをバージョンなしで挙げている、https://developer.apple.com/documentation/uikit/uiapplication/significanttimechangenotification ↩↩↩↩↩↩ -
Apple Developer Documentation、
NSNotification.Name.NSSystemTimeZoneDidChange(Foundation)、2026年10月5日に本記事用の著者の証拠フォルダにapple-systemtimezonechange.htmlとして保存したページのJSON:「A notification posted when the time zone changes」(タイムゾーンが変わったときに送られる通知)。iOS 2.0以降、https://developer.apple.com/documentation/foundation/nsnotification/name-swift.struct/nssystemtimezonedidchange ↩↩↩ -
Apple Developer Documentation、
EnvironmentValues.timeZone(SwiftUI)、2026年10月5日に本記事用の著者の証拠フォルダにapple-timezone.htmlとして保存したページのJSON:「The current time zone that views should use when handling dates」(ビューが日付を扱うときに使うべき現在のタイムゾーン)。iOS 13.0以降、https://developer.apple.com/documentation/swiftui/environmentvalues/timezone ↩ -
Apple Developer Documentation、
EnvironmentValues.accessibilityReduceMotion(SwiftUI)、2026年10月5日に本記事用の著者の証拠フォルダにapple-reducemotion.htmlとして保存したページのJSON:「Whether the system preference for Reduce Motion is enabled」(Reduce Motionのシステム設定が有効かどうか)。「If this property’s value is true, UI should avoid large animations, especially those that simulate the third dimension」(このプロパティの値がtrueなら、UIは大きなアニメーション、特に3次元を模したものを避けるべきだ)。var accessibilityReduceMotion: Bool { get }と宣言。iOS 13.0以降、https://developer.apple.com/documentation/swiftui/environmentvalues/accessibilityreducemotion ↩↩↩↩ -
Apple Developer Documentation、WeatherKit、2026年10月5日に本記事用の著者の証拠フォルダに
apple-weatherkit.htmlとして保存したページのJSON:「Deliver weather conditions and alerts to your users」(ユーザーに気象状況と警報を届ける)。iOS 16.0以降、https://developer.apple.com/documentation/weatherkit ↩↩↩ -
Kiradexのソース、
Kiradex/World/CollectorComposer.swift、2026年10月5日18:07にコミット66c116b0の時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ。ファイルの日付は10月4日07:40)、Kiradex/Resources/World/characters.json(日付は10月4日07:20、16:51の読み取りのときと同じバイト)と、同じときにコピーした123の人物のシートfig-*.pngとともに:ヘッダー、どのシートも「an 8-bit plane whose value is an index × 2 (0 clear, 63 the eraser」(値がインデックス × 2である8ビットの面(0が透明、63が消しゴム))(5〜14行目)。sparse(_:)、面の不透明なピクセル、つまり透明でも消しゴムでもないもの(66)。layers(for:)、常に体、目、持っているカードを加える(131)。そしてindexPlane(for:)、各向きについてマニフェストの順にレイヤーを重ね、最後の不透明なインデックスが勝つ(153)。 ↩↩ -
Kiradexリポジトリ、2026年10月15日23:53にgitを実行せずに閲覧:ファイルとして読んだ
.git/refs/heads/main、fc9d4876(10月15日17:45にコミット)。以下の各ファイルはそのコミットのオブジェクトからzlibで取り出し、作業ツリーのコピーとバイト単位で比べ、どの場合も同じだった(非公開リポジトリ。行番号はそのコミットのもの):Kiradex/World/PlazaClient.swift、roomClockとroomZone(79〜83)、roomDate、「The room’s time now, from the welcome’s clock」(welcomeの時計から得た、部屋の今の時刻)(109〜113)、そしてjson["clock"]とjson["zone"]を読むwelcomeのハンドラー(265〜267)。server/app/main.py、"zone"と"clock"を運ぶwelcome(21、22、228)とZONE、「one for the whole world until rooms are sharded by region」(部屋が地域ごとに分割されるまでは世界全体で1つ)、PLAZA_ZONEが設定されていなければUTC(77〜79)。Kiradex/World/PlazaStage.swift、clock「re-read each minute: the light follows it」(毎分読み直す。光はそれに従う)(64と65)、それを読むrelight()(86)、そして「A quiet plaza joins no room」(静かな広場はどの部屋にも参加しない)(919)。scripts/forge/protected_names.txt、「Names the world never uses」(世界が決して使わない名前)、そしてserver/tests/test_names.py、「The deny list: no franchise word and no canon place in anything the world names」(拒否リスト:世界が名付けるものには、フランチャイズの語も正典の場所も入れない)。作業ツリーのKiradex/とKiradexTests/でsignificantTimeChangeとNSSystemTimeZoneDidChangeを検索したが、何も見つからなかった。読み取りのスクリプトとコピーは本記事用の著者の証拠フォルダにある。 ↩↩↩ -
Kiradexのソース、2026年10月5日16:51にコミット
cf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ):Kiradex/World/QuestBoardView.swift(日付は10月2日)、クエストボード、独自のビューで、PlazaStage.swiftのPlazaViewから(日付17:22のファイルの690行目、17:42にコミット5a344e3fの時点で読んだ)と、Kiradex/Views/Me/MeView.swiftから(日付07:52のファイルの65行目)シートとして表示される。 ↩ -
Blake Crosley「Pixel-Art People: Characters and a Creator on iPhone」、blakecrosley.com、2026年10月3日:iPhone 18 Pro Maxで、「a 440-by-956-point view at 3× shows 165 by 358 world pixels」(3倍での440×956ポイントのビューはワールドの165×358ピクセルを見せる)、https://blakecrosley.com/blog/pixel-art-characters-on-iphone ↩
-
Kiradexのソース、2026年10月5日16:51にコミット
cf3beb1eの時点で、その日編集されていた作業ツリーから閲覧(非公開リポジトリ):Kiradex/Views/Me/MeView.swift(日付はその日の07:52)、Meタブの「Your Room」ボタン、me-room(272〜277行目)、これは広場のサーバーなしでプレイヤー自身の部屋を開く。そしてフォージのscripts/forge/interiors.py(日付は10月3日)、そのROOMのグリッド(57〜70行目)は1階の(3, 1)にカーテン付きの窓Kを、(12, 1)に窓Nを置き、window(259行目)とcurtained_window(278行目)で描く。書き出したroom.jsonとroom-up.jsonは窓のセルのリストを持たない。 ↩↩ -
Blake Crosley「Pixel-Art Routes: Map Connections and Districts on iPhone」、blakecrosley.com、2026年10月5日:そのブリーフの名前とアート、「The deny list does not exist yet: the dossier promised one in the repository, and the repository has none」(拒否リストはまだ存在しない。ドシエはリポジトリに置くと約束したが、リポジトリには何もない)、リストとそのテストを作ることをそのブリーフの一部にしている、https://blakecrosley.com/blog/pixel-art-world-beyond-the-plaza ↩