Code Prettify

Thursday, July 3, 2014

一些關於 node.js 的分享

之前在用node.js寫game server
每當有新的model(資料格式)
也需要寫一個class去封裝(encapsulation)

例如寫完player這款model後
需要添加player的itemBag,用作儲存player的所有物品

這些model的功能大多都包括 定義 / 讀取 / 寫入 資料庫
有不少的重複性

為了提高效率
於是設計了一套格式,方便加入新的model


這套格式使用了以下插件
  • node-cache
    • 用作暫時儲存資料到記憶體,避免頻繁的資料庫讀/寫
  • knex
    • 用作簡化生成sql statement
  • node-mysql
    • 用作連接mysql 資料庫


格式結構


scheme.js 定義所有資料格式
schemeMgr.js 使用node-cache儲存指定scheme的實體資料
schemeModel.js scheme的model實體
實作了insert、update、load單一model的功能
schemeListModel.js scheme list的model實體
實作了insert、update、load多於一款model的功能(使用一個SQL 指令)

格式例子

Scheme Model

  player : {
    param : {
      id : 0,
      name : 'defaultName',
      lv : 1,
      exp : 0,
      coin : 0,
      gold : 0
    },
    cache : {
     stdTTL : 300,
     checkPeriod : 300,
     saveIfExpired : true
},
    db : {
     tableName : 'player',
     onCreateTable : function(table) {
      table.increments('id');
      table.string('name');
      table.integer('lv');
      table.integer('exp');
      table.integer('coin');
      table.integer('gold');
     }
    },
  },

param就是model的模版
產生Scheme Model時會整個複製過去
因為javascript 是weak typing的關係
怎樣定義結構也都可以

 cache是node-cache使用的參數
stdTTL(standard time to live),即物件的在記憶體內的生存時間
checkPeriod是node-cache每隔多久去檢查物件的生存時間
saveIfExpired若是true,在過期的時候會update到資料庫

我作過unit test,如物件過了生存時間但未被檢查
若嘗試從node-cache提取物件 會強制檢查一次
所以不會拿到過期的物件 

db內就是跟資料庫有關的
onCreateTable是knex開設新table時的callback function

Scheme List Model

  itemBag : {
   param : {
    id : 0,
    playerID : 0,
    itemID : 0,
    count : 0
   },
   cache : {
     stdTTL : 300,
     checkPeriod : 300,
     saveIfExpired : true
   },
    db : {
     tableName : 'player',
     onCreateTable : function(table) {
      table.increments('id');
      table.string('playerID');
      table.integer('itemID');
      table.integer('count');
     }
    },
    keyList : {
     playerID : 0
    }
  }
};

Scheme List Model 只比 Scheme Model多了一個 keyList
是在讀取/寫入 資料庫時使用的key


使用這個格式,只需要幾行就可以新增一款model
省了很多 read/write 資料庫的code
更省了很多很多unit test 的code
既方便又快捷 :)


Monday, January 6, 2014

再來

Image by NASA














已經很久沒更新了
談談這幾年技術的轉變

之前都很主張擁有自己的技術
因為相信獨特的技術可以在市場上擁有獨特的價值
所以一直開發自己的遊戲引擎及使用C#開發編輯器
但成本非常高昂,而且會像雪球一樣滾大

現在免費遊戲開發工具百花齊放
於是開始了尋找一個容易使用的跨平台開發工具

使用過MOAI SDK,一個以Lua 為開發平台的開源SDK
感覺上不錯,但提供的功能不多
很多時也需要動手新增功能

也使用過
Gideros(安裝一次Player後可透過Network deploy,但有待改進)
Corona(不能自己寫Plugin?!)
Cocos2d-x(C++效能是很快,但使用C++會很慢,特別是Debug的時候)

之後就嘗試了Unity
使用的感覺是...很熟悉的新軟件
因為有開發3D遊戲引擎的經驗
看了一會文檔,摸索十分鐘左右就會用了

除了一應俱全的功能外(圖像、2D/3D物理、特效、聲音、還有C#附帶的龐大程式庫)
實時遊戲編輯器加上Component Base Model,非常好用!
Component Base Model將code size大大下降了
而且沒有傳統Object Oriented那種容易變得笨重的架構
再者,程序員跟美術之間可以很容易協作

現在一個上午就可以完成一個粗糙的遊戲原型(Prototype)
數天就可以完成一個比較完整的遊戲原型

從構想到遊戲原型
從沒有這樣短的時間
現在可以將更多的時間投入遊戲核心
做更多的測試

但有一個問題
就是源碼的保護
如果不處理的話,是差不多完全暴露的程度
很多在營收榜名列前茅而又使用Unity開發的遊戲
是可以透過dll看到源碼的

使用過Unity後,整個開發週期短了很多
很期待下一款作品完成的日子

Wednesday, November 2, 2011

Data Driven 的 2D Avatar System

下一款遊戲需要Avatar系統(紙娃娃系統?)
於是上星期便著手開發
以我上年開發的Flash Animation套件作藍本擴充
(由Flash 導出圖像及動畫資料, 再以OpenGL ES繪畫)
前幾天終於完成

2D Avatar 最重要的是Draw Order
整個系統的設計也以Draw Order為中心
經過多番修改
最後決定將動畫資料及圖像資料分開
因為可以得到最大程度的彈性





將最底層的動畫稱作骨骼動畫可能有點誤導
因為"骨"只是一幅圖像, 一個2D Matrix Transform
而"骨"與"骨"沒有任何關連

系統特色:
  • 以Flash製作動畫並導出
  • 以骨骼動畫圖層次序決定Draw Order
  • 沒有身體部件的限制, 身體的構造完全由Artist決定
  • 可換不同Skin圖像花紋
  • 可換不同膚色 (顏色可在程式內自由調試)
  • 可換不同裝備
  • 裝備可換不同顏色 (顏色可在程式內自由調試)
  • 裝備圖像支援多圖層, 所以一個裝備圖像可轉換多層顏色, 如一雙眼睛可有不同顏色
  • 裝備動畫與骨骼動畫以名字作配對
  • 不同裝備圖像可共用相同的裝備動畫, 新增裝備時可用回舊的裝備動畫
  • 骨骼動畫之外, 裝備擁有自己獨立的動畫, 兩者可以同時播放並擁有各自的週期, 例如步行動畫跟眨眼動畫
以上功能應該可以製作任何2D Avatar
最方便是Artist可以設定整個Avatar系統
Programmer (是我) 將整套資料載入程式後
只需作轉換部件/顏色的code
就可控制整個Avatar

這系統概念上好像不複雜
但是確保整個流程正確及順暢, 真的需要花點工夫

Monday, October 17, 2011

尋人

最近遇到的難題並不是技術,是時間
而是如何將四、五天的工作在一、兩天內完成實作及測試
難題一個接一個,有成功的,也有失敗的
很多時心急就會趨向失敗
雖然有點辛苦,不過技術的確進步了不少

我的工作室(這麼小的公司還是不敢自稱公司)最近幾個月都在招人
跟幾個剛畢業的大學生面試,他們都頗有潛質
可惜要短時間內投入實戰還差一點點
在這麼緊迫的進度下,實在抽不出資源教導他們
說「如果有多點資源,一定會聘請」好像有點不負責任,但那是真的呢

香港的朋友
如果你曾使用C++製作遊戲
又或者畫得一手好圖
又或者曾製作遊戲
...
如有興趣加入我們歡迎聯絡
(怎麼好像尋找失蹤人口的呼籲...)

Wednesday, June 1, 2011

Unicode字串

最近在研究Unicode字串
一直以為使用 std::wstring 及 wchar_t 就可以
但wchar_t 在 Win32 上是16bit, 而在Mac OS 上是32bit

為免夜長夢多,決定繼續使用std::string 及 char
加上UTF8 encoder/decoder
渲染的時候,一個字需要一個整數去表示
所以沒有甚麼複雜的整合

今天嘗試載入中文的文字檔
發現讀取檔案後
字串Buffer內Mac OS比Win32多了一個character
是哪一個?



是Carriage Return
這大概和兩個平台的換行符號有關

就這樣
大致完成了跨平台的Unicode字串

Tuesday, May 24, 2011

理想遊戲

最近幾天都在全速寫CODE
早上9點左右開始,瞬間就會到達6點
從來也沒有試過時間過得這麼快的感覺

今天被問及往後的發展計劃
腦內瞬間湧出大量遊戲畫面
其實也沒有甚麼發展計劃
每次都是專心做好眼前的遊戲後
意想不到的事就會發生
之前訂立好的計劃也會立即完全改變
不太敢奢想甚麼
因為自己還遠遠未達到自己的要求

其中一個在腦內閃過的遊戲:
可能小時候受過小說與電視薰陶
不知為何總是有一點武俠情結
可惜沒有讓人滿意的3D武俠ARPG可玩
就算業績報告收入以億計算
每年也不過是推出一式一樣的線上遊戲

試試玩歐美的ARPG
擁有"細膩"表情,面孔花上過萬polygon的"美女"
也實在讓人提不起勁

理想的武俠ARPG大概是:
Fable的遊戲世界換了武俠世界
加上飛簷走壁的輕功系統
加上飄逸的布質衣服與長髮
加上自由配搭的劍招,但不要加上現在線上武俠遊戲的特效
加上細緻的面孔
加上...(下省數百點)

當然這只是玩家角度的幻想 :P

Thursday, March 31, 2011

遊戲設計筆記

無意中翻查舊文件,找到了約6年前的遊戲設計筆記
那時候正值大學Final Year,對製作遊戲興趣很濃厚
有點技術,但要做甚麼遊戲呢?
想了很久,也得不到好的設計

"會有公式嗎?" "為甚麼我想不到?"
懷著好奇又帶點不忿,在圖書館找了很多本遊戲設計書藉
忘了看過多少本書,得不到結論
但對遊戲設計了解更深,歸納了5條問題
幫助反思一個遊戲概念(排名分先後)

1. What makes your game fun? 你的遊戲有甚麼有趣的地方?
一個沒趣的遊戲只是一個程式(Application)
有趣的地方當然越多越好,但注意不要多餘。

2. What makes your game unique? 你的遊戲有甚麼獨特性?
獨特性很重要﹕這世界不需要二個一樣的遊戲。
世界上有相似的遊戲嗎? 如有,你們有甚麼相同及不同之處?
有甚麼地方勝過相似的遊戲? 可以由相似的遊戲上得到寶貴的經驗嗎?
人喜歡比較,尤其是相似的東西。
你的遊戲將無可避免地與其他遊戲比較,尤其是相似範疇內最高質素的遊戲。
如果沒有比較,你就是最棒的了!

3. What are the expected emotions of player? 玩家會得到甚麼感覺/情感?
玩家情感隨著時間/互動事件會有不同的變化,
如果能掌握玩家情緒將能大大提升投入度。
外國還有一個專門詞語:Emotion Engineering

4. When will player get rewarded? 玩家甚麼時候有獎勵?
獎勵的用途很廣泛,如誘餌一樣,
引導玩家跟循設計者預設的方向走。
在困難挑戰後給予的果實,特別甜美。

5. When will player discover new elements? 玩家甚麼時候會發現新元素?
定期發現新元素能保持新鮮感,也是讓人沈迷的起點。
這問題也在問設計者﹕你的遊戲玩法會有甚麼變化?


我通常會在遊戲開發初期,使用以上5條問題去幫助思考
如果這5條問題都能有令人滿意的答案,就會再始更詳細的設計
約6年前的產物到今天還有用,書籍內果然蘊含了大師們的知慧