Supercell程式設計師分享:從COC到Everdale,單人玩法到社交遊戲轉變

語言: CN / TW / HK

【GameLook專稿,未經授權不得轉載!】

GameLook報道/Supercell是業內最為獨特的手遊公司,沒有之一。從成績來看,這家芬蘭公司上線了5款遊戲,而且都是十億美元級獨角獸,甚至還有CoC這樣成功超過10年的產品。另一方面,Supercell旗下游戲還有一個非常鮮明的特點,那就是幾乎所有遊戲從本質上來說都是單人體驗(單機或者一對一競技)。

不過,2021年測試的《Everdale》改變了這一現狀,這款遊戲雖然目前仍未加入競技玩法,但從一開始就要求多玩家合作。在GDC 2022大會演講中,Supercell高階程式設計師Tristan Williams講述了該公司為新遊戲打造技術的過程與心得。

以下是GameLook聽譯的完整內容:

Tristan Williams:

從CoC到Everdale

我們今天要分享的是“從CoC到Everdale,從單人玩法到社交玩法”,我是Tristan Williams,在Supercell擔任高階程式設計師,我是2014年加入的公司,在此之前,曾在Remedy、Splash Damage和Ratbag等多家遊戲工作室就職。

今天的主要話題是開場介紹,遊戲設計我們會淺嘗輒止,大部分都是從技術層面來說的,最後分享一些心得。

你們可能有人聽說過CoC,但比較神奇的是,這款遊戲釋出於2012年,並且自此之後就一直保持在iOS暢銷榜Top 50以內,至今已經10年了。《Everdale》是我們最近測試的新遊戲之一,釋出於去年。

CoC是一款城建遊戲,你建造各種資源,比如聖水和金礦,打造自己的防禦設施和軍隊,然後通過塔防玩法攻擊其他玩家的基地以獲得資源,隨後用這些資源訓練更多軍隊並獲得天梯分數。

在這款遊戲裡,你同時在螢幕上只能看到一個玩家的大本營,其核心玩法完全是單人的。

遊戲裡的部落實際上是可選玩法,你不會被強制要求加入部落,當然,部落成員還可以通過部落戰更快速得到更多資源,不過它更多的是作為單機玩法之外的另一個資源收入渠道,你的進度依然完全是自己的。

《Everdale》的靈感來自於一些經典遊戲,比如《工人物語2(The Settlers 2)》是我青少年時候最喜歡的一款城市建造遊戲,還有《模擬人生4》以及《輻射避難所》,它們對這款遊戲的角色和互動設計都有所影響。

另一個靈感來源是《文明6》,更多的不是對玩法的影響,而是遊戲的規模,我們希望將《Everdale》做成一個比以往Supercell產品都更大的遊戲。

在這款遊戲裡,玩家可以安排不同的角色建造各種建築,還可以分配角色伐木、採石等多項工作,每個建築都可以分配不同的角色,收集資源擴張小鎮,並不斷解鎖新建築和新角色,所有的工作和資源都是相互影響的,但首先要伐木才能建造更多的建築。

以上並不是全部,這裡是科技樹,如果玩過《文明》系列可能會對此比較熟悉,你可以解鎖新建築、新等級。從遊戲的一開始,玩家們就是在山谷裡共同生活的,你可以在小鎮看到其他玩家的村落,彼此之間不用轉換,整個小鎮地圖是無縫連線的,所有人共同打造一個更大的世界。

你可以安排村民到羊毛紡織廠工作,得到羊毛之後我們可以找裁縫做襪子,這些建築並不屬於某一個玩家,而是屬於整個小鎮。Great Library裡的科技需要所有人努力解鎖,這些進度屬於整個山谷的人。

這是交易系統,所有的訂單都來自於很遠的地方,通過這些訂單,你可以獲得資源以及山谷升級點,遊戲玩法是非常放鬆的。

總的來說,山谷與你的城鎮玩法深度關聯,山谷技能解鎖可以幫助城鎮玩法推進,你還可以贏得金幣建造更多的建築。從一開始,山谷和城鎮就是相互影響的,這是遊戲的核心玩法,我們有共享的進度以及玩家之間的深度合作。

在談更多內容之前,我們先說說《Everdale》的團隊,這樣更容易理解遊戲中的一些決策。與很多的Supercell遊戲一樣,《Everdale》的團隊非常小,實際上,我們從2016年就開始了這個專案,但團隊人數大多數時候不到6個人,直到測試釋出之前,才將團隊擴充至10-20人之間。團隊規模最大的時候,我們有4名客戶端程式和2名伺服器程式,這就是《Everdale》的背景。

做Everdale的夢想

接下來我想說說“夢想”。

所有的創意,不管是一款遊戲、一幅畫還是一本書,都是從某種形式的夢想開始的,哪怕你不是以這種方式思考,比如在你腦海中想要實現的想法,也是一種夢想,這些夢想都有不同的形式和大小。

我是如何區分夢想大小的?比如一個小的夢想可以是個非常酷的玩法機制,就像是在《卡通農場》裡,你收割莊稼的時候不是點選螢幕,而是劃屏的方式實現鐮刀一樣的收割動作。一個小的夢想也可以是個獨特的玩法想法、一種藝術風格(比如Limbo),或者一些有趣的技術。

這些小的夢想就像是一粒種子,種在地下,隨後慢慢發芽、成長,通常情況下,對於這些夢想,你都有比較清晰的參照物以便進行創造。但這裡真正的挑戰是做出差異化,你該如何做出獨特的東西?

大的夢想,可以是你“崇高的目標”,它通常是使用者體驗或者情感驅動的,當玩家體驗遊戲的時候會有什麼感覺?他們會不會在遊戲裡覺得自己是外星人、大廚或者管理城市的市長?它是從高度幻想開始的,與小夢想不同的是,大夢想是從最高處開始,然後向下生長,你考慮的是,我要打造什麼樹枝才能支撐這樣的大樹?最終你可能會找到種子,然後從下再次向上增長。

另外,你還可以同時擁有大夢想和小夢想。

大的夢想是令人生畏的,因為你可能還不瞭解其玩法機制,可能你只是有一個想法,“我想做一個感覺自己是神明的遊戲”,但你該如何打造這樣一款遊戲?這樣的夢想缺少參照物,有時候你可能在打造一個新品類,需要的技術可能並不存在。

說回《Everdale》,一開始的時候,我們希望觸及大眾使用者,不想要加入戰鬥。這個想法來自於觀察妻子玩CoC和《帝國時代》,如果你玩過CoC,就知道剛開始的時候會有幾天的護盾,這個期間其他人沒辦法攻擊你,因此也不會偷走你的資源。

所以在最開始幾天的時候她很開心地建造基地,升級建築,並設計了她很喜歡的陣型,然而幾天之後,保護期結束,她的基地被人攻擊了,丟失了很多資源,她覺得很失落,於是解除安裝了遊戲。

《帝國時代》也是類似的經歷,她派軍隊到處探索,填滿了城鎮,隨後戰爭開始了,她受到了攻擊,感受到了很大的壓力,然後她退出了遊戲,重新開始玩,到了戰爭開始之前的時候再次重新開始遊戲,隨後又一次解除安裝了遊戲。

這讓我看的眉頭緊鎖,我在想,或許市面上沒有戰鬥的城建遊戲很少,這是一個我們應該解決的挑戰,或許並不是所有遊戲都一定要戰鬥。我每天都玩很長時間的《Everdale》,也會投入時間玩《毀滅戰士》,或許沒有戰鬥的遊戲可以作為一種休閒放鬆方式。我們的另一個夢想是,讓它比之前任何一款Supercell遊戲都更需要合作,都更有沉浸感。

我們再從夢想角度來看看這款遊戲,小夢想方面,我們希望把它做成一款優秀的城建遊戲,它的氛圍應該是和平與放鬆的;大夢想角度來說,我們希望一開始就需要玩家之間的合作,我們要做的是真正有意義的合作,而不只是形式上的合作,我們希望打造一個無縫的世界和多個城鎮。

因此,所有遊戲都是以某種夢想形式開始的,你一開始可能意識不到,但腦海中或許會有某種感覺,努力確定這些夢想,因為它可以幫你在早期確定遊戲的核心原則,在我們的案例中,它還可以推動技術決策。

我還想談談什麼是合作玩法

這裡用CoC舉例,這是部落介面的截圖,你可以看到部落成員,可以點選訪問他們的基地,甚至還可以與他們聊天。

接下來就是部落戰爭,雖然依舊是單機戰鬥,但你們可以通過積累星星的方式幫部落獲勝,你可以根據戰鬥表現獲得星星和不同的資源數量,這些資源都是你的,所以本質上來說它依然是單人玩法。

對於升級版的合作,我們希望打造一個無縫的世界,可以實時看到其他人玩遊戲,可以在世界當中有真正的玩法互動,而不只是選單層面的互動。我們希望團隊協作是真正有意義的,玩家之間有共同的目標,我們對這些目標非常的興奮。

但是,對這個目標,我們同樣有些擔心,比如更大的遊戲世界模擬和渲染起來會比較昂貴,因為《Everdale》的目標是手機硬體,而不是PC或者主機裝置。我們覺得這樣的遊戲設計起來可能會很複雜,測試起來或許更復雜。

不過,我們依然毫不猶豫地開始了這個專案。

Everdale的技術迭代

技術層面,我們挖掘了CoC的潛力,它使用了內部引擎打造,每次只能在螢幕上展示一個城鎮,而且合作僅停留在選單層面,雖然現在不完全是2D,但過去它只能做2D。

另外,它是客戶端/伺服器架構,伺服器授權並實時驗證客戶端,我們是通過大量的“程式碼”在客戶端和伺服器執行實現的,這些程式碼當中沒有任何浮點值。它的邏輯狀態是固定的,因此你不用定製化。

CoC的客戶端和邏輯程式碼非常依賴單項物,比如遊戲物體設計經理負責提供所有的物體,商店促銷管理者決定所有的商店促銷活動,這種方式很方便也很容易寫程式碼,但問題在於,你一次只能執行一個城鎮。

在多城鎮設計中,我們把它拆分為“上下文”概念,它打包了城鎮執行狀態所需要的一切子系統,不管是物體、商店還是任何環節,都知道它們所處的執行狀態是什麼,雖然沒什麼大不了的,但是很好用。

這樣做的優勢在有,我們甚至可以在後臺執行城鎮拷貝版本,還可以用它做邏輯驗證的debug,我們可以預測未來。總得來說,這些設計目標給了我們很不錯的技術優勢。

我們想要做一個無縫世界,意味著每個城鎮都有一個“渲染世界”,也就是每個城鎮都有自己對應的系統,比如,我的城鎮和你的城鎮都是從0開始,然後各自發展為不同的規模。山谷也是一個渲染世界,它包括山谷裡的建築和物體,與玩家城鎮不同。山谷的視覺是由不同世界組成的,每個世界都用補償的方式渲染。

我們希望把它做成一個城鎮建造遊戲,村民有不同的文化、服飾,而且可以執行大量不同的任務,我們還希望對村民進行定製化,比如每個人的服裝。如果從2D角度來看,這需要大量的內容排列,一旦想要改變某一樣東西,就需要重新渲染大量的東西。

因此我們決定採取3D風格,但問題是,我們還沒有一個真正的3D引擎。我們可以做一些3D的東西,比如《荒野亂鬥》裡的角色是3D的,但環境是2D;《海島奇兵》的一些環境是3D的,《皇室戰爭》的一些選單也是3D。

所以,我們打造了一個非常簡單的3D引擎,之所以說簡單,是因為它的用途幾乎與我們的2D使用者非常接近,因為Supercell大部分的人都沒有3D遊戲背景,只有我和少數人具備3A主機遊戲的研發經歷。 做引擎非常重要的是,能夠讓人們快速上手做出新內容,這也是我們做簡單3D引擎的原因。

另一個決策就是,我們的攝像頭控制直接複製了CoC,你們可能注意不到,但一定可以感覺到的是,你看到的視野與手指碰到一致,而且,這個引擎在《荒野亂鬥》的時候就開始做了,到了《Everdale》的時候我們一起對它進行提升,所以它一直在變得更好用,這樣一個小小的夢想,最終帶來了一個讓整個公司都受益的大技術。

合作玩法的支撐技術

真正的主菜是合作玩法技術,我們想要的是一個無縫世界裡的多人遊戲,一開始的時候,玩家們的動作會發送給其他客戶端,但你並不能對此做出互動,也無法一起完成某些事,在你自己的成長,驗證過程很簡單,你想要做的動作會發送給伺服器,得到驗證後即可執行,如果是無效的,伺服器會發回正確的方式。

然而,如何處理共享狀態呢?之前的遊戲裡,我們所有的共享狀態、資訊處理以及每個功能的糾錯都是手動的,所以每次做新功能的時候,我們都需要客戶端和伺服器方面的程式設計師加入。但我們想要更復雜的功能,而之前的技術只能帶來比較乏味的合作功能,而且會限制研發時間。

那麼,我們該怎麼做?我們的第一件事就是為山谷增加共享的邏輯狀態,包括共享的 邏輯程式碼和上下文,我們還確定了“行為”目標,包括玩家動作與引數,以及所有的驗證核查、驗證失敗狀態的處理以及需要的回撤。

具體過程就是,如果客戶端驗證通過,就傳送給伺服器,每個城鎮以及山谷都是獨立的,如果驗證失敗,客戶端會執行失敗程式碼並回撤到之前的狀態,如果驗證成功,則傳送給山谷狀態伺服器,如果山谷伺服器驗證失敗,則傳送回城鎮伺服器和客戶端,執行回撤程式碼,驗證通過,則分發給其他客戶端。

你們可能已經看出,這種方式並不夠好。不過,它的優點在於,你可以在一個地方更簡單更整潔的看到所有的處理過程,而且可以共享大量的邏輯程式碼。這種方式下,一名遊戲程式設計師就可以打造完整的交換過程,不需要伺服器程式的幫助,因為伺服器程式需要他們更擅長的事情。

劣勢在於,程式要預測所有可能的失敗條件,並且對所有情況下加入合理的回撤程式碼。而且,它依舊很冗長、需要大量的人力,很多方面都和之前的舊方法相似。所有的客戶端和UI程式碼都需要寫下來,以保證所有不同場景下的邊緣情況都可以被處理,這需要大量的時間和努力。

為了改善這種狀況,我們採取了resimulation-based approach,如果你寫過多人遊戲,可能對這種方式比較熟悉,客戶端先於伺服器執行,如果遇到了錯誤就回到之前的狀態,然後重新預測重新執行,在玩家沒有注意到之前就完成了這一切。

因此,伺服器會同時執行山谷內所有的城鎮,客戶端比伺服器執行稍早一些,如果發生改變,客戶端就可以回到上一個良好的狀態並重新模擬遊戲。因此,伺服器同時驗證並應用城鎮和山谷的所有動作。

這種情況下,我們不再需要做所有的錯誤解決方案或者回撤,只是在需要的情況下驗證和執行特定行為。這種方式非常強大,伺服器狀態始終都有明確的定義,大多數情況下錯誤的方案都可以被統一解決。

儘管不是所有情況,儘管不適合快節奏的動作遊戲,但這種方法很適合慢節奏遊戲。

這種方法的不利在於,它在客戶端和伺服器儲存了很多東西,對CPU和儲存要求較高。有些情況下,客戶端和UI仍需要謹慎處理,因為錯誤的預測可能導致狀態變化很大。它避免了直接從邏輯程式碼轉為客戶端程式碼,比如有時候導致聲音或者特效可能在重新模擬期間被觸發很多次。

實際上,這對《Everdale》專案來說是一個很大的成功,因為我們可以更快速地研發複雜的合作遊戲系統,與CoC技術相比,我們把某些東西的研發時間從數月縮短到數週,一個功能只需要一個程式就可以搞定。

最後,如果你做過手遊,就會知道迭代時間是很關鍵的,尤其是團隊非常小的情況下,很多時候我們只有3個程式,而其他們還要處理渲染技術,因此節約他們的時間,快速測試功能是很重要的。

如何保證遊戲效能?

我們的問題是,每個山谷有10個城鎮,每個城鎮都有成百上千個物體,因此每個物體做debug需要的工作量很大,我們的邏輯也非常複雜,你無法一直推進,只能等待上一個結果之後才能進行下一個流程,所以效能成為了比較大的問題。

所以在渲染方面,我們選擇將成長渲染為紋理代名,我們首先載入整個城鎮而不是城鎮裡的所有物體,隨著你放大城鎮,再對代名進行更新,避免了一直要渲染所有城鎮帶來的效能問題。

如果你知道自己想要的是什麼,就會發現還有很多工作要做,我們將城鎮渲染成正常的大小,但放大之後會顯得有些嘈雜,所以遠距離看到的是icon版本的城鎮。與此同時,我們做了大量的努力,讓縮小和放大之間的視覺切換儘可能無縫化。

優化的邏輯是可以在伺服器同時執行多個城鎮,並且在客戶端可以快速重新執行。我們的玩法是相對慢節奏的,所以我們發現可以將logic tick rate從25Hz降低到5Hz,與此同時,玩家還不會注意到任何差別。

反應時間是一個問題,從你的動作到真正看到反饋可能會有最高200毫秒的時延,所以客戶端的反應方式是,如果同步沒有發生,那就直接跳到下一個城鎮,讓他們感覺所有動作帶來的反饋都是即時的,必要的時候客戶端還會插入到邏輯狀態中,這種方式是行之有效的。

我們還確保所有的不同長度邏輯的更新都是確定的,如果能夠重新去做,我們或許會選擇不同的方式,但考慮到當時的限制,這是我們最好的選擇。我們允許所有物體、系統申請它們可以更新的次數,我們發現很多物體可以一次數秒跳過更新。我們讓客戶端一點一滴的推進,而伺服器可以快速推進。

雖然這個資料有點保守,但我們降低了80-90%的伺服器負載,這裡我們說的是與CoC的城鎮對比,所以即便是同時要執行10個城鎮,我們也只需要使用一個CoC城鎮的伺服器負載,我們還在客戶端做了螢幕外的城鎮邏輯更新。

但遇到的問題是,我們如何保證確定性,所以我們可以執行後臺驗證,後臺的城鎮副本快速執行並與現在的版本對比,如果出錯則可以儲存其軌跡,我們可以載入到客戶端深度執行,並找到解決方法。Debug伺服器也可以在同步中斷的情況下儲存執行軌跡,我們可以找到對應的問題。

有了確定性和分離式邏輯執行方式之後,我們可以做回退測試,將玩法“回放”儲存用來測試遊戲bug,我們儲存所有城鎮並且在變化發生之前和之後進行模擬,確保帶來同樣的結果,所有形式的驗證都可以在後臺執行。

我們還打造了可以玩遊戲的AI邏輯,一開始只是在客戶端這樣做,但後來我們發現可以在邏輯程式碼庫執行,還可以將同步邏輯移植到邏輯程式碼庫,然後將伺服器連線到負載測試狀態,再次執行。我們運行了數千個bots,收集了大量的平衡與穩定性資料,這種方式幫我們避免了很多罕見的bug,當然也非常複雜,因為是很多系統一起工作。

結果是,我們實現了夢想,至少它已經進入了測試階段,即使是沒有最終進入全球釋出狀態,這個專案的技術也可以在後續被全公司繼續使用。

心得

這裡主要的心得是:

擁有大的夢想,但要睜大眼睛。追逐巨集大的夢想並不一定是容易的,但你的努力不會白費,遊戲設計和技術之間是深度影響的,你在技術方面的投入可能會在以後有用處,希望今天的分享能夠幫助你們追尋自己的夢想和目標,更希望未來看到更多非常酷的新遊戲出現。

問答環節:

1、你在演講中提到了交易系統的討論,以及每次做一個功能,開發者參與到這些功能的設計過程中嗎?

A:當然如此,尤其是在小團隊當中,讓所有人都參與到每個環節的對話,這可以節約大量的修改時間。

2、提到變焦(放大或者縮小)的問題,你說遊戲允許多種方式的縮放,多大或者多小才是合適的?有時候在大螢幕上的表現很好,但如何讓它適應各種尺寸的螢幕?

A:適配不同的機型,適應不同尺寸的手機螢幕,做到自然流暢的縮放,這需要大量的嘗試,所以始終有可以提高的地方。我們做了很多測試,團隊所有人都玩過很多次,以找到最合適的感覺。

3、在漫長的嘗試當中,由於團隊很小,你們如何平衡迭代與遊戲API更新之間的關係,以便遊戲不會被移出PlayStore?

A:這是個非常好的問題,我要說的是我們沒有完美的標準,只是用一些常識,通常一批優秀的開發者共同努力可以做出比較好的決策,我們公司內部有一個說法,那就是“Supercell優先”,也就是說,我們做決策的時候更多考慮的是對公司有好處,而不只是為了滿足我個人的天馬行空的想法,這對我們是很有幫助的。

4、談到確定性,你們如何保證同樣的程式碼能夠適配所有的CPU架構,帶來同樣的結果?

A:這個問題很好,實際上問題比這個還複雜,因為我們的伺服器是用Java支援的,我們使用了固定點(fix point),沒有浮點(float point),這樣做會在M1處理器條件下有些邊緣案例出現,我們需要手動去解決,但這些都是比較特殊的情況。

5、當你提到伺服器架構的時候,曾提到多次反應,客戶端也有多次重構(refactor),如何平衡快速創意和重構之間的關係?有時候重構是被直接跳過的,因為它不一定會進入最終的產品中,你們是如何做的?

A:對於這個問題,我個人有一些原則,如果複製黏貼程式碼超過三次,我就會開始考慮重構,這取決於考慮什麼是對的,有時候我可能希望更早這麼做,雖然需要投入更多的努力,但完全是值得的,所以這是根據個人經驗來處理的。

6、這聽起來可能會耗費比較長的時間,你如何處理它和其他計劃的關係,比如你要跟製作人說,這個功能需要重構,所以還需要一兩個月,那麼是否意味著專案要因為這個功能往後推遲,還是說會採取一些折中方案?

A:有時候一些功能確實需要很長時間,但我們可以在它的基礎上讓以後的進度快很多。如果不是團隊所有成員都要參與,只是我自己的工作,那我可以專門投入時間去解決它,等所有系統都完成之後,其他人也可以在你的基礎上繼續。最重要的是讓你的製作人瞭解它的代價,當然更重要的是你要清楚需要付出的真正代價是什麼,努力做出最好的決定。

7、你在提到專案夢想的時候說到,遊戲不需要加入戰鬥以避免損失帶來的挫敗感,但《英雄聯盟》這樣的遊戲更有競技性,但你不會損失任何資源,所以團隊有沒有考慮加入這樣的玩法保持遊戲的競技性?

A:實際上我們是考慮過的,但遊戲當時仍處於很早期,包括現在,我們也討論過,或許兩種玩法可以共存,讓休閒和競技玩家可以同時享受這款遊戲,或許未來我們會考慮這樣的玩法。

8、從玩家的體驗觀察當中,你們學到了什麼?

A:目前來看玩家們的反饋很好,不過有一點比較意外的是,我們本以為這款遊戲會對全新的使用者型別更具有吸引力,結果發現很多的CoC玩家也很喜歡。如果願意,實際上也可以用很硬核的方式玩《Everdale》,但我並不提倡。

玩家構成方面,我們原以為女性使用者會佔絕對優勢比例,但結果發現實際上那女比例比較均衡,這也是非常不錯的結果。當然,遊戲目前還處於早期階段,我們還需要學習很多東西。

9、你在總結的時候提到,這款遊戲有可能不會進入全球釋出階段,那麼它的原因可能是什麼?沒有戰鬥還是說付費表現不好?

A:可能是我的措辭有問題,目前《Everdale》仍處於測試階段,我們還在觀察玩家的反應,收集更多的資料,有些玩家的行為甚至和我們預期的不一樣,我們還在學習很多東西。我沒辦法保證它一定能夠全球釋出,但在Supercell,我們所有的專案決策都是團隊做出來的,比如,我們是否還相信它能夠成為一款讓人們體驗10年以上的遊戲?

我說的意思並不是要強調它不會全球釋出,一切還要看後續的玩家反饋和遊戲表現。

10、CoC是一款競技向的遊戲,經濟因素可能更容易讓人付費,因此可以圍繞這方面設計變現系統,對於《Everdale》有沒有這樣的變現考慮?

A:我們還處於學習階段,有些時候你總能看到驚喜,人們不會按照你的設想去玩遊戲,所以我們在不斷地學習、適應,嘗試更多東西。

11、我看到人們在社交行為方面有很多的溝通,比如在Discord、Facebook或者Reddit形成討論組談論遊戲策略,你們是否考慮過打造自己的工具或者在遊戲內做特定功能支援這些社交行為?

A:始終有大量的想法出現,我們會看到底會發生什麼。有時候看CoC的頭部玩家行為,你會覺得很瘋狂,他們甚至畫出了各種各樣的防禦佈局,這些都是非常酷的事情。

如若轉載,請註明出處:http://www.gamelook.com.cn/2022/04/480642

「其他文章」