那個教我卡 Bug 的學長,後來去當工程師了
這裡必須先打個岔,因為很多人一聽到「卡 Bug」就直接聯想到外掛,這對當年的我們其實有點冤。這三個詞在社群裡常被混用,但本質完全不同:
第三種的灰色地帶最大:單機遊戲裡你自己卡自己,沒人管你,甚至遊戲設計師還會覺得有趣;但線上遊戲裡,如果這個 Bug 能讓你大量產出資源、影響到其他玩家的體驗與遊戲經濟,那它就跟外掛沒有本質差別了,開發商一樣會處理。
學長當年的原則很清楚,我到現在都還記得:「單機遊戲,你想怎麼玩都是你的自由,因為那是你的存檔。線上遊戲,任何會影響到別人倉庫數量的 Bug,我碰都不碰。」他說他研究 Bug 是為了「理解系統」,不是為了「印鈔票」。
1-3 學長的第一課:先學會「記錄」
他教我的第一份作業是這樣的:買一本最便宜的橫線筆記本,每次卡到東西,就寫下五件事。
你在哪張地圖、哪個座標(很多遊戲有座標顯示,沒有的話用大地標相對位置描述)。
你當時的狀態:等級、負重、有沒有騎乘、身上有沒有增益效果。
你做了什麼動作:走、跑、跳、蹲、翻滾、施法、切換武器。
動作的順序:這是最關鍵的,順序錯一步就重現不出來。
結果:角色卡住、掉出地圖、NPC 消失、傷害判定失效……描述得越具體越好。
我當時覺得超麻煩,卡個 Bug 還要寫日記。但兩週之後我就懂了:不能重現的 Bug,等於不存在。你只是「剛好」遇到了某個狀況,下次想再玩一次,只能靠賽。能重現,你才開始有資格談「為什麼」。
這個習慣後來被我原封不動搬到工作上。寫不出來的 Bug 報告,工程師是沒辦法修的。「有時候遊戲會當掉」跟「在副本第三區、裝備弓箭、連續翻滾三次後立刻開啟背包,有 80% 機率畫面凍結」,這兩句話的價值差了大概一百倍。
二、學長的筆記本:卡 Bug 其實是一門除錯手藝
那本筆記本后来被我翻爛了。裡面沒有什麼神祕的「密技大全」,反而像一本很樸素的物理與程式觀察日誌。條列幾個當年最經典的類型,你會發現它們背後其實對應到幾種非常標準的軟體問題。
2-1 地圖邊界與座標:為什麼角色會浮在半空中
第一類是「空間判斷」的問題。遊戲世界通常由兩層東西組成:你看得到的「模型」(Mesh)和你看不到的「碰撞」(Collision)。美術把山壁畫得漂漂亮亮,但真正決定你能不能走過去的,是另一組簡化過的幾何資料。這兩者只要有一點點對不上,就會出現「看起來有路,但走不過去」或「看起來是牆,但你鑽得進去」的狀況。
更常見的是「卡在半空中」——角色站在一個其實沒有地面的位置,動不了也掉不下去。這通常代表角色的狀態被判定為「已著地」,而物理系統每隔一段時間才重新檢查一次腳下有沒有東西。如果那一次檢查剛好被跳過(例如幀率波動、場景切換、或伺服器端的延遲補償),角色就會停在一個不該存在的支撐點上。
學長當年的說法很可愛:「你踩在一個已經被刪掉的樓梯上。」
從工程角度來看,這類問題的根源往往是「狀態不同步」:客戶端認為你在 A 點,伺服器認為你在 B 點,兩邊各自用自己的答案繼續跑,於是你就卡在兩個世界的夾縫裡。這也是為什麼很多線上遊戲只要一「卡點」,官方最有效的解法不是修地圖,而是給你一個「回城」或「脫離卡點」的指令——直接強制重設狀態,比對帳還快。
2-2 時間差與狀態同步:複製道具的萬年老梗
第二類是「時間差」問題,也是歷史上最惡名昭彰的一類。你有沒有想過,為什麼複製道具的 Bug 幾乎每一款線上遊戲都出現過?因為「交易」這個動作,本質上是兩邊的資料庫要同時完成扣款與入帳。只要中間有任何一個環節可以被打斷——例如交易視窗開啟時對方斷線、例如你把道具丟在地上同時切換場景、例如兩個角色同時對同一個箱子按開啟——就有機會出現「我這邊已經拿到了,但對方那邊還沒扣掉」的狀況。
這在資訊科學裡有個正式的名字,叫做「競態條件」(Race Condition)。白話文就是:兩個流程在賽跑,誰先到、誰後到不一定,而程式設計師只想到了「A 先到」的情況。
學長當年對這類 Bug 的態度非常明確:知道原理可以,但絕對不去用。他會花一個下午推論「為什麼理論上這裡可能有洞」,然後把結論寫在筆記本上,隔天照樣去打他的副本。他有一句話我印象很深:「知道門沒鎖,不代表你要進去搬東西。知道了,你就可以去告訴管理員。」
這句話在後來的職涯裡變成我的職業道德底線:發現漏洞的價值,在於修補它,而不是利用它。現在業界流行的「漏洞賞金」(Bug Bounty)制度,本質上就是把這件事制度化——你找到洞,回報,拿獎金,大家都開心。這是卡 Bug 玩家最體面的出路。
2-3 仇恨值與 AI 路徑:讓王卡在柱子後面的原理
第三類是「AI 行為」的問題,這一類最有趣,因為它牽涉到遊戲設計師的「預期」與程式的「實際」之間那條裂縫。
很多遊戲的 Boss 有「尋路」(Pathfinding)機制:牠會計算一條從自己位置到你位置的最短路徑,然後沿著路徑移動。如果這條路徑被障礙物擋住,牠會嘗試繞路;如果繞不過去,有些遊戲的 AI 會進入「發呆」狀態,有些則會直接「穿牆」撲向你。學長當年最愛研究的就是:什麼樣的地形會讓 AI 判斷失誤。
例如柱子、轉角、高低差。當你站在一根柱子的正後方,Boss 的射線被遮擋,牠的攻擊判定就失效;但牠的尋路又認為「直線距離最短」,於是不斷往柱子撞,形成一個完美的僵局。這在玩家社群裡被稱為「卡視角」或「風箏」,某些遊戲甚至把它當成正式的战斗技巧,不算 Bug。
但界線在哪?如果遊戲設計師明擺著在關卡裡放了很多柱子,那大概是故意的,屬於「設計允許的策略」;如果是你爬山爬了二十分鐘,找到一個連美術都沒去過的山頂裂縫,然後從那裡把王射死,那就是 Bug 了。
學長對這種灰色地帶的判斷標準很務實:「看這個方法需不需要『非預期的操作』。需要的話,就是 Bug;不需要,就是技巧。」
2-4 從「試出來」到「想出來」:五個除錯習慣
筆記本寫久了,我發現學長其實有一套很固定的思考流程。後來我在寫程式、找問題、做效能調校的時候,幾乎是照著同一套在跑。整理成五點給你:
你可能會覺得,這不就是「科學方法」嗎?對,就是。但你要知道,台灣很多高中生是在遊戲裡第一次真正體會到「假設—實驗—驗證」這個循環有多爽。課本上的東西是別人的問題,遊戲裡的 Bug 是你自己的問題,而且破了會掉寶。
三、從卡 Bug 到寫程式:同一顆腦袋的兩次編譯
升上高三那年,學長考完學測,跑去念了資訊工程。我們還是有在玩,但他上線的時間越來越少,偶爾出現,講的話也開始變得很奇怪——以前他會說「這面牆有縫」,後來他會說「這個碰撞查詢沒有回傳正確的法向量」。我當時想,這人是不是被課業逼瘋了。
直到我自己也開始寫程式,才發現他只是換了一種語言描述同一件事。
3-1 卡 Bug 的人,其實在做逆向工程
所謂逆向工程(Reverse Engineering),是在沒有原始碼的情況下,透過觀察外部行為去推斷內部結構。你在遊戲裡卡 Bug 的時候,做的完全是同一件事:
你觀察到「跳上懸崖邊緣會浮空」,於是你推論「那邊的地形判定有洞」。
你觀察到「交易到一半對方斷線,道具會變兩個」,於是你推論「扣款與入帳不是原子操作」。
你觀察到「Boss 在轉角會發呆」,於是你推論「尋路演算法在窄通道會回傳失敗」。
這三句話,翻譯成工程語言,分別對應到:幾何碰撞資料的邊界條件錯誤、資料庫交易缺少原子性、圖搜尋演算法在特定圖形下的退化行為。當年的我們當然講不出這些名詞,但我們思考的路徑是一模一樣的。
學長有句話我一直記著:「你不需要看得懂程式碼,才能知道程式碼在想什麼。你只要一直戳它,看它哪裡會叫。」這句話對工程師來說其實是一種很重要的能力——面對一個陌生的、龐大的、沒有文件的系統,你能不能靠觀察與實驗,建立一個夠用的心智模型?
很多工程師卡住,不是因為不會寫程式,而是因為不會「問對問題」。而卡 Bug 的訓練,本質上就是在訓練你問對問題。
3-2 學長後來怎麼了:一封五年前的信
大學畢業後我們各奔東西。我進了內容產業,他進了軟體業,中間有好幾年只剩臉書按讚的交情。五年前他寄了一封信給我,那時候他剛換到一間做後端服務的公司,信的內容大概是这样:
「最近在處理一個很靠北的線上問題。使用者偶爾會在下單之後,庫存扣了、訂單沒成立。重現率大概千分之三,log 看不出來。我盯了兩天,最後發現是兩個服務之間的非同步訊息,在極端延遲下順序會顛倒。」
「你知道最好笑的是什麼嗎?我解決它的那個晚上,腦子裡想的居然是十五年前那款遊戲的交易視窗。那時候我就在想『為什麼扣東西跟拿東西不是同時發生』,現在我在修的,是同一件事,只是幣別從金幣變成新台幣。」
「我老闆說我很有耐心,適合做這行。他不知道我這個耐心是小時候在城門口蹲了三個小時,只為了驗證『到底是不是只有下雨天 NPC 才會消失』練出來的。」
我看完那封信笑很久。後來我問他,面試的時候有沒有講過這段經歷。他說有,而且是他履歷上最有用的一段故事。
「面試官問我『你怎麼 debug 一個沒看過的系統』,我就講我怎麼在沒有原始碼的遊戲裡找出一條能穿過地圖邊界的路。我講完,他問我下一步會做什麼,我說我會去寫一份重現步驟,然後回報給官方。他就笑了,說這正是我們要的人。」
他現在是那個團隊的技術主管,帶六個人。他說他面試新人的時候,最喜歡問的一個問題是:「你最近一次找到一個別人沒發現的問題,是什麼?」他說答案是不是遊戲、是不是程式都無所謂,重點是那個「發現」的過程有沒有邏輯。
3-3 如果你也想走這條路:從玩家到工程師的學習地圖
如果你看到這裡,心裡想的是「我好像也是這種人」,那我認真給你一條路徑。不是雞湯,是可以照著做的:
學長當年沒有什麼特別的資源,網咖的電腦連編譯器都沒有。他能做的只有兩件事:觀察,還有記錄。而這兩件事,你今天在任何一台手機上都能做。
四、底線與安全:卡 Bug 的紅線在哪裡
聊到這裡,我必須把話說清楚,因為這篇文章掛在「遊戲攻略」分類底下,一定會有人想歪。
「研究 Bug」跟「利用 Bug 得利」,中間有一條非常清楚的線。這條線不是道德勸說,是實實在在會影響你帳號、甚至影響你法律責任的線。
4-1 單機、連線、線上遊戲的三種尺度
第一種是單機遊戲。這是你自己的存檔,你自己的世界。你想用控制台指令、想卡進牆裡看風景、想把整個村莊的 NPC 疊在一起,那都是你的自由。很多遊戲設計師甚至會在訪談裡說,他們最愛看玩家用奇怪的方式破關,因為那代表設計有彈性。這一類,放心玩,玩壞了重開就好。
第二種是連線合作遊戲(例如幾個人一起打副本)。這裡的尺度是「你的隊友同不同意」。你們自己開房、自己玩、自己承擔存檔壞掉的風險,通常沒問題。但如果你隨機組隊,然後用一個會讓隊友也受益或受害的 Bug,就要看對方了。基本禮貌是:開始前先講。
第三種是大型線上遊戲、有交易市場、有排行榜、有真實金錢流動的那種。這裡的紅線最硬,因為你的每一個操作都會影響到其他真人玩家的資產與體驗。
學長的原則我再說一次,因為它真的很好用:「任何會影響到別人倉庫數量的 Bug,我碰都不碰。」你可以把它當成一句口訣,套用在任何灰色情境上。
4-2 一份實用的自我檢查清單
當你在遊戲裡發現一個「好像不太對」的現象時,先問自己這五個問題再決定要不要繼續:
一、這件事會讓我拿到原本不該拿到的資源嗎?會的話,停。
二、這件事會影響到其他玩家的體驗或公平性嗎?會的話,停。
把研究 Bug 當成一種「資安素養」的練習,而不是「遊戲攻略」的捷徑,你的這條路才會走得長。現在的遊戲公司幾乎都有漏洞回報管道,有些還真的會發獎金或發虛寶感謝你。這比偷偷摸摸刷道具,體面太多了。
五、結語:那些 Bug 教我們的事
去年我跟學長吃了一頓飯。他現在頭髮少了一點,講話還是那副德行,開口閉口都是系統、架構、延遲、監控。吃到一半我問他:「如果當年網咖沒有那款遊戲,你現在會在哪裡?」
他想了很久,說:「應該還是在做同一件事吧。可能不是寫程式,是修車、或是抓漏、或是做水電。反正我這個人就是喜歡找『哪裡怪怪的』。」
他說他後來發現,工程師的工作有一半時間不是在「寫」,而是在「找」。找為什麼上一次部署之後這支 API 變慢了、找為什麼這個使用者偶爾會登不進去、找為什麼這筆錢扣了但訂單沒成立。這些事情的本質,跟十五年前蹲在城門口等下雨,一模一樣。
所以如果你問我,卡 Bug 到底教會了我們什麼,我會這樣回答:
它教會我們,世界不是理所當然的。你眼前看到的牆,背後是由一堆判斷條件堆起來的;你以為順暢的流程,中間可能有十幾個環節在接力。當你開始對「理所當然」感到好奇,你就會去戳它、去問它、去實驗它。
它教會我們,重現問題比解決問題更難。大部分時間我們不是不夠聰明,是我們根本不確定自己看到的是什麼。能把問題講清楚的人,就已經解決一半了。
它教會我們,紀錄很重要。那一本橫線筆記本,我早就不知道丟到哪去了,但「寫下來」這個習慣留了下來,變成我的工作日誌、我的 bug tracker、我的文件資料夾。
最後,它教會我們,知道門沒鎖,不代表你要進去搬東西。
那個教我卡 Bug 的學長,後來去當工程師了。而我,後來也去寫了程式。我們從來沒有在遊戲裡刷過任何一件不該拿的道具,但我們在真實世界裡,靠著當年蹲在網咖裡練出來的耐心與好奇心,找到了屬於自己的飯碗。
如果你現在正在某個遊戲的角落裡,對著一面奇怪的牆發呆,別急著走開。拿起手機,記下你剛剛做了什麼。也許十五年後,你也會在某個會議室裡,對著一群工程師說:「這個問題我小時候遇過,我知道它在哪裡。」
那會是一個很棒的下午。
```