日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Shopee Games 游戏引擎演进之路

發(fā)布時間:2023/12/10 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Shopee Games 游戏引擎演进之路 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文作者: Shopee Games 前端團隊。
首發(fā)于微信公眾號“Shopee技術(shù)團隊”。

摘要

Shopee Games 團隊致力于豐富 Shopee 電商內(nèi)的互動性和娛樂性,讓用戶在購物之余獲得更多愉悅感,同時游戲也能為 Shopee 帶來持續(xù)的活躍用戶和更多的優(yōu)惠券發(fā)放渠道。在這個背景下,從游戲誕生之初,我們希望游戲足夠輕量,而且能夠快速迭代,持續(xù)給用戶提供多種多樣的游戲體驗,同時又不會對 Shopee App 的體積造成較大影響。因此,我們需要選擇合適的游戲引擎,并打造適合 Shopee Games 的工具鏈。

本文將介紹 Shopee Games 團隊如何選擇游戲引擎,如何擴展游戲引擎以提高生產(chǎn)效率,如何讓游戲開發(fā)流程和成熟的前端工程化體系結(jié)合,實現(xiàn)游戲規(guī)范化和研發(fā)質(zhì)量的提升。Shopee Games 是內(nèi)嵌在 Shopee App 的游戲,所以對于有同樣內(nèi)嵌游戲需求的業(yè)務(wù)團隊,本文總結(jié)的經(jīng)驗會有一定借鑒意義。

1. 游戲引擎選型

Shopee Games 當(dāng)前以休閑類游戲為主,為了減少對 Shopee App 體積的影響,技術(shù)選型上會偏向于 H5 游戲。而如何選擇 H5 游戲引擎,我們主要考量以下幾個方面的因素:

  • 2D 還是 3D 游戲?
  • 是否對開發(fā)友好?包括是否支持 TypeScript、文檔是否完善、研發(fā)流程是否適合以開發(fā)為主導(dǎo)。
  • 性能和兼容性如何?
  • 官方工具鏈?zhǔn)欠裢晟?#xff1f;
  • 是否開源?
  • 是否有成功的游戲案例?
  • 官方是否有客服支持?
  • 官方是否有持續(xù)更新?

首先,我們的休閑類游戲主要為 2D 游戲,所以我們先聚焦在針對 2D 設(shè)計的游戲引擎上。雖然 3D 引擎可以通過正交視角來實現(xiàn) 2D 效果,但渲染性能和輕量化都不如專門的 2D 引擎,所以我們先把 3D 為主的引擎排除掉,例如 Unity3D、LayaBox、Three.js、Babylon.js。而 2D 引擎,國內(nèi)主要有老一些的 lufylegend.js、Cocos2d-JS 和持續(xù)更新的 Egret、Cocos Creator,國外有 Phaser/Pixi 和 CreateJS。

接著,從可持續(xù)性、性能方面考慮,可以先把較老的 lufylegend.js、Cocos2d-JS 排除。而 CreateJS 實際并不是一個完整的游戲引擎,它更接近于一個精簡的渲染引擎,缺少整體的工具配套,難以支持大型游戲,也排除。

那么,最后我們重點對比 Egret、Cocos Creator 和 Phaser。Phaser 的渲染引擎就是 Pixi,后續(xù)用 Phaser 代表這兩者。

以上三款游戲引擎都支持 TypeScript 和 WebGL,性能差異不大。對于 Shopee Games 團隊而言,Egret 有較大優(yōu)勢:

  • Egret 支持 canvas 模式,因此東南亞市場中的一些低端手機用戶也能夠運行我們的游戲;
  • Egret 的理念是面向開發(fā)者的,而我們團隊有較強的研發(fā)能力,以開發(fā)者為導(dǎo)向能夠讓整個游戲性能更好;
  • 在工具鏈上,Egret 有自研的龍骨動畫和編輯器,非常適合我們的游戲開發(fā)。

因此,綜上所述,我們選擇 Egret 作為主流引擎,并在 Egret 的生態(tài)基礎(chǔ)上,持續(xù)優(yōu)化和打造能夠提高游戲開發(fā)效率的工具鏈。

2. Egret 引擎優(yōu)化和公共庫

2.1 Egret 引擎優(yōu)化

Egret Engine 是白鷺時代研發(fā)的遵循 HTML5 標(biāo)準(zhǔn)的開源游戲引擎,包含 2D/3D 渲染核心、EUI 體系、音頻管理、資源管理等游戲引擎的常用模塊。

目前我們使用 Egret Engine 開發(fā)了 Shopee Candy、Shopee Pet、Shopee Fruit、Shopee Link 這四款游戲,在項目開發(fā)和迭代過程中,我們發(fā)現(xiàn)官方引擎存在一些問題,無法完全滿足業(yè)務(wù)需求和性能標(biāo)準(zhǔn)。于是,我們對 Egret 引擎做了定制開發(fā),下文稱之為“定制化引擎”。

2.1.1 性能上報

針對游戲的一些數(shù)據(jù)指標(biāo),如 FPS、DrawCall、First Paint、GPU Size 等等性能指標(biāo)進(jìn)行上報。

上報流程如下:

通過分析上報的游戲性能數(shù)據(jù),我們能更好地分析性能瓶頸,從而有側(cè)重性地提升游戲性能。其中,涉及到的詳細(xì)性能指標(biāo)如下:

2.1.2 性能優(yōu)化

我們在官方引擎基礎(chǔ)上針對性能做了一些優(yōu)化,幫助開發(fā)人員提升游戲性能。

靜態(tài)合圖

在開發(fā)過程中將散圖合成一張大圖的圖集,達(dá)到降低 DrawCall 的目的。

動態(tài)合圖

在項目運行時,動態(tài)地將貼圖合并到一張大貼圖中。當(dāng)渲染一張貼圖的時候,動態(tài)合圖系統(tǒng)會自動檢測這張貼圖是否已經(jīng)被合并到了圖集(圖片集合)中。如果沒有,并且此貼圖符合動態(tài)合圖的條件,就會將此貼圖合并到圖集中。

動態(tài)合圖是按照渲染順序來選取要將哪些貼圖合并到一張大圖中的,這樣就能確保相鄰的 DrawCall 能合并為一個 DrawCall。

和前面的靜態(tài)合圖原理一樣,都是以合圖紋理代替碎圖紋理,從而減少 DrawCall。而動態(tài)合圖最大好處是提高了一些無法提前靜態(tài)合圖的場景,例如用戶的裝扮。

節(jié)點順序調(diào)整

引擎底層的性能優(yōu)化,目的是保證相同紋理的渲染順序。例如在同級 addChild 時,如果原始順序為 img1>text>img1,引擎能自動優(yōu)化成 img1>img1>text,降低 DrawCall。

DrawCall 優(yōu)化工具開啟

游戲 Main 函數(shù)開啟 Benchmark.init(null,null,true);或者 Benchmark.optimizeDc 設(shè)為 true 即可。

2.1.3 引擎瘦身

官方引擎默認(rèn)包含所有模塊,其中有一些在我們的實際項目中使用不到。因此,為了減少引擎包體積大小,需要剔除掉用不到的代碼,例如:

  • Native 代碼;
  • Runtime 代碼;
  • WX 等小游戲端兼容代碼;
  • KTX 紋理相關(guān)代碼;
  • ETC Loader 代碼。

修改前后對比:

最終,游戲前端 JS 加載量共減少 16KB,約 7%。雖然這個體積看起來很小,但對于部分網(wǎng)絡(luò)較差的地區(qū),少量的體積優(yōu)化也是有價值的。

2.1.4 Bug 修復(fù)

對于項目遇到的一些引擎層面的 bug,由于引擎官方可能會更新修復(fù)不及時,很多時候需要我們自己去修復(fù)。例如:iOS 14/15 渲染卡頓問題、龍骨庫渲染問題、網(wǎng)絡(luò)以及音效問題等等。其中,我們解決 iOS 14/15 卡頓問題后,很榮幸貢獻(xiàn)了代碼幫助 Egret 官方團隊解決這個問題。

2.1.5 API 增強

官方引擎的一些用法過于繁瑣,不夠友好,如設(shè)置節(jié)點寬高等。因此我們在官方引擎基礎(chǔ)上,擴展了方便快捷的 API,供大家使用。

2.2 公共庫

為了提高開發(fā)效率,避免大家重復(fù)造輪子,基于優(yōu)化后的 Egret 引擎,我們做了公共庫的開發(fā),封裝通用工具類、通用模塊、通用 UI 組件等等。

2.2.1 工具庫

我們封裝游戲中常用的一些工具庫:

  • SoundUtil:音樂播放工具類,支持音效/背景音樂的播放/暫停/倍數(shù)播放等;
  • DragonUtil:龍骨工具類,負(fù)責(zé)龍骨動畫的創(chuàng)建/銷毀等,隱藏龍骨創(chuàng)建細(xì)節(jié),簡化龍骨動畫使用難度;
  • ResUtil:游戲資源管理類,方便開發(fā)者加載/釋放游戲資源;
  • SmartEvent:封裝的消息通知類庫,方便大家使用,便于模塊之間的解耦,包含自定義事件/UI 事件的監(jiān)聽和移除;

封裝工具庫是為了降低開發(fā)難度,以及避免不同團隊重復(fù)造輪子。目前已在 Shopee Games 的四款 Egret 游戲中使用,平均節(jié)約人力 2 周以上。

2.2.2 基礎(chǔ) UI 組件

我們對 Egret 基礎(chǔ)組件進(jìn)行了擴展,并提供了生命周期等一系列鉤子函數(shù),降低開發(fā)難度,提升開發(fā)效率;同時,提供了一些各項目通用的組件,如:分享界面/好友界面/小怪獸彈窗等公共 UI 組件。

Egret 基礎(chǔ)組件擴展

我們?yōu)?UI 組件提供了一些生命周期的鉤子函數(shù)方便游戲業(yè)務(wù)使用,開發(fā)者實現(xiàn)每個 UI 類時不必再單獨實現(xiàn)事件監(jiān)聽和移除。同時,內(nèi)置的事件管理也避免了開發(fā)者可能因開發(fā)遺漏而導(dǎo)致的內(nèi)存泄漏問題。

具體的鉤子函數(shù)如下:

2.3 定制化引擎同步更新

隨著定制化引擎的修改越來越多,隨之而來的問題是:如果官方引擎更新了,我們怎么快速合并官方引擎版本?

這里采用的方案是 git 雙 remote 的方案,流程圖如下:

詳細(xì)步驟如下:

  • 為了表示方便,我們把 Egret 引擎開源庫定義為 A,我們自己的定制化引擎?zhèn)}庫為 B;
  • 通過 git clone B ,拉取修改項目 B;
  • 通過 git remote add A repository,以及 git fetch A,增加 A 遠(yuǎn)程并獲取 A 的倉庫信息;
  • 假設(shè) B 的開發(fā)分支是 dev,切換到此分支;
    假設(shè)我們需要合并的是 A 的一個 tag,如 v5.4.0,使用 git merge v5.4.0 --allow-unrelated-histories,強制合并。

由于需要同步源框架項目代碼,我們的改動會受到一些限制,否則每次合并都會有重復(fù)的工作量:

  • 盡量不要重命名或者刪除原本的文件,或者改動代碼里面的函數(shù)及變量名;
  • 如果需要拓展一個類的功能,盡量采用原型鏈拓展的形式;
  • 自定義內(nèi)部工具類可以內(nèi)部自行定義,只要不重名即可;
  • 行內(nèi)代碼盡量采用增加的模式,盡量不改動原本的代碼;
  • 有些庫代碼會增加很多渠道兼容的代碼,我們可以適當(dāng)減少,合并時會基于從共同祖先分析改變的機制,因此不會每次都要 diff。

通過以上方案,我們就可以實現(xiàn)官方倉庫和定制化引擎的快速同步。

3. 游戲研發(fā)工程化

雖然 Egret 引擎能滿足 Shopee Games 的基本業(yè)務(wù)需求,官方也提供了一系列工具來滿足開發(fā)者的開發(fā)需求。但在使用 Egret 引擎的過程中,我們還是遇到了以下一些痛點:

  • 缺乏模塊概念:采用默認(rèn)的 TypeScript 方式編譯,不支持文件頂層 import 和 export,所有編譯文件內(nèi)容被視為全局可見,容易造成變量污染以及安全問題;
  • 無法使用 npm:業(yè)務(wù)項目根目錄下不支持 package.json 文件,不支持模塊化的第三方庫;
  • 缺乏工程化方案:沒有提供工程化的相關(guān)方案,如代碼審查、單元測試等,項目也無法輕易接入常規(guī)的 Web 前端工程化方案;
  • 部署流程復(fù)雜:代碼編譯工具依賴于官方工具,沒有提供命令行版本,無法在服務(wù)器上單獨部署。

顯然 Egret 工程無法滿足我們的工程需求。即便現(xiàn)在的 Web 前端工程化技術(shù)十分成熟,我們?nèi)蕴幱谑骰瘯r代,因此決定把 Egret 工程前端工程化。

3.1 Egret 前端工程化

3.1.1 支持根目錄 package.json

package.json 文件可以說是目前前端項目必備的一個文件,Egret 引擎起家比較早,當(dāng)時的前端工程化還沒有那么成熟,Egret 引擎的構(gòu)建是官方自己寫的一套構(gòu)建系統(tǒng)。

不支持根目錄下 package.json 文件,很多事情也很難執(zhí)行下去,還好 Egret 引擎的構(gòu)建工具代碼也是通過 JS 編寫,而且跟引擎代碼一樣開源。

通過源碼斷點調(diào)試,我們發(fā)現(xiàn) Egret 項目不支持根目錄下 package.json 的原因是:Egret 構(gòu)建的時候,通過判斷根目錄下是否存在 package.json 來區(qū)分工程項目和庫項目,從而使用不同的構(gòu)建流程,構(gòu)建出不同的產(chǎn)物。

為了做到最小化的改動,且也能支持工程項目根目錄下存在 package.json,我們把構(gòu)建項目的判斷修改為判斷 package.json 內(nèi)自定義字段的值,來區(qū)分是否為工程項目。

支持根目錄下存在 package.json,后續(xù)的一些工程化改造就比較容易進(jìn)行下去了。

3.1.2 引擎 npm 包

官方構(gòu)建依賴于本地機器上的構(gòu)建工具,每次的部署發(fā)布,都需要在本地構(gòu)建完成后再上傳到服務(wù)器上,與 Shopee 業(yè)務(wù)的部署規(guī)范和流程不太相符,并且嚴(yán)重阻礙了項目快速迭代的節(jié)奏。

為了使構(gòu)建能夠支持在服務(wù)器上單獨部署,我們把定制化引擎的代碼進(jìn)行改造和封裝,發(fā)布成一個 npm 包的形式,項目依賴從一個本地的構(gòu)建工具變成 npm 包。

"dependencies": {"@egret-engine/egret-core": "1.6.2-alpha.1",}

npm 包主要包含兩部分:

  • build 目錄:引擎相關(guān)的庫文件;
  • tools 目錄:構(gòu)建編譯相關(guān)工具。

發(fā)布成 npm 不僅使得項目的編譯運行脫離本地環(huán)境,也能更好地去做項目的版本管理。但是僅發(fā)布成 npm 包是不夠的,還需要結(jié)合以下的 Webpack 打包構(gòu)建才能達(dá)到我們的目的。

3.1.3 Webpack 打包構(gòu)建

為了支持模塊化編譯以及在服務(wù)器上單獨部署,我們選擇了成熟的 Webpack 構(gòu)建方案接入到 Egret 項目中。

改造 Egret 項目構(gòu)建前,首先需要分析一下 Egret 項目的依賴以及構(gòu)建產(chǎn)物:

  • *.js:代碼構(gòu)建產(chǎn)物。
  • *.ts:TypeScript 業(yè)務(wù)代碼文件。
  • res:項目資源文件。例如:圖片、音頻、JSON 文件等。
  • egret libs: Egret 項目依賴模塊,即相關(guān)的 JS 庫文件。
  • *.exml:Egret 特有的標(biāo)簽語言文件類型,用作 UI 布局,可編譯成 JS 文件和 JSON 文件。

官方的構(gòu)建類似于 gulp ,按照一定的順序執(zhí)行每個任務(wù)。雖然官方也提供了自定義任務(wù)插件的方式,讓開發(fā)者自定義構(gòu)建流程,但這都需要開發(fā)者重新去開發(fā),比較耗費人力。

exml 文件類型是 Egret 引擎特有的文件類型,目前前端生態(tài)沒有相關(guān)的解析編譯工具;res 文件處理也沒有必要重新造輪子,所以我們沿用官方的工具,封裝到 @egret-egine/egret-core/tools 上,作為構(gòu)建工具的一個依賴。

而 egret libs 依賴處理和 *.ts 代碼編譯,我們都能在前端生態(tài)上找到更好的方案,根據(jù)需求使用即可。

通過 Webpack 去打包 Egret 項目,構(gòu)建依賴來源于 npm,這樣就可以脫離本地環(huán)境,直接在服務(wù)器上部署構(gòu)建。而且產(chǎn)物也跟官方打包產(chǎn)物保持一致,做到良好兼容。

3.1.4 工程化配置

經(jīng)過以上改造,其實 Egret 工程項目跟普通的 Web 前端工程沒有太大區(qū)別,成熟的 Web 前端工程化方案在我們的項目中能得到很好的實踐,不僅能夠?qū)崿F(xiàn)在服務(wù)器上單獨部署,也能輕松接入質(zhì)量把控的工具,例如 eslint、jest 等,提高代碼質(zhì)量。

3.2 Egret-Webpack-CLI 實現(xiàn)

在項目初期,我們主要根據(jù)業(yè)務(wù)和工程需求,基于 Egret 和 Webpack 搭建了項目腳手架模版。但在創(chuàng)建新項目和創(chuàng)建 demo 項目的時候,仍需要從倉庫 clone 模版?zhèn)}庫下來,并且根據(jù)項目進(jìn)行一定的人工配置。在目前的使用上看,問題不大,但仍然比較繁瑣,也有可能會遺漏一些配置,新建項目不能做到開箱即用。因此開發(fā)腳手架工具,能夠快速生成對應(yīng)的模版項目。

3.2.1 CLI

一般腳手架工具主要分為 CLI 和 Template 兩部分。腳手架模版內(nèi)容并沒有與 CLI 一起放到同一個倉庫,而是分別放到不同的倉庫進(jìn)行管理和迭代。通過分離,可以確保兩部分獨立維護,不會互相干擾;模版配置或依賴更新只需要更新項目模版即可,無需影響 CLI 部分,導(dǎo)致重新發(fā)包。

參考其他腳手架的思路,模版作為獨立資源發(fā)布到遠(yuǎn)程倉庫上,然后運行的時候通過 CLI 工具下載下來,經(jīng)過 CLI 的交互信息,作為交互的輸入元信息渲染項目模版。

終端執(zhí)行 egret-cli 后,即可根據(jù)交互信息,生成對應(yīng)的 Egret 工程項目。

3.2.2 Template

由于我們需要對應(yīng)不同的需求,且業(yè)務(wù)相關(guān)的配置較多,導(dǎo)致模版業(yè)務(wù)配置差異比較大,暫不能完全做到一個統(tǒng)一的模版。同時,為了保證一個模版內(nèi)沒有冗余的配置,我們做了區(qū)分,主要提供了 base、standard、Shopee、native 四種項目模版。

需要做小 demo 的時候,可以直接使用 base 模版,比較簡潔;如果需要研究跟業(yè)務(wù)有關(guān)的功能,可以選擇 Shopee 模版;如果是新項目的成立,則直接使用 native 模版。

3.3 最終 Egret 游戲開發(fā)流程

Egret 項目與常規(guī) Web 前端工程接軌,既解決了開發(fā)痛點,滿足了工程需求,也讓我們從石器時代正式步入工業(yè)時代,從開發(fā)到部署都有很好的工具去輔助執(zhí)行,提高了代碼質(zhì)量和開發(fā)效率,新來的同學(xué)也能很好地上手項目。

成熟的 Web 前端工程不僅有利于我們的業(yè)務(wù)擴展,也賦予了項目更多的可能性。一些在前端很容易實現(xiàn)而在原來游戲引擎比較難實現(xiàn)的功能,例如動態(tài)邏輯代碼加載、多頁應(yīng)用、Egret+React 混合頁面等,在我們的項目中也得到了很好的實踐。

4. 更多研發(fā)問題

4.1 iOS 審核問題背景

在 Shopee Games 推出早期,用戶量和訪問量都不大,蘋果公司沒有著重針對 HTML5 版本的 Shopee Games 提出意見。但是,隨著 Shopee 業(yè)務(wù)不斷發(fā)展,用戶量和訪問量持續(xù)增加,2021 年初,蘋果公司對 Shopee 內(nèi)嵌的 HTML5 游戲提出了意見,認(rèn)為 Shopee App 違反了《App Store Review Guidelines》的 4.7 條款。

蘋果公司的審查條款原文是這樣的:

4.7.1 Software offered under this rule must: - be free or purchased using in-app purchase; - only use capabilities available in a standard WebKit view (e.g. it must open and run natively in Safari without modifications or additional software); and use WebKit and JavaScript Core to run third-party software and should not attempt to extend or expose native platform APIs to third-party software; - be offered by developers that have joined the Apple Developer Program and signed the Apple Developer Program License Agreement; - not provide access to real money gaming, lotteries, or charitable donations; - adhere to the terms of these App Store Review Guidelines (e.g. do not include objectionable content); and - not offer digital goods or services for sale.

歸納起來,包含以下幾點要求:

  • 全免費的 H5 游戲或使用蘋果支付;
  • 僅使用 WebKit 自帶功能,不允許擴展,例如 JSBridge;
  • H5 開發(fā)者需要加入蘋果開發(fā)者計劃;
  • 不允許涉足金錢賭博,而且內(nèi)容要符合其他審查條款一般限定。

而 Shopee Games 內(nèi)嵌在 Shopee App 內(nèi),天生需要和 Shopee 深度結(jié)合,必然涉及 JSBridge (例如登錄、跳轉(zhuǎn)電商店鋪)。并且,Shopee Games 還使用了 Shopee Coins 作為游戲中的貨幣,而 Shopee Coins 并不是通過蘋果支付得到的,是用戶在電商購物中累積獲取的。從這兩個角度來看,Shopee Games 使用 HTML5 技術(shù)必然觸犯以上的蘋果審查條款。

我們參考了 Egret 引擎官方的建議,改變了 iOS 平臺上 Shopee Games 的技術(shù)架構(gòu),從原來的 HTML5 改為了 Native,使用的是 Egret Native Runtime。Egret 官方工具支持一鍵生成 iOS 工程并發(fā)布對應(yīng)的 App 安裝包,這能夠滿足獨立游戲的需求。但是 Shopee Games 需要內(nèi)嵌在 Shopee App 中,并不是獨立的游戲 App,所以無法直接簡單使用官方的一鍵發(fā)布機制,我們需要進(jìn)一步研究 Egret Native 的原理,從而和 Shopee App 做整合。

4.2 Egret Native 原理

分析 Egret Native 工具創(chuàng)建的 iOS 模板工程,可以發(fā)現(xiàn):

  • Egret Native Runtime 依賴一系列的系統(tǒng)庫和獨立封裝的 libEgretNativeIOS.a,主要核心邏輯和網(wǎng)絡(luò)功能都在這個庫中。由于 Egret Native 并不開源,從模板工程無法得知這里的具體實現(xiàn);
  • 固定以 App 根目錄的 assets 文件夾作為資源目錄,H5 版本的生成文件需要固定存在此處,而且這里只支持一個游戲;
  • 通過 libEgretNativeIOS 庫,可以創(chuàng)建相應(yīng)的 EgretNativeIOS 實例和對應(yīng)的 view。

雖然 Egret Native 并不開源,但根據(jù)官方文檔,再結(jié)合模擬器斷點調(diào)試分析,還是可以對 Egret Native 有進(jìn)一步的發(fā)現(xiàn)。

Egret Native 游戲架構(gòu)包括三層:前端游戲?qū)印gret Native Runtime 和 iOS Native 層。

  • 前端游戲?qū)颖3趾?H5 版本的文件內(nèi)容一致;
  • Egret Native Runtime 是核心的適配層,它使用 JSCore 對游戲包內(nèi)的 JS 文件進(jìn)行解析,搭建 JSBridge 實現(xiàn) JS 和 Native 兩側(cè)的通信。運行時渲染的方式和 Web 有所區(qū)別,Egret Native 有一個針對 Native 的 JS Polyfill 和 JS Engine 補充,并不是在 Runtime 層實現(xiàn)了全部瀏覽器功能;
  • iOS Native 層,主要是管理 Egret Native Runtime 生命周期和管理視圖。

啟動 Egret Native 游戲時,先從 iOS Native 層初始化 Egret Native 實例,并創(chuàng)建對應(yīng)的游戲 view,掛載到主界面上。然后,Egret Native 初始化 JS 引擎,綁定 JSBridge,讀取前端游戲?qū)拥挠螒蛸Y源,解析 HTML 和 JS,調(diào)用 OpenGL 接口,最終顯示游戲畫面。

4.3 Egret Native 和 Shopee App 結(jié)合

從模板工程來看,把 Egret Native 游戲內(nèi)嵌到 Shopee App 的方式是比較清晰的,把 libEgretNativeIOS.a 和其他必要的依賴庫添加到 Shopee App 項目工程中,再把游戲包存放到 assets 目錄中,最后綁定必須的 Shopee JSBridge,供游戲邏輯實現(xiàn)登錄、支付、跳轉(zhuǎn)等操作,整個結(jié)合工作就完整了。

但是,在最終實現(xiàn)過程中,發(fā)現(xiàn)一些深層次問題,需要通過業(yè)務(wù)側(cè)的方式解決或規(guī)避。這些問題包括:

1)模板工程不支持多個游戲

Shopee Games 包含多個游戲,而上述 assets 目錄只支持存放一個游戲的資源。并且 Egret Native Runtime,也就是上述的 libEgretNativeIOS.a 沒有開源,無法做針對性的修改。

最后,我們在官方的《熱更新方案說明》中,發(fā)現(xiàn)了 Egret Native 可以設(shè)置 preload 目錄路徑,而 preload 目錄內(nèi)的資源優(yōu)先級比 assets 目錄高。

于是,我們可以在 Shopee App 內(nèi)置多個游戲,分別存放于一個單獨的目錄中,在啟動 Egret Native 前設(shè)置 preload 路徑為對應(yīng)游戲的路徑。Egret Native 啟動后會優(yōu)先讀取 preload 目錄的資源來啟動游戲,忽略后續(xù) assets 的內(nèi)容。

2)網(wǎng)絡(luò)緩存文件無限增大

Egret Native Runtime 對網(wǎng)絡(luò)請求做了緩存,但沒有完善的清理機制,導(dǎo)致本地緩存目錄會隨著游戲下載的資源增多而無限增大。這部分需要在 Shopee App iOS Native 邏輯層面進(jìn)行補齊。

3)部分第三方庫命名沖突

libEgretNativeIOS.a 自帶了一些第三方庫,例如 SocketRocket,而 Shopee App 也引入了這個庫,雙方都沒有對這個庫做別名處理,導(dǎo)致命名沖突編譯失敗。由于 libEgretNativeIOS.a 無法修改,只能在 Shopee App 業(yè)務(wù)層面自行修改 SocketRocket。

4)Egret Native 存在內(nèi)存泄漏

由于在 Shopee App 中,Egret Native Runtime 需要反復(fù)啟動和銷毀,只要 Egret Native Runtime 對對象、紋理處理稍有不當(dāng),都會引起內(nèi)存泄漏。而對于 Egret Native 獨立游戲來說,這個問題就不存在,因為每次關(guān)閉游戲都是整個 App 的銷毀。這個問題已經(jīng)反饋給 Egret 官方,但由于官方團隊不會專門針對我們的使用場景做處理,所以目前暫無進(jìn)展。慶幸的是,這部分內(nèi)存泄漏很小,暫時不構(gòu)成大的問題。

通過解決上述一系列問題,最終我們實現(xiàn)了 Egret Native 和 Shopee App 的結(jié)合,能夠在 Shopee App 上運行多款自研游戲。在蘋果審核的角度,我們這個方式脫離了 Webkit,而且所有代碼邏輯內(nèi)置在提審的安裝包中,完全符合審查條款的要求。因此,方案上線后,Shopee App 和 Shopee Games 順利通過了 App Store 的審核。

4.4 未來規(guī)劃

雖然 Egret Native 已經(jīng)能夠結(jié)合在 Shopee App 中,但在持續(xù)運營半年后,我們發(fā)現(xiàn) Egret Native 還是存在一些問題:

  • Runtime 不開源,存在無法解決的問題;
  • Runtime 只支持 Egret 游戲,無法支持其他游戲引擎。尤其是,Egret 引擎對 3D 游戲開發(fā)來說,暫時還不是最佳選擇。

于是,我們正在籌劃更長遠(yuǎn)的解決方案——自研的 Native Runtime,能夠同時支持多家 H5 游戲引擎。

這個解決方案采用類似微信小游戲的整體架構(gòu),但在 JS 層面會做進(jìn)一步的封裝,方便 Shopee 內(nèi)各個游戲團隊快速接入。技術(shù)層面概要來說,就是 Native 基于 JS 引擎向 JS 側(cè)暴露對齊 WebGL 標(biāo)準(zhǔn)的接口和必要的 BOM 接口,從而普通 H5 游戲引擎就可以無縫運行在瀏覽器和我們自研的 Runtime 上。

這個方案的好處有:

  • 兼容性好,能同時支持多家游戲引擎;
  • 方便存量 H5 游戲轉(zhuǎn)移;
  • 能利用各家引擎成熟的開發(fā)工具鏈。

但是,相應(yīng)也存在劣勢:

  • iOS 12 之后的版本正逐步放棄對 OpenGL 的支持;
  • 由于兼容多家引擎,難以使用新的圖形圖像標(biāo)準(zhǔn),例如 Metal、WebGL2、Vulkan。

目前 iOS 已經(jīng)迭代到 15,OpenGL 和 WebGL 還是能夠平穩(wěn)運行,而要支持多款 H5 游戲引擎,WebGL 標(biāo)準(zhǔn)是無法繞過的,所以這些劣勢暫時不得不接受。另外,微信小游戲也會面臨一樣的問題,相信未來會有蘋果官方的遷移方案,可能在 Metal 上層封裝類 OpenGL 的接口。

目前這套方案還在預(yù)研開發(fā)中,預(yù)計 2022 年內(nèi)會實現(xiàn)并全面使用。之后不單是 Shopee Games,我們希望在更多的電商場景也能復(fù)用這套 3D/GPU 渲染的方案,給用戶創(chuàng)造更豐富多彩的互動玩法。

4. 總結(jié)

通過在多款 H5 游戲引擎中做比較,Shopee Games 選擇了更適合業(yè)務(wù)特點和團隊人才特點 Egret 引擎。

在長期的業(yè)務(wù)開發(fā)運營中,我們?yōu)榱烁玫刂С謽I(yè)務(wù)需求,對 Egret 引擎進(jìn)行了定制化改造,包括 bug 修復(fù)和公共庫的修改。

優(yōu)化引擎的同時,為了和官方倉庫保持同步,我們利用了 git 多 remote 倉庫的特性,實現(xiàn)了雙倉庫代碼合并。

再進(jìn)一步,為了復(fù)用成熟的前端 Webpack 構(gòu)建體系和 CI/CD 流程,我們自研了 Egret-Webpack-CLI,把 Egret 游戲從原來單機本地打包的模式,改為了服務(wù)器 Webpack 打包,從而方便復(fù)用大量的優(yōu)秀前端 npm 庫。上述這些創(chuàng)新,都給 Shopee Games 的研發(fā)帶來了重大提效。

在 iOS 審核問題上,我們遇到了一些困難,最終通過深度整合 Egret Native 和 Shopee App,順利實現(xiàn)游戲的 Native 化,通過了 App Store 的審核。

總結(jié)

以上是生活随笔為你收集整理的Shopee Games 游戏引擎演进之路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。