創作內容

0 GP

Minecraft 研究日誌(2017年4月20日)

作者:無云│2017-04-20 21:15:35│巴幣:0│人氣:279
不知不覺距離上一次的Minecraft心情日記已經兩年多了, 時間過得真快.
回過頭來看看現今的Forge, 看得我又哭又愛的, 哭的是程式碼變動又一大步了(啊娘喂~快追不上了), 愛的是許多模組之間的相容性變得更好了.
Forge現在有了檔案更新檢查器的功能, 以前的模組作者都要自己另外寫一個檔案更新的方式, 現在不用了, 只要用Forge內建的更新檔案(json檔)方式去建構就能達到此功能.
能力系統(Capability System)這個東東是讓我最喜歡的部分, 它的出現讓許多模組作者不用去煩惱自己的模組要如何讓別人的模組來進行溝通存取, 只要模組作者們都採用這個架構去寫模組, 就不用像以前那樣子還要自己寫一個API提供其他模組作者來應用, 省事很多.

最近看了一下Forge的一些我還沒接觸的架構, 我發現之前寫的"私人時間"模組我無法更新了, 最後的1.8版所使用的程式架構到了 1.11版後, 變動太多, 很多以前我用的"手法"都被改掉了.
所以, 從 1.11 版起, 我要開始用「單一道具」的製作方式來製作模組, 這樣子可以避免遇上無法解決的問題時, 整個模組才不會因為卡在某幾個道具無法更新而整個放棄掉.

目前已開發了 4 個模組, 裡面都是只有一項道具或功能而已, 這對我日後要維修或更新也比較容易, 而且現在又有Forge更新器的加持, 我也不用煩惱"通知使用者更新"的問題.

模組一: 自動收集道具
這個道具在以前的"托羅斯"模組有寫過, 但以前的作法是將大範圍內所掉落的道具, 令它們用跳的方式來到玩家身邊, 以現在來看我覺得太OP了, 而"聖騎士之鎚"模組也是仿照它的作法來製作的.
現在我將這個"收集道具"的方式直接寫成固定式的, 不用任何道具, 只要玩家按一下開關即可控制運作(on/off), 而且限定吸取的範圍, 避免在多人模式下產生"偷拿"的情況.
我後來也額外增加"箭"的拾取方面, 讓原本不能撿的箭變成可以撿, 所以玩家如果缺箭的話, 找骷弓泡茶一下, 就能收集到滿滿的箭了.

模組二: 精煉加倍
雖然Minecraft到了1.11.2版, 對礦物生成方面也改善很多, 但我還是不滿足, 想要用漏斗製作大型儲物室需要很多的鐵錠, 而我又不想建造「煉鐵廠」, 所以就乾脆寫了這個模組.
這個模組運作非常簡單, 只要Minecraft內建的熔爐在冶煉時, 判斷該成品是否為模組設定的加倍對象, 如果是, 就將數量隨機增加, 就這麼簡單而已.

模組三: 填補機
這個道具在以前的"托羅斯"模組有寫過, 主要是用來將洞穴裡的空間給填滿, 這樣子在製作生怪塔時, 效率才會提升. 以前的作法是將一個立體四方形範圍直接一次填滿, 但這次的做法我考慮到電腦負荷大量資料的問題, 所以改採用「一層一層」的填滿, 並且將範圍修改為圓形, 也比較符合Minecraft的怪物偵測敵人的作法.
運作方式為, 當玩家放下此道具到世界時, 會馬上計算有多少個方塊需要填補, 但這個數值不是絕對的, 是概數而已. 當填補機接收到紅石動力後, 才會開啟運作, 沒有紅石動力就會停止運作, 每隔20秒計算一次大面積的填補作業, 玩家的電腦如果不夠力, 會看到畫面停頓一下, 那是正常的, 因為一次性填補量太多了.

模組四: 傳送站
這個道具在以前的"托羅斯"模組也有寫過, 但我回去看以前的程式碼, 發現我當時沒考慮到一點, 就是Chunk unload的問題, 以前的"時之旅"道具也是用通訊碼的方式來進行兩點之間的傳送, 但是, 如果在Chunk Unload後, 會發生找不到對應的傳送點, 因為World把TileEntity都卸載了, 所以就無法查到相對的傳送點在哪裡了.
後來, 我實際操作程式碼去研究了一下, 當Minecraft在chunk unload後, 並不是一定會將TileEntity的NBT進行儲存動作, NBT的存檔動作是由另一個機制去運作的, 例如我們按了ESC鍵回到遊戲選單主畫面時, 那時候都一定會有NBT儲存動作, 或許這在World的Save Data事件裡可以攔截得到, 但我不想用這方法, 如果用這方法是逼遊戲每次要儲存NBT就一定要做一次World Save Data的動作, 這對伺服器來說負載太多了, 尤其是傳送站越多時就會越明顯了.

為了改進這個缺點, 我想了兩種方式,
  • 第一種是將相對應的傳送點座標儲存在TileEntity裡, 用NBT的方式記錄下來.
  • 第二種是將相對應的傳送點座標儲存在外部資料檔.
而第一種方式會有個嚴重缺點, 當 Chunk unload 後, 還沒到達world save data的事件時, 處在該位置的TileEntity就不會儲存所設定的通訊碼, 這問題在單人模式下最為明顯.
  • 例如: A點(1,1), B點(256, 256)兩點相差很遠, 當玩家在A點時, 通訊碼設定為 123, 當玩家走到B點後(此時A點Chunk Unload), 通訊碼也設定為123, 這時候傳送站就無法起作用了, 因為找不到A點, 所以就算通訊碼一樣也是沒路用.
  • 再承上個例子, 當遊戲重新開啟後, 只會讀取靠近玩家限定範圍內的chunk, 在那些chunk裡如果有傳送站才會被讀取NBT資料, 假設玩家在B點, 因為重開遊戲後, A點沒有被載入(因為距離太遠), 這樣子B點也找不到相對應的A點了.
因為第一種方式無法滿足我的要求, 於是我採用第二種方式, 但這個方式也是有缺點的, 因為需要依賴外部資料檔的關係, 會變成資料檔的資料在輸出入方面都要很精準, 而且該資料檔不能毀損或遺失, 哪一方面出問題都會讓傳送站無法找到相對應的傳送站.
所以我的作法是:
  • 當玩家放下這個傳送站到世界後, 要立即輸入通訊碼, 這個TileEntity的NBT就會馬上儲存通訊碼和持有者名字, 並且馬上將資料額外儲存到外部資料檔, 並且將座標組相關資料儲存在模組變數裡.
  • 當玩家拆除這個傳送站時, 只需要將模組變數裡的這筆資料刪除即可, 然後再將整個模組變數寫入外部資料檔.
  • 當遊戲整個關閉又重開後, 在world的load事件裡做判斷, 如果模組變數裡是空的, 就將外部資料檔的內容讀進來放到模組變數, 這樣子玩家在靠近傳送站時, 傳送站就能讀取模組變數的資料來判斷相對應的傳送站在哪裡了.
當然, 這個方式或許還不是最穩定的做法, 將來我能發現更穩定的作法時, 我會另外改寫程式碼.

目前打算將Forge的能力系統搞懂後(希望...), 將"私人時間"模組的各道具抽離出來, 分別寫成單一模組, 這樣子日後我也方便更新版本或選擇不更新.

在製作模組的期間, 不斷的在網路爬文, 很幸運爬到一篇從以前我就一直很想做的事, 就是一個專案裡同時做好幾個模組, 而且可以分別編譯, 目前的這四個模組就是用這方法來製作的, 往後在專案管理方面也不會像以前那麼麻煩了.

我也稍微弄了一下GitHub這個東西, 以後會把更新的模組直接放到那個網站上, 而我自己的Google協作平台主要寫模組詳細的用法, 日後或許會增加一些技術文章.

只存放模組的空間 : Minecraft Mod Storage
我目前的主網頁: 無云屋の民間作品
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=3550514
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:Minecraft

留言共 1 篇留言

草莓龍♥
加油OAO
私人時間真的是很實用呢#
不比JABBA差XD

04-20 22:47

無云
3Q[e12]大家一起加油!04-20 23:02
我要留言提醒:您尚未登入,請先登入再留言

喜歡★unoya 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:Path Of Exil... 後一篇:Minecraft 研究...

追蹤私訊切換新版閱覽

作品資料夾

jason990505各位巴友
歡迎各位巴友來我小屋觀看小說及文章 或單純交流認識!看更多我要大聲說7小時前


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】