listen - MUD Game

Oliver avatar
By Oliver
at 2019-07-27T18:16

Table of Contents

這個是我最近接觸音遊後(6/2 起),覺得可以寫進 mud 的東西。

它的 demo 類似底下影片
https://www.youtube.com/watch?v=5zYmrBORZKs

以 mud 來說,就類似在一座城鎮裡頭,的某一個房間,裡面會看
到兩隻 npc 在做交談的動作,我的想法是:

道具店
這裡是位於城鎮中心,噴水池廣場旁的的一間小小的道具店,
裡頭販售著一些好用的東西,可以來看看喔(list)。

明顯出口有: south.

(listen)兩位村民正在這裡交談著。
>

我希望玩家看到這樣的畫面,會想下 listen 指令,下了之後,
會看到如下的畫面呈現

> listen
冒險者A: 聽說這裡有賣小鎮地圖,我們進去看看好不好
冒險者B: 有需要買嗎, 你不是早就把地圖都背下來了?
冒險者A: 就買來研究看看咩,說不定會發現什麼隱藏入口
冒險者B: 厚~ 有那種東西的話早就一傳十、十傳百了
冒險者A: 不管, 我就是要買......什麼! 一張地圖要5000!?
冒險者B: 你今天才知道喔? =.=

[ 你獲得了 0.1% 的經驗值。 ]


那上面要怎麼寫呢?


首先,跟道具店這樣的房間有關的對話,假設都儲存在一個叫
grocery.o 的物件儲存檔內,那麼它的格式就類似底下

mapping talks=([
"一個適當的key名":@LONG
冒險者A: 聽說這裡有賣小鎮地圖,我們進去看看好不好
冒險者B: 有需要買嗎, 你不是早就把地圖都背下來了?
冒險者A: 就買來研究看看咩,說不定會發現什麼隱藏入口
冒險者B: 厚~ 有那種東西的話早就一傳十、十傳百了
冒險者A: 不管, 我就是要買......什麼! 一張地圖要5000!?
冒險者B: 你今天才知道喔? =.=
LONG
,
.
.
]);

(資料不是透過宣告建立的,真正只有一行宣告 mapping talks)

之所以使用 mapping 而不使用 array,是因為這樣要做對話資
料的指定動作(比方刪除),會比較方便而且精確。

我目前是以 time() 的字串( ""+time() )當 key 名,當我這樣
做的時候,在 mud 內透過指令去編輯對話資料,按 . 儲存時,
就能以儲存當下的 ""+time() 做為 key 名,甚少會發生 key名
重覆的情況,還能依 key 名看出建立的時間。

從這裡來逆推,建資料的指令可以這樣寫

> listen -log grocery
請開始編輯, 按 ~q 離開, 按 . 結束
===================================================


後面指定 grocery,它就會將編好的東西假設叫 talk_str:

if(ob=find_object(TALK_DIR+"grocery"))
ob->log_talks(talk_str);

而 log_talks 的函數大致長這樣

int log_talks(string str)
{
string times=""+time();

// 如果真的有重覆 key 就不儲存
if(!undefinedp(talks[times])) return 1;

talks[times]=str;

save_object(TALK_DIR+"grocery");
return 1;
}

這樣就能儲存對話資料。

那現在假設我們儲存了很多筆 grocery 這類房間可以用的對話
,那很自然的會寫提取對話的指令,其提取到的對話是隨機的,
那可以這樣寫

// user = 下指令的玩家
void listen_talks(object user)
{
int r,s;
mixed tmps=({});

if(!user) return 1;

tmps=keys(talks);
s=sizeof(tmps);
r=random(s);

// 依分行符號 \n 將字串拆成陣列 tmps
tmps=explode(talks[tmps[r]],"\n");

call_out("dump_talks",1,user,tmps,0,s);
return ;
}

void dump_talks(object user,mixed tmps,int i,int s)
{
if(!env) return ;
tell_object(user,tmps[i]);

i=i+1;
if(i>s) // 代表對話結束
{
i=user->query("exp_up");
user->add_exp(i/1000); // 0.1%
tell_object(user,HIW"[ 你獲得了 0.1% 的經驗值. ]"NOR"\n");
return ;
}

// loop call_out
call_out("dump_talks",1,env,tmps,i,s);

return ;
}



以上是這東西的簡單寫法,給 sanc 用的部份我已經寫得差不多
了,預計八月就會正式實裝,只是我不是用 call_out,而是用
我以前提過的 times_check 系統,就是用 heart_beat 心跳的
方式。

各家寫法不同很正常,這沒有說一定要怎麼寫。

sanc 的 listen 指令實際說明長底下這樣

listen 指令語法:
============================================================
listen -export 房間檔->資料檔的指向列表
listen -add 房間檔 = 資料檔 設定房間檔指向特定資料檔
listen -del 房間檔 刪除房間檔的指向設定
listen -check 房間檔or資料檔 列出資料指向設定狀況

listen -log 資料檔 儲存某一資料檔的對話資料
listen -here 資料檔 儲存某一資料檔的此地限定對話
listen -clean 資料檔 編號 清除某一資料檔的對話資料
listen -list 資料檔 列出某一資料檔的對話資料
============================================================

上面都是給 wiz 使用的指令格式,玩家則只要下 listen 即可。



順便藉這個例子來說明,我想大家都同意,要把看到的什麼
東西,寫進 mud 裡頭,對於像我這種程度的 mud coder 來
說並不難,這樣的人很多。

但是對 coder 來說我覺得最頭痛的還是內容的擴充、擴充到
一定程度後的資料管理(增刪改)、以及後續如何不間斷地再
擴充其內容、..

內容才是重點。

我個人是先玩了音遊,然後覺得這東西可以寫進 sanc 裡面
,然後多年經驗下來,我第一優先思考的就是:

我有沒有能力及時間,建立足夠的資料量?

之後,我覺得我應該有能力及時間,那接著,我才開始寫這
個系統,包括儲存用物件、listen 指令等。

反之,如果我覺得我沒有這個能力,或是沒有這個時間,那
我就不會去寫,因為寫了也沒意義,它能 work 但是內容會
很貧乏。

那我評估「我可以」的其中一個依據,是網路上能找到很多
東西,基於 sanc 的開放性風格,很多找到的東西都能拿來
用,所以我預期資料量是不會太低的...大概。

然後我的想法是,只要對話是有內容的,那對話本身就不是
重點了,玩家固然會聽看看對話在說些啥,但重點仍會放在
聽完對話後能取得的東西上面,也就是說,只要先確保對話
是有內容的,然後這時對話就變成只是一個過程了,講白一
點今天就是要送玩家 0.1% 經驗值,但總是要透過一些機制
來給予,才會比較像是在玩遊戲。

那,可以將這種東西的遊戲性設計到什麼程度呢?

比方,我可以在一百則對話裡面,穿插一則重要的情報,例
如這座小鎮真的有一個隱藏出口存在,則玩家如果幸運地聽
到這則對話,他就有機會發現到這個隱藏出口。

(因為對話基本上是隨機的,不過,這同樣是各家寫法)


我想說的就是,搜集資料、消化資料(才能變成可用的東西)
、思考資料(夏天很容易想到腦袋發燒發熱)、....這些是很
煩人的,反過來說,這種事有其它人做,並且將我要的東西
依我要的格式(這裡的格式指的是"至少要對話六句"這種)提
供給我時,要建多少資料、或是要讓資料做怎樣的呈現,都
不會是問題。

分工的重要性,就在這個地方,最好 coder 跟非 coder 角
色要分開,各司其職。

校長兼撞鐘,開發效率一定差。


補充一下,除了 loop callout,還有另一種也算常見的寫法

for(i=1;i<=s;i++)
call_out("dump_talks",user,i,tmps[i-1]);

一次做 n 個 call_out 讓它們前後都差 1 秒的時間。


--
Tags: 線上

All Comments

Iris avatar
By Iris
at 2019-07-29T19:12
好文~ 推一個!
Skylar DavisLinda avatar
By Skylar DavisLinda
at 2019-07-31T20:08
讚,我也是看到什麼idea就會想實裝
Andrew avatar
By Andrew
at 2019-08-02T21:04
推!

兩位OW老設計師離開BZ

Rebecca avatar
By Rebecca
at 2019-07-27T16:34
https://i.imgur.com/7gkDOkq.jpg Jeremy Craig 參與BZ 10年 原本最早負責 BATTLE.NET 網路服務設計 擔任過OW的角色技能設計,包括拳王、碧姬、莫伊拉的這些設計 戰鬥動畫流暢,以及更新遊戲介面、等級設計等 2018 OWL也參與過整體視覺設計、制服 ...

Regina avatar
By Regina
at 2019-07-27T15:29
【07/28】闇影詩章ES大會 in 諾亞方舟益智遊戲 活動資訊 1030~1100 玩家報名 1100~1300 對戰時間 1300~1400 會外賽、小活動、頒獎及合照 活動人數上限:24人(活動滿八人開賽) 報名方式: 即日起至7月27日 2200 1. 在活動網頁中點擊報名 https:/ ...

無限制優勝

Megan avatar
By Megan
at 2019-07-27T13:56
最近被大學同學拉回來玩拿以前的資源 合了一副毒瘤剛剛運氣很好拿了5勝oand#39;_and#39;o 所以來分享一下 https://i.imgur.com/E8GRKJe.jpg https://i.imgur.com/K8ApPbq.jpg 5場分別打了2場主教 復仇 妖精 血鬼各1場 對上主教的 ...

OCP 2019 S2 Week 7 Day 2

John avatar
By John
at 2019-07-27T10:56
比賽時間 6/13 ~ 8/9 每周四 19:00 ~ 21:00 、每周六 11:00 ~ 13:00 直播網址 https://www.twitch.tv/overwatchzhtw (中) https://www.twitch.tv/overwatchcontenders (英) ...

7/23的更新 新職業

Jacky avatar
By Jacky
at 2019-07-27T10:05
※ 引述《millcassee (貝雅)》之銘言: : 超五任務 : 登入-5閃耀蕾米 : 4回黎明-哈林升級盒子 都是需求道具減少ˊˋ : 3回鳥背-鳥背升級盒子 : 1回超時空-超界升級 : 上面全清-活動附魔寶珠盒子+6鳥背票+100夏日硬幣 : 其餘說明不太重要...打就對了 兩隻都衝到95了 ...