Chrome で背景色が描画されない

Chromium 系ブラウザの Comodo Dragon で、CSSbackground-color が画面に反映されないバグに遭遇した。

環境

再現した環境は以下の通り。

  • CPU: Celeron(R) Dual-Core CPU T3100 @ 1.90GHz
  • メモリ: 888MB
  • OS: Windows XP Professional 32bit SP3
  • ブラウザ: Comodo Dragon 26.2.2.0

再現コード

再現する HTML は以下の通り。

ファイル: http://0mg.github.io/etc/2013/chcssbug.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
#parent {
  position: absolute;
}
.foo {
  position: absolute;
  background-color: yellow;
  color: blue;
}
.bar {
  background-color: aqua;
  color: red;
}
</style>
<title>background-color not work in chrome</title>
</head>
<body>
<div><button id="button">add and change className</button></div>
<ul id="parent"></ul>
<script>
document.getElementById("button").onclick = function() {
  var parent = document.getElementById("parent");
  var child = document.createElement("li");
  var text = document.createTextNode("");

  // append child to document
  child.appendChild(text);
  parent.appendChild(child);

  // change className and text
  child.className = "foo";
  text.nodeValue = child.className;

  // change className and text
  setTimeout(function() {
    child.className = "bar";
    text.nodeValue = child.className;
  }, 300);
};
</script>
</body>
</html>

バグの概要

バグの概要を説明する。

上記の HTML を開くと、ボタンが表示されるが、これを押すと、JavaScript によって「foo」と書かれたリストアイテムが画面上に追加される。

「foo」には class 属性が設定されており、その値は "foo" である。

ステップ 1 (add)

.foo の CSS スタイルは以下の通り。

.foo {
  position: absolute;
  background-color: yellow;
  color: blue;
}

黄色い背景に、青い文字で「foo」と表示されるのが、正しいレンダリングである。

ナイスでーす

Comodo Dragon 上で確認すると、正常に CSS が反映されていることが分かる。

ステップ 2 (change)

「foo」の表示から、0.3 秒後に、その文字が「bar」に変化する。その際、class 属性の値も "foo" から "bar" へと書き換えられる。

.bar の CSS スタイルは以下のように定義してある。

.bar {
  background-color: aqua;
  color: red;
}

水色の背景に、赤い文字で「bar」と表示されれば成功だが……。

あらぁ!?

赤い文字で「bar」と正しく表示されている一方で、背景が水色になっていない。

他のブラウザでは正しい

今度は Firefox で確認してみる。

  1. いいぞっ
  2. 歪みねぇな

期待通り、水色の背景と赤い文字で表示された。

IE8 と Opera においても、Firefox と同様、「bar」は水色に浸る。

分析

当バグの再現条件は、5 つの要因が組み合わさって成り立っている。

  • 「foo」追加先の親要素が position: absolute などによって、絶対配置されている
  • 「foo」も同様の方法によって絶対配置されている
  • 「bar」は絶対配置されていない
  • 「bar」のテキストは、「foo」のテキストと異なっている
  • 「foo」から「bar」への変化は、setTimeout などによって、非同期のタイミングで行われている

たとえば、以下のようにコメントアウトすることで、Comodo Dragon においても、背景が水色になることが確認できる。

#parent {
  /* position: absolute; */
}

あるいは、以下。

.foo {
  /* position: absolute; */
  background-color: yellow;
  color: blue;
}

これでも水色になる。

// setTimeout(function() {
  child.className = "bar";
  text.nodeValue = child.className;
// }, 300);

真相

CSS では背景色を水色に指定しているのに、どうして、画面上では、水色で表示されないのだろうか。

デベロッパーツールで調査したところ、実は、「bar」の width が 0px であることが判明した。

おぉ!?

幅がゼロであるということは、背景色が塗られる面積もゼロであるから、当然、視認することはできない。

次のように CSS を変更してみる。

.bar {
  width: 10px;
  background-color: aqua;
  color: red;
}

やっぱりな

.bar に width: 10px を追加したことによって、部分的に水色に染まることが確認できた。

おわり

今回の現象は、background-color のバグではなく、まれな条件下で要素の width が 0px になるという謎の振る舞いなのであった。

あなごるとは

Web 上でコードゴルフができるサイト Anarchy Golf を略して「あなごる」と呼ぶ。

「問題」のタイプ

あなごるには 3 種類の問題が存在する。

active:
通常の問題
endless:
制限時間の無い問題
post mortem:
制限時間を過ぎた問題

問題一覧のページを開くと、問題へのリンク一覧が表示される。2007 年頃からの合計で、すでに 700 問を超えている。

リンクのうしろには (post mortem) や (endless) と付加されており、これが問題のタイプを表している。active の場合は、制限時間データ表示がなされている。

「問題」のページ

まずは、問題一覧のページなどから、問題のページを開く。

ページは、いくつかのセクションに分かれており、上から下に向かって以下のような構成になっている。

  1. 問題名
  2. Submit セクション
  3. Problem セクション
  4. Options セクション
  5. Sample input セクション
  6. Sample output セクション
  7. Ranking セクション
  8. Language Ranking セクション

これらについて、順番に一つずつ説明していく。

問題名

一番上には、問題の名前が表示されている。しばしば、問題名自体が、問題を解く手がかりとなる。

Submit セクション

Submit セクションにて、回答コードを入力して、投稿することができる。

投稿オプション

投稿に際しては、いくつかのオプションを選択することができる。

Your name 入力ボックス:
自分の名前を入れる。匿名の場合は、空のままにしておくのもいいだろう。ログインの仕組みはないので、いくらでも詐称ができる。書き間違いに注意だ。
File 入力ボックス:
言語の拡張子付きファイルを選択する。C のコードで書いたのなら、ファイル名を "test.c" などにしておく。
use form ボタン:
あるいは use form ボタンを押して、出現した複数行入力ボックスに直接コードを書いて提出することもできる。その際、ドロップダウンリストから、言語を選択することを忘れずに。
Open code-statistics チェックボックス:
active, endless 問題の場合、投稿したコードの中身は、制限時間を過ぎるまで公開されない。ただし、このオプションを選択することによって、どのような文字種がいくつずつ含まれているかを露出することができる。
詳細: binary, alnum, symbol

投稿ログ

回答コードを投稿して、問題に正解すると、ランキングおよび履歴に、自分の名前やコードサイズなどが記録される。逆に、失敗すると、どこにも載らない。

正解するコード・失敗するコード

  • 無限ループなど、処理に長い時間がかかるコードを投稿すると、たとえ正しい出力ができていたとしても、タイムアウトとなり、失敗する。
  • コードがエラーを起こした場合でも、正しい出力ができていれば、正解となる。
  • 最後に出力した文字が改行コードだった場合、それは出力に含まれない。

Problem セクション

Problem セクション には、出題者による、問題の概要が書かれている。

Options セクション

Options セクションには、問題のタイプや、制限時間の情報などが書かれている。

ここに「exec is denied」という表記がなければ、あなごるサーバー内のファイルにアクセスするようなコードの実行が可能である。

Sample input と Sample output セクション

Sample input と Sample output セクションは、最も重要な部分である。

参加者は、Sample output に書かれている文を出力するコードを書き、その短さを競う。

Sample output は最高で 3 つ設置される。

どう書く?

問題に正解するためには、全ての Sample output と同じ出力を行うコードを一つだけ書かなければならない。

たとえば、以下の Sample output 2 つが並んでいたとしよう。

  1. Sample output: A
  2. Sample output: B

「A」あるいは「B」を出力するコードを書けばいいのだが、一つのコードでどうやってそれを実現するのか。

方法 1

方法の一つとして、「ランダム要素を使う」というものがある。

たとえば、JavaScript には、Math.random() という関数がある。この関数は、0 から 1 の間の小数をランダムに返す。これを利用して、以下のようなコードを書く。

var output, rand = Math.random();
if (rand > 0.5) {
  output = "A";
} else {
  output = "B";
}
print(output);

rand 値が 0.5 より大きければ "A" を、そうでなければ "B" を表示する。

このコードを投稿すると、あなごるサーバーは、このコードを実行する。

重要なのは、その工程が Sample output の数だけ行われるということだ。

この場合は Sample output が 2 つなので、このコードは 2 回 実行されることになる。

Math.random() は、呼び出すたびに数値が変わるため、2 回 実行されたこのコードの出力は、別のものになる可能性が高い。

出力の 1 回目と 2 回目が以下のようになれば、正解である。

  1. 出力1: A
  2. 出力2: B

これは、ちょうど、Sample output と同じ並びになっている。

方法 2

二つ目の方法として、「Sample input を使う」というものがある。

ある Sample output には、必ずそれに対応する Sample input が付属している。

空の場合もあるが、何かしらの文が含まれている場合が多い。

たとえば、Sample input と Sample output の組が以下のようになっていたとしよう。

  1. Sample input: A
  2. Sample output: A
  3. Sample input: B
  4. Sample output: B

Sample input を利用すると、以下のようなコードで正解することができる。

var output = readline();
print(output);

readline() 関数は、Sample input から、一行分、文を読み取り、返す。

入出力に利用できる関数

JavaScript
  • 入力: readline()
  • 出力: print(), putstr()

2013 年 5 月 現在、あなごるでは、SpiderMonkeyJavaScript shell が使われている。

参考: Introduction to the JavaScript shell - SpiderMonkey | MDN

C
  • 入力: scanf(), gets(), read() など
  • 出力: printf(), puts(), write() など

Ranking セクション

active, endless において、問題に正解すると、投稿した言語のランキングに、コードサイズや日付などとともに自分の名前が掲載される。

ある一つの言語のランキングにおいて、すでに jack という名前の記録があり、その上で jack という名前で、その記録を上回る短いコードを投稿すると、その記録は消えて、新しい記録が載る。

一度ランキングに名前が載ると、消すことはできない。

Language Ranking セクション

ページの一番下には、どの言語のコードが一番短いかランキングが表示される。有名どころでは、Perl, Ruby が安定して強い。

おわり

よいコードゴルフライフを。

コードゴルフとは

プログラミングとは

世の中には、プログラミングという行為がある。コンピュータ上で動くプログラムをつくる営みを指して、そう呼ぶ。

YouTube という動画投稿・閲覧サイトがある。ビデオ再生画面で、再生ボタンを押せば、動画が再生され、一時停止ボタンを押せば、一時停止する。この処理は、プログラミングによって実現されたものだ。

マウスのクリック、画面のタップ。それらをしたとき、コンピュータに、「クリックした」「タップした」という信号が送られる。

ボタンのプログラミングでは、その信号をどう扱うかをコンピュータに命令(するコードをファイルに記)し、「再生させる」「一時停止させる」はたまた「暴れ回る」などの処理を規定する。

ショートコーディングとは

プログラミングによって記されるコードは、分かりやすさを優先して冗長に書くこともできるし、洗練性を重視して短く書くこともできる。まるで、人間の読み書きする言語と同じで、感謝の表明を「ありがとうございました」と書くか「㌧」と書くかの違いのようなものである。

たとえば、以下のコードを見てみよう。

var message = "Hello, world!";
print(message);

このコードは、JavaScript というプログラミング言語で書かれた、画面上に「Hello, world!」と表示するプログラムと成る。

以下のような流れだ。

  • var でこれから 変数 を作成することを表す
  • 実際に、message という名前で、変数をつくる
  • 代入演算子 = を用い、message の内容として "Hello, world!" という文字列を代入する
  • 画面上に文字を表示する能力を有す print 関数に message を渡して呼び出す
  • 「Hello, world!」という一文が画面上に表示される

このコードは十分に短いが、一文を表示するという目的を達成するためだけなら、さらに短く書くことができる。

このように

print("Hello, world!")

コードを短く書くことを、ショートコーディングという。

コードゴルフとは

一体、究極に短縮されたコードというものは、どれくらい短いのだろうか。

その追究は、コードゴルフというゲームの中で行われる。

コードゴルフでは、1 試合ごとに、先述の Hello, world! のよう、何を出力するかをまず設定する。これを「出題」と呼び、出題されたものを「問題」と呼ぶ。

参加者は、その目標を達成するためだけのコードをできるだけ短く書く。そうして提出された回答は、他の参加者には公開されず、何文字で書いたのかだけが示される。「自分のコードはまだ長すぎる。どうしてそんなに短く書けるんだ」という驚嘆の発生は、このゲームの醍醐味の一つである。

制限時間以内に、最も短く書ければ、勝利となる。

やってみよう

コードゴルフするなら、Anarchy Golf というサイトを訪れるといい。

サイト上で、多種多様なプログラミング言語で競い合うことができる。

出題は、頻繁に行われているので、すぐに始められる。

副次的メリット

コードはどれだけ短くなるのか。それは神のみぞ知る。複数人が同じ文字数の、短い回答に辿り着き、長いあいだ記録が更新されない状況でも、突然、さらに短くなるケースはいくらでもある。諦めずに、しつこく励んでいれば、きっと短くなる。ならずとも、真剣な努力は、プログラミング言語の特性の理解を深め、プログラミング力を向上させるであろう。

おわり

つづく。

<要素>.textContent = undefined

DOM 操作である <要素>.textContent = undefined すると、何が入るのだろうか。あるいは、 null を代入すると、どうなるか。色々なパターンを、色々なブラウザで調べた。

生成元: http://0mg.github.io/etc/textcont.html

  1. 行の見出しセルは、代入の仕方 および 代入した値 を示している。
  2. 列の見出しセルは、代入後、どのプロパティにアクセスしたかを示している。
  3. ふつうのセルは、どんな値が返ってきたかを示している。
  4. 空欄のセルは、ブラウザでサポートしていないプロパティであるか、!p.hasChildNodes() である。

Opera

Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.15
p.firstChild.nodeValuep.textContentp.innerText
p.firstChild.nodeValue = undefined(string) "undefined"(string) "undefined"(string) "undefined"
p.textContent = undefined(string) "undefined"(string) "undefined"(string) "undefined"
p.innerText = undefined(string) "undefined"(string) "undefined"(string) "undefined"
p.firstChild.nodeValuep.textContentp.innerText
p.firstChild.nodeValue = null(string) "null"(string) "null"(string) "null"
p.textContent = null(string) ""(string) ""
p.innerText = null(string) ""(string) ""

Firefox

Mozilla/5.0 (Windows NT 5.1; rv:20.0) Gecko/20100101 Firefox/20.0
p.firstChild.nodeValuep.textContentp.innerText
p.firstChild.nodeValue = undefined(string) ""(string) ""
p.textContent = undefined(string) ""
p.innerText = undefined(string) ""
p.firstChild.nodeValuep.textContentp.innerText
p.firstChild.nodeValue = null(string) ""(string) ""
p.textContent = null(string) ""
p.innerText = null(string) ""

Comodo Dragon

Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.2.2.0 Safari/537.31
p.firstChild.nodeValuep.textContentp.innerText
p.firstChild.nodeValue = undefined(string) "undefined"(string) "undefined"(string) "undefined"
p.textContent = undefined(string) "undefined"(string) "undefined"(string) "undefined"
p.innerText = undefined(string) "undefined"(string) "undefined"(string) "undefined"
p.firstChild.nodeValuep.textContentp.innerText
p.firstChild.nodeValue = null(string) ""(string) ""(string) ""
p.textContent = null(string) ""(string) ""
p.innerText = null(string) ""(string) ""

Internet Explorer 8

Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
p.firstChild.nodeValuep.textContentp.innerText
p.firstChild.nodeValue = undefined(string) ""(string) ""
p.textContent = undefined(string) ""
p.innerText = undefined(string) "undefined"(string) "undefined"
p.firstChild.nodeValuep.textContentp.innerText
p.firstChild.nodeValue = null(string) "null"(string) "null"
p.textContent = null(string) ""
p.innerText = null(string) "null"(string) "null"

Opera のような手軽さで Chromium 用 UserJS 開発したい

まえおき

長らく愛用してきた PC 用 Opera. 次期、新バージョンは Chromium ブラウザと成って登場する。

Opera の UserJS 実行の仕組みは単純で、「ユーザー JavaScript フォルダ」として指定したフォルダに *.js ファイルを置いておけば、全ての Web サイト上で読み込まれ、実行してくれる。

UserJS の編集もシンプルだ。置いておいた *.js をエディタで開き、編集後、上書き保存し、ページを再読み込み(F5)することで、変更が反映される。

ChromiumOpera では、このやり方が通用しない可能性がある。

Chromium で UserJS を使うには、逐一インストール的な作業をする必要がある。すなわち、「ツール>拡張機能」のページを開き、そこへ *.user.js ファイルをドラッグアンドドロップするのだ。 (これは、UserJS を 拡張機能に変換するための作業である。実は、Chromium にあるのは UserJS の実行機能ではなく、拡張機能実行機能と、UserJS の拡張機能化機能なのだ。)

とにかく、UserJS ファイルを編集する度にこの動作を行わなくてはならないので、効率が良くない。

Opera の UserJS のように、簡単に編集&反映する方法はないものか。

そこで、調べてみると、すごくいいサイトがあった。

Chrome Extensions API リファレンス」 http://dev.screw-axis.com/doc/chrome_extensions/

拡張機能には、「コンテント・スクリプトとして使う」という使い方があり、そうした拡張機能は、UserJS と使い勝手が似ている。

はじめてみよう | Chrome Extensions API リファレンス http://dev.screw-axis.com/doc/chrome_extensions/tutorials/getting_started/

サイトのチュートリアルを参考に、manifest.json を作成する。

コンテント・スクリプト | Chrome Extensions API リファレンス http://dev.screw-axis.com/doc/chrome_extensions/guide/content_script/

やりかた

manifest.json として以下の内容のファイルを保存する。

{
  "name": "UserJS",
  "version": "1.0",
  "manifest_version": 2,
  "content_scripts": [
    {
      "matches": ["https://api.twitter.com/robots.txt?-=/*"],
      "js": ["tw-minus.user.js"]
    },
    {
      "matches": ["http://www.pixiv.net/*"],
      "js": ["pixivid.js"]
    }
  ]
}

この manifest.json と同じフォルダに自分の UserJS を置いておく。 この内容の場合だと、 tw-minus.user.js と pixivid.js だ。

そして、「ツール>拡張機能>パッケージされていない拡張機能を読み込む...」を実行し、上記のフォルダを指定すると、うまくいけば、拡張機能としてインストールされるはずだ。

うまくいかなくても、「○○が足りない」のように具体的なエラーメッセージが出るので、対処はしやすいだろう。現に、"manifest_version" という項目を持たせなければならないことは、エラーメッセージから教わった。

こうして作成した拡張機能のインストールが成功したところで、開発に入る。

流れとしては、

  • UserJS を編集する
  • 「ツール>拡張機能」のページを再読み込みする
  • UserJS 適用先のサイトを再読み込みする

を繰り返す。

おわり

ChromiumOpera にも、上記の方法が通用するかどうかは、現時点では不明だ。

MGS4 トロフィーコンプリート完了

iPod 曲のコンプリートを目指し、全称号獲得後、 SNAKE EATER が入手できたが、まだ終わりではなかった。

9 つも取り逃していたのである。

iPod 曲を取り逃していたエリア

  • Act1: 廃墟
  • Act1: ミレニアムパーク
  • Act2: 市場
  • Act3: PMC をボディチェック
  • Act4: 戦車格納庫
  • Act4: ウルフ戦場
  • Act4: ベルトコンベアのある場所
  • Act4: 暗証番号その1
  • Act4: 暗証番号その2

Act1: 廃墟

ドラム缶ジョニームービーがスタートするエリア手前の崖。右にいけることは知っていたが、左にもいけるとは思わなかった。

Act1: ミレニアムパーク

暗がりに PMC が佇むビルの中。なんで取ってないのか不思議なくらい簡単な場所に落ちていた。

Act2: 市場

箱の中にある。

市場にあるという情報は仕入れていたので、東西南北あらゆる路地や、露店の中をチェックしたが、全く見当たらなかった。

MAP 付きの素晴らしい攻略サイト http://gamejikan.web.fc2.com/wt/mgs4/mgs4_item_act2.html を見て、ようやく解答を得た。

単に落ちてるとは限らないのだなあ。

Act3: PMC をボディチェック

MGS4についての質問なのですが… iPod(R)の曲で「One Night in NEO KOBE CITY」が... - Yahoo!知恵袋 http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1119265691

PMC をボディチェックして出現させるパターン。民兵からのお返しや、レジスタンスからはあっさり出てくるが、 Act3 のここは出にくいらしい。

自分は、公園の近くに立っている PMC ボディチェックで出現した。

レジスタンスが公園を抜けたあとに、公園沿いの道路を回っていたら、見たことのない立ち位置の PMC がいた。特定のタイミングで新たに出現するのか、直前に CAUTION にしたから、それで新しく配置されたのか、もとからいたのか、分からない。

知恵袋で回答している方も、「公園の周りの PMC」で入手したとのことなので、ひょっとすると、ボディチェックにて低確率で出現するんではなく、特定の場所に出現する PMC から必ず入手できるものなのかもしれない。

Act4: 戦車格納庫

電源復旧後に、戦車格納庫へ戻ると、扉が開くようになり、その中に落ちている。いい仕掛けだ。

Act4: ウルフ戦場

オタコンから DISC2 に入れかえなきゃというネタ無線が入るエリア内に、簡単に落ちていた。

Act4: ベルトコンベアのある場所

ゲーム進行上、行く必要のない場所に落ちていた。ありがちやね。

Act4: 暗証番号その1

こればかりは攻略情報仕入れないと無理ではなかろうか。どっかにヒントが落ちてるんだろうか。

Act4: 暗証番号その2

暗証番号入力は、プレイ一周につき、一回しか入力できないので、一周半する必要があった。

感想

祝・プラチナトロフィー獲得!というわけで、ひと段落でございますが、趣味が一つがなくなったので、ちょっとさびしい。

コンプリートしたとはいえ、攻略サイト見ながらだったので、完全にやり込んだとはいえない。

「儀式の人」がやってる、CQCボタン+武器チェンジボタン連打で連続CQC掴みのような小技、あるいは、バグなど、自然と発見してしまうくらいに、のめり込んでプレイしてこそだなあと思います。

付録

称号コンプリートの際に、攻略 wiki から仕入れた情報 http://www7.atwiki.jp/mgs4wiki/pages/38.html をもとに作成した表を公開しました。

MGS4称号表 http://0mg.github.com/etc/mgs4em.html

称号間の取得条件の関係が把握しやすいです。

MGS4 トロフィーコンプリート作業中

つい最近は…、MGS4 のトロフィーコンプリートのため、周回プレイをやっとる。

以下の攻略 wiki を大いに参照している。管理人・編集者の方々に感謝。

[METAL GEAR SOLID 4 攻略wiki]http://www7.atwiki.jp/mgs4wiki/

フラッシュバックマニア

フラッシュバックのトロフィーは獲得済。

攻略 wiki を参照しながら、フラッシュバックが発生するシーンにて○ボタン連打。

フラッシュバックがない(もしくは出し終えた)と判明しているシーンにおいては、徹底的に SKIP を行った。

もれなく全て見ることができた。

攻略 wiki の情報は正確だ。

疑問点(解決済)

フラッシュバック画像は全部で 264 種類あるそうだ。

自分のデータでは 289 枚見たことになっている。

どういうことなの…

[MGS4について質問があります。 フラッシュバックは全部でいくつあるの... - Yahoo!ゲーム]http://games.yahoo.co.jp/qa/detail?qid=1192542791

2 周目以後のプレイにおいて、重複して見た分もカウントされるからとのこと。

感想

このトロフィーが一番めんどくさかった。

MGS4 は、プレイヤーがスネークを動かすこと其れ自体によって、プレイヤーの脳内において快楽物質が分泌されるゲームであるから、それができないことは、ストレスの発生につながる。

まだ取ってないトロフィー

  • iPod 曲コンプリート

全称号獲得時に入手できる iPod 曲があるそうだ。

そのため、現在、各称号の条件を満たしつつの周回プレイ中。

あとみっつ。

(ALERT,KILL,CONTINUE)

  1. 少,少,多
  2. 少,多,多
  3. 多,少,少

懸念

もしかすると、これで iPod 曲を入手しても、曲のコンプリートには至らないかもしれない。 Act.5 のハッチ下に潜れることと、其処に落ちている曲の存在を、ついこないだ知ったからだ。他にも、探索不足のエリアが在るかもしれない。

情報源と其の感想

ガンヒデ(BGM のない中、一人の男が、体調不良で休んだという報告をするところから始まる回)(最終回の数回前)において、Act.5 の攻略情報が聞ける。ヘリポートの赤白部分がレアカモフラだとかいう面白情報も。ふつうにプレイしたのでは気付かないような、開発者側の細かい情報が聞けるこのラジオ番組は、いいものだな。

コンティニュー回数

コンティニュー回数を稼ぐのに適した場面も wiki に掲載されており、役立った。

よくやったのは以下の方法である。

  • OP 間もなく出現する月光の蹴りを食らう
  • カエル戦後のエレベーターホール付近に屯ってるジョニー達を殺す
  • カエル戦後の民兵戦車ゾーンでポリゴンの隙間にローリング
  • レイヴン戦で窓を突き破って落下する
  • ウルフ戦前のゲートロック解除イベントで Mk.III にジョニー砲

多用したのは、レイヴン戦における落下である。タイミングを調整して爆風に当たるようにすると、無味乾燥の作業にやや彩りを与えることができる。

速度的に効率を求める場合、キルならマンティス戦でのメリル殺害、ノーキルなら Mk.III が良さそう。

ALERT 回数

ALERT 回数を稼ぐには、 ALERT を出して間もなく ALERT を解除し、再び ALERT を出し…繰り返すといった方法が望ましい。

76 回程度であれば、理論的には、 76 人に対して 1 ALERT ずつ発生させればいいので、散歩がてら増やしていける。

知っている内、最も効率のいい方法は、カエル戦後の民兵戦車ゾーンで、民兵側勝利後、民兵達が集合している場所付近で、ドラム缶(段ボール)の脱着を繰り返すことにより、数人の民兵達から ALERT をもらう方法である。

前提条件: 民兵から発見されたとき「なんだ あんたか」と言われるが、その際、ハートマークが出ない程度の英雄度を有する服を着ていること

スネークが中東で最初に着ていた民兵服には、デフォルトでその英雄度がこもっている。

もし、そのような服がない場合は、敵を麻酔銃で攻撃したり、民兵に食べ物を与えたりして英雄度を上げたり、民兵を攻撃して英雄度を下げたりして調整する。

  1. 民兵側が勝ち、「やったー!」などと勝利の歓声を上げる
  2. 規定場所に民兵達が集合する
  3. ドラム缶(段ボール)をかぶったスネークを彼らに発見させる
  4. 移動する
  5. ALERT が発生する
  6. ドラム缶(段ボール)解除
  7. 「なんだ あんたか」ALERT が解除される
  8. ドラム缶(段ボール)装着→再び3へ

以上を繰り返す

ドラム缶(段ボール)の脱着を高速で連続して行った場合、民兵がうまくハマってくれると、 4 の工程を省略できるようになる。

つまり、 L2 ボタン連打のみで継続的に ALERT 発生・解除が行われるようになる。数人に発見された状態ならば、民兵達がこちらを発見するのに一人一人時間差が生じてくることがある。そうなれば、ALERT 解除直後に間を置かず再び ALERT に移行する確率が高まり、 1 秒間に 2 ALERT くらい稼げるようになる。

感想

近頃の日常生活において、心身の 3 割ほどを MGS4 トロフィーコンプリートに捧げている。果たしてトロコンした先に待っているのは、趣味の一つの喪失である。なかなかハマっているだけに哀しい。

トロフィー情報は、 PSN にアップロードでき、ネット上のプロフィールに表示されるから、他ユーザーに対して無言でドヤれる状態が半永久的に持続するというメリットはある。