Skip to content

Basic

第 1 章 SGC 程式設計基礎

1-1 雲端服務功能與 API 物件模型

SGC 雲端服務功能為四大類,幾乎已涵蓋多人連線遊戲運營所需的功能:
(1) 以即時通訊為主的場景服務,主要 api 程式類別為 CloudGame 與 CloudScene。
(2) 以資料存放與資料存取為主的服務,主要 api 程式類別為 CloudItem、CloudScore、CloudGuild、CloudMailbox。
(3) 與系統運作有關的服務,主要 api 程式類別為 CloudSystem。
(4) 與電子商務有關的服務,主要 api 程式類別為 CloudShop。

SGC API 物件模型與程式語言無關,為了方便說明,SGC 所釋出的 API 物件模型參考手冊是以 C#語言說明。 由於 SGC API 的物件模型非常簡單,這也降低了開發者的學習門檻,對於初學者來說非常容易入門,但是 SGC 所提供的服務是線上遊戲製作與營運全方位解決方案,所以 SGC API 雖然簡單,但其所涵蓋的內容與功能則是一點也不含糊。

SGC API 總共有八個類別(Class),幾乎涵蓋所有多人連線遊戲所需的功能:

類別之間彼此獨立,沒有物件導向上的繼承關係,但是有著使用上的先後順序關係,除了 CloudGame 與 CloudScene 以外,其餘類別只提供 static method。

  • CloudGame API 的主要類別,建立其它物件必須先有 CloudGame 物件才能進行,也就是說要先有遊戲(Game),然後才有遊戲中的各種功能(Scene、Item、Score、Shop)等。

  • CloudScene 場景是遊戲玩家互動的基礎,CloudScene 用來管理遊戲場景,除了負責訊息傳送與接收外,還有一些與玩家互動有關的功能。

  • CloudItem 物品是遊戲運作時屬於玩家專有的資料,CloudItem 用來管理這些資料。

  • CloudScore 登錄遊戲分數,由伺服器統計分數,並產生積分板(Leaderboard)

  • CloudShop 用在 iOS 的 in-app purchase 與 Android 的 in-app billing 之 Server Product Delivery 服務,以確保購買流程的穩定與安全。

  • CloudGuild 建立與管理公會,包括公會成員、公會基本資料等。

  • CloudMailbox 遊戲中的郵箱,此類別用來發送與讀取玩家與公會群組的離線信息,信息將會存放在雲端儲存,並佔用遊戲的存放額度。

1-2 非同步非阻塞式(Asynchronous Non-blocking) API

SGC 對於耗時(Time-Consuming) API 採用非同步非阻塞式設計,呼叫時必須指定 callback 函式, 好讓 API 完成工作後透過 callback 函式通知呼叫者。

Callback 是開發者自己所設計的函式,由在背景中執行的 API 工作程式所呼叫,如果 API 完成工作後有資料要傳回,就要把這些資料當成參數,在呼叫 callback 時傳回給開發者程式。

SGC API 函式有兩個重要的參數:callback 函式與 token 物件。

把 callback 函式當成參數傳給 API,API 執行結束後就會呼叫這個 callback 函式;另外,token 物件則會原封不動的傳遞給 callback 函式。這樣的設計架構可以讓 callback 函式與呼叫者程式連結起來, 讓雙方透過共用的 token 物件傳遞資料。 callback 函式有兩種定義型別(function prototype),分別是OnCallCompletionOnCallCompletionWithData

  • OnCallCompletion

只傳回函式執行結果的整數代碼,依照代碼判斷執行結果。OnCallCompletion 的函式定義如下:

void OnCallCompletion(int code, object token);

  • OnCallCompletionWithData

除了傳回結果碼外,另外傳回資料物件 data,程式設計師依照 API 函式的個別定義,將資料物件改型(cast)為正確的型態,就可以存取 API 執行後所得的資料。OnCallCompletionWithData 定義如下:

void OnCallCompletionWithData(int code, object data, object token);

callback 函式的最後一個參數 token 是呼叫 API 時所傳入的物件參數,程式設計師可以傳入任何資料,在 API 完成時原封不動的傳給 callback 函式,這樣的架構可以讓程式設計師在呼叫多次或不同的 API 時共用同一個 callback 函式,透過 token 參數的內容區別原始呼叫 API 的作業是那一個,減少撰寫 callback 函式的工作量。

1-3 多執行緒程式設計

SGC API 支援多執行緒程式設計,為了多執行緒程式的同步協調(Synchronization)問題,請務必在主執行緒中建立 CloudGame 物件,API 將會在主執行緒中觸發事件(Event)。

前一節已經介紹過耗時(Time-Consuming) API 是採用非同步非阻塞式設計,函式返回不代表工作已經完成,系統會在作業完成後,以主執行緒呼叫 callback 函式,就算當初不是在主執行緒中呼叫 API, 最後的 callback 還是會在主執行緒中執行。

也因為 API 事件與 callback 都是在主執行緒中被呼叫,所以當它們被觸發時,可以直接控制應用程式的 UI 元件,在多數只允許主執行緒控制 UI 元件的系統,這是相當方便的設計。

由於主執行緒運行與應用程式畫面有相當的關係,因此程式設計師不應該在主執行緒中執行過於耗時的程序,以免造成應用程式的操作發生 Lag 的狀況。

以下列舉幾種可能的程式架構,請依此規範原則設計您的應用程式。

  • 事件處理程式不是耗時工作
  • 事件處理程式是耗時工作,無法立刻結束

  • callback 是耗時工作,無法立刻結束

1-4 事件處理(Event Handler)

有兩種方式撰寫事件處理程式:

  • 重新定義(Override Event Handler) 程式設計師另行設計繼承自 SGC API 類別的子類別,然後在此類別內改寫事件處理函式。
 ...
 MyCloudGame mag = new MyCloudGame();
 mag.Launch();
 ...
 public class MyCloudGame : CloudGame // MyCloudGame繼承自CloudGame
 {
  private const string userid = "...";
  private const string passwd = "...";
  private const string gguid = "...";
  public static byte[] cert = { ... };
  public MyCloudGame() : base(userid, passwd, gguid, cert) {}
  protected override void OnCompletion(int code, CloudGame game)
  { // 自行定義的事件處理函式
  }
}
  • 指定事件函式(Assign Eevent Handler) 透過物件內的「事件函式變數」,把程式設計師自行設計的事件處理函式指定給它們,就可以讓 SGC API 執行開發者自定的事件函式。
 ...
 private const string userid = "...";
 private const string passwd = "...";
 private const string gguid = "...";
 public static byte[] cert = { ... };
 ...
 CloudGame ag = new CloudGame(userid, passwd, gguid, cert);
 ag.onCompletion += new EventHandler(myCloudGameCompletion,CloudGame game);
 ag.Launch();
 ...
 private void myCloudGameCompletion(int code, CloudGame game)
 { // 自行定義的事件處理函式
 ...
 }

請注意,如果沒有指定「事件函式變數」,也沒有重新定義事件處理函式,當事件觸發時並不會有任何由程式設計師所指定的程式碼會被執行,而 SGC API 也不會有任何內部處理,換句話說,事件等同於失效了。雖然這樣子不會造成編譯或執行錯誤,但是程式設計師應該避免讓 API 事件失效, 因為 SGC API 已經簡化許多工作,其所定義的事件都應該被處理。

1-5 遊戲管理

使用 SGC API 須配合開發者後台的遊戲管理,以遊戲為單位,管理遊戲的場景、物品、積分板、公會、信箱等功能。

  • 遊戲(Game) 開發者決定要製作一款遊戲時,請到開發者後台建立一個新的「遊戲開發專案」,然後才能配合使用 API 的 CloudGame 類別。 建立新遊戲時必須輸入「遊戲名稱」與「說明」後,這兩個欄位的資料將會出現在 SGC 的玩家網站上,也是讓玩家瞭解遊戲的文字說明。
  • 場景(Scene) 遊戲場景分為「靜態場景」與「動態場景」兩種。

  • 靜態場景
    靜態場景是遊戲系統建立時就已經存在,無法另建副本,玩家可以進入與離開靜態場景,但是不能刪除。

  • 動態場景
    動態場景在遊戲建立時並不存在,玩家可依遊戲機制在遊戲中建立副本,已經建立的動態場景副本才是已經存在遊戲中的場景,玩家才能進入或離開場景。

  • 物品(Item)
    CloudItem 類別用來處理遊戲中的物品,物資依照用途分為「商品」、「性質」、「資料」三種類型,開發者在後台新增一個物資時,必須依照需求為新增的物品選擇一種類型。「商品」是指遊戲中可出售給玩家的物品,通常是指寶物或道具。「性質」用於定義遊戲中各種人物、環境、物品等的特性、度量等,也可用來定義不在商城出售的寶物或道具。「資料」用於記錄玩家在遊戲中的各種資料,也可視為玩家遊戲程式儲存於伺服器中系統變數。

  • 積分板(Leaderboard) CloudScore 類別用來處理玩家在遊戲中的成績,可產生玩家成績排行,也可以用來記錄玩家個 人分數。積分板分為總排行、日排行、週排行、月排行等,並且可以設定事件觸發後進行物資設定。例如 我們想要讓排行前幾名的玩家獲得某種寶物道具,只要在開發者後台進行積分板的事件觸發設定 即可,不必另外撰寫排程程式。

  • 公會(Guild) 公會等同於遊戲中的玩家群組,和場景、物品、積分板不同的是,公會並沒有類別(Class)與實例 (Instance) 的物件架構,所以不像場景、物品、積分板需要後台管理類別庫,但是仍需要管理與 安全有關的 api 執行權限。

  • 信箱(Mailbox) 信箱是玩家訊息的離線存放系統,可用來進行一對一的玩家訊息寄送,以及一對多的公會成員群 組寄送。

1-6 遊戲資料

遊戲資料儲存就是一般所稱的雲端資料庫,SGC 已經針對多人連線遊戲的特性與需求,設計好專用的資料庫系統,依照功能區分,開發者只要使用對應的 api 存取資料庫即可。

  • 玩家個人資料 (Personal Data) 玩家個人資料有:物品實例(Item Instance),個人成績(Score)、信箱(Mailbox)、主暫存器(AX, BX, CX, DX)、R 暫存器(R1, R2, R3, R4)。

  • 遊戲公共資料 (Public Data) 遊戲公共資料有:物品類別(Item Class)、積分板(Leaderboard)、公會(Guild)、G 暫存器(G1, G2, G3, G4)。

暫存器是一種特殊用途的遊戲資料,只能存放 32 位元整數值,在呼叫某些 api 以取得陣列資料時,可用來指定陣列的排序方式。 玩家暫存器總共有三種,分別是主暫存器(AX, BX, CX, DX)、R 暫存器(R1, R2, R3, R4)、G 暫存器(G1, G2, G3, G4),主暫存器與 R 暫存器是每個玩家都有,G 暫存器是加入公會的玩家才會有。

由於 SGC 並沒有定義暫存器資料用途,開發者可以自行定義,例如可將 R1, R2 暫存器定義為玩家生命值、經驗值等,如果物品實例(Instance)中也會有對應的屬性資料(Item Instance Attribute),開發者可以使用 CloudItem.SetItemInstanceAttribute()同時寫入 Item 的屬性和暫存器中。 下圖是一個遊戲玩家在一個 SGC 遊戲中的資料儲存架構:

當遊戲玩家有很多人時,每個玩家都有自己的個人資料區,因而形成如下圖的資料儲存架構:

1-7 伺服器邏輯

為了確保遊戲機制的安全性與公平性,開發者有時候必須撰寫中央集權式的遊戲控管程式,做為遊戲伺服器功能的延伸,這樣的控管程式我們稱為遊戲伺服器邏輯,SGC 採用分散式插件(Distributed Plugin, 簡稱 DP)技術來實現伺服器邏輯功能,因我們也可以把伺服器邏輯稱為 DP。 一般來說伺服器邏輯分為以下幾種功能:

  • 系統監控與記錄 遊戲運行中的每個邏輯控制,透過用戶端遊戲程式傳到 DP 時,DP 便將這些控制訊息記錄起來, 或是針對異常狀況進行監控,讓管理者隨時掌握遊戲玩家的狀況。
  • 場景控管 (Scene Control) 場景控管是遊戲大廳的功能之一,像是場景副本的建立與刪除,或是控管玩家進出遊戲場景,如人數控制、自動配對、進出權限管理等。
  • 遊戲仲裁(Arbitration) 將原本分散於用戶端遊戲程式中的邏輯控制程式集中至 DP 中運行,避免遊戲在不同玩家的用戶端程式中發生不同步的狀況,進而影響遊戲正常運作。

設計 DP 的主要目的是延伸遊戲伺服器的功能,SGC 提供開發者可以在不碰觸高階遊戲伺服器程式設計的狀況下,讓遊戲可以擁有專用的遊戲伺服器。由於 DP 只是單純的資料處理程式,比起設計用戶端遊戲程式還簡單,且使用的 API 和設計遊戲程式所用的 API 一樣。此外 DP 與 SGC 伺服器連接的帳號密碼就是一般的玩家帳號,開發者請自行到 SGC 網站申請,基於帳號管理之專用原則,此帳號請讓 DP 專用,不要在遊戲程式中登入使用。

1-8 超級使用者與特權函式

超級使用者(Super User)又稱特權使用者,是 DP 登入遊戲所使用的帳號。由於 DP 擔任遊戲主控者的角色,因此必須賦與存取其它玩家資料的特權。SGC 為了讓 DP 擁有此種能力,也針對 CloudItem 與 CloudScore 中的函式,提供存取其他玩家資料的權限,這些函式又稱為「特權函式」。 特權函式只有登入帳號是超級使用者才能呼叫,否則 callback 將會傳回「無使用權限」錯誤碼。超級使用者函式的功能與參數和一般玩家函式相似,函式名稱以 su 開頭,如果該特權函式是針對特定玩家的資料進行操作,函式就會有一個額外的參數 userid,用來指定該特定玩家的帳號。

特權函式使用時機

  • 資料讀取
    當遊戲運行時,用戶端的程式可以隨時讀取資料庫,也就是透過 CloudItem 與 CloudScore 的靜態函式讀取玩家的資料,為了提高 DP 的效能,由一般使用者讀取資料是被允許的,除非所讀取的資料可能會與遊戲公平性有關,為了避免外掛程式擾亂遊戲,此類的資料應該由 DP 負責讀取。
  • 資料寫入
    由於寫入資料通常都與遊戲成績、戰果、等級有關,為了避免駭客非法破壞,資料寫入還是交給 DP 程式來做比較合適。

超級使用者設定與管理

開發者可在 SGC 遊戲管理後台的「權限管理」中設定各種權限:

權限分為超級使用者與一般使用者兩種:

  • 超級使用者
    (1) 指定「超級使用者」帳號,只有此帳號才能有完整的資料庫存取權限。
    (2) 指定存取的遠端 IP,為了進一步的資料存取安全,此處還可以限制「超級使用者」帳號只能從特定的 IP 進行完整的資料庫存取權限。指定 IP 的類型分為三種:
Type 說明
Any 沒有設限,任何 IP 都可存取
Single host 指定一個 IP,只有這個 IP 才能存取
Network 指定一個 IP 範圍,只有在這個 IP 範圍內才能存取
  • 一般使用者 可以設定一般使用者對於資料庫的存取權,分為「沒有權限」、「只可讀」、「可讀寫」三種。

特權函式

CloudItem 與 CloudScore 類別中的函式,都有讓超級使用者呼叫的特權函式,一般使用者函式和特權函式的差別是:

使用者類型 存取範圍 指定方式
一般使用者函式 一般使用者 自己的資料 (無)
特權函式 超級使用者 其他玩家的資料 某玩家的 userid

CloudItem 的超級使用者函式可以至上方的 API物件模型 => CloudItem => 超級使用者,來查看所有函式。
CloudScore 的超級使用者函式可以至上方的 API物件模型 => CloudScore => 超級使用者,來查看所有函式。

1-9 API 下載

SGC 支援多種程式語言與平台的 API,以下是 API 的開放狀況:

平台 程式語言 已開放下載
Unity3D 遊戲引擎 C# V
MS Visual C# C# V
iOS Objective-C X
Android Java X
Java Java X
Flash Action Script X

API 請至 SGC 開發者網站,登入開發者帳號後進入下載區下載。