長文:Minecraft 的多人遊戲是如何發展起來的?(一)

這個問題太想自問自答了,因為這段血淚史完全可以寫成精彩紛呈的長篇小說!作為在 Minecraft 業界打滾多年的人,必須得給大家侃侃背後的故事!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

// Survival Multiplayer 時代(2010)

讓時光回溯到五年前的 8 月 9 日的凌晨。我們的故事主角兼 Minecraft 創始人,Markus 'Notch' Persson,正二十四個小時宅在家裡,撐著雙眼死瞪電腦屏幕,雙手則 迅速地敲著鍵盤,廢寢忘食地調試著程序。再過一個小時就是 8 月 10 日了,Minecraft 生存多人遊戲(Survival Multiplayer,SMP)正式發佈的日子。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

你看 Notch 這妖魅的小眼神

Minecraft SMP 的名字聽上去很高大上,但其實就是一個叫做 minecraft_server.jar 的文件罷了,小巧綠色又便攜。使用方法也非常簡單,雙擊打開,它就會自動在默認端口上設置好一個 Minecraft 的服務器,別人只需憑你的 IP 即可進入。理所當然地,一些基本的命令也包含在其中:/kick 用來踢人,/gamemode 用來從生存轉創造...

現在看來,第一個版本的 SMP 相當簡陋,但玩家們正沉醉於和朋友一起玩生存的樂趣裡,再簡陋也讚不絕口。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

SMP 的發佈,正是迎合 Minecraft 迅猛上升的用戶註冊量。截至 2010 年 5 月,Minecraft 的付費用戶已經達到兩萬,YouTube 上以 Minecraft 作為關鍵字的視頻日益增長,而此時,這個遊戲還只是在 Alpha 階段!

而 SMP 的出現,更讓 Minecraft 的知名度登上又一巔峰:什麼!?可以和好基友在開放式的 LEGO 世界裡生存、探險、搞基(?);還可以開創造起個鬥獸場戰個痛或者堆滿 TNT 然後炸地圖;最給力的是神似編程的紅石系統,直接令 Minecraft 一躍成為遊戲開發工具!哪個 AAA 級遊戲有這麼爽的體驗?!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

即使從五年後看來,SMP 的第一個版本也有相當高的遊戲性

在 SMP 發佈僅僅兩個月後,Minecraft 的付費用戶就翻了個 1.5 倍,兩個月就賺了一百多萬!SMP 的巨大成功並沒有讓 Notch 怠慢,沒過多久就向玩家們宣佈了 Beta 版本的到來。而 Notch 也正式註冊了 Mojang AB 的商標,為之後發行遊戲鋪路。

// hMod 時代(2010 ~ 2011)

SMP 好玩歸好玩,可是不能在上面裝 mod 這一點讓不少玩家很苦惱。當然了,可以通過反編譯 minecraft_server.jar 修改裡面的代碼,比如調整一下玩家的默認速度什麼的,然後每個玩家一走起路來就跑十公里遠,上天入海不是夢。畢竟 Mojang 也沒有做什麼簽名驗證,也沒什麼坑爹的全程聯網驗證(育碧:...),要修改幾個變量然後重新編譯,理論上來講不難啊。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

可行歸可行,問題是修改起來太麻煩:代碼全部被混淆(obfuscated)了!

什麼叫代碼混淆呢?舉個栗子,比如說原本的代碼是這樣的:

private String playerName = "你爸爸"; // 定義玩家名稱
private double health = 20.0D; // 定義玩家血量
private float walkSpeed = 1.2F; // 定義玩家速度
public void chat(String message) { // 定義一個說話的函數
Server.broadcastMessage(this, message); // 向服務器裡的函數傳遞參數
}

沒學過 Java 是不是也很清晰明瞭?這修改起來還不容易,簡直就是填空嘛,小學生都會。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

問題是在編譯的時候,代碼被 Mojang 事先混淆了,可能到你手裡的時候就變成這樣了:

String a = Base64.decodeFromBase64("5L2g54i454i4");
double b = 20.0D;
float c = 1.2F;
public void d(String a) {
bl.aE(this, a);
}

尼瑪這叫一個狠哪,若是沒有原本的代碼,你看得懂嗎?

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

你或許說,上面這幾行,我也能猜出個大概吧?嗯,b 是血量,因為玩家血量最高就是 20,然後 c 是... bl 是... aE 是...

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

別忙著翻桌,我們再來看看真實個例,下面是 Minecraft 1.8 裡面的 aap 類:

public class aap extends um {
private static final Logger b = ;
public float a = (float) (Math.random() * 3.141592653589793D * 2.0D);
private int c;
private int d;
private int e = 5;
private String f;
private String g;

public aap(amp paramamp, double paramDouble1, double paramDouble2, double paramDouble3) {
super(paramamp);
a(0.25F, 0.25F);
b(paramDouble1, paramDouble2, paramDouble3);
this.y = ((float) (Math.random() * 360.0D));
this.v = ((float) (Math.random() * 0.2000000029802322D - 0.1000000014901161D));
this.w = 0.2000000029802322D;
this.x = ((float) (Math.random() * 0.2000000029802322D - 0.1000000014901161D));
}
public aap(amp paramamp, double paramDouble1, double paramDouble2, double paramDouble3, aio paramaio) {
this(paramamp, paramDouble1, paramDouble2, paramDouble3);
a(paramaio);
}
public aap(amp paramamp) {
super(paramamp);
a(0.25F, 0.25F);
a(new aio(apg.a, 0));
}
protected boolean q_() {
return false;
}
protected void g() {
F().a(10, 5);
}
public void j() {
if (k() == null) {
H();
return;
}
super.j();
if ((this.d > 0) && (this.d != 32767)) {
this.d -= 1;
}
this.p = this.s;
this.q = this.t;
this.r = this.u;
this.w -= 0.03999999910593033D;
this.T = j(this.s, (aL().b + aL().e) / 2.0D, this.u);
d(this.v, this.w, this.x);
int i = ((int) this.p != (int) this.s) || ((int) this.q != (int) this.t) || ((int) this.r != (int) this.u) ? 1 : 0;
if ((i != 0) || (this.W % 25 == 0)) {
if (this.o.p(new dl(this)).c().r() == big.i) {
this.w = 0.2000000029802322D;
this.v = ((this.V.nextFloat() - this.V.nextFloat()) * 0.2F);
this.x = ((this.V.nextFloat() - this.V.nextFloat()) * 0.2F);
a("random.fizz", 0.4F, 2.0F + this.V.nextFloat() * 0.4F);
}
if (!this.o.C) {
v();
}

}
float f1 = 0.98F;
if (this.C) {
f1 = this.o.p(new dl(sr.c(this.s), sr.c(aL().b) - 1, sr.c(this.u))).c().K * 0.98F;
}
this.v *= f1;
this.w *= 0.9800000190734863D;
this.x *= f1;
if (this.C) {
this.w *= -0.5D;
}
if (this.c != -32768) {
this.c += 1;
}
if ((!this.o.C) && (this.c >= 6000)) {
H();
}
}
private void v() {
for (aap localaap : this.o.a(aap.class, aL().b(0.5D, 0.0D, 0.5D))) {
a(localaap);
}
}
private boolean a(aap paramaap) {
if (paramaap == this) {
return false;
}
if ((!paramaap.ad()) || (!ad())) {
return false;
}
aio localaio1 = k();
aio localaio2 = paramaap.k();
if ((this.d == 32767) || (paramaap.d == 32767)) {
return false;
}
if ((this.c == -32768) || (paramaap.c == -32768)) {
return false;
}
if (localaio2.b() != localaio1.b()) {
return false;
}
if ((localaio2.n() ^ localaio1.n())) {
return false;
}
if ((localaio2.n()) && (!localaio2.o().equals(localaio1.o()))) {
return false;
}
if (localaio2.b() == null) {
return false;
}

if ((localaio2.b().k()) && (localaio2.i() != localaio1.i())) {
return false;
}
if (localaio2.b < localaio1.b) {
return paramaap.a(this);
}
if (localaio2.b + localaio1.b > localaio2.c()) {
return false;
}
localaio2.b += localaio1.b;
paramaap.d = Math.max(paramaap.d, this.d);
paramaap.c = Math.min(paramaap.c, this.c);
paramaap.a(localaio2);
H();
return true;
}
public void i() {
this.c = 4800;
}
public boolean T() {
return this.o.a(aL(), big.h, this);
}
protected void f(int paramInt) {
a(ua.a, paramInt);
}
public boolean a(ua paramua, float paramFloat) {
if (b(paramua)) {
return false;
}
if ((k() != null) && (k().b() == aip.bU) && (paramua.c())) {
return false;
}
X();
this.e = ((int) (this.e - paramFloat));
if (this.e <= 0) {
H();
}
return false;
}
public void b(eu parameu) {
parameu.a("Health", (short) (byte) this.e);
parameu.a("Age", (short) this.c);
parameu.a("PickupDelay", (short) this.d);
if (m() != null) {
parameu.a("Thrower", this.f);
}
if (l() != null) {
parameu.a("Owner", this.g);
}
if (k() != null) {

parameu.a("Item", k().b(new eu()));
}
}
public void a(eu parameu) {
this.e = (parameu.e("Health") & 0xFF);
this.c = parameu.e("Age");
if (parameu.c("PickupDelay")) {
this.d = parameu.e("PickupDelay");
}
if (parameu.c("Owner")) {
this.g = parameu.j("Owner");
}
if (parameu.c("Thrower")) {
this.f = parameu.j("Thrower");
}
eu localeu = parameu.m("Item");
a(aio.a(localeu));
if (k() == null) {
H();
}
}
public void d(adq paramadq) {
if (this.o.C) {
return;
}
aio localaio = k();
int i = localaio.b;
if ((this.d == 0) && ((this.g == null) || (6000 - this.c <= 200) || (this.g.equals(paramadq.b_()))) && (paramadq.bg.a(localaio))) {
if (localaio.b() == ahw.a(apg.r)) {
paramadq.b(rl.g);
}
if (localaio.b() == ahw.a(apg.s)) {
paramadq.b(rl.g);
}
if (localaio.b() == aip.aA) {
paramadq.b(rl.t);
}
if (localaio.b() == aip.i) {
paramadq.b(rl.w);
}
if (localaio.b() == aip.bq) {
paramadq.b(rl.A);
}
if ((localaio.b() == aip.i) && (m() != null)) {
adq localadq = this.o.a(m());
if ((localadq != null) && (localadq != paramadq)) {
localadq.b(rl.x);
}
}
this.o.a(paramadq, "random.pop", 0.2F, ((this.V.nextFloat() - this.V.nextFloat()) * 0.7F + 1.0F) * 2.0F);

paramadq.a(this, i);
if (localaio.b <= 0) {
H();
}
}
}
public String b_() {
if (i_()) {
return aG();
}
return eq.a("item." + k().a());
}
public boolean az() {
return false;
}
public void c(int paramInt) {
super.c(paramInt);
if (!this.o.C) {
v();
}
}
public aio k() {
aio localaio = F().f(10);
if (localaio == null) {
if (this.o != null) {
b.error("Item entity " + D() + " has no item?!");
}
return new aio(apg.b);
}
return localaio;
}
public void a(aio paramaio) {
F().b(10, paramaio);
F().h(10);
}
public String l() {
return this.g;
}
public void a(String paramString) {
this.g = paramString;
}
public String m() {
return this.f;
}
public void c(String paramString) {
this.f = paramString;
}
public void o() {
this.d = 10;
}

public void p() {
this.d = 0;
}
public void q() {
this.d = 32767;
}
public void a(int paramInt) {
this.d = paramInt;
}
public boolean r() {
return this.d > 0;
}
public void t() {
this.c = -6000;
}
public void u() {
q();
this.c = 5999;
}}
長文:Minecraft 的多人遊戲是如何發展起來的?(一)

能猜得出來算你狠。

於是,雖然 SMP 的第三方修改成為可能,但基本沒有服主會閒的蛋疼去玩這個。除了代碼被混淆之外,由於 Minecraft 長期都是 Notch 一個人開發,所以內部的業務邏輯也寫得很亂,或者說實在太有 Notch 特立獨行的代碼風格了,窩們實在猜不粗來呀!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

Notch 表示:“你丫反編譯我的代碼還瞎逼逼”(設計對白)

不過就是有些人點錯天賦了,就在 SMP 發佈後沒多久的 2010 年年底,一位叫 hey0 的大神在自己的個人網站上發佈了 hMod。hMod 一出,激起千層浪,眾人紛紛驚呼:民間奇才!

hMod 是個什麼玩意兒?我儘量簡單地解釋一下。以往的 SMP modding 模式(也就是上面提到的,直接修改源代碼),我們畫個流程圖出來:

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

hMod 的原理,就是將那些不可讀的代碼,通過 hey0 君敏銳的觀察能力,“翻譯”成可讀而清晰明瞭的東西。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

還記得剛才那堆亂七八糟的代碼嗎?有興趣的同學可以自行閱讀“翻譯”過後的代碼。

(“翻譯”這詞實際上並不準確,實際上 hMod 是對 SMP 的半封裝,詳細的技術細節在此略過。)

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

這實在太偉大了!要在服務器上加入自己原創的內容,頓時簡單了起來。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

不過如此偉大的 hMod 更新了幾個月,原作者就突然潛水,小道消息是說回老家結婚去了,然後由另一位現已就職 Mojang 的大神 Dinnerbone 繼續填坑。還沒填到一半 Dinnerbone 就不幹了:靠,代碼真亂!於是拉上幾個志同道合的同志一起推翻重做,扛起“翻譯”的任務,Bukkit 計劃就這麼誕生了。

// Bukkit 時代(2011 ~ 2014)

Bukkit 計劃實際上分為兩部分:Bukkit API 和 CraftBukkit。廢話不多說,我們再畫個流程圖:

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

原理和 hMod 是一樣的,但 Bukkit API 寫得更好之餘,最重要的成就就是加入了事件系統,不過這個話題說下去完全可以另起爐灶了,所以咱們暫且跳過。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

好了我知道你們都在吐槽上面的魔法是什麼鬼,那麼我儘量簡單講一講,沒有面向對象編程基礎的同學可以跳過下面這幾段。

Bukkit API 裡全部都是抽象的類與方法,打個比方有個方法叫 getOnlinePlayers(),返回當前玩家數量。為什麼要抽象?為什麼我們不直接整合實現(implementation)?比如我發現下面這行代碼就可以返回當前玩家數量,這不搞定了嗎,分兩步幹嘛。
aJ.e();

問題是我們的這行代碼的基礎,是通過破解 Minecraft SMP 的源代碼對吧?更準確的說,是通過破解 Minecraft SMP 當前版本的源代碼作為基礎。而代碼混淆這個過程,是每個版本都會重新進行一次的。上面那行代碼或許在 Minecraft SMP 1.7 能用,但到 1.8,可能就完全報錯了。因為或許在 1.8 裡,要獲取當前玩家數量的代碼是這樣的:
b.aX();

所以,在 Bukkit API 的部分裡,這個方法是抽象的,留給相應版本的 CraftBukkit 去實現。並且這麼一來,有了抽象的接口作為參考,新版本的 SMP 發佈時,Bukkit 團隊也能更方便地更新 CraftBukkit。在這裡也順便吐槽一下,常常見到有人說用 Bukkit 開服,其實是錯的 —— Bukkit 裡全是抽象的接口而已,開個鬼啊。正確的說法是用 CraftBukkit 開服(其他服務器端另計)。所以下次你見到誰跟你炫耀說“我會用 Bukkit 開服務器你造嗎”,記得高大上的回他一句:“乖,那個叫 CraftBukkit。跟我讀,科阿哇夫特巴可以特。”
長文:Minecraft 的多人遊戲是如何發展起來的?(一)


好了話題扯遠了,那麼有了 Bukkit 能做些什麼呢?能做的事太多了!比如用 Bukkit API 的自定義命令功能,加個叫 /launch 的命令,然後輸入 /launch 就將目標玩家噴上天,這無論在原生 Minecraft 裡或者 SMP 裡都是做不到的!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

效果請參見左下角~ 這些基於 Bukkit API 的小程序被統稱為插件(plugin)

好了,我知道你們又要吐槽了。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

當然不是!這種插件實在太膚淺了,Bukkit API 真正最廣泛的應用是用來開發小遊戲(minigame)。你沒聽錯,在遊戲裡開發遊戲!只要有足夠的人力物力,依靠著 Bukkit API,要弄出個 Minecraft 版《無主之地》或者《使命召喚》是絕對可行的!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

國外知名服務器 Hypixel 近日推出的新遊戲 Warlords,武器到裝備的模型都是完全自制的。Warlords 的核心玩法其實就是搶旗,但又加入了武器收集,附魔系統和角色系統等等,目前平均在線玩家 2000+,稱其為小型 PvP 網遊也絕不為過。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

毫不誇張地說,Warlords 甚至要比 Steam 上不少免費的 FPS 好玩;光是收集要素就足夠吸引了!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

另一知名大服 Wynncraft,則主打 RPG 玩法,照搬了當今網絡上 MMORPG 的很多元素:饒有趣味的任務,廣闊宏偉的地圖,專門刷經驗升級的地城... 倒也弄得趣味橫生。

我們還是先回到 2011 年,回到 Bukkit 剛剛發展起來的時候吧:那時大眾對 Minecraft 多人遊戲的概念,還只是停留在與好基友一起玩生存的程度。真正將 Bukkit 計劃推向大眾視野的,當屬在 2011 年發展起來的 MCSG(Minecraft Survival Games)服務器。聽過《飢餓遊戲》吧?熟悉裡面的設定吧?而 MCSG,就是飢餓遊戲在 Minecraft 的翻版:24 個玩家在開放式的地圖裡生存,到處開箱尋找物資,誰生存到最後就贏。SMP 可能也弄得出來,但是想做複雜一點,將箱子的物品完全隨機化,或者將玩家數據保存在 mySQL 數據庫裡,又或者加入一堆炫目的技能,那是 SMP 絕不可及的。而以上這一切,利用 Bukkit API,小 case 啦。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

當然 Survival Games 遠遠沒有如今的 Warlords 吸引,但是在當年卻可謂掀起了一陣 Minecraft 潮。在 YouTube 上實況大型服務器裡遊戲的實況主越來越多,即使是如今已經超過千萬訂閱的 SkyDoesMinecraft —— 就是那個玩了 Flappy Bird 的小夥 —— 也是玩 Minecraft 發家的(好吧,這個看名字就知道)。

好了,我知道你看到這裡有點無聊了。所以下面重點來了!!v(。・ω・。)ィェィ♪

因為也是在 2011 年,一個名為 Buycraft 的東東進入了服主們的視野。Buycraft 是一個 CMS 系統,服務器的玩家可以通過在前端用 Paypal 或者信用卡購買東西,來獲得服務器上的增值服務。用 Minecraft 賺錢不再是夢!

真是爆炸性的大新聞。

......

(超燃 BGM 響起)

這豈止是爆炸性,簡直是歷史性!!!這不正是現在手遊最喜歡加入的課金系統嗎?!!

你嫌你的裝備太差嗎??

你覺得打怪升級太慢嗎???

你羨慕那些滿身神裝的高富帥嗎????

快來買 VIP 會員吧!!!!!!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

一個月只需 10 美刀,即可讓你得到最尊貴的享受!!!!!!!!!!!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

雙倍金錢!!!

三倍經驗!!!!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

換裝系統!!!!!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

寵物陪伴!!!!!!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

房間防踢!!!!!!!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

非 VIP 說話全是灰色的!!!!買了 VIP 你就算罵髒話我們也幫你加個白色高亮!!!!!!還有高端洋氣上檔次 VIP 字樣的前綴!!!!!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

別人死了最多就一句死亡信息!!!!!!!!你死掉我們在你死亡的地點放個七彩煙花!!!!!!!!!讓整個世界都知道你死了!!!!!!!!!!!

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

於是,Minecraft 的多人遊戲到這裡已經完全發展起輕工業來了,首先是開發難度低兼成本小,插件還不一定要自己開發,網上現成的一堆,實在不行開價讓別人來做;然後就等著收錢吧,五十美刀一個月的 VIP 照樣有人買!

Bukkit 計劃也從此聲名大噪,越來越多的熱心人士加入了開發行列,每一個更新都是無數服主歡呼的時刻。和 SMP 一樣簡單的開服流程也讓服務器越來越多,保守估計也有幾十萬 —— 甚至有了 Minecraft Server List,Minecraft Servers 這樣的網站,只是列出互聯網上公開的服務器地址,同時暗中通過競價為某些服務器提升排名,一個月就能賺上萬。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

吃驚吧?更恐怖的在後頭呢。剛才提到過的,2012 年迅速崛起的小遊戲服務器 Hypixel,也是通過增值內容付費的方式,賺了個盆滿缽滿!根據我一位認識 Hypixel 開發者的外國朋友的可信消息,高峰期的 Hypixel,日均 30000+ 玩家,一年的淨利潤 $1000000+。除以 12,一個月九萬多美元,也即五十七萬人民幣。

一個月五十七萬。

一個月五十七萬。

一個月五十七萬。

一個月五十七萬。

一個月五十七萬。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

可能有人會質疑以上的數字,那麼我曬曬親身經歷吧:學生黨一枚,有多年編程基礎,閒著沒事也寫寫插件。我曾經在 2013 年 9 月在一家名為 Minecade 屬下的 SkyDoesMinecraft 服務器工作過三個月,月薪一千。2014 年年尾幫 ArkhamNetwork 服務器做過外包項目,六百。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

還有一些零零碎碎的小項目,在此不表。而無論是 Minecade 還是 ArkhamNetwork,甚至還擠不進大服務器的行列。可以想像得見一線服務器的員工們,一個月能賺多少了!

所以說如今 Minecraft 的多人遊戲完全是一條成熟的產業線,服主帶著充足的資金聘請員工,為服務器開發高質量內容吸引玩家;玩家則購買增值內容甚至主動捐款來令服務器盈利。這樣的良性循環在整個遊戲界來講都是很難得的。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

與此同時,單人遊戲的體驗也在穩速提高,1.5 的紅石更新,1.6 的馬匹更新,1.7 的世界觀更新,而勤快追上步伐的 Bukkit 計劃又讓服務器們得以爭先搶後地在 CraftBukkit 新版本發佈的第一時間更新服務器上的內容,為的就是吸引人流。

原本就蓬勃的 Minecraft 遊戲界在 2013 年進入了黃金時代。有充足的利潤打底,服務器們開發的新內容一次比一次高質量,Quakecraft、Hide and Seek、Prison、Factions、Arcade 等遊戲模式的名字已經深入民心,玩家們也樂意付錢,於是兩邊和樂融融,近年來遊戲業流行的 Freemium 的模式竟然在他們身上得到最好的實現。Minecraft 在這一年突破 1000 萬銷量,很大程度上要歸功於辛勤的服主們。

黃金時代終究是要過去的。狂喜的人們似乎沒有發現,一朵烏雲已經慢慢逼近......

// 輝煌背後

Bukkit 時代看似輝煌,但實際上有不少隱患出現:

第一是 Bukkit 本身的衰落。2012 年 2 月,Bukkit 的開發團隊(Dinnerbone,EvilSeph,Grum,Tahg)收到來自 Mojang 的 offer,於是欣然應邀加盟 Mojang;作為條件,他們不能再開發 Bukkit,而是負責開發新版本的 SMP 和其他與 Minecraft 有關的工作,比如編寫 Plugin API。

Dinnerbone 和 Grum 這兩位可以說是對整個 Bukkit 計劃貢獻最大的人,反編譯和反混淆由 Grum 全權負責,然後 Dinnerbone 則接過代碼坐在電腦桌前除了上廁所外不停歇地碼上二三十個小時(這就是愛啊 <3),為的就是以最快的速度將新版本的 Bukkit API 和 CraftBukkit 呈現在大眾面前。如今他們走了,雖然有人接班,但是他們都沒有了 Dinnerbone 和 Grum 的那份旁人難以理解的激情,更新對他們來說更像是一份義務而不是責任。這也不能怪他們,但伴之而來的就是 CraftBukkit 的更新越來越慢,當初兩天就能更新完,現在要花上兩個月;而Bukkit 在 1.5 後鮮有再加入新的 API,意思就是上文提到的“翻譯”活越來越少人肯去做,導致許多 SMP 的新功能都無法單純地利用 Bukkit API 實現,必須還得配合之前提到的那種直接修改源代碼的蛋疼方法...

作為過來人,我可以肯定地告訴你們:閱讀 Minecraft 的源代碼太蛋疼了...

第二是收費氾濫。服務器們收費的方式推陳出新,以 Hypixel 為例,VIP 出完了出 VIP+,VIP+ 出完了出 MVP,MVP 出完了再出 MVP+...

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

幾十美金幾十美金地收... 國內一線 MMO都沒這麼貴啊

就算玩家們樂意,他們的家長也不樂意呀!不少熊孩子一個月花了幾千美刀在 Minecraft 上,而家長們又怎會了解 Bukkit 服務器們的商業模式,於是出現了家長們憤怒地在推特上向 Notch 投訴並要求全額退款,否則要將 Mojang 告上法庭的啼笑皆非的情況。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

Mojang 躺著也中槍:關我屁事啊!?

第三是版權問題。CraftBukkit 內置了 Minecraft 反編譯過後的源代碼,無形中已經侵犯了 Mojang 的版權;更搞笑的是,Bukkit 計劃採用的是 GPL 協議!一個開源計劃裡卻包含了反編譯過的商業代碼,這一點本身能夠不被大眾口誅筆伐實屬幸運。

Mojang 當然知道 Bukkit 計劃是怎麼回事,不過他們對這些第三方服務器端也就是睜一隻眼閉一隻眼,只要你不把 Minecraft 重新打包一次就拿出去賣,你改成 Q 塊世界我也不管你。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

我知道你們還沒完全消化這幾段的內容 (o´Д`)=з 但敬請記住這幾個關鍵詞吧:Bukkit 衰落、收費氾濫和版權糾紛。

因為故事要進入高潮階段了。

長文:Minecraft 的多人遊戲是如何發展起來的?(一)

淡定,淡定

(待續……)


分享到:


相關文章: