最近在摸熟 C++11 導入的 Regex 函式庫中使用的 regular expression 語法。C++11 Regex 預設是採用 ECMAScript (也就是 JavaScript) 中定義的 regular expression 規格 (詳見 spec),而該語法並不完全相容於我比較熟悉的 awk/egrep 中所使用的 regular expression 語法。
最快摸熟的方式當然是實際去試試看。最先是很快地寫一個簡單的 C++ 命令列程式,反覆餵它一些資料然後觀察運作結果。幾次後發現這樣的土法煉鋼法,最好還是配合 GUI 程式比較
便於操作。正準備要動工時,腦袋中突然閃過前陣子在 SlideShare 上看到的一個簡介 emscripten 的投影片。透過 emscripten 的協助,我大可直接把原本那個 C++ 命令列程式轉譯成 asm.js 嵌入網頁中,再小改一下輸入輸出的部分,最終得到一個網頁 GUI 的版本。
2017年12月31日 星期日
2017年11月23日 星期四
C/C++ 如何實現 coroutine (fiber)?
近幾年不論在 Lua 、或 Unity C# 中,都能看到大量 coroutine 的應用範例。一旦了解 coroutine 的工作原理,很難不愛上它。C/C++ 中其實也可以實現 coroutine,但不知為何很少看到大規模應用,也或許是因為 multi-threading 的提倡而被冷落。結果反倒是在 Lua、Unity 等等以 single thread 應用為主的場合才又重新獲得關注。
2017年11月16日 星期四
C/C++ 伺服器藉由 FastCGI 快速提供 RESTful Web API
我負責的遊戲伺服器是以 C/C++ 開發的。而現今這年頭無論是跟哪家營運商合作,無可避免要提供 RESTful Web API 方便讓營運後台對伺服器進行動態的設定或提取即時資訊。我原本對 Web 後端技術所知不算多,不過整個流程摸索過一次之後,發現也沒想像中那麼複雜。以下說說心得。
首先你要知道 CGI 跟 FastCGI 是什麼東西。
首先你要知道 CGI 跟 FastCGI 是什麼東西。
2017年11月12日 星期日
說說 C/C++ 網路伺服器使用的各種多工器 (Multiplexer)
若想單單只靠作業系統提供的 API 來實作 C/C++ 網路伺服器程序,首先面臨的問題就是該怎麼設計連線的多工處理 -- 同時間與伺服器建立的連線可能成千上萬,怎麼有效地查覺誰送了資料過來需要回應? 在通訊和資訊網路的領域裡,像這樣「把眾多輸入訊號合併匯集後循序處理」的過程稱為「多工」(Multiplexing,大陸譯為「多路復用」)。因此,由作業系統提供,判斷現有連線中是否有待處理事件的 API ,即稱為「多工器」(Multiplexer)。
我在學校裡只學到一種最基本的多工器,就是 select()。踏入業界幾經歷練,才又陸續接觸到 poll(), epoll(), kqueue(), IOCP 等等的多工器。麻煩的地方在於每個作業系統支援的多工器種類都不一致。就算是以現今 2017 年來看,也只有最古老的 select() 幾乎能保證被各作業系統支援。因此,如果跨平台運行是伺服器的一個主要考量點,那麼伺服器端通常都還要自行開發一層網路事件分派層來統整各平台上多工器的使用差異,或著直接利用現用的第三方函式庫如 boost.asio 或 ACE 等。
我雖能力一般水平有限,但對於想一窺全貌但不知何處入門的同好們,提供一點走馬看花式的導覽,還是可勝任的。
我在學校裡只學到一種最基本的多工器,就是 select()。踏入業界幾經歷練,才又陸續接觸到 poll(), epoll(), kqueue(), IOCP 等等的多工器。麻煩的地方在於每個作業系統支援的多工器種類都不一致。就算是以現今 2017 年來看,也只有最古老的 select() 幾乎能保證被各作業系統支援。因此,如果跨平台運行是伺服器的一個主要考量點,那麼伺服器端通常都還要自行開發一層網路事件分派層來統整各平台上多工器的使用差異,或著直接利用現用的第三方函式庫如 boost.asio 或 ACE 等。
我雖能力一般水平有限,但對於想一窺全貌但不知何處入門的同好們,提供一點走馬看花式的導覽,還是可勝任的。
2017年10月27日 星期五
大量運行 Unity Headless Player 遭遇的坑
Unity 支援將專案輸出為 Linux 平台上以 Headless 模式運行的 Player。Headless 指的是沒有圖形環境 (Ex: 沒有執行 X-Server)、甚至沒有接螢幕的電腦。通常放在機房中代管的伺服器、或是雲端平台上租用的虛擬主機都是以 Headless 的方式來運行。Headless Player 在應用上除了可利用來製作簡單 Server 程式之外,也可以用來製作「特殊的」客戶端版本,例如開發線上陪玩的 BOT 機器人、或是功能測試機器人等等,這麼做的考量點通常是想最大程度地共用既有的客戶端程式碼。
當我試著要在一台 Linux 機器上大量跑 Headless Player 時,總會發現運行到 170 ~ 180 隻後,系統就會開始出現無法 fork 的錯誤訊息,甚至整個系統都被癱瘓無法做事。就算是空的 Unity 專案也會有這個現象,因此懷疑一部分的原因出在 Unity 本身。
2017年10月23日 星期一
免費且快速地搞定 HTTPS 環境 (非自簽憑證)
遊戲營運後端免不了要跟 Web API 打交道。呼叫第三方的 Web API 是最常見的,另有少數場合必需提供簡易的 Web API 接口讓第三方查詢營運數據、或是使用第三方服務必需提供的 Webhook等等。這幾年,尤其是在 Apple 帶頭打壓 iOS 裝置上的 HTTP 的使用後,感覺要求全面以 HTTPS 來溝通的第三方服務日漸增多。其中不乏也有跟 Apple 一樣,完全不接受「自簽署 (Self-Signed) 憑證」的情況。如果對於 URL 中的域名長相並不在意 (例如說只是要提供 Webhook),這裡倒是可以分享一下怎麼快速的搞定這類需求。
2017年10月20日 星期五
C/C++ 靜態函式庫中的全域變數暗藏的陷阱
Windows 平台上使用靜態函式庫時,對比其它類 Unix 平台如 Linux, BSD, Mac 等,存在一個關鍵的差異: Windows 上一個靜態函式庫在同一個程序空間 (Process space) 被 N 個程序模組 (exe, dll) 引用時, 會產生 N 份獨立的全域變數空間。而同樣的情況在其它類 Unix 平台上則是會共用同一份。
2017年10月19日 星期四
處理阿拉伯文繪製的心得
先澄清一點,我本人對阿拉伯文是半點不懂的。
我參與的第一款手遊使用的是自製的成像引擎。內部使用了 FreeType2 來繪製 TTF 文字、實現勾邊/陰影等。開發初期只有考慮橫式由左至右書寫文字的排版方向。產品上線後不知誰給老闆進的讒言說中東地區的玩家所得高、含金量高,若遊戲內語言能支持阿拉伯文肯定有錢景。於是乎就有了以下的研究與實作,提供給大家參考。(註: 最終還是沒有在中東地區上架,因為接洽不到當地營運夥伴)
我參與的第一款手遊使用的是自製的成像引擎。內部使用了 FreeType2 來繪製 TTF 文字、實現勾邊/陰影等。開發初期只有考慮橫式由左至右書寫文字的排版方向。產品上線後不知誰給老闆進的讒言說中東地區的玩家所得高、含金量高,若遊戲內語言能支持阿拉伯文肯定有錢景。於是乎就有了以下的研究與實作,提供給大家參考。(註: 最終還是沒有在中東地區上架,因為接洽不到當地營運夥伴)
2017年10月14日 星期六
在桌機中準備 OpenGL ES 的開發環境
大約在 2013 年中,公司的產品方針由桌機網遊轉變為手遊。由於當時還是採用自製的呈像引擎所以立刻要處理的就是把 Render API 切換為手機上通用的 OpenGL ES 2.0。
雖說手機遊戲最終是運行在手機上,但是為了方便開發和測試,遊戲也必需能在一般的桌機上運行。這一點在現今 Unity 稱霸的時代已經是很基本的需求,但對於當時一切 DIY 的我們來說還算是一項考驗。那時負責呈像的同仁拋出了兩個方案 -- 一是只在手機上使用 OpenGL ES API、桌機環境上維持使用既有的 OpenGL API;二是無論如何都使用 OpenGL ES API,桌機環境上去找 OpenGL ES Emulator 來提供 OpenGL ES 的支持。最後考慮到維護成本採取的是後者,這樣只需要統一維護 OpenGL ES 的部分即可。
Emulator 與 Simulator 傻傻分不清楚
Emulator 跟 Simulator 這兩個詞,Google Translate 給出的中文翻譯都是「模擬器」。然而它們並不是同義詞,至少在資訊工程的領域不是。尤其是每當有新的硬體平台發表時,開發者們都會很關切一件事 -- 它對桌面環境的開發者提供的是「Emulator」還是「Simulator」? ? 這兩者帶開發者的痛苦程度不太相同。
「Emulator」通常意指的是「同質性的模擬」,而「Simulator」則是「表像上的模擬」,通常也暗示者「異質性的模擬」。有同時開發過 Android 與 iOS 平台的朋友們一定都知道是怎麼回事 -- Android 對開發者提供的 Virtual Device 就是「Emulator」,設定 Virtual Device 時可以選擇 ABI,如果選的是 ARM,那 Emulator 中就真的是跑 ARM 的指令集。反觀 iOS 對開發者只有提供「Simulator」,它實際上運行的是 x86 的指令集,跟真實的 iOS 裝置上使用的指令集完全無關,所以稱為「異質性的模擬」。
最近正在進行某 N 社平台的移植工程,該社的開發機供不應求有價無市,除此之外對開發者只提供「Simulator」 -- 而且與實機環境的差異還蠻大的。有感而發。
「Emulator」通常意指的是「同質性的模擬」,而「Simulator」則是「表像上的模擬」,通常也暗示者「異質性的模擬」。有同時開發過 Android 與 iOS 平台的朋友們一定都知道是怎麼回事 -- Android 對開發者提供的 Virtual Device 就是「Emulator」,設定 Virtual Device 時可以選擇 ABI,如果選的是 ARM,那 Emulator 中就真的是跑 ARM 的指令集。反觀 iOS 對開發者只有提供「Simulator」,它實際上運行的是 x86 的指令集,跟真實的 iOS 裝置上使用的指令集完全無關,所以稱為「異質性的模擬」。
最近正在進行某 N 社平台的移植工程,該社的開發機供不應求有價無市,除此之外對開發者只提供「Simulator」 -- 而且與實機環境的差異還蠻大的。有感而發。
2017年10月13日 星期五
重拾筆頭
算一算離上次發表文章,竟已有四年半的時間了。回顧這幾年,大部分的時間都耗費在公司手遊的研發上,雖有陸續在日、港、全球上線營運,但成績始終未達預期。產品的細節礙於公司規定是不便多說的。但技術上積累了不少可分享的心得倒是想陸續發上來。
還記得 2012 年我剛從電子業轉換跑道進這行時,面試我的上司問我為什麼要轉行? 我那時候回答他,我認為遊戲產業是「最多種不同面向的技術同時交匯的產業」,所以我覺得這裡的挑戰最多元、身為資工出身的我能貢獻最多,並且也能學到最多東西。四年半之後回顧初衷,還真是一點也不錯,一路走來果真挑戰連連,常常得面臨一關闖不過就要鳥獸散的窘境。雖不敢說對某門技術功力很深,但盡力要求自己各項都要摸要懂,漸漸地也常感受到觸類旁通的領悟。
雖然遊戲開發會粗略分為 Client 與 Server 兩種人員,但小團隊裡通常壁壘不會這麼分明,反而是靠部分通才人員兩邊一起顧。我在開案時最初擔任的是 Server 的架構及開發,最終上架時已經要兼顧一部分 Client 的功能、Client 端第三方 SDK 串接,以及幾乎所有營運後台需要的工具了。試想像還有哪個行業會同時磨練你 3D呈像、美術製程、各種 mobile 平台、Socket Programming、RESTful WEB API、Database (SQL and NoSQL)、雲端平台的背景知識呢? 當時的產品 Client 端甚至還是採用自有的引擎而非 Unity,那陣子承受的壓力與成長幅度都是我人生中的高峰。
很感謝身邊幾位才華洋益的同伴一起打拼,有些驚險關卡想在回想起來還冒冷汗。但受用最多的還是網路上搜尋到的各種技術內容探討、心得分享。這也是我要求自己把心得發佈上來的主因。
敬請期待。
還記得 2012 年我剛從電子業轉換跑道進這行時,面試我的上司問我為什麼要轉行? 我那時候回答他,我認為遊戲產業是「最多種不同面向的技術同時交匯的產業」,所以我覺得這裡的挑戰最多元、身為資工出身的我能貢獻最多,並且也能學到最多東西。四年半之後回顧初衷,還真是一點也不錯,一路走來果真挑戰連連,常常得面臨一關闖不過就要鳥獸散的窘境。雖不敢說對某門技術功力很深,但盡力要求自己各項都要摸要懂,漸漸地也常感受到觸類旁通的領悟。
雖然遊戲開發會粗略分為 Client 與 Server 兩種人員,但小團隊裡通常壁壘不會這麼分明,反而是靠部分通才人員兩邊一起顧。我在開案時最初擔任的是 Server 的架構及開發,最終上架時已經要兼顧一部分 Client 的功能、Client 端第三方 SDK 串接,以及幾乎所有營運後台需要的工具了。試想像還有哪個行業會同時磨練你 3D呈像、美術製程、各種 mobile 平台、Socket Programming、RESTful WEB API、Database (SQL and NoSQL)、雲端平台的背景知識呢? 當時的產品 Client 端甚至還是採用自有的引擎而非 Unity,那陣子承受的壓力與成長幅度都是我人生中的高峰。
很感謝身邊幾位才華洋益的同伴一起打拼,有些驚險關卡想在回想起來還冒冷汗。但受用最多的還是網路上搜尋到的各種技術內容探討、心得分享。這也是我要求自己把心得發佈上來的主因。
敬請期待。
訂閱:
文章 (Atom)