[閒聊] 關於武防精鍊的做法評估

看板mud作者 (揮淚斬馬雲)時間4年前 (2020/05/21 11:15), 4年前編輯推噓3(303)
留言6則, 4人參與, 4年前最新討論串1/1
灌個水。(真物理灌水,咕嚕咕嚕... sanc 還沒真正實裝這個東西,想說來研究看看,或許打著打著, sanc 那邊就給它實裝了也說不定。 在部份 mud,玩家資料檔的 obj_data 欄位可以做如下儲存: obj_data ([ "/weapon/lodoos/sword1#123456":(["improve_lv":5, ...]), . . ]) 也就是以物品的檔名做為 key 值,後面接這個物品的額外儲存資 料,當玩家 login 時,依照 key 值 clone_object 物品出來的 同時,再做以下的動作: ob=clone_object(files); foreach(str in keys(obj_data[files])) ob->set(str,obj_data[files][str]); 例如把上述的 improve_lv 值 5 設定到該 clone_object 出來的 物品上面,再把該物品 move 到玩家身上。 這類關於額外儲存的資料,需滿足以下條件: 一、最少設定(儲存)項目 二、最簡設定(儲存)原則 比方也有人是用 refine 做為精鍊的意思,我個人的評估思維是, 如果指令敲起來好敲(refine蠻好敲的),意思也有點兒到了,長度 沒有很長....這裡的長度指的是 refine_lv 精鍊等級 refine_stat 精鍊所提升的屬性質 . . 做為儲存欄位來說看起來還 ok,那我多半就會用了。 那首先就 refine_lv 即精鍊等級來說,像 RO 可以精練到 1x 等 ,而且是武器防具都可以,而且還有套裝及插卡方面的設定,還會 有依精鍊值做額外屬性加成的設定,因此我會一併考慮精鍊是否額 外儲存 refine_stat 的問題。 我的思維是,假設做額外儲存,那直覺上會有幾個問題: 1.如果我改變精鍊規則,我很難去更動之前已被玩家精鍊的物品 2.若不存這個欄位,我怎麼解決載入時的 loading 問題 3.我將來要怎麼去統一管理這些已經被精鍊的物品的refine_stat 儲存值 1 的部份就是說,比方我原先訂 +1 就是該武防各屬性 +5,那後來 我覺得 +5 太多了想改 +3 時,玩家之前已精鍊的東西我就得做額 外的處理(把那些 +5 改成 +3)。 而既然以後可能會有這個問題,那還不如在 loading 時就處理: ob=clone_object(files); foreach(str in keys(obj_data[files])) { ob->set(str,obj_data[files][str]); switch(str) { case "refine_lv": lv=obj_data[files][str]; ob->set("refine_stat",lv*5); . . 上面的意思就是說我只儲存 refine_lv,而當玩家登入時,我再依該 物品的 refine_lv 值,來設定 refine_stat 的值是多少;玩家save 或是把該物品儲放進倉庫時,只存 refine_lv 不存 refine_stat,也 就是上述的最少設定(儲存)項目,而上面的 switch..case.. 用來做 為額外的處理。 那麼 coding 常遇到的情況就是 當我們儲存的項目越多時 就可以減少很多額外的處理 當我們儲存的項目很少時 就需要很多其它額外的處理 例如我們只單存一個 refine_lv 時,就可以想見在很多地方都需要先 讀取出這個值,然後再做額外的運算來得到其它我們想要的東西,例 如 refine_stat、refine_name、.... 等等。 通常根據均值定理,可得出一個適當的儲存項目數量,使得儲存的項 目不至於過多,且不會增加很多需做的額外處理。 但是根據經驗,其實還有另一種做法,就是 RO 所採取的額外描述法 例如 RO 的蛇披,它的 Special DEX 部份是這麼說的 https://upload.8591.com.tw/ware/201905/1557133186868273AY.png
Dex+1 精鍊值+8時Dex+3 當精鍊值+9時MATK+1% 當精練值+12時ASPD+1,固定詠唱時間-7% 也就是說,玩家登入或從倉庫拿出此物品時,只載入 refine_lv 的設 定值,但是當玩家做 wear 或 wield 時,才做以下的動作: lv=ob->query("refine_lv"); switch(lv) { case 1..7: ob->add("stat/dex",1); case 8 : ob->add("stat/dex",3); . . } 而其它時候,比方玩家 view 該物品時,只會看到上面的「描述」,以 及該物品的精鍊值,既然玩家只有在做 wear 及 wield 時,該精鍊值才 會有作用,那自然只需在玩家 wear 及 wield 時做相關的處理就好。 我相信 RO 也是這樣做的,所以它們才會規定物品在手持或穿戴時無法 精鍊,必須先脫下來才行。 因此理論上,只儲存 refine_lv 值應該是可以的。 而這可以帶來幾個好處: 一、refine_lv 這個儲存欄位的變動性不高,應該確定就是這個欄位, 連同精鍊指令也可以順便定為 refine。 二、之後可以只先處理 wield/wear 指令,馬上就能進行相關測試,例 如穿脫時的玩家屬性變化、quit/login 時是否正常載入等。 三、再之後才是其它與觀看該物品相關的指令,例如 inventory、look 、view、auc、.....等。 精鍊名稱的部份,最直覺是以下的顯示: +0時: 羅德斯長劍(lodoos sword) +9時: +9羅德斯長劍(lodoos sword) 然後最優先考量是戰鬥時,是否希望+9出現: 你以手中的羅德斯長劍刺向小麻雀 你以手中的+9羅德斯長劍刺向小麻雀 看起來好像讓 +9 出現也不錯?當然這與各家 mud 風格有關且因人而 異。 其它的話問題就小一點,如果希望到處都能帶 +9,那麼在載入時就做 處理是比較好的: foreach(str in keys(obj_data[files])) { ob->set(str,obj_data[files][str]); switch(str) { case "refine_lv": lv=obj_data[files][str]; if(lv>0) { shorts=ob->query("short"); ob->set("short",sprintf(HIG"+%d"NOR"%-s",lv,shorts)); . . 這樣它就到處帶 +9 時,那萬一玩家將 +9 精鍊成 +10 呢,也很簡單 因為它格式是固定的: shorts=ob->query("short"); lv=ob->query("refine_lv"); shorts=replace_string(shorts,"+"+lv,"+"+(lv+1)); 因為 +n 這個東西在物品的 short 只會出現在精鍊識別名稱區塊,平 常不可能有精鍊值為 0 的物品,其名稱會帶 +n 的,就容易做名稱上 的取代。 有時間再打點別的回在下篇。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.33.66.104 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/mud/M.1590030949.A.FC2.html ※ 編輯: laechan (114.33.66.104 臺灣), 05/21/2020 11:16:04 ※ laechan:轉錄至看板 mud_sanc 05/21 11:16 ※ 編輯: laechan (114.33.66.104 臺灣), 05/21/2020 11:19:21

05/21 12:20, 4年前 , 1F
感謝發文 !!
05/21 12:20, 1F

05/22 09:44, 4年前 , 2F
幻世的寶石系統也類似作法 clone_object()
05/22 09:44, 2F
每個 mud 有每個 mud 的風格,設定也因人而異,出發點都差不多, 過程則會在各種思維及考量下而迥異,但只要弄出來的東西都是可以 work 的就行了,特別是2020的現在,隨便弄一台server功能都數倍 於以前,目前比較不需要考量很多(我主要是已經習慣了)。 ※ 編輯: laechan (114.33.66.104 臺灣), 05/22/2020 10:53:54

05/22 15:38, 4年前 , 3F
感謝分享思路
05/22 15:38, 3F

05/22 17:51, 4年前 , 4F
我那邊是 int wear(){ if( ::wear() ){ ....
05/22 17:51, 4F

05/22 18:03, 4年前 , 5F
我寫過精練,是屬於你外部儲存,如果要修改已經精練的
05/22 18:03, 5F

05/22 18:05, 4年前 , 6F
再read_file()單一檔案,取代refine_state對我較簡單
05/22 18:05, 6F
文章代碼(AID): #1UnV9b_2 (mud)