Grid系統概述

目錄

概念及功能

網格對象(Grid Object) 和世界對象(World Object)

工作流程


  • 概念及功能

    TrinityCore 的 Grid 系統是一套復雜的地圖分區管理機制,其核心目標是通過動態管控游戲世界的區域狀態和對象生命周期,在保證玩家體驗的同時最大化服務器性能。它具有以下功能:

    • 地圖劃分與定位
      TrinityCore 將每一張地圖(Map)都劃分成 64*64 的小方塊,即網格(Grid),每個 Grid 的大小是 533.33 碼。網格的坐標從右下角 (0,0) 到左上角 (63,63),以 (32,32) 為中心點。這種劃分方式便于服務器和客戶端對地圖進行管理和定位,例如可以在GM模式下使用 “.go grid 48,18” 類似命令跳到當前地圖編號為 (48,18) 的格子。

    • 資源加載與卸載
      客戶端和服務端均按 Grid 為單位進行地圖資源的加載和卸載。當角色在地圖中移動時,客戶端只加載角色附近的 Grid,當角色走到一個 Grid 邊界時,再新加載相鄰的 Grid,同時卸載遠離角色的 Grid,從而有效控制內存占用。服務端也是如此,只有當某個 Grid 有角色進入時,才會將其標記為活躍狀態,加載其中的動態信息,如怪物、NPC、礦點等;當 Grid 內沒有活躍角色且超過一定時間后,會將其標記為不活躍狀態,卸載其中的動態對象,回收 Grid。

    • 對象管理
      Grid 用于管理其中的各種對象,包括網格對象(grid object)和世界對象(world object)。Grid 類提供了一系列方法來插入、移除和統計這些對象,如add_grid_object方法用于將一個對象插入到網格中,get_world_object_countingrid方法用于獲取網格中世界對象的數量。

    • 尋路支持
      Grid 與尋路功能相關,TrinityCore 可以利用導航網格(Grid)做尋路,通過 Detour 庫等實現角色在地圖上的路徑規劃,確保角色能夠在網格劃分的地圖上順利找到目標位置。

  • 網格對象(Grid Object)世界對象(World Object)

    • 世界對象(World Object)
      是游戲世界中所有 “可交互實體” 的基類(WorldObject),代表游戲中具有獨立存在意義的實體,例如角色(Player)、NPC(Creature)、物品(Item)、動態物體(GameObject,如箱子、門)等。世界對象(World Object)是游戲邏輯的核心載體,擁有獨立的屬性(如位置、方向、狀態)和行為(如移動、戰斗、交互),并直接參與游戲玩法(如任務、戰斗、交易)。

      • 世界對象負責實現具體的游戲邏輯,例如:處理玩家輸入(移動、技能釋放),NPC 的 AI 行為(巡邏、攻擊、對話),物品的拾取、使用效果,碰撞檢測、交互判定(如點擊 NPC 觸發對話),等等。
      • 世界對象生命周期與實體本身綁定:例如玩家登錄時創建,下線時銷毀;NPC 被刷新時創建,被刪除(如死亡后消失)時銷毀。
      • 當世界對象(如角色移動)從一個 Grid 進入另一個 Grid 時,其對應的網格對象會從舊 Grid 移除,添加到新 Grid 中。
      • 世界對象在整個游戲世界中具有唯一標識(GUID),可被全局查詢和引用。

      • 世界對象是基類,派生類包括Corpse、Creature、DynamicObject、GameObjectPlayer、AreaTrigger、SceneObject、Conversation等,每個派生類都有獨特的屬性和方法(如Player有背包系統,Creature有 AI 組件)。

    • 網格對象(Grid Object)
      是與 Grid 網格綁定的 “輔助管理對象”(GridObject),主要用于銜接世界對象與 Grid 系統,負責將世界對象 “錨定” 到具體的網格中,以便 Grid 系統對其進行定位、加載 / 卸載和區域管理。它更像是世界對象在 Grid 系統中的 “代理” 或 “索引”,本身不直接參與游戲邏輯,僅用于 Grid 內部的管理和查詢。

      • 網格對象主要服務于 Grid 系統的管理需求,例如:記錄世界對象在 Grid 中的位置偏移,輔助 Grid 快速定位實體;作為 Grid 內部的 “容器項”,參與 Grid 的對象列表維護(如添加、移除、遍歷);觸發 Grid 的狀態變化(如當 Grid 中首個世界對象進入時,標記 Grid 為 “活躍” 并加載資源)。
      • 網格對象生命周期與 Grid 綁定:當一個世界對象進入某個 Grid 時,Grid 會為其創建對應的網格對象;當世界對象離開 Grid 或 Grid 被卸載時,網格對象會被銷毀。
      • 網格對象僅存在于所屬 Grid 中:每個網格對象嚴格屬于一個 Grid,用于在該 Grid 內標記世界對象的存在,方便 Grid 快速定位其中的所有實體。
      • 網格對象是模板類(GridObject<T>),其中T通常是WorldObject的派生類(如GridObject<Creature>),它內部持有一個指向對應世界對象的指針,實現 Grid 與世界對象的關聯。
  • 工作流程

????????工作流程分為初始化與地圖劃分、Grid 激活與對象加載、活躍狀態管理、Grid 失活與資源回收四個階段,各階段緊密銜接,形成完整的閉環邏輯。

????????一、初始化與地圖劃分:構建 Grid 的 “骨架”

????????Grid 系統的工作從地圖(Map)加載開始,當服務器啟動或角色首次進入某張地圖時,系統會先完成 Grid 的基礎構建:

  1. 地圖元數據加載
    從數據庫(如map表)和地圖資源文件(.adt等)中讀取地圖的基礎信息,包括地圖 ID、尺寸、地形數據等。每張地圖被視為一個獨立的 “世界區域”,由Map類實例管理。

  2. Grid 網格劃分
    按照固定規則將地圖劃分為64×64 的 Grid 網格(共 4096 個 Grid),每個 Grid 的物理尺寸為 533.33 碼(約 133.33 游戲單位)。網格坐標以地圖右下角為原點 (0,0),左上角為 (63,63),形成類似二維數組的索引體系(如 Grid (10,20) 代表第 10 列、第 20 行的網格)。

  3. Grid 基礎實例化
    為每個 Grid 創建基礎實例(Grid類對象),此時的 Grid 僅包含坐標信息和空的對象列表,處于 **“未初始化” 狀態 **(不加載任何世界對象,僅作為占位符存在)。這些 Grid 由GridManager統一管理,通過地圖 ID+Grid 坐標可快速定位。

????????二、Grid 激活與對象加載:從 “休眠” 到 “活躍”

????????Grid 默認處于 “休眠” 狀態,僅當需要響應用戶交互時才被激活。“有玩家角色進入” 是觸發 Grid 激活的核心條件

  1. 玩家位置檢測
    當角色(Player對象)通過移動、傳送、復活等方式進入某 Grid 時,系統通過角色坐標計算其所在的 Grid 坐標(如通過Map::GetGridX()Map::GetGridY()方法),并檢查該 Grid 的當前狀態。

  2. Grid 狀態切換:從非活躍到活躍

    • 若 Grid 處于 “非活躍狀態”(無玩家且未加載對象),系統會將其標記為 “活躍狀態”(Active),并觸發Grid::Activate()方法。
    • 激活時,Grid 會向Map模塊注冊自身,加入 “活躍 Grid 列表”,以便后續接收定期更新(如每 100ms 一次的邏輯幀更新)。
  3. 世界對象加載
    激活后,Grid 開始加載其內 “應存在” 的世界對象(WorldObject)。

    • 查詢數據源:根據地圖 ID 和 Grid 坐標,從數據庫(如creaturegameobject表)查詢該 Grid 內的靜態對象(如固定刷新的 NPC、門、礦點)和動態對象(如任務觸發的怪物)。
    • 實例化對象:根據查詢結果,創建對應的世界對象實例(如CreatureGameObject),初始化其屬性(位置、方向、狀態、AI 腳本等)。
    • 綁定網格對象(GridObject):為每個世界對象創建對應的GridObject(網格對象),作為其在 Grid 中的 “代理”,并將GridObject添加到 Grid 的對象列表(Grid::m_objects)中。
    • 通知周邊系統:對象加載完成后,通知視野管理模塊(讓附近玩家可見)、AI 系統(啟動 NPC 巡邏 / 戰斗邏輯)、事件系統(注冊交互事件,如點擊 NPC 觸發對話)。

????????三、活躍狀態管理:維持對象交互與更新

????????Grid 處于活躍狀態時,核心任務是實時管理其內對象的狀態和交互,確保游戲邏輯正常運行,主要包括以下操作:

  1. 定期邏輯更新
    Grid 會隨服務器的邏輯幀(通常每 100ms 一次)執行Grid::Update()方法,完成:

    • 對象狀態同步:更新世界對象的位置、血量、狀態(如 NPC 的巡邏路徑進展、GameObject 的開關狀態)。
    • AI 與行為驅動:觸發 NPC 的 AI 邏輯(如檢測玩家進入仇恨范圍、執行技能)、物品的定時消失(如掉落的裝備過期)。
    • 事件檢測:檢查對象間的交互(如玩家點擊門、拾取物品),觸發對應的游戲事件(如任務進度更新、成就解鎖)。
  2. 對象跨 Grid 移動處理
    當世界對象(如玩家、移動的 NPC)從當前 Grid 進入相鄰 Grid 時,觸發對象轉移流程

    • 舊 Grid 移除對象:原 Grid 通過Grid::RemoveObject()方法,將對象的GridObject從自身列表中移除,并通知舊 Grid(若此時舊 Grid 內無玩家,開始失活倒計時)。
    • 新 Grid 添加對象:新 Grid 檢測到角色進入后,若自身處于非活躍狀態則立即激活,然后通過Grid::AddObject()方法創建新的GridObject,將對象納入管理,并同步其狀態到新 Grid 及周邊系統。
  3. 動態對象生成與銷毀
    對于臨時產生的對象(如玩家召喚的寵物、技能創建的幻象、任務觸發的怪物),Grid 會在其生成時立即創建GridObject并納入管理;當對象過期(如寵物消失、幻象時間結束)或被銷毀(如怪物被擊殺)時,Grid 會移除其GridObject并回收內存。

????????四、Grid 失活與資源回收:從 “活躍” 到 “休眠”

??????? 當 Grid 內不再有角色活動時,系統會逐步卸載資源,釋放服務器內存和 CPU 占用。

  1. 失活觸發條件

    • 所有角色離開該 Grid(如移動到其他 Grid、下線、傳送);
    • Grid 內無角色的時間超過閾值(默認約 5 分鐘,可通過配置調整)。
      滿足條件后,Grid 被標記為 “待失活狀態”,觸發Grid::Deactivate()方法。
  2. 對象篩選與卸載
    Grid 會先篩選可卸載的對象,保留必要數據:

    • 不可卸載對象:角色(Player)本身不會隨 Grid 失活卸載(其生命周期與登錄狀態綁定);帶有 “永久保存” 標記的對象(如玩家放置的營地)會保留狀態。
    • 可卸載對象:大部分 NPC、GameObject、臨時物品等,會先將狀態同步到數據庫(如 NPC 的刷新時間、已打開的箱子狀態),然后銷毀其實例和對應的GridObject
  3. Grid 資源回收

    • 清空 Grid 的對象列表,釋放與對象相關的臨時數據(如視野緩存、AI 狀態)。
    • Grid 從 “活躍 Grid 列表” 中移除,回到 “非活躍狀態”,僅保留基礎坐標信息,進入 “休眠”。
    • 若后續有角色再次進入該 Grid,重復 “激活→加載” 流程。

????????五、特殊場景的補充處理

????????Grid 系統針對特殊需求做了優化,確保極端場景下的穩定性:

  • 強制激活 / 失活:GM 可通過指令(如.go grid.grid activate)強制激活某 Grid,用于調試或事件觸發;也可強制失活 Grid 以快速釋放資源。
  • 超大對象處理:對于跨多個 Grid 的大型對象(如團隊副本的 Boss 場地),系統會將其關聯到多個 Grid,確保在任何相關 Grid 激活時都能正確加載。
  • 動態地圖(如副本):副本地圖的 Grid 生命周期與副本實例綁定,當副本內所有玩家離開并超過超時時間后,整個副本的 Grid 系統會被徹底銷毀,而非僅失活。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/93560.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/93560.shtml
英文地址,請注明出處:http://en.pswp.cn/web/93560.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一文搞懂LLM大模型!LLM從入門到精通萬字長文(2024.12月最新)

LLM從入門到精通精品文章 目錄 一、LLM基本概念 二、LLM發展歷程 三、LLM大模型的分類 四、LLM主流大模型類別 五、LLM大模型建立的流程 六、Fine-Tuning 七、Prompt-Tuning 八、超大規模參數模型Prompt-Tuning方法 8.1上下文學習 In-Context Learning 8.2.指令學習 …

Next.js跟React關系(Next.js是基于React庫的全棧框架)(文件系統路由、服務端渲染SSR、靜態生成SSG、增量靜態再生ISR、API路由)

文章目錄**1. React 是基礎&#xff0c;Next.js 是擴展****2. Next.js 解決了 React 的哪些痛點&#xff1f;****3. 核心區別****4. Next.js 的核心特性**1. **文件系統路由**2. **服務端渲染&#xff08;SSR&#xff09;**3. **靜態生成&#xff08;SSG&#xff09;**4. **增量…

Nightingale源碼Linux進行跨平臺編譯

最近使用Nightingale 需要實現對服務的監測&#xff0c;想要在Windows 系統中使用&#xff0c;看官方文檔中并不直接提供執行程序&#xff0c;原文如下&#xff1a; 準備工作 本地環境 本地已經安裝git 本地安裝git 便于后續下載源碼并進行自動編譯。 Linux操作系統環境&…

抽絲剝繭丨PostgreSQL 系國產數據庫%SYS CPU newfstatat() high 調優一例(二)

續接上回《PostgreSQL 系國產數據庫%SYS CPU newfstatat() high 調優一例&#xff08;一&#xff09;》&#xff0c;這個問題還在持續&#xff0c;并且原因并不只是一個&#xff0c;從調了文件系統級atime&#xff0c;到調整wal size減少日志被動清理&#xff0c;還有在驗證tem…

【新手入門】Android Studio 項目結構拆解,快速理解文件作用!

目 錄 一、【Project】視圖下項目結構&#xff08;真實目錄&#xff09; 二、【Android】視圖下項目結構 三、【app/】下重要文件解析 1、 build.gradle 2、AndroidManifest.xml 3、res/ 作為剛剛接觸Android開發的小白&#xff0c;使用Android Studio創建項目后&…

Python實現點云Kmeans、歐式和DBSCAN聚類

本節我們分享點云處理中的三種常見聚類方法&#xff0c;分別是K-means、歐氏與 DBSCAN聚類。具體介紹如下&#xff1a;1. K-means 聚類定義&#xff1a;一種基于距離度量的無監督學習算法&#xff0c;將數據劃分為 K 個緊湊的簇&#xff0c;使簇內數據相似度高、簇間差異大。算…

【Java后端】MyBatis-Plus 原理解析

MyBatis-Plus 原理解析 其實 MyBatis-Plus 的 Service 層設計就是為了讓開發者不用重復寫很多樣板代碼。我們來一點點剖析 UserServiceImpl、IService、UserService、ServiceImpl 之間的關系和調用鏈。1. 類/接口關系圖IService<T>▲│UserService (接口) <-- 自定義…

Nacos 注冊中心學習筆記

&#x1f389; Alibaba微服務組件 Nacos 注冊中心超詳細學習筆記 &#x1f389; &#x1f4cc; 寫在前面&#xff1a;本文基于官方PDF文檔與實戰經驗&#xff0c;整理了Nacos注冊中心的核心知識點、部署流程與實戰技巧&#xff0c;力求圖文并茂、通俗易懂&#xff0c;適合收藏反…

java 策略模式 demo

策略模式介紹策略模式&#xff08;Strategy Pattern&#xff09;是一種行為型設計模式&#xff0c;它定義了一系列算法&#xff0c;將每個算法封裝起來并使它們可相互替換。策略模式讓算法的變化獨立于使用算法的客戶端&#xff0c;從而實現靈活的算法切換。核心角色&#xff1…

SAP Valuation Category在制造業成本核算中的使用場景與配置方案

Valuation Category在制造業成本核算中的使用場景與配置方案一、核心使用場景&#xff08;制造業特有&#xff09;1. 內制 vs 外購成本分離業務需求&#xff1a;同一物料可能通過內部生產&#xff08;成本含料工費&#xff09;或外部采購&#xff08;成本含采購價運費&#xff…

我的 LeetCode 日記:Day 36 - 動態規劃,背包問題的千變萬化

昨天&#xff0c;我初步掌握了 0/1 背包問題的理論基礎和標準解法。今天&#xff0c;我將這種思想應用到了更廣泛的場景中。今天的幾道題&#xff0c;乍一看和背包沒什么關系&#xff0c;但通過巧妙的數學轉化&#xff0c;它們的核心都變成了 0/1 背包問題。 這讓我深刻體會到…

本地處理不上傳!隱私安全的PDF轉換解決方案

PDF能鎖定排版、字體、圖片位置&#xff0c;無論在什么設備打開都保持一致。它是無廣告、簡潔高效的專業PDF處理工具。功能豐富&#xff0c;支持批量操作&#xff1a;只需將文件拖入界面&#xff0c;選擇目標格式&#xff08;如Word、PPT、Excel、圖片等&#xff09;&#xff0…

Docker build創建鏡像命令入門教程

一、核心概念Dockerfile 定義鏡像構建步驟的文本文件&#xff0c;包含一系列指令和配置&#xff0c;用于自動化創建鏡像。鏡像層&#xff08;Layer&#xff09; Docker 鏡像由多層只讀層疊加而成&#xff0c;每個指令&#xff08;如 RUN、COPY&#xff09;會生成一個新的層。層…

Redis 是單線程模型嗎?

最近在面試中經常被問到這個問題&#xff1a;"Redis是單線程的嗎&#xff1f;"很多同學都會脫口而出&#xff1a;"是的&#xff01;"但其實這個答案并不完全正確。今天我們就來聊聊Redis的線程模型&#xff0c;把這個問題徹底搞清楚。 先說結論 Redis的線程…

Hologres實戰:路徑分析函數

前言 Hologres提供了一套高效的路徑分析函數&#xff0c;包括路徑明細計算和結果解析功能&#xff0c;能夠幫助用戶深入理解用戶行為路徑&#xff0c;并通過桑基圖實現數據可視化。 一、核心功能 路徑明細計算&#xff1a;精確記錄用戶在產品或功能中的完整訪問路徑結果解析…

產品開發實踐(常見的軟硬結合方式)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】前面說過&#xff0c;傳統的純軟件開發&#xff0c;在國內的大背景下面是很難存活的。但是如果是把軟件&#xff0c;構建在硬件基礎之上&#xff0c…

Linux | i.MX6ULL網絡通信-套字節 UDP(第十八章)

01 Linux | i.MX6ULL網絡通信-套字節 TCP(第十七章) 02 iTOP-IMX6ULL 實現基于 UDP 的 socket 編程。

學習嵌入式第三十天

文章目錄進程和線程&#xff08;續&#xff09;線程1.線程傳參2.線程屬性3.線程間通信1.概念2.方式3.互斥鎖4.死鎖5.信號量習題 進程和線程&#xff08;續&#xff09; 線程 1.線程傳參使用第四個參數實現對線程內部的傳參 代碼實現&#xff1a; #include <stdio.h> #inc…

GaussDB 數據庫架構師修煉(十三)安全管理(3)-行級訪問控制

1 背景行級訪問控制特性將數據庫的訪問控制精確到數據表行級別 &#xff0c;只允許用戶查看 、更新或刪除特定的行數據。2 實例場景實例以醫生只能看到治療的病人&#xff0c;不能看其它醫生的病人為例&#xff1a;1)醫院病人的信息表pat_info&#xff1a;csdn> set search_…

Wi-Fi 與蜂窩網絡(手機網絡)的核心區別,以及 Wi-Fi 技術未來的發展方向

在日常生活中&#xff0c;我們既離不開家里的 Wi-Fi&#xff0c;也離不開手機的 4G/5G 網絡。它們都能把我們連接到互聯網&#xff0c;但底層的工作方式卻大不相同。一、設計初衷的不同Wi-Fi誕生于 1997 年的 IEEE 802.11 標準&#xff0c;定位是局域網無線替代。它的目標是讓電…