⚔️ Combat Simulator

Tham chiếu JSON cấu hình trận (schema 2)

Tài liệu dành cho người dùng cần lưu, chia sẻ hoặc chỉnh sửa cấu hình ngoài các control của GUI Builder. Chỉ các trường nêu ở đây nằm trong phạm vi hỗ trợ đã công bố; JSON hợp lệ về cú pháp vẫn có thể bị từ chối nếu giá trị hoặc tổ hợp không được hỗ trợ.

Khung cấu hình tối thiểu

{
  "schema": 2,
  "init": {
    "seed": 1,
    "gap": 1,
    "tier_factor": 10000,
    "threshold": 0
  },
  "mode": 1,
  "wall": null,
  "left": {
    "level": 25,
    "formation": 0,
    "troops": [
      {"type": "infantry", "tier": 5, "count": 1}
    ],
    "bonuses": {}
  },
  "right": {
    "level": 25,
    "formation": 0,
    "troops": [
      {"type": "infantry", "tier": 1, "count": 1}
    ],
    "bonuses": {}
  }
}

schema, init, mode, wall, left và right là thành phần cấp cao nhất. Schema 2 yêu cầu init có đủ seed, gap, tier_factor, threshold; mỗi bên cần có level, formation, troops và bonuses. wall có thể là null. Các số nguyên phải là integer JSON: không dùng chuỗi, số thập phân hoặc boolean.

Có thể thêm "description": "..." làm ghi chú. Đây chỉ là metadata, không thay đổi trận.

Tham số chung

Trường Phạm vi Ý nghĩa sử dụng
schema 2 Chọn định dạng cấu hình hiện hành.
init.seed 1–1000 Điểm bắt đầu của chuỗi random của trận. Giữ nguyên seed khi muốn thử lại cùng thiết lập.
init.gap 1–100 Tham số bước của chuỗi random. Giữ nguyên cùng seed và gap để so sánh các cấu hình nhất quán.
init.tier_factor 1–10000 Hệ số dùng trong xử lý chênh lệch số lượng theo tier; 10000 là giá trị mặc định trong UI.
init.threshold 0–100 Ngưỡng phần trăm được dùng khi xác định kết quả ở giới hạn thời gian; mặc định 0.
mode 1 Chỉ mode 1 hiện thuộc contract được hỗ trợ.
wall null hoặc object Tắt wall bằng null; xem cấu trúc wall bên dưới.
left, right object Cấu hình hai bên của trận.

Seed và gap không phải bonus chiến đấu. Với mục đích so sánh hai cấu hình, giữ chúng giống nhau; thay đổi chúng có thể làm thay đổi chuỗi random sử dụng.

Cấu hình mỗi bên

Trường Phạm vi / dạng Ý nghĩa
level 1–75 Level của bên. Giá trị cần có dữ liệu cấp độ tương ứng trong runtime.
formation 0–5 Formation index. UI hiển thị tên tiếng Anh tương ứng; JSON vẫn lưu số này.
troops Mảng troop Các loại/tier có count lớn hơn 0. Có thể là mảng rỗng.
bonuses Object Bonus mặc định của bên. Các channel không khai báo được hiểu là 0.
kind_bonuses Object, tùy chọn Override thưa theo loại lính; chỉ channel khai báo mới thay bonus mặc định.
advantages Object, tùy chọn Giá trị khắc chế cho Infantry, Cavalry, Ranged; không thuộc bonuses.
heroes Mảng, tùy chọn Tối đa 5 hero record mỗi bên, theo giới hạn hỗ trợ hiện hành.
pets Mảng, tùy chọn Tối đa 5 pet record mỗi bên; tổ hợp còn phải được runtime chấp nhận.
hero_ultra 0–100000, tùy chọn Tham số hero-ultra raw; mặc định 0. Chỉ dùng khi cấu hình hero/skill tương ứng được hỗ trợ.

Troop record

{"type": "infantry", "tier": 1, "count": 1000}

Bonus thông thường

Các giá trị dưới đây là raw value. Quy ước hiển thị là 100 raw tương ứng 1% modifier; giới hạn là giới hạn đầu vào, không phải gợi ý về giá trị nên dùng.

Channel Giới hạn raw Diễn giải tên trường
attack, defence, hp 0–1000000 Attack, defence, HP của bên.
reduce_attack, reduce_defence, reduce_hp 0–1000000 Channel giảm attack, defence, HP.
curse_attack, curse_defence, curse_hp 0–1000000 Channel curse cho attack, defence, HP của đối phương cùng loại lính.
add_damage, reduce_damage 0–100000 Channel damage bổ sung hoặc giảm damage.
magic 0–100000 Channel magic của bên.

Ví dụ:

"bonuses": {
  "attack": 5000,
  "hp": 10000,
  "reduce_damage": 2500
}

Channel bị bỏ qua dùng giá trị mặc định 0. Chỉ dùng tên channel được liệt kê; channel lạ không được xem là ghi chú.

Override theo troop kind

kind_bonuses là map giữa troop kind và một object chỉ chứa các channel muốn override:

"bonuses": {
  "attack": 1000,
  "hp": 2000
},
"kind_bonuses": {
  "infantry": {"attack": 5000},
  "ranged": {"hp": 0}
}

Trong ví dụ này, Infantry dùng attack 5000 và kế thừa HP 2000; Ranged kế thừa attack 1000 và dùng HP 0; các loại lính không có entry kế thừa cả hai giá trị chung. Giá trị override thay thế, không cộng với bonus chung. Entry {} có nghĩa là kế thừa toàn bộ. Các channel và giới hạn giống bảng bonus thông thường.

Khắc chế (advantages)

advantages là tham số riêng, không nằm trong bonuses hoặc kind_bonuses. Chu trình được tài liệu hóa là Infantry khắc chế Ranged, Ranged khắc chế Cavalry, Cavalry khắc chế Infantry. Object nhận các khóa infantry, cavalry, ranged; mỗi giá trị nguyên 0–100000 raw.

"advantages": {
  "infantry": 5000,
  "cavalry": 5000,
  "ranged": 5000
}

Siege không có khóa advantages trong contract này. GUI Builder có ba ô trong phần Advantages (counters) của mỗi bên. Ô trống bỏ key (mặc định core là 0), nhập 0 giữ key với giá trị 0; 100 raw tương đương 1%. Nạp JSON giữ nguyên các giá trị thưa, kể cả 0. Xóa ô đã nạp loại bỏ riêng key đó khi xuất cấu hình.

Heroes và pets

"heroes": [{"id": 1, "rank": 1, "star": 5}],
"pets": [{"id": 26, "level": 1}],
"hero_ultra": 0

Wall và lực lượng phòng thủ

Khi bật wall, cấu trúc có dạng:

"wall": {
  "defence": 1,
  "maximum": 0,
  "force": [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
  "health": 10000,
  "attributes": {"attack": 5000}
}

Đặt "wall": null nếu không có wall. Wall mode được xác định từ cấu hình lính; không cần tự đặt một trường wall mode.

Import, export và kiểm tra lỗi

Tên resource là lớp hiển thị từ catalog tiếng Anh đã xác minh. JSON chỉ dùng ID/index và thứ tự force hiện tại; tên không phải key nhập và không mở mechanic.

File Army Profiles, Battle Presets và library backup

Các file thư viện dùng envelope version 1, tách khỏi combat JSON schema 2. Envelope không gửi tới /api/run. Import to library nhận envelope hoặc JSON trận schema 2; Import battle JSON file chỉ nạp trận schema 2 vào builder.

Ví dụ Army Profile hợp lệ:

{
  "format": "combat-simulator-army-profile",
  "version": 1,
  "profile": {
    "name": "Infantry army",
    "notes": "",
    "army": {
      "level": 25,
      "formation": 0,
      "troops": [{"type": "infantry", "tier": 5, "count": 1000}],
      "bonuses": {},
      "advantages": {"infantry": 0}
    }
  }
}

profile.army là toàn bộ object của một bên, không có wrapper left/right, init hay wall. Các trường side tùy chọn dùng cùng contract ở trên.

Battle Preset có format: "combat-simulator-battle-preset", version: 1 và object preset gồm name, notes, battle. preset.battle là toàn bộ trận schema 2, gồm wall và cả hai đội quân. Export JSON của trận hiện tại vẫn trả riêng schema 2, không có metadata thư viện.

Library backup có format: "combat-simulator-library", version: 1, mảng armies và presets. Mỗi record có id, name, notes, created_at, updated_at (timestamp dạng chuỗi), cùng army hoặc battle. Import tạo ID mới, thêm hậu tố cho tên trùng và giữ timestamp từ backup; không ghi đè dữ liệu cũ. Tên phải khác nhau trong từng loại (không phân biệt hoa/thường), tối đa 100 ký tự; notes là chuỗi tối đa 2000 ký tự, có thể rỗng.

Toàn bộ file được kiểm tra trước khi ghi. Version chưa hỗ trợ, key JSON trùng, numeric token thập phân/exponent, số nguyên không biểu diễn chính xác hay cấu trúc builder không biểu diễn được đều bị từ chối. Các trường combat nâng cao được giữ; core vẫn kiểm tra mechanic khi chạy. Dữ liệu thư viện chỉ lưu trong trình duyệt theo địa chỉ site; xem hướng dẫn để backup và phục hồi storage.

Kết quả đầu ra

Giao diện hiển thị bên thắng, thời gian/tick, weighted loss và casualties theo loại/tier. Nếu có wall, defence loss được hiển thị riêng. Playback cho xem các tick đã ghi nhận và trạng thái quan sát được. Weighted loss là chỉ số loss của simulator, không được tài liệu hóa như điểm Might/KVK.