---
doc_id: "DOC-GDD-011"
title: "Hệ Thống NPC Hoang Dã, Cây Thoại & Trao Đổi Barter"
category: "game_design"
diataxis_type: "explanation"
status: "canonical"
version: "2026.1"
owner_role: "poe2_game_designer"
last_updated: "2026-09-29"
tags: ["npc-system", "dialogue-trees", "barter-exchange", "quest-binding"]
related_code:
  - "server/world/npc_engine.py"
  - "server/world/npc_catalog.py"
related_docs:
  - "docs/game_design/QUEST_SYSTEM_ARCHITECTURE.md"
summary: "State machine quản lý NPC, cây thoại phân nhánh theo tiến độ sinh tồn, tích hợp đổi chác Cổ Cốt không dùng vàng."
---

# TÀI LIỆU KIẾN TRÚC KỸ THUẬT: HỆ THỐNG NPC HOANG DÃ, CÂY HỘI THOẠI & LIÊN KẾT BẢN ĐỒ - NHIỆM VỤ SINH TỒN
# ARCHITECTURAL DESIGN RECORD (ADR) & TECHNICAL SPECIFICATION 2026
# ĐỊNH HƯỚNG: CỔ VÕ HOANG DÃ & HẮC ÁM LƯU ĐÀY (GRIMDARK SAVAGE PRIMAL EXILE ARPG - 100% POE2 SPIRIT)

> **Trạng thái**: APPROVED & FULLY IMPLEMENTED  
> **Chủ quản**: [Trưởng Ban Kiến Trúc Server](file:///c:/Projects/FreeExile/AGENTS.md) (`server_systems_architect`), [Trưởng Nhóm Thiết Kế Game](file:///c:/Projects/FreeExile/AGENTS.md) (`poe2_game_designer`), [Kiến Trúc Sư Tài Liệu](file:///c:/Projects/FreeExile/AGENTS.md) (`lead_documentation_architect`), [Trưởng Khối Bảo Mật CISO](file:///c:/Projects/FreeExile/AGENTS.md) (`security_anticheat_lead`).  
> **Module liên quan**: [server/world/npc_engine.py](file:///c:/Projects/FreeExile/server/world/npc_engine.py), [server/world/quest_engine.py](file:///c:/Projects/FreeExile/server/world/quest_engine.py), [server/world/zone_engine.py](file:///c:/Projects/FreeExile/server/world/zone_engine.py), [proto/npc.proto](file:///c:/Projects/FreeExile/proto/npc.proto), [tests/unit/test_npc_system.py](file:///c:/Projects/FreeExile/tests/unit/test_npc_system.py).

---

## 1. BỐI CẢNH & QUYẾT ĐỊNH KIẾN TRÚC (CONTEXT & ARCHITECTURAL DECISIONS)

### 1.1. Trục Xuất Hoàn Toàn Lối Mòn Tu Tiên (Xianxia Tropes Eviction)
Tuân thủ nghiêm ngặt chỉ đạo chiến lược của Studio:
- **Tuyệt Đối Cấm**: Các khái niệm tu tiên, tiên hiệp, đạo sĩ, tiên cô, đan điền, linh thạch, thiên đạo, phi thăng, đan dược trường sinh.
- **Tái Định Vị Tinh Thần**: **Cổ Võ Hoang Dã & Hắc Ám Lưu Đày (Grimdark Savage Primal Exile ARPG)**. Không gian thế giới là vùng đất chết rợn ngợp, bùn lầy, xác quái, xương thú, dã tính, bản năng sinh tồn man dại và tàn khốc (đậm chất *Path of Exile 2*).
- **Hình Tượng NPC**: Là những kẻ sống sót lưu đày (Outcasts, Savages, Bone-Carvers, Blood Smiths, Scavengers, Feral Trackers). Họ mang đầy sẹo chém, cụt tay ghép sọ thú, ánh mắt rực lửa khát máu, nói năng cộc lốc, thực dụng và tôn thờ quy luật kẻ mạnh.

### 1.2. Quyết Định Thiết Kế (Architectural Decisions)
Dự án `FreeExile` triển khai kiến trúc **Server-Authoritative Reactive Feral NPC Ecosystem**:
- **Tam Giác Tương Hỗ Khép Kín (Triple Interconnection)**:
  - **NPC $\leftrightarrow$ Bản Đồ ([ZoneEngine](file:///c:/Projects/FreeExile/server/world/zone_engine.py))**: NPC cắm chốt tại các phân vùng địa hình khắc nghiệt: Doanh Trại Vô Định (Outcast Camp), Vực Táng Kiếm đẫm máu (Bone-Cliff Chasm), Hố Chôn Tàn Binh (Ancient Barrow), Vô Định Bão Cát (Dune Desert). Hỗ trợ NPC dị biến chỉ hiện hình khi bão cát cuồng phong (`SANDSTORM`) hoặc chướng khí ngút trời (`MIASMA_TOXIC`).
  - **NPC $\leftrightarrow$ Nhiệm Vụ ([QuestEngine](file:///c:/Projects/FreeExile/server/world/quest_engine.py))**: Khế ước săn quái đoạt huyết tủy, róc xương lột da, rèn đúc vũ khí hoang dã. Hỗ trợ mục tiêu `TALK_NPC` và `DELIVER_TO_NPC`.
  - **Kỳ Duyên Đàm Đạo (Feral Serendipity Triggers)**: Không có dấu chấm hỏi/than màu vàng trên đầu. Chỉ khi người chơi chọn đúng nhánh đối thoại tàn sát hoặc dâng tế rượu máu, NPC mới hé lộ hố chôn cổ ma hay mật thất tàn tích (`HiddenTriggerType.NPC_DIALOGUE_CHOICE`, `NPC_GIFT_OFFERING`).
- **Nền Kinh Tế Barter Hoang Dã (Barter Economy Integration)**: Mọi dịch vụ NPC định giá qua **Huyết Hồn Thạch, Cổ Cốt Ấn, U Minh Cốt Đinh, Hắc Sơ Thạch, Uẩn Ma Thạch, Cổ Cốt Huyết Thạch**. Loại bỏ 100% tiền giấy giả mạo hay linh thạch hư ảo.
- **Thẩm Quyền Cự Ly Zero-Trust (Zero-Trust Anti-Cheat Distance Gate)**: Kiểm tra khoảng cách Euclid bắt buộc tại Game Server với sai số mạng $\epsilon = 0.5m$:
  
  $$\text{ValidInteraction}(P, N) \iff \begin{cases} P.\text{zone\_id} = N.\text{zone\_id} \\ \sqrt{(x_P - x_N)^2 + (y_P - y_N)^2} \le N.\text{interaction\_radius} + 0.5m \\ P.\text{level} \ge N.\text{required\_level} \end{cases}$$

---

## 2. KIẾN TRÚC TỔNG THỂ & SƠ ĐỒ ĐIỀU PHỐI (SYSTEM TOPOLOGY)

```mermaid
flowchart TD
    subgraph Client_Layer["CLIENT LAYER (iOS Metal & PWA Simulator)"]
        UI["HUD: Feral NPC Dialogue Box (Xương thú & Gai sắt gỉ)"]
        RADAR["Proximity Radar (Dò mùi máu & Tọa độ NPC)"]
        CHOICE["Survival Choice Buttons (Ngón tay >= 44pt)"]
    end

    subgraph Network_Gateway["GATEWAY PROTOCOL (proto/npc.proto)"]
        REQ_INT["InteractNpcRequest"]
        RESP_INT["InteractNpcResponse"]
        REQ_CHOICE["SelectDialogueChoiceRequest"]
        RESP_CHOICE["SelectDialogueChoiceResponse"]
    end

    subgraph Server_Authoritative["SERVER CORE (server/world/npc_engine.py)"]
        DISTANCE_GATE["Anti-Cheat Euclidean Distance Gate (d <= R + 0.5m)"]
        ROUTER["Adaptive Dialogue Router (Theo tiến độ Huyết Cốt)"]
        SESSION["PlayerDialogueSession Tracker"]
        DISPATCHER["Feral Service Dispatcher"]
    end

    subgraph Subsystems["HỆ THỐNG KẾT NỐI KHÉP KÍN"]
        ZONE["ZoneEngine (Tọa độ 2.5D, Bão cát dã ngoại, Mật thất cổ)"]
        QUEST["QuestEngine (Khế ước săn quái, Giao tế huyết nhục)"]
        VAULT["ConsignmentVault (Hắc Thị Hoang Vực 2PC)"]
        FORGE["ItemCraftingEngine (Rèn Cốt Thiết, Khảm Cổ Cốt Ấn)"]
    end

    RADAR --> REQ_INT
    CHOICE --> REQ_CHOICE
    REQ_INT --> DISTANCE_GATE
    REQ_CHOICE --> DISTANCE_GATE
    DISTANCE_GATE --> ZONE
    DISTANCE_GATE --> ROUTER
    ROUTER --> QUEST
    ROUTER --> SESSION
    SESSION --> DISPATCHER
    DISPATCHER --> QUEST
    DISPATCHER --> VAULT
    DISPATCHER --> FORGE
    DISPATCHER --> RESP_INT
    DISPATCHER --> RESP_CHOICE
    RESP_INT --> UI
    RESP_CHOICE --> UI
```

---

## 3. MÁY TRẠNG THÁI HỘI THOẠI THÍCH ỨNG (ADAPTIVE FSM)

Cây hội thoại của NPC phản ứng trực tiếp với tiến trình sinh tồn của người chơi trong [QuestEngine](file:///c:/Projects/FreeExile/server/world/quest_engine.py):

```mermaid
stateDiagram-v2
    [*] --> RESOLVE_ENTRY: Người chơi áp sát NPC (interact_with_npc)

    state RESOLVE_ENTRY {
        [*] --> CHECK_QUEST_STATE
        CHECK_QUEST_STATE --> COMPLETED_NODE: Thu thập đủ Huyết Tủy / Xác quái (COMPLETED)
        CHECK_QUEST_STATE --> IN_PROGRESS_NODE: Đang săn mồi dã ngoại (IN_PROGRESS)
        CHECK_QUEST_STATE --> CLAIMED_NODE: Đã nạp tàn cốt, xong việc (CLAIMED)
        CHECK_QUEST_STATE --> DEFAULT_ROOT_NODE: Chưa lập khế ước săn mồi
    }

    DEFAULT_ROOT_NODE --> LORE_NODE: Hỏi thăm vết sẹo / Bản năng sinh tồn
    DEFAULT_ROOT_NODE --> QUEST_OFFER_NODE: Tiếp nhận Tà Đao & Đi săn quái
    DEFAULT_ROOT_NODE --> SERENDIPITY_NODE: Đàm luận tàn sát bí truyền (Kỳ Duyên)

    QUEST_OFFER_NODE --> [*]: Nhận khế ước (accept_quest) & Rời đi
    COMPLETED_NODE --> REWARD_CLAIM_NODE: Nạp Huyết Tủy, nhận Hắc Sơ Thạch
    REWARD_CLAIM_NODE --> [*]: Đóng dấu hoàn tất (CLAIMED)
    SERENDIPITY_NODE --> [*]: Kích hoạt Nhiệm Vụ Ẩn Cổ Ma (trigger_hidden_quest)
```

---

## 4. MA TRẬN NHÂN VẬT HOANG DÃ ĐIỂN HÌNH (CANONICAL FERAL ROSTER)

Hệ thống NPC được bài trí theo phong cách sống còn hoang dã, phân bổ trên 5 đại địa bàn:

| Mã Định Danh | Tên NPC | Danh Hiệu / Thân Phận | Bản Đồ Trú Ngụ | Tọa Độ $(x, y)$ | Vai Trò Hoang Dã | Dịch Vụ Nghiệp Vụ Cung Cấp |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| `npc_doc_co_tan_kiem` | **Lão Độc Cốt** | Kẻ Gọt Xương Cụt Tay | `zone_tang_kiem_nhai` | $(60.0, 55.0)$ | `WAR_CHIEF` | • Dạy kẻ mới bị lưu đày cách chém giết<br/>• Trao thanh Tà Đao Mẻ đầu tiên<br/>• **Kỳ duyên đàm đạo**: Tiết lộ hố chôn tàn binh Cổ Ma |
| `npc_van_gioi_thuong_nhan` | **Gian Thương Cẩu Khấu** | Gian Thương Hắc Thị | `zone_boundless_sanctuary` | $(-25.0, 20.0)$ | `OUTCAST_SCAVENGER` | • Mở [Hắc Thị Hoang Vực](file:///c:/Projects/FreeExile/server/trade/consignment_vault.py) (2PC Vault)<br/>• Barter đổi Huyết Hồn Thạch, Cốt Đinh, phôi thô |
| `npc_thiet_tuong_au_da_tu` | **Thiết Tượng Huyết Đồ** | Thợ Rèn Cốt Thiết | `zone_boundless_sanctuary` | $(30.0, -20.0)$ | `BONE_BLACKSMITH` | • Đập đe nung máu đen dã thú<br/>• Rèn Cốt Thiết, dập U Minh Cốt Đinh, khảm Cổ Cốt Ấn |
| `npc_chan_vo_truyen_thua` | **Huyết Vu Bà Bà** | Trưởng Lão Tế Cốt | `zone_boundless_sanctuary` | $(0.0, 45.0)$ | `BLOOD_SHAMAN` | • Khơi thông Huyết Cốt Ma Đồ<br/>• Đánh thức Thú Tính & Dị Biến Cực Hạn bằng máu thú |
| `npc_bach_hieu_sinh` | **Bách Hiểu Sinh** | Kẻ Săn Tin Hắc Thị | `zone_boundless_sanctuary` | $(15.0, 15.0)$ | `FERAL_TRACKER` | • Cung cấp tin tức tàn sát & mùa Đại Nạn Hoang Vực<br/>• Bán manh mối hang ổ quái vật<br/>• Chỉ dẫn Thần Hành Trận |
| `npc_tieu_dau_lao_ma` | **Thợ Săn Lão Mã** | Trinh Sát Hoang Dã | `zone_tang_kiem_nhai` | $(220.0, 175.0)$ | `FERAL_TRACKER` | • Cảnh báo bầy Thi Cẩu đói thịt<br/>• Khai mở Thần Hành Trận Đỉnh Táng Kiếm Nhai |
| `npc_sa_mac_du_than` | **Cuồng Nhân Bão Cát** | Dị Biến Ẩn Sĩ | `zone_boundless_sandstorm` | $(180.0, 160.0)$ | `SAVAGE_HERMIT` | • **Hiện hình giữa bão cát** (`SANDSTORM`)<br/>• Nhận dâng tế Hỗn Nguyên Huyết Tửu (`DELIVER_TO_NPC`)<br/>• Rống mở Vòng Xoáy Hư Không vào Mật Thất Cổ Ma |

---

## 5. DIÁTAXIS FRAMEWORK IMPLEMENTATION GUIDE

### 5.1. Hướng Dẫn Nhập Môn (Tutorial): Tiếp Cận Lão Độc Cốt & Cầm Tà Đao Đi Săn
Khi nhân vật lưu đày bị quẳng xuống Vực Táng Kiếm:
1. Men theo vách đá đầy xác quái đến tọa độ $(x: 60.0, y: 55.0)$ gặp **Lão Độc Cốt**.
2. Client gửi gói tin `InteractNpcRequest`:
   ```python
   from server.world.npc_engine import create_canonical_npc_engine
   from server.world.quest_engine import create_default_quest_engine

   npc_engine = create_canonical_npc_engine()
   quest_engine = create_default_quest_engine()

   # Tiếp cận chuẩn Zero-Trust (Server xác thực khoảng cách Euclid)
   success, msg, node, relevant_quests = npc_engine.interact_with_npc(
       player_id="exile_warrior_01",
       npc_id="npc_doc_co_tan_kiem",
       zone_id="zone_tang_kiem_nhai",
       player_x=61.0,
       player_y=55.5,
       player_level=1,
       quest_engine=quest_engine
   )
   ```
3. Lão Độc Cốt gắt gỏng ném thanh tà đao mẻ (`node_doc_co_intro`) kèm 3 lựa chọn sinh tồn.
4. Chọn cầm đao đi chém quái:
   ```python
   ok, msg, next_node, service, payload = npc_engine.select_dialogue_choice(
       player_id="exile_warrior_01",
       npc_id="npc_doc_co_tan_kiem",
       current_node_id="node_doc_co_intro",
       choice_id="choice_accept_first_quest",
       quest_engine=quest_engine,
       player_level=1
   )
   # Khế ước 'quest_intro_doc_co' lập tức được kích hoạt trong QuestEngine!
   ```

### 5.2. Hướng Dẫn Thực Hành (How-To Guide): Kích Hoạt Kỳ Duyên Tàn Sát Cổ Ma
1. Tương tác với Lão Độc Cốt và chọn nhánh đàm luận về bí mật tàn sát:
   ```python
   ok, msg, next_node, service, payload = npc_engine.select_dialogue_choice(
       player_id="exile_warrior_01",
       npc_id="npc_doc_co_tan_kiem",
       current_node_id="node_doc_co_martial_talk",
       choice_id="choice_inquire_ancient_sword_secret",
       quest_engine=quest_engine
   )
   # QuestEngine lập tức kích hoạt 'hidden_ancient_sword_secret'!
   # Không có bất kỳ icon chấm hỏi/than nào trên bản đồ - hoàn toàn dựa vào ngộ tính và đàm đạo.
   ```

### 5.3. Hướng Dẫn Thực Hành (How-To Guide): Hiến Tế Rượu Máu Mở Lối Mật Thất
```python
# Người chơi mang theo hũ Hỗn Nguyên Tửu tiếp cận Cuồng Nhân Bão Cát giữa cơn bão cát
ok, msg, updated = npc_engine.deliver_item_to_npc(
    player_id="exile_warrior_01",
    npc_id="npc_sa_mac_du_than",
    item_id="item_hon_nguyen_tuu",
    count=1,
    quest_engine=quest_engine
)
# Ghi nhận mục tiêu DELIVER_TO_NPC, Cuồng Nhân gầm rống mở đường qua Vô Định Bão Cát!
```

---

## 6. ĐẶC TẢ KỸ THUẬT TRA CỨU (REFERENCE SPECIFICATIONS)

### 6.1. Schema Protobuf (`proto/npc.proto`)
Xem chi tiết tại [proto/npc.proto](file:///c:/Projects/FreeExile/proto/npc.proto):
- **`NpcRole`**: `OUTCAST_SCAVENGER`, `BONE_BLACKSMITH`, `BLOOD_SHAMAN`, `FERAL_TRACKER`, `SAVAGE_HERMIT`, `FERAL_SPIRIT`, `WAR_CHIEF`.
- **`NpcServiceType`**: `DIALOGUE`, `QUEST_DISPATCH`, `SHOP_VAULT`, `CRAFTING_FORGE`, `MERIDIAN_INSIGHT`, `MAP_TELEPORT_GUIDE`, `SECRET_TRIAL`.
- **`NpcDialogueChoicePayload`**: Lựa chọn phân nhánh thoại, kiểm tra cấp độ hoang dã và tham số kích hoạt nghiệp vụ sinh tồn.
- **`InteractNpcRequest / InteractNpcResponse`**: Gói tin tương tác cự ly với định danh bản đồ và tọa độ thực tế.
- **`SelectDialogueChoiceRequest / SelectDialogueChoiceResponse`**: Gói tin chọn nhánh thoại chuyển tiếp trạng thái.

---

## 7. ĐÁNH GIÁ KIẾN TRÚC & PHÒNG CHỐNG GIAN LẬN (ADR & SECURITY VERIFICATION)

### 7.1. Chống Gian Lận Tọa Độ & Can Thiệp Giao Dịch
- **Euclidean Tolerance Boundary**: Mọi tương tác NPC đều phải qua hàm `validate_interaction_distance`. Khoảng cách tối đa $R + 0.5m$ ngăn chặn triệt để việc người chơi dùng client hack mở shop/trả quest từ xa khi đang chạy trốn trong PvP hoặc dã ngoại.
- **Atomic Two-Phase Dialogue Transition**: Phiên làm việc [PlayerDialogueSession](file:///c:/Projects/FreeExile/server/world/npc_engine.py) được ghi nhận nguyên tử trên server. Client không thể tự ý nhảy cóc sang node nhận thưởng nếu chưa đi qua các node điều kiện trước đó.
- **Anti-Double Claim trên Trả Thưởng NPC**: Khi một lựa chọn thoại kích hoạt `NpcServiceType.QUEST_DISPATCH`, hệ thống chuyển hướng trực tiếp vào [QuestEngine.claim_quest_reward](file:///c:/Projects/FreeExile/server/world/quest_engine.py) với khóa trạng thái `CLAIMED` và kiểm toán giao dịch sổ cái bất biến, loại trừ 100% rủi ro spam nhận thưởng kép.

### 7.2. Kiểm Thử Độc Lập Khép Kín (TDD Verification)
Bộ kiểm thử tự hành [tests/unit/test_npc_system.py](file:///c:/Projects/FreeExile/tests/unit/test_npc_system.py) đạt tỷ lệ vượt qua $100\%$ ($8/8\text{ tests passed}$) bao gồm:
1. `test_npc_registration_and_zone_querying`: Đăng ký và chỉ mục không gian theo bản đồ hoang dã.
2. `test_anticheat_proximity_validation`: Bác bỏ tương tác vượt cự ly và sai lệch phân vùng.
3. `test_branching_dialogue_flow`: Luồng chuyển node phân nhánh sinh tồn mượt mà.
4. `test_npc_quest_interaction_talk_objective`: Tự động cập nhật mục tiêu `TALK_NPC`.
5. `test_npc_quest_deliver_item_objective`: Giao nộp vật phẩm `DELIVER_TO_NPC`.
6. `test_npc_adaptive_dialogue_based_on_quest_state`: Hội thoại biến chuyển theo trạng thái khế ước săn mồi.
7. `test_hidden_quest_serendipity_trigger_via_npc_choice`: Kích hoạt kỳ ngộ ẩn qua đàm đạo tàn sát.
8. `test_map_zone_integration_and_environmental_conditions`: Ràng buộc môi trường khí tượng bão cát dã ngoại.
