沒穿方服

索引

顯示╱隱藏內文

最好的遊戲

「心目中最好的遊戲」如果想不出答案,那就保留吧,不必降低高度。

十年前買了平時沒需求的雜誌「月刊アルカディア 2002 - 1 月号」,當期有 4 彩頁的『斑鳩 IKARUGA』遊戲介紹 + 開發者訪談,還有最震撼我的在後面——黑白頁的「Old Game Mesuem」專欄,題目是:

輪廻する世界 井内洋と『プロジェクトRS』

『斑鳩』を前にして、我々が知っておくべきこと。

內容簡介 Project-RS(註 1)相關事情,在 google jp 還挖得到整篇備份。
專欄只有 2 頁,我的日文也不好,還是讀得無比激動。 這個作品講的問題就是我的問題,想表達的東西準確配在遊戲裡,用強烈的演出釋放出來。

註 1:RS 指的是 Radiant Silvergun(閃亮銀槍),『斑鳩』原本是 RS 三部中的 2。關於銀槍的介紹,推薦一篇 Xbox Life - Xbox 360遊戲攻略‧情報- 傳說般的射擊遊戲再臨!《閃亮銀槍》遊戲介紹

以下記錄「到目前為止」對斑鳩的觀感,因為

我連一道都沒玩過!

寫這篇的時候我才剛買 Xbox 360,準備買 XBLA 上的斑鳩而已,真的是一 coin 都沒投過。 這麼難得應該記錄一下使用前後的差別,也體驗看看「遊戲是否一定得用玩的」。

印象中的 gameplay 都是 Super Play,例如旁邊影片的 Chapter 1 或者 1 Player - 2 Player game,手上也有一片『斑鳩 APPRECIATE DVD』收錄高手的夢幻表現。

回到現實自己 STG 技術卻相當爛,也沒空練習,大概會玩得很艱辛…… 不過那就將來再提吧。

砲火方向正確

「只生產使用者吃過的東西,餵飽 Light User 還剩下什麼?」是我所知 Project-RS 的重要動機。 (註 3

不限於 STG 主流退化為「射擊 + 炸彈」這件事,也不限於遊戲業,「滿足大眾需求」一直是娛樂界的常規工作。 雖然接受人各有選擇,但是生活被低俗充斥,還是讓我不堪其擾。

閃亮銀槍的世界設定,就是創作停滯的遊戲界的縮影。 一個明顯宣示是 SS 版最終戰的人聲訊息,可以還原(註 2)為開發者、商人、退出者……等立場的對話; 而故事描述的輪迴思想,也能套用在 STG 的出生成長、飽和到沒落。 作者所說的「幅」,專欄解釋是「多樣性」變得狹隘,我的話「生存空間」被壓縮也是同一件事。

因為「偏偏執著在這個議題」正是我需要的,所以很快被吸引,並準備推崇。

  1. 註 2:「還原」乃透過在雜誌揭露每句的發言角度與原意,遊戲中的台詞仍是隱晦、投射的。
  2. 註 3:這段很多文字來自原專欄,但不見得是原意(萬一我會錯意),請了解。

遊戲語言是最得心應手的母語

語言能力有障礙、說話在試誤,表達就沒有力道,意思錯了也未可知。

過場動畫很棒,開始操作卻帶來困惑、讓人質疑原始設計—— 這是作者懂動畫語言,卻不熟遊戲語言的例子; 即使音樂、劇本、○○高明,又注重細節、隱藏要素豐富…… 我還是覺得他沒做對。

反之對語言愈能掌握,就能用愈精準的句子把話說透。

斑鳩作為硬派射擊遊戲,這方面的「正確」基本讓人放心, 常被談及的設計「簡潔」我想延伸下去也是在追求這個正確。

70~90 的 STG 屬於一個時代

有意地重現了 STG 發展以來的魅力要素,所以有人說閃亮銀槍是 STG 的集大成。 這件事之所以很酷,因為它是這個世代的創作者,為了講自己的問題而忠實做的反省。

從 1978 的『Space Invaders』(太空侵略者,TAITO)開始,除了確立基本的「射擊」「閃避」外,因為無法像現在一樣連發子彈,甚至用光束橫掃敵人,所以還能提取出單發瞄準的獨特「狙擊感」。 在斑鳩裡按住射擊鈕是自動連發的 double shot(一次射出兩發,範圍較廣),單按則是 single shot,搭配連續擊破同色敵人便會額外加分的 chain combo 系統,就是在重現這個樂趣。

Invader 框架的後繼者『Galaxian』(小蜜蜂,1979 / namco)和『GALAGA』(大蜜蜂,1981 / namco)在敵人行動模式等各方面有不少進步,但火力還是一樣陽春,要等子彈離開畫面才能再開砲。

接下來 Project-RS 相當重視的「地形」與「解謎性」初步出現在『Scramble』(1981 / KONAMI)開始的橫向捲軸遊戲中(註 4),因為視點能辨別高低差,自然發展出起伏的地勢,拓展了攻略想像。 地形不但造成射擊屏障,移動時也要小心不能撞山,或者畫面捲動時被山撞死。

註 4:其實美國 Williams 於 1980 年已有相似的遊戲 Defender,不過這邊就以偏日本的史觀將它略過。

縱向捲軸的 XEVIOUS(鐵板陣,1983 / namco)也值得一提,遊戲故事和世界觀、音樂等內容有了講究的製作(雖然遊戲本身只有音樂表現比較明顯),因此在整個遊戲史上有一定地位。 閃亮銀槍的細膩製作固然也受推崇,但這裡特別提的是遊戲中偷藏了不少其他作品的料,其中就包括 XEVIOUS 發明的「隱藏角色」(藏在地圖中,找到可以加分),某個出現位置更是仿得非常露骨。

1985 延續橫向射擊優點的『Gradius』(宇宙巡航艦,KONAMI)登場,地形造成的戰略意義和關卡特色變得相當強烈, 此外還多了重要的「機體強化」設計—— 自機收集道具後,可以自由「Power Up」提升速度、武器、option(子機)、護盾等能力。 對比閃亮銀槍也有多樣的武器系統和升級要素,斑鳩倒是轉為完全不做,機體始終一致。

之後 STG 持續鑽研深度,新鮮感降低,難度提升而更挑玩家,各種理由加上 1991 格鬥熱潮爆發,終於衰退去了。

跳到 1997『怒首領蜂』(CAVE)開始發展出一系列「彈幕遊戲」,超大量敵方子彈溢滿畫面,形成驚人的華麗彈幕,是一股遊戲樂趣由「射擊」往「閃避」方向變態的極端風潮。

閃亮銀槍(1998)和斑鳩(2001)都不算彈幕遊戲,但最後都是絕望的閃避關卡,於是輪迴的最後階段正是彈幕,不曉得是否巧合。

※關於射擊遊戲的歷史,可以參考記錄片 盒子內的時間 » GameOne《射擊遊戲的歷史》中文字幕版

其他疑問

目前想到的大概就這樣,其他可能要玩著才會發現。再記幾件好奇的事:

  1. 閃亮銀槍是不是比斑鳩更好?
  2. 斑鳩似乎有很固定的最佳攻略法,這樣好嗎?
  3. Project-RS 原定第三作主題是「未來」,不過我看一、二所講的「輪迴」其實是差不多、而且暗喻不能突破的,開發者井内洋又已離開 TREASURE,關於未來的想法會不會根本沒出現過。

把 git-diff 的差異開在 Vim 分頁裡,也可以指定要看的版本,用 Vim 查閱 commit 歷史。
bootleq/vim-gitdiffall - GitHub

gitdiffall 指令

zsh 呼叫 gitdiffall 這個指令(目前是用 ruby 寫的,需要系統能跑 ruby)

gitdiffall --help

參數跟 git diff 大致一樣。

查看某個 commit 改的東西

想知道 1836777 這個 commit 改了些什麼。

log graph

使用 gitdiffall @1836777,會比較 1836777 和它的前一個 commit。
註:前一個 commit 不一定是 1836777^,而是從 git log 取出的前一項,這是為了提供更線性的用法。

指定看一個 commit

就會開在 Vim 裡面。

開了 7 個分頁

這時可以下 :GitDiffInfo logs(同 :GitDiffInfo 不加參數)看 git log。
但是在 diff 進行中,比較常用的可能是 :GitDiff(同 :GitDiffInfo log,注意參數是 log 不是 logs,後面會說明)。

GitDiff 只顯示一個 log

看完請用 :GitDiffOff 來關閉 diff,確保幾件事:
1. 跳回編輯該檔案的目前版本。
2. 還原比較前的 diff 相關 option(Vim 內建的 :diffoff 會設回預設,不一定是原來的值)。

看完 1836777,想看下一個 commit,因為剛才有顯示 Shortcut for this commit is 7,所以只要 gitdiffall 6 就行了。

看下一個 commit

看現在改了什麼

以下圖來說,gitdiffall 會打開兩個紅色的檔案;
gitdiffall --cached 會打開綠色的。

--cached 和不加任何 revision 的情況

以前寫的將複數 git diff 以 vim 分頁一次開啟,現在可以用 gitdiffall 取代了。

在 Vim 裡使用 GitDiff

在 Vim 裡面也可使用 :GitDiff,會比較目前檔案和它的某個版本,這時就不需要 ruby 了。
參數跟 gitdiffall 類似,也稍微支援自動完成。

Vim 裡的指令也能自動完成

Diff 中可以用 :GitDiffInfo 看比較範圍內「全部 commit」的 log,
加上參數 :GitDiffInfo log 可以看「最相關的一個 commit」的 log(跟前述「GitDiff 時再呼叫 :GitDiff」效果一樣)。

GitDiffInfo 會顯示多個 log

GitDiff 另外支援一個用法,就是 revision 的部分使用 +<n> 的型式,有別於 <n> 是找前一個 commit, +<n> 會找「包含目前檔案」的前一個 commit,可以避免 <n> 找不到變更的情況。

例如 :GitDiff +1

快速答案是「一元運算子」。


NOT matter 要寫成 ! matter 還是 !matter 這個問題……
很長一段時間我是用前者,多個空白比較明顯,不會漏看驚歎號。


  1. ruby 文件 not 運算子的範例! mep(! false) 也有空白,我想就是求明顯、清楚。

  2. Kohana framework 的 Conventions and Style 也有類似考量:

    The ! (bang) character must have a space on either side to ensure maximum readability.

    ! 的兩邊都必須有一個空白,以確保最大可讀性。』
    註:這一章是講括弧用法,所以是說 if ( ! $foo)if (!$foo) 的情況。

  3. 不過我發現別人的寫法,絕大部分都是不空白的 !matter 風格。
    我已經沒印象上次看到 ! matter 是何時了。

    我也到 PTT ruby 板問了一下

  4. 沒有明確出處,但找到一些敘述,一般不空白的理由是「Unary operation(一元運算子)後面不加空白」。
    就像 -4 不會寫成 - 4

  5. 更精確地說是「一元運算子和它的運算元之間」不加空白。
    就像這個 NetBeans 選項 Bug 135699 – Use option "space between unary operator and operand"

  6. 最後在 Douglas Crockford 的 JS Code Conventions 看到更具體、可以照做的規範:

    No space should separate a unary operator and its operand except when the operator is a word such as typeof.

    『一元運算子和它的運算元之間,不該有空白,除非該運算子是一個 word,例如 typeof。』


其實我已經改用 !matter 一段時間了。 仍然懷疑 ! matter 沒有錯,但眼前還是解決風格一致的問題先了。

Group 是什麼

cycle.vim 搜尋相關候選字時 (例如目前是 true,應該要找到 false),會在一連串的 group 中查詢; 每個 group 是由 items 和 options 組成,以下便是一個簡單 group:
{ 'items': ['true', 'false'], 'options': {} }
如果想讓 foo 變成 bar,增加一個 items 為 ['foo', 'bar'] 的 group 就可以了。


怎麼設定 group

使用中的 groups 會存在 cycle_groups 這個變數,可以用 :echo string(g:cycle_groups) 查看; 但是這東西比較繁瑣,所以不建議直接修改它的值。

比較好的方式是在 .vimrc 定義 g:cycle_default_groups 這個變數, cycle.vim 啟動時會自動解析它,把需要的 group 都建好。

具體例子如下:

let g:cycle_default_groups = [
      \   [['true', 'false']],
      \   [['yes', 'no']],
      \   [['on', 'off']],
      \   [['+', '-']],
      \   [['>', '<']],
      \   [['"', "'"]],
      \   [['==', '!=']],
      \   [['0', '1']],
      \   [['and', 'or']],
      \   [['in', 'out']],
      \   [['up', 'down']],
      \   [['min', 'max']],
      \   [['get', 'set']],
      \   [['add', 'remove']],
      \   [['to', 'from']],
      \   [['read', 'write']],
      \   [['save', 'load', 'restore']],
      \   [['next', 'previous', 'prev']],
      \   [['only', 'except']],
      \   [['without', 'with']],
      \   [['exclude', 'include']],
      \   [['width', 'height']],
      \   [['asc', 'desc']],
      \   [['是', '否']],
      \   [['上', '下']],
      \   [['男', '女']],
      \   [['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
      \     'Friday', 'Saturday'], ['hard_case', {'name': 'Days'}]],
      \   [['{:}', '[:]', '(:)'], 'sub_pairs'],
      \   [['(:)', '「:」', '『:』'], 'sub_pairs'],
      \ ]

可以只為特定檔案類型設 group 嗎

cycle_groups 可以分成 global 和 buffer 兩個 scope(作用範圍)的版本,分別是 g:cycle_groupsb:cycle_groups 兩個變數。 搜尋的時候會以 buffer 版為優先,你可以讓 "get" 在 html 類型的 buffer 中轉為 "post",在其他類型 buffer 中則轉為 "set"

設定方式是在 .vimrc 定義 g:cycle_default_groups_for_{filetype},其中 {filetype} 表示想生效的檔案類型。
例如 html 專用的設定是:
let g:cycle_default_groups_for_html = [ ...(後略)

註:可以用 :echo string(b:cycle_groups) 檢查設定。


調整 group 行為

Group 的行為可以用 options 微調。目前(version 0.1.0)支援的選項如下:

  • name

    名稱,目前沒什麼用,只有處理衝突時(在多個 group 都有搜尋到目標字時)會顯示一下。

  • match_case

    搜尋候選字時,大小寫預設是不計的,所以 TruetruetrUe 都會被 cycle,只要設定其中一個即可。
    反之若要限制大小寫相符才 cycle,就要設定這個選項。

  • hard_case

    預設情形會保留關鍵字的大小寫位置,也就是 true/false 互換時,True 會變成 FalsetRUe 會變成 fALse
    這個選項可以停用此功能,互換時「若設定中是寫 fAlse,就一律換成 fAlse」。

  • sub_tag

    如果開啟這個選項,cycle.vim 會搜尋成對的 xml 開啟/結束標籤,有的話就一起 cycle 掉。
    例如 <EM>example</EM> 可以變成 <STRONG>example</STRONG>

  • sub_paris

    這個比較特別,它是 sub_pairend_withbegin_with 三個選項的簡易寫法,具體請看 doc。(建議用 sub_pairs 即可)

    [['(:)', '「:」'], 'sub_pairs'] 為例, 各個 item 會由 ":" 拆開, (:) 會拆成 「:」 會拆成
    cycle.vim 處理 "(" 時,會搜尋成對的 ")",若有的話就一起 cycle,
    例如 請保密) 可以變成 請保密」


具體要怎麼設定選項(options)

設定 group 時,每個 group 的第一個參數是 items,之後就都是 options 了。
支援以下各種型式:

  • [['true', 'false']] - 沒有 options
  • [['true', 'false'], {'match_case': 1}] - 以 hash 型式指定 options
  • [['true', 'false'], 'match_case'] - options 可以是字串,cycle.vim 會把它轉成 hash,hash 的預設值依各個 option 而不同,此處 'match_case' 的預設值為 1
  • [['true', 'false'], 'match_case', {'name': 'BOOL', 'sub_tag': 1}, 'hard_case'] - 字串和 hash 混著用也沒關係

你說完了沒

這篇應可滿足一般使用,我自己用到的也差不多這樣了。
在 doc 裡一些比較深入、低階的操作也有介紹,需要的話可以參考看看。

2012-09-22: 現在插入的 HTML 不一定有 <div class="separator"> 部分,script 也改為沒有這個 div 也能取代。

Blogger 文章編輯器「上傳圖片」自動插入的 HTML 為:

做了一支 bookmarklet 把它改成以下格式:

將 bookmarklet 加進書籤 → 清理 blogger 插入的圖片標籤
在文章編輯器的 HTML 模式執行就立刻取代,不保證原文的安全,請自己保重。


原始碼

var
  $textarea = document.getElementById('postingHtmlBox'),
  pattern = [
    '(<div class="separator" style="clear: both; text-align: center;">\n)?',
    '<a href="(.+)"',
    ' imageanchor="1" style=".*"><img border="0" height=".+" width=".+" ',
    'src="(.+)" /></a>(</div>)?'
  ].join(''),
  re = new RegExp(pattern, 'g');

if ($textarea) {
  $textarea.value = $textarea.value.replace(re, function (str, p1, p2, p3, p4, p5) {
    return [
      '<a href="', p2, '">',
      '<img src="', p3, '" alt="" /></a>'
    ].join('');
  });
} else {
  alert('錯誤,找不到 textarea#postingHtmlBox。');
}