🕶️🚲 470(ヨンナナマル)くん
ヨットの帆なのに、なぜか陸で三輪車を漕いでいるこのブログの案内役です。わからないことがあると、帆についたテルテール(吹き流し)がバタバタします。
小学生の時、妖怪ウォッチの交換の時に後ろのカセットを抜くと妖怪が増えるっていう話がありました。
僕は本家もバスターズも遊んでいたので、正直どっちでやってたかもう覚えてないんですけど、ただレベルファイブが2015年12月14日に『妖怪ウォッチバスターズ』について出した告知はまだ残っています。
一部のユーザーが行っている、妖怪メダルの交換中に不正にソフト(ゲームカード)を抜くキャラクター増殖技は、高確率でデータが破壊されます
ということは、増える技は確かにあったし、公式も困っていたそうです。
でもよく考えると不思議じゃないですか。交換って妖怪を1体減らして、相手に1体増やすだけですよね。
🤔 足し算と引き算が1回ずつなのに、なんで壊れるの?
この連載は、この疑問から分散システム(ネットでつながった何台ものコンピュータが、一緒に1つの仕事をする仕組み)を学んでいく3本立てです。
| 中身 | レベル | |
|---|---|---|
| 第1部(この記事) | 妖怪ウォッチの言葉だけで、なんで壊れるのかと、それでも打てる手を考える | 噛み砕き |
| 第2部 | その話の正式な名前と、AWS や銀行が実際にどうしているか | 大学レベル+実務 |
| 第3部 | 今、3DS の交換を作り直すならどうするか | 応用 |
この記事でわかること
- 交換が壊れる本当の理由(僕は最初、ちょっと違う理由だと思ってました)
- 「せーので同時にセーブ」が無理な理由
- 返事が来ないとき、「届いていない」のか「返事だけ消えた」のかが見分けられない問題と、送り直しても大丈夫にする工夫(冪等性)
- 増えも消えもしない交換の作り方と、その代わりに払うもの
先に1つだけ断っておくと、ゲームの中の仕組みについて、レベルファイブが公開している資料は見つかりませんでした。なので、ここから先は「こういう作りならこう壊れる」という、仕組みを理解するための模型の話です。実際のゲームがこの通りに作られているかはわかりません。
1. 僕がやってた「カセット抜き」
僕がやるときは、僕がめっちゃレアな妖怪、相手が雑魚妖怪を出して、せーので交換した瞬間にカセットを抜くんですよ。エラーでホーム画面に戻るんですけど、カセットを挿し直して起動すると、妖怪が増えてる。
この流れを、もう少しだけ細かく分けてみます。
| 段階 | 何をしてる? |
|---|---|
| ① | 僕と相手が、それぞれ交換に出す妖怪を選ぶ |
| ② | 3DS 同士が通信して、妖怪のデータを送り合う |
| ③ | それぞれの 3DS が、自分のカセットに「交換したあと」をセーブする ← たぶんここで抜いてた |
| ④ | 交換完了 |
ここで何が起きるのかを考えるのが、この記事の全部です。
2. 1台なら起きない。2台だと「片方だけ終わる」
1台の中なら、止まっても「やる前」に戻せる
まず、1台の 3DS の中で妖怪を並べ替える場合を考えてみます。手持ちの1番目と2番目を入れ替える、みたいなやつです。
これって、途中で電池が切れても大した問題にならないですよね。並べ替えの途中で止まっても、次に起動したときは**「並べ替える前」のセーブから始まるだけ**です。
実は 3DS のセーブも、書いている途中で止まったら前の状態に戻るように作られているらしいです1。
| 3DS のセーブのしかた(解析資料より) | |
|---|---|
| 置き場所 | セーブを2つの場所に分けて持つ |
| 書くとき | 使っていないほうに新しい内容を書く |
| 確定 | 最後に「こっちが本物」という印を切り替える |
| 途中で止まったら | 印を切り替える前なら、古いほうがそのまま本物として残る |
ただ、実際に書いている途中でカセットを抜いたらどうなるかを確かめた資料は見つかりませんでした。公式も「データが破壊されます」と言っているので、いつでも綺麗に戻るとまでは言えません。
それでも考え方としては、1台の中だけなら「やる前」か「やった後」のどちらかに寄せる作りにできる、ということです。
2台だと、セーブが2つに分かれる
じゃあ交換はどうか。交換には 3DS が2台出てきます。
| セーブする内容 | |
|---|---|
| 僕の 3DS | 僕のカセットに「レア妖怪を渡した」 |
| 相手の 3DS | 相手のカセットに「レア妖怪を受け取った」 |
セーブする場所が2つに分かれていて、どっちか片方だけ書き終わる瞬間がある。 困るのはここなんです。
1台の中なら「印の切り替え」は一瞬で1回だけですけど、2台の印を同じ瞬間に切り替えるボタンはありません。僕の 3DS が印を切り替えたことを、相手の 3DS は通信で教えてもらうまで知りようがないからです。
3. 先に渡したら消える、先に受け取ったら増える
2台のセーブが同時に終わらないなら、どっちかが先に終わります。僕のレア妖怪で、2通り考えてみます。
パターン1:僕のほうが先にセーブを終える
- 僕の 3DS が「レア妖怪を渡した」とセーブし終える
- 相手の 3DS が「受け取った」とセーブする前に止まる
僕のカセットからはレア妖怪がいなくなっています。相手のカセットにはまだ来ていません。ということは、レア妖怪はどっちにもいない。消えます。
パターン2:相手のほうが先にセーブを終える
- 相手の 3DS が「レア妖怪を受け取った」とセーブし終える
- 僕の 3DS が「渡した」とセーブする前に止まる(ここでカセットを抜く)
相手のカセットにはレア妖怪がいます。僕のカセットは「渡す前」のままなので、レア妖怪がまだいます。ということは、2人ともに残る。増えます。
並べてみると
| 先にセーブが終わる | そこで止まると | 結果 | |
|---|---|---|---|
| パターン1 | 僕(渡した) | 相手は受け取っていない | 💀 消える(0体) |
| パターン2 | 相手(受け取った) | 僕はまだ渡していない | 👯 増える(2体) |
僕がやってた「増える」は、パターン2の隙間にカセットを抜いていた、と考えると説明がつきます。
逆に、タイミングがずれてパターン1の隙間に当たったり、セーブの途中で変な止まり方をしたりすると、妖怪が消えたりデータが壊れたりする。公式の告知が言っている「高確率でデータが破壊されます」が、この隙間のせいなのか、セーブの書き方そのものの問題なのかは、公開されていないのでわかりません。
ちなみに実際の交換は、僕のレア妖怪と相手の雑魚妖怪が逆向きに同時に動くので、レア妖怪は増えたのに雑魚妖怪は消えた、みたいなことも起きえます。ここでは話を簡単にするために、レア妖怪の動きだけ追っています。
ここまでを一言でいうと、「先に渡す」か「先に受け取る」かで、隙間で起きることが**「消える」か「増える」か**に分かれる。どっちを選んでも隙間はあります。
4. 🕶️🚲「せーので同時にセーブすれば?」
ここで、たぶん誰でも思うことがあります。僕も思いました。
🕶️🚲 順番があるからダメなんでしょ? 2台が「せーの」でまったく同じ瞬間にセーブすれば、隙間なんてなくなるじゃん。
僕は最初、これができない理由を2つ考えてました。両方とも、調べたら違いました。
僕の勘違い①:光の速さに限界があるから
最初は「どんな情報も一瞬では届かない。光の速さにも限界があるから、離れた2台で本当の同時はありえない」と思ってました。
でも計算すると、光は1秒に約30万km進むので、30cm 先の相手の 3DS までなら約10億分の1秒で届きます。カセットを抜く手の速さとは比べものにならないくらい速いです。
ということは、光の速さは原因じゃない。
僕の勘違い②:2台の時計がズレるから
次に考えたのが「時計を合わせて『12時ちょうどに2台でセーブ』と予約すればいいけど、機械の時計は少しずつズレるから無理」という理由です。
これも、よく考えると違いました。仮に2台の時計が完璧に合っていたとしても、セーブそのものに時間がかかります。12時ちょうどに2台がセーブを始めたとして、書き終わるまでの間にカセットを抜かれたら、結局片方だけ書き終わる瞬間ができます。
ということは、時計を完璧にしても隙間は消えない。
本当の理由
| 僕が最初に思ってた理由 | 実は | |
|---|---|---|
| 勘違い① | 光の速さに限界がある | 30cm なら約10億分の1秒。原因じゃない |
| 勘違い② | 2台の時計がズレる | 時計が完璧でも、セーブ中に抜かれたら同じ |
| 本当の理由 | ― | セーブには時間がかかり、その途中で片方だけ止まることがある。しかも相手が止まったかは、教えてもらうまでわからない |
「同時」が無理なのは、時間が足りないからじゃなくて、2台がそれぞれ別々に止まれるからなんです。
1台なら全部いっしょに止まるけど、2台だと片方だけ止まる、ということが起きます。
5. 🕶️🚲「じゃあ、確認し合ってからセーブすれば?」
同時が無理なら、次に思いつくのはこれです。
🕶️🚲 だったら「受け取った?」「受け取ったよ」って確認し合って、2人とも OK になってからセーブすればいいじゃん。
やってみます。
1回ずつ追ってみる
1回目:僕 →「レア妖怪送るよ。届いたら教えて」
僕は、まだ自分のレア妖怪を消せません。届いたかわからないからです。届いてないのに消したら、パターン1(消える)になります。
2回目:相手 →「届いたよ」
相手は「届いたよ」と返しました。じゃあ相手はセーブしていいか。実は、まだダメです。 この「届いたよ」が僕に届かなかったら、僕は「失敗したんだな」と思って交換をやめて、レア妖怪を手元に残します。そこで相手がセーブしていたら、パターン2(増える)です。
3回目:僕 →「『届いたよ』、見たよ」
これで相手は安心できる……かと思いきや、今度は僕が困ります。 この「見たよ」が相手に届かなかったら、相手は「僕の返事が届かなかったんだな」と思って交換をやめるかもしれません。そこで僕がレア妖怪を消していたら、パターン1(消える)です。
4回目、5回目……
ここで困るのは、最後に送った人が毎回「今の、届いたかな」と不安になることなんですよね。それを消すにはもう1回返事が必要で、その返事を送った人がまた不安になる。
実際にルールを決めて交換してみる
言葉だけだとわかりにくいので、ルールを決めて、僕のレア妖怪と相手の雑魚妖怪を交換してみます。
ルールA:「③の『見たよ』まで来たら、2人ともセーブする」
| 手順 | 送る人 → 受け取る人 | 中身 | 届いた? | 僕の3DS | 相手の3DS |
|---|---|---|---|---|---|
| ① | 僕 → 相手 | レア妖怪送るよ | 届いた | 返事待ち | ③待ち |
| ② | 相手 → 僕 | 届いたよ | 届いた | ③を送る | ③待ち |
| ③ | 僕 → 相手 | 「届いたよ」見たよ | ⚡届かなかった(ここでカセットを抜かれた) | ③を送ったので、ルールどおりレア妖怪を消してセーブ | ③が来ないので「交換失敗」。受け取らない |
結果:僕は渡したことになっていて、相手は受け取っていない。レア妖怪はどっちにもいない(消える)。
「じゃあ④まで待てばいいじゃん」と、ルールを1回増やしてみます。
ルールB:「④の『「見たよ」見たよ』まで来たら、2人ともセーブする」
| 手順 | 送る人 → 受け取る人 | 中身 | 届いた? | 僕の3DS | 相手の3DS |
|---|---|---|---|---|---|
| ①〜③ | (ルールAと同じ) | 全部届いた | ④待ち | ④を送る | |
| ④ | 相手 → 僕 | 「見たよ」見たよ | ⚡届かなかった(ここでカセットを抜いた) | ④が来ないので「交換失敗」。レア妖怪を手元に残す | ④を送ったので、ルールどおりレア妖怪を受け取ってセーブ |
結果:相手は受け取っていて、僕の手元にも残っている。レア妖怪が2体(増える)。
何回にしても同じ
ルールを5回にしても、10回にしても同じです。最後の1通を送った人は「もう送ったから」とセーブして、受け取るはずだった人は「来ないから失敗」と判断する。その最後の1通が消えた瞬間に、2人の判断が食い違います。
何往復しても、最後の1通が届いたかどうかは、送った本人にはわからない。
だから「2人とも完全に安心してからセーブ」の瞬間は、いつまでたっても来ません。
これは妖怪ウォッチだけの話じゃなくて、通信の世界では昔から有名な問題で、ちゃんと名前もついています。名前は第2部で出てきます。
ただ、1つ大事なのは、これは**「必ず2人そろう、とは保証できない」**という話だということです。「だから交換は絶対に作れない」という話ではありません。じゃあどうするかが、次の話です。
6. 返事が来ない。届いてないの? それとも、返事だけ消えたの?
さっきの往復で困っていたのは、「最後の1通が届いたかわからない」でした。これを送った側から見ると、もっと身近な困りごとになります。
僕の 3DS に見えるのは「返事が来ない」だけ
僕がレア妖怪を送ったのに、相手から「届いたよ」が来ない。このとき、相手の 3DS では何が起きていたんでしょうか。
| 相手の 3DS で本当に起きていたこと | 相手のカセット | |
|---|---|---|
| ア | 送ったレア妖怪が、そもそも届いていない | レア妖怪なし |
| イ | 届いたけど、セーブする前に相手のカセットが抜かれた | レア妖怪なし |
| ウ | 届いてセーブもしたけど、「届いたよ」の返事だけが消えた | レア妖怪あり |
| エ | 通信が遅いだけで、まだ届いている途中 | これから届く |
相手のカセットの中は、ア・イと、ウとでまるで違います。でも、僕の 3DS から見えるのは、4つとも同じ「返事が来ない」だけなんですよね。
じゃあ、どうする?
返事が来ないとき、僕の 3DS ができることは3つです。それぞれ、本当はどの場合だったかで結果が変わります。
| 僕の 3DS がすること | 本当はア・イだった | 本当はウだった |
|---|---|---|
| ① あきらめて、レア妖怪を手元に残す | 交換しなかっただけ(OK) | 相手にもいるのに、僕にも残る → 👯 増える |
| ② 届いたことにして、レア妖怪を消す | どっちにもいない → 💀 消える | ちゃんと交換できた(OK) |
| ③ もう1回送る | 今度こそ届く(OK) | 相手に2回届く → 👯 増える |
どれを選んでも、どれかの場合で壊れます。 しかも、どの場合だったかは僕からは見分けられません。
①は第3章のパターン2、②はパターン1と同じ形ですよね。そして、一番自然に思える「③ もう1回送る」も、ウのときは増えてしまいます。エ(遅いだけ)なら待てば返事が来るんですけど、いつまで待てばいいかも、僕にはわかりません。
「送り直しても大丈夫」にする:番号で2回目を見分ける
じゃあ③を安全にできないか。ここで出てくるのが番号です。
- 送るときに、この交換だけの番号(例:No.0721)を付ける
- 相手の 3DS は、受け取ったら「No.0721 受け取り済み」とメモして一緒にセーブする
- 同じ No.0721 がもう一度来たら、「もう受け取ってるよ」と返事だけして、妖怪は足さない
こうすると、③の表がこう変わります。
| 僕の 3DS がすること | 本当はア・イだった | 本当はウだった |
|---|---|---|
| ③ 同じ番号で、もう1回送る | 今度こそ届く(OK) | 相手は「No.0721 はもう受け取ってる」と気づいて、2回目を捨てる(OK) |
何回送っても、結果は1回送ったのと同じになる。 これには**冪等性(べきとうせい)**という名前があります(詳しくは第2部で)。
でも、番号にも落とし穴がある
番号を付ければ全部解決、かというと、そうでもないんですよね。冪等性の難しいところは、ここからです。
| 落とし穴 | どうなる? |
|---|---|
| 送り直すたびに新しい番号を付けてしまう | 相手には「別の交換」に見えて、2回目も受け取ってしまう。番号は交換1回ごとに1つで、送り直しでは同じ番号を使う |
| 僕の 3DS が番号を覚えていない | 途中で止まって番号を忘れると、送り直しのときに同じ番号を付けられない。番号は送る前に決めて、自分もセーブしておく |
| 相手が「受け取り済み」のメモを、妖怪を足すのと別のセーブで書く | 2つのセーブの間で抜かれると、「妖怪は足したのにメモがない」になって、2回目を見分けられない。妖怪とメモは1回のセーブで書く |
| そもそも送り直せない | 番号が効くのは、もう一度つなげるときだけ |
最後の1つが、3DS のカセット抜きでは一番大きいです。
僕がやってたカセット抜きを思い出すと、抜いたあとは「1回エラーが出て、ホーム画面に戻る」だけでした。カセットを抜いた人が、わざわざつなぎ直して「さっきの No.0721、届いてた?」なんてしてくれません。送り直しすら起きないんです。
ということは、3DS の交換では「送り直しても大丈夫」だけでは足りなくて、**「送り直せなくても増えない」**形にしておく必要があります。それが、次のおあずけ札です。
🕶️🚲 番号は、おあずけ札でも使います。札に書く「取引番号」が、この番号です。
7. 3つ目の道:「おあずけ札」を貼ってから送る
ここまでで、こうなりました。
| 作り方 | 隙間で起きること |
|---|---|
| 先に渡す | 💀 消える |
| 先に受け取る | 👯 増える |
| せーので同時 | できない |
| 確認し合ってから | 終わらない |
| 返事が来なくて送り直す | 届いていたら2回届いて 👯 増える(番号があれば防げるけど、3DS では送り直しすら起きない) |
隙間そのものはなくせません。でも、隙間で何が起きるかは変えられます。 そのための手が「おあずけ札」です。
おあずけ札の交換の手順
僕がレア妖怪を渡す側だとします。
- 送る前に、僕のレア妖怪に**「おあずけ中」の札と、この交換だけの取引番号(例:No.0721)**を貼って、先にセーブする
- それから相手に送る
- 相手の 3DS は、受け取ったら「No.0721 を受け取った」と一緒にセーブする
- 僕の 3DS は、相手から「No.0721 受け取ったよ」が届いたら、札付きのレア妖怪を消してセーブする
「おあずけ中」の札が貼られている間、そのレア妖怪はバトルにも、別の交換にも使えないことにします。
いろんな瞬間で抜いてみる
ここでも、レア妖怪の動きだけを追います。
| どこで抜く? | 僕のカセット | 相手のカセット | 使えるレア妖怪 |
|---|---|---|---|
| 1 のセーブ前 | 札なしのレア妖怪 | なし | 1体(交換が始まらなかっただけ) |
| 1 のあと、送る前 | 札付きのレア妖怪 | なし | 0体(一時的。あとで札をはがして戻す) |
| 送ったあと、相手のセーブ前 | 札付きのレア妖怪 | なし | 0体(一時的。あとで札をはがして戻す) |
| 相手のセーブ後、4 の前 | 札付きのレア妖怪 | レア妖怪(No.0721) | 1体(相手の分だけ) |
| 4 のあと | なし | レア妖怪(No.0721) | 1体 |
この模型では、どの瞬間に抜いても、使えるレア妖怪が2体になることはありません。
隙間はまだあるけど、隙間で「増える」ことはなくなりました。
「0体」はどう片付ける?
ここで取引番号が効きます。次に僕と相手が通信したとき、僕の 3DS が「No.0721 ってそっちで受け取ってる?」と聞きます。
| 相手の答え | 僕の 3DS がすること |
|---|---|
| 「受け取ってるよ」 | 札付きのレア妖怪を消して、交換完了 |
| 「知らない」 | 札をはがして、レア妖怪を使えるように戻す |
その代わりに払うもの
ただし、タダではありません。
おあずけ札の間、レア妖怪は使えません。札がはがれるのは、同じ相手ともう一度つないだときです。休み時間に一回だけ交換した子と二度と会わなかったら、僕のレア妖怪はずっとおあずけのままです。
ということは、この方法は「消える」「増える」の代わりに、「しばらく待たされる」を選んでいるわけです。
さらに言うと、札を貼る前のセーブをどこかに取っておいて書き戻すような、もっと本気のズルには、この方法だけでは勝てません。この「じゃあ現実にはどこまで作れるの? いくらかかるの?」は、第3部で考えます。
まとめ
第1部のまとめ
- 1台の中の並べ替えなら、全部いっしょに止まるので「やる前」に寄せられる。2台だとセーブが2つに分かれていて、片方だけ終わる瞬間がある。
- 先に渡せば隙間で消え、先に受け取れば隙間で増える。
- 「せーので同時」が無理なのは、光の速さや時計のせいではなく、2台がそれぞれ別々に止まれるから。
- 「確認し合ってから」は、最後の1通が届いたか誰にもわからないので終わらない。
- 返事が来ないとき、「届いていない」のか「届いたのに返事だけ消えた」のかは見分けられない。送り直すなら、同じ番号で2回目を見分ける(冪等性)。でも 3DS のカセット抜きでは、送り直しすら起きない。
- 隙間はなくせない。でも、隙間で何が起きるか(消える/増える/待たされる)は選べる。「おあずけ札」は、増えない代わりに待たされる道。
最初の疑問は「足し算と引き算が1回ずつなのに、なんで壊れるの?」でした。答えは、その足し算と引き算が別々の 3DS の、別々のカセットで行われていたから、でした。
僕の学び
分散システムって聞くと難しそうですけど、簡単に言うと**「いかに通信に信頼を持たせて、相手を疑ってかかるか」**なんだと思いました。そもそも信用しない。信用できないことを、最初から設計に入れておく。
ということは、手順をはっきり決めたり、何を根拠に「届いた」とするのかを決めたりするのって、人間同士のやり取りと同じなんですよね。分散システムは、それをアルゴリズムにしただけなんだなぁ、っていうのが僕の学びです。
この問題自体は昔からあって、ネットとか、違う媒体に乗り換えているだけ。どこでもこれが大事なんだなぁと思いました。
🕶️🚲 テルテール、ピシッと風に乗りました。
次回の第2部では、この話にちゃんと名前をつけて、AWS や銀行や、50年前の通信が同じ問題とどう戦ってきたかを見ていきます。
連載「妖怪ウォッチの『カセット抜き増殖』から学ぶ分散システム」
- 第1部(この記事) なんで2台の交換は壊れるの?(噛み砕き)
- 第2部 AWS も銀行も50年前の通信も、同じことで悩んでた(大学レベル+実務)
- 第3部 今、3DS の交換を作り直すなら(応用)
参考にした資料(クリックで開く)
- レベルファイブ「『妖怪ウォッチバスターズ 赤猫団/白犬隊』及び、無料更新データ『月兎組』のセーブ中に不正にソフトを抜く行為による、データ破壊について」2015年12月14日 http://www.youkai-watch.jp/busters/topics/151214/
- レベルファイブ『妖怪ウォッチバスターズ』更新データ Ver.2.2(「増殖技の発生率を下げました」)https://www.youkai-watch.jp/busters/guide/update.html
- wwylele「DISA.md」(3DS セーブデータ形式の解析資料。非公式)https://raw.githubusercontent.com/wwylele/3ds-save-tool/master/DISA.md
- Martin Kleppmann, Distributed Systems 講義ノート(University of Cambridge, 2021/22)§2.1 https://www.cl.cam.ac.uk/teaching/2122/ConcDisSys/dist-sys-notes.pdf
-
3DS のセーブデータ形式を解析した人の資料(非公式)によります。wwylele「DISA.md」https://raw.githubusercontent.com/wwylele/3ds-save-tool/master/DISA.md ↩



