遊戲 Lag 白皮書 › 依症狀查找
卡頓:60 個原因與負責團隊
其他說法:卡卡的、一頓一頓、像在掉幀
在含圖解的完整版症狀辭典中開啟 →
動作不流暢,不斷短暫停住又繼續動。
其他角色或自己的整個畫面「頓、頓」地走。軌跡點一下擠在一起、一下又拉開。
ping 值正常時,多半是自己電腦的畫格問題(用戶端、OS);ping 忽高忽低時,多半是 Wi-Fi 或線路的抖動。不過遊戲內顯示的 ping 通常是在每個畫格跑一次的遊戲迴圈裡量的,所以畫格時間飆高時,ping 數字也可能跟著跳。
造成這個症狀的原因
L1 用戶端遊戲程式
- 畫格時間尖峰: 某一個畫格的計算時間比平常多出好幾倍,畫面短暫停住。 (遊戲開發團隊(用戶端開發))
- 用戶端垃圾回收: 回收用過即丟的記憶體(垃圾)期間,整個遊戲會暫停。特徵是以規律的間隔出現卡頓。 (遊戲開發團隊(用戶端開發))
- 主執行緒同步載入、著色器編譯: 要繪製第一次出現的地圖、怪物、特效之前,得先讀取檔案並建立著色器,畫面因此停住。 (遊戲開發團隊(用戶端開發))
- 儲存裝置太慢,資源串流跟不上: 在 HDD 這類較慢的儲存裝置上,讀取開放世界貼圖與模型的速度跟不上移動,物件會晚出現,或遊戲為了等待讀取而卡頓。 (遊戲開發團隊(用戶端開發))
- 大量角色同畫面的渲染負載: 攻城戰、世界王這類數百人擠進同一個畫面的場合,光是繪製的成本就負荷不了。 (遊戲開發團隊(用戶端開發))
- 沒有內插緩衝或緩衝太短: 一收到伺服器封包就立刻繪製時,抖動(封包抵達間隔忽長忽短)會原封不動地出現在畫面上。 (遊戲開發團隊(用戶端開發))
- 過度外插(dead reckoning): 封包沒來的期間,照最後的速度繼續顯示移動,等發現猜錯再拉回來。 (遊戲開發團隊(用戶端開發))
- 固定時間步長追趕失控: 停過一次之後集中補算落後的部分,又因為這些計算而再度落後。 (遊戲開發團隊(用戶端開發))
- 時鐘同步誤差: 用戶端推估的伺服器時間不準時,內插時間點與冷卻判定就會出現偏差。 (遊戲開發團隊(用戶端開發))
- float 時間精度損失: 以精度較低的浮點數格式(float)保存遊戲時間時,開著的時間越久,時間解析度(能分辨的最小時間差)就越差,動作與特效會顫動。 (遊戲開發團隊(用戶端開發))
- 垂直同步(V-Sync)與渲染佇列: GPU 畫好的畫格會先在佇列裡堆上幾張,再配合螢幕的更新週期送出,這段期間輸入就被延遲。 (遊戲開發團隊(用戶端開發))
- 用戶端記憶體洩漏: 開得越久,記憶體用量越大,遊戲越來越慢,最後被強制關閉。 (遊戲開發團隊(用戶端開發))
- 遊戲安全模組(反作弊)檢查: 為了防範外掛而與遊戲一起執行的安全模組會定期檢查。檢查太重,或與安全伺服器往來的心跳封包(定期確認連線存活的訊號)延遲時,就會卡頓或斷線。 (遊戲開發團隊(用戶端開發))
L2 用戶端 OS 與裝置
- 背景處理程序占用 CPU: 防毒掃描、Windows Update、直播軟體、瀏覽器影片占住 CPU 核心時,遊戲執行緒分配不到 CPU,只能等待。 (外部(外部))
- 省電模式、過熱降頻: 筆電的電池模式、手機的省電模式、裝置過熱,都會讓 CPU、GPU 速度下降。過熱的特徵是一開始正常,過了一段時間才變慢。 (外部(外部))
- 計時器解析度: Windows 的預設計時器以 15.6ms 為單位,所以「只休息 1ms」實際上會等到下一個計時器週期,最長拉長到 15.6ms。 (遊戲開發團隊(用戶端開發))
- 安全軟體的封包檢查: 防毒軟體、防火牆檢查每一個封包時延遲會增加,太過頭還會把遊戲誤判為攻擊而封鎖。 (外部(外部))
- 用戶端記憶體不足、swap: 同時開著數十個瀏覽器分頁和遊戲時,OS 會把遊戲的一部分記憶體移到磁碟上。 (外部(外部))
- 顯示記憶體(VRAM)不足: 畫質選項需要的記憶體比顯示卡記憶體還大時,OS 會把貼圖移到電腦的主記憶體再搬回來,因此出現卡頓。 (遊戲開發團隊(用戶端開發))
- Wi-Fi 背景掃描: OS 為了尋找周圍的 Wi-Fi,會定期切換到其他頻道,這段期間通訊會短暫停止。 (外部(外部))
- 網路卡省電、驅動程式問題: 有線網路卡或 Wi-Fi 晶片在封包與封包之間進入省電狀態時,要重新喚醒需要時間。 (外部(外部))
- 視窗最小化或非作用中時的處理限制: 切到其他視窗或把遊戲最小化時,遊戲與 Windows 會為了省電讓遊戲跑得比較慢。回到遊戲時,累積的封包會一口氣湧入,或者早已斷線。 (遊戲開發團隊(用戶端開發))
- overlay 程式干擾: 通訊軟體、啟動器、錄影、FPS 顯示程式為了在遊戲畫面上疊加自己的 UI,會介入遊戲的渲染流程(hook)。每個畫格的工作量因此增加,偶爾還會與遊戲衝突,造成頓一下或遊戲被強制關閉。 (外部(外部))
L3 家用網路
L4 網際網路線路
- 衛星網路(低軌/同步軌道): 衛星網路的電波必須往返太空。同步軌道衛星光是往返就超過 0.5 秒;Starlink 這類低軌衛星平時很快,但在重新分配路徑的瞬間延遲會忽高忽低,有時還會短暫中斷。 (外部(外部))
- 尖峰時段 peering 區段壅塞: 晚上 9~11 點左右影音流量暴增,電信業者之間的互連區段(peering)容易壅塞。 (基礎設施團隊(網路基礎設施))
- ECMP 其中一條路徑異常: 電信業者與資料中心會為同一個目的地準備多條路徑,並替每條連線指定其中一條傳送。只要其中一條路徑故障,被分配到那條路徑的人就會持續遇到 lag。 (基礎設施團隊(網路基礎設施))
L6 伺服器網路卡
L7 伺服器 OS(kernel)
- 執行緒過多與 context switch: 執行緒數量遠多於 CPU 核心時,OS 會把 CPU 花在輪流切換執行緒上。 (遊戲開發團隊(伺服器開發))
- CPU steal(虛擬機器): 實體伺服器(hypervisor)把虛擬機器的 CPU 時間暫時讓給其他虛擬機器(CPU steal)時,遊戲伺服器會停住。 (基礎設施團隊(伺服器基礎設施))
- 容器 CPU 節流(CFS 配額): 容器設了 CPU 上限時,只要在固定週期(通常是 100ms)內用完配額,剩下的時間就會被強制暫停(節流)。 (基礎設施團隊(伺服器基礎設施))
- 記憶體回收與壓縮(compaction)造成的暫停: OS 為了組出大分頁(huge page)而壓縮記憶體,或回收可用記憶體時,處理程序會停住。 (基礎設施團隊(伺服器基礎設施))
- 排程工作: 每天固定時間執行的 log 壓縮、備份、安全掃描會占用 CPU 與磁碟。 (基礎設施團隊(伺服器基礎設施))
- OS、kernel、驅動程式、韌體更新後的效能變化: 遊戲程式碼沒變,但伺服器 OS、kernel、驅動程式、韌體更新後就變慢。更新有時會改變預設值、排程器、CPU 漏洞緩解措施(mitigations)與驅動程式的行為。 (基礎設施團隊(伺服器基礎設施))
L9 伺服器遊戲程式
- 超出 tick 預算: 一個 tick 內要做的事超出預算時,伺服器的 tick 週期會拉長,整個區域的遊戲進行變慢,或出現卡頓。 (遊戲開發團隊(伺服器開發))
- 視野(AOI)計算量暴增(N²): 若要判斷誰能看到誰而讓所有人兩兩比較,人數變成 10 倍時,運算量會變成 100 倍。 (遊戲開發團隊(伺服器開發))
- 遊戲執行緒上的同步呼叫: 在 tick 進行中等待 DB 回應或檔案寫入時,伺服器上整個遊戲進行就會停住同樣長的時間。 (遊戲開發團隊(伺服器開發))
- 計時器集中同時觸發: 所有怪物重生、所有 buff 到期、整點獎勵都擠在同一個 tick 時,那一個 tick 的負擔會變成平常的數十倍。 (遊戲開發團隊(伺服器開發))
- 物件累積(未清理的道具、召喚物): 該消失的地上道具、召喚物、已結束的計時器沒有清理而不斷累積時,伺服器開得越久,每個 tick 要做的事就越多。 (遊戲開發團隊(伺服器開發))
L10 記憶體
- 腳本引擎的 GC 暫停: 即使是 C++ 伺服器,只要任務、AI、技能是用 Lua 等腳本執行,腳本引擎進行 GC 的期間,該 zone 就會停住。 (遊戲開發團隊(伺服器開發))
- 記憶體配置暴增: 活動期間大量產生暫時物件時,GC 執行的頻率會比平常高出許多。 (遊戲開發團隊(伺服器開發))
L11 磁碟
- 同步寫入 log: 遊戲執行緒每寫一行 log 都要等磁碟寫完的話,磁碟一忙,遊戲進行也會跟著停住。 (遊戲開發團隊(伺服器開發))
- fsync 暴增: 要求把資料「確實」寫入磁碟時,依磁碟不同,每次需要 0.1ms~數十 ms;請求一多,佇列就會變長。 (遊戲開發團隊(伺服器開發))
- 雲端磁碟 burst credit 耗盡: 部分雲端磁碟與小規格伺服器有 burst credit(突發額度),可以短時間跑得比基準效能快;忙碌時段一拉長、額度用完,速度就會突然下降。 (基礎設施團隊(伺服器基礎設施))
- 備份、壓縮、掃描作業: 凌晨的備份、log 壓縮、安全掃描獨占磁碟時,遊戲伺服器的讀寫就會被擠到後面。 (基礎設施團隊(伺服器基礎設施))
L12 資料庫
L13 伺服器架構與維運
- log 與監控過載: 發生故障時 log 會暴增,以同步方式送出 log 的伺服器會因為 log 變得更慢。 (遊戲開發團隊(伺服器開發))
同步設計
- Lockstep 中等待最慢的玩家: 在所有人一起計算同一回合的架構中,只要一個人的輸入晚到,所有人都要等。 (遊戲開發團隊(伺服器開發))
- 沒有時間戳記、一到就播放: 伺服器事件沒有附上發生時間、一收到就播放時,網路抖動會讓演出時機跟著忽快忽慢。 (遊戲開發團隊(用戶端開發))
- 主機(房主)架構: 由某個玩家的電腦擔任伺服器時,那個人的線路與電腦效能決定了所有人的體感。 (遊戲開發團隊(伺服器開發))
- 快照傳送頻率太低: 伺服器每秒只送幾次位置更新(快照)時,內插緩衝就得相應拉長,看到的其他角色會是更久以前的狀態。 (遊戲開發團隊(伺服器開發))
只有部分人遇到的問題
- 各玩家的輸入緩衝大小: 伺服器替每個人暫存一點輸入、每個 tick 取出一個使用時,在其他人眼中很流暢,但本人的動作在伺服器上確定的時間點也會晚上這麼多。 (遊戲開發團隊(伺服器開發))
- 怪物控制權在慢速用戶端上: 有些遊戲為了減輕伺服器負載,把怪物移動的計算交給附近某位玩家的用戶端。那個人線路差時,該怪物在所有人的畫面上都會動得很怪。 (遊戲開發團隊(伺服器開發))
- 記憶體/VRAM 不足導致串流失敗: 兩個用戶端分著用顯示記憶體時,沒有空間載入新需要的模型與貼圖,部分物件就畫不出來。 (遊戲開發團隊(用戶端開發))
- 時鐘推估誤差導致物件暫緩顯示: 用戶端推估的伺服器時間有誤時,會把剛抵達的物件資訊當成「還在未來」而暫緩,或當成「太舊」而丟棄。 (遊戲開發團隊(用戶端開發))
TCP 重傳的根本原因
- 封包亂序造成的不必要快速重傳: 封包經過多條路徑或聚合鏈路時順序被打亂,接收端會以重複 ACK 告知「有封包缺漏」,傳送端就把其實已正常送達的封包再送一次。 (基礎設施團隊(網路基礎設施))
查看含圖解的完整版症狀辭典