CatGunner CookbookBardCat 1.1.59 · L1 ANALYSIS · tài liệu học
Trang chủCookbook › 00 — Bắt đầu từ đâu: bản đồ cả game và lộ trình đọc
Nguồn: 00-bat-dau-tu-dau.md · Cập nhật lần cuối: 2026-09-05 03:34 +07 · sha256 nguồn c0d8ea3888f8

00 — Bắt đầu từ đâu: bản đồ cả game và lộ trình đọc

Nguồn framework: docs/framework/00-README.md (ranh giới, bảng bằng chứng), [liveops catalog: SCREEN_CATALOG.md] §2/§5 (các chế độ chơi và nút), [liveops catalog: UNLOCK_GATES.md] §2 (thang mở khoá), docs/framework/01-economy-money.md §3.2 (chuỗi thu nhập). Cấp bằng chứng: L1 ANALYSIS — dựng lại clean-room từ disasm + metadata + quan sát runtime; không phải source gốc. Mỗi dòng bên dưới mang nhãn bằng chứng riêng.

Mục tiêu

Bạn (dev) và artist muốn làm một game idle tương tự CatGunner. Cookbook này biến 11 tài liệu framework thành các công thức ngắn: muốn làm X thì làm thế này — game gốc làm thế này (kèm bằng chứng) — bẫy đã gặp — checklist. Trang này là bản đồ: game gồm những gì, các hệ nối nhau ra sao, đọc theo thứ tự nào.

Ba quy ước đọc trước khi vào bất kỳ trang nào:

  1. Mọi con số đều có nguồn (RVA trong libil2cpp.so, dòng trong dump.cs, dòng trong Main.unity, số lần gọi trong trace, ảnh chụp). Không có nguồn thì không có số.
  2. UNKNOWN là UNKNOWN. Một tài liệu chưng cất không có UNKNOWN nào là một tài liệu đang đoán (00-README.md §"Tổng quan số liệu": 301 claim / 90 UNKNOWN là tỉ lệ cố ý).
  3. Mọi C# trong tài liệu là L1 ANALYSIS — dựng lại clean-room, không phải source gốc, và không thay thế bản restore 1:1 trong [restore project: CatGunner].

Game gốc làm gì

Game là idle-shooter nhìn từ trên: một đàn mèo tự bắn vào mục tiêu, tiền rơi ra, người chơi mua nâng cấp, qua màn, rồi Rebirth để đổi tiến độ lấy hệ số vĩnh viễn. Các hệ thống lớn và cách nhận ra chúng trong UI:

Điều game làm Con số / hằng số Mức bằng chứng Nguồn
Một scene duy nhất chứa toàn bộ game (gameplay + mọi menu/popup) Main.unity 481 217 168 B, 143 032 object, 38 375 GameObject asset-census doc 08 §2.2
Chế độ chính: chặt cây (Tree) theo wave, 5 level/stage Level_Now 0..4, Stage_Now 0-based; hiển thị Stage {S+1}-{L+1} VERIFIED UNLOCK_GATES §1.3–1.4 (RVA 0x2B45820, 0x2B156E4)
Các chế độ phụ, mỗi cái một *_manager + nút trong Main_UI/Btn_list Mine (quặng Ore), Hunt (Monster), Boss, Play (SpeedRun), Trip (Adventure), Fish, Pet, Gun, Skin, Relic, Mission, Shop, Rank VERIFIED (scene) SCREEN_CATALOG §2, §5
Nội dung có trong binary + scene nhưng không có lối vào cho người chơi Raid (Raid_manager m_IsActive: 0, 690 object UI, không có Raid_Btn) VERIFIED (negative evidence) SCREEN_CATALOG §6; GAPS G153
Một biến cổng duy nhất mở dần nội dung Stage_Value_Max = max(Level_Now + 10·Stage_Now); thang 20 / 30 / 50 / 90 / 110 / 110 / 340 cho Rebirth / Mine / Fish / Boss / Pet / Hunt / Trip VERIFIED UNLOCK_GATES §1.2, §2 (Contents_Lock_Reload RVA 0x2B4441C)
Thu nhập là chuỗi nhân phần trăm, 100 % = trung tính Upgrade × Rebirth × Skin × Pet × Relic (mỗi cái /100) rồi ×3 nếu Money_Buff disasm-proven + runtime-verified doc 01 §3.2 (RVA 0x2A4E7B0; parity ×7.61)
Số lớn không dùng double package InfiniteValue.InfVal (Asset Store 194963), 5 chữ số có nghĩa package-source + runtime-verified doc 01 §2
Bảng cân bằng lúc chạy là mảng bake sẵn trong scene, sinh bằng lặp có cắt cụt — không phải pow() v[i] = trunc3(v[i-1]·1.08); Balance_Reload là dead code (0 caller) VERIFIED doc 09 §3.2; CONVERGENCE; GAPS G138a
Prestige = Rebirth, tiền tệ meta là Ruby, không tốn gì, thưởng siêu tuyến tính reward = n^2.5 · relic%/100, n = Level_Now + 5·Stage_Now, 0 nếu Stage_Now <= 1 disasm-proven doc 09 §2 (RVA 0x2B22F18)
Bộ khung code: singleton X_manager gọi thẳng nhau, không DI 35 singleton; 731 type, 190 vào scene, 66 class "nóng" scene-census + metadata-proven doc 07 §2.1, doc 08 §3.5
Dịch vụ ngoài (ads / IAP / analytics / remote-config / login) nằm sau interface, mặc định fail-closed 5 interface, NullService không bao giờ grant quy tắc dự án + source quy tắc dự án (nội bộ) R1; doc 07 §3.6
Liveops không ghi đè kinh tế trong 1.1.59 remote chỉ gate quảng cáo / version; 1 rủi ro còn mở (Google Sheet súng) VERIFIED (+ G144 OPEN-HIGH-RISK) LIVEOPS_SURFACE §0, §4; CONVERGENCE U4

Bản đồ luồng dữ liệu (đọc từ trái sang phải)

[Mèo bắn]  Cat.TrySpawnBulletEx ─▶ Bullet.OnTriggerEnter ─▶ Gamemanager.Damage_Collider ─▶ Damage_Tag ─▶ Enemy.Damaged
                                                                                                          │
                                                          Health_Now <= 0 ──▶ Enemy.Die ──▶ Gamemanager.Get_Money(Money, pos)
                                                                                                          │
                       MoneyValue_return(v) = v × Upgrade% × Rebirth% × Skin% × Pet% × Relic% (/100 mỗi mắt) × (Money_Buff ? 3 : 1)
                                                                                                          │
                                                                    Money += v'   Money_Accum += v'   OnMoneyChanged
                                                                                                          │
[Người chơi]  mua Upgrade (Power/Speed/Money) ◀──── tiền ────┘         cây đổ ──▶ TreeCount_Now-- ──▶ Game_Win ──▶ StageAdvance
                                                                                                          │
                                                          Stage_Value_Max = max(Level_Now + 10·Stage_Now) ──▶ Contents_Lock_Reload (mở khoá)
                                                                                                          │
[Rebirth]  reward = n^2.5·relic%/100 (Ruby) ──▶ RESET: Money, Money_Accum, mọi Lv upgrade, Stage/Level
           PERSIST: Ruby, Rebirth_Count, cây prestige, Dia, PetCoin, súng/pet/relic/skin/mission, Stage_Value_Max

Mọi mũi tên đều có RVA trong doc 02 §3.1, doc 01 §3.2, doc 09 §3.1 và UNLOCK_GATES §1.

Công thức / pseudocode

Không có code ở trang này — nó là bản đồ. Công thức của từng hệ nằm trong trang tương ứng. Bảng dưới là lộ trình đọc:

Bạn muốn Đọc theo thứ tự Ghi chú
Dựng vòng lặp idle từ đầu (dev) 01 Vòng lặp cốt lõi02 Kinh tế & số lớn03 Prestige10 Tiến trình & mở khoá04 Chiến đấu Bốn trang đầu là toàn bộ "trái tim" của idle; 04 là cách tiền được sinh ra
Game "đã có" nhưng chưa "đã tay" 07 Juice09 VFX & pooling08 Âm thanh Toàn bộ juice của game gốc là ~20 dòng mỗi component, gắn ở 1 939 chỗ
Đông vui trên màn hình: đàn mèo, pet, quái 06 Pet & nhân vật05 Kẻ địch & wave Boids 3 lực, breadcrumb, MaterialPropertyBlock thay Animator
Kiếm tiền (IAA + IAP) 11 Monetization Tổng hợp từ doc 10 framework (đã landed 2026-09-04)
Nạp save không phá tiến độ, trả tiền vắng mặt đúng luật 14 Lưu game & offline10 35 field, AllowSave cuối, kẹp buff, null-save bất đối xứng, sàn 30 s / trần 8 h, hai lần ComputeElapsed (đợt 3)
Biết mình phải vẽ bao nhiêu thứ (artist) 13 Checklist content050607 Bảng đếm lấy từ doc 11 kiểm kê content (đã landed 2026-09-04)
Hiểu quy mô thật và cái giá của "một scene" 12 Kiến trúc & scale 481 MB, > 30 phút import, một lần SIGKILL
Biết cái gì chưa biết Điều chưa biết và mục "Điều chưa biết" cuối mỗi trang 90 UNKNOWN trong framework + gap list

Cách đọc một trang recipe

Mỗi recipe có đúng 7 mục, luôn theo thứ tự này:

Mục tiêu                 → 2–4 câu: muốn làm X
Game gốc làm gì          → bảng: điều game làm | con số | mức bằng chứng | nguồn
Công thức / pseudocode   → code, ghi rõ dòng nào có RVA (L1 ANALYSIS) và dòng nào là gợi ý framework
Bẫy đã gặp               → lỗi thật đã gặp khi dựng lại, kèm gap ID
Checklist khi tự làm     → tick khi làm game của bạn
Điều chưa biết (UNKNOWN) → chép nguyên từ doc nguồn, kèm cách khoá
Đọc thêm                 → link tới doc framework / liveops / gaps

Nhãn bằng chứng (chép từ 00-README.md §"Bảng ghi công bằng chứng")

Nhãn Nghĩa Tin đến mức nào
disasm-proven Đọc từ ARM64 / Hex-Rays của libil2cpp.so tại RVA được ghi Mạnh nhất về logic
metadata-proven Từ IL2CPP metadata đã giải mã (dump.cs): tên, kiểu, offset, RVA, const chính xác — không có thân method Mạnh về cấu trúc, không nói gì về hành vi
runtime-verified Oracle field-delta trên thiết bị xác nhận bản dựng lại dự đoán đúng phép ghi thật Mạnh nhất về hành vi
runtime-observed Thấy chạy trên thiết bị (số lần gọi), giá trị field chưa đối chiếu Biết nó chạy, chưa biết nó ghi gì
scene-census / scene-YAML Đếm / đọc từ Main.unity (30 082 tham chiếu m_Script) Dữ liệu inspector thật
asset-census Từ inventory asset (UnityPy / AssetRipper) Số lượng asset thật
package-source Từ package Asset Store / upstream mà user sở hữu Cẩn thận lệch version
build-measured Đo được trong lúc build/import thật Chi phí thật
observed Ảnh chụp SOT đang chạy Bằng chứng về hiển thị, không phải về code
derived Tính lại từ công thức đã disasm-proven Ghi riêng khỏi dữ liệu oracle
VERIFIED / HYPOTHESIS Nhãn của lane liveops (IDA xrefs + scene + đối chiếu ảnh) / giả thuyết có nêu cách kiểm
UNKNOWN Chưa biết. Không được thay bằng một con số hợp lý.

Bẫy đã gặp

  • Tin công thức thay vì tin bảng. Doc 01 §2 (viết trước) nói ToPrecision làm tròn và Balance_Reload sinh bảng lúc chạy; doc 09 §3.2 (viết sau, hai nhà phân tích độc lập hội tụ — CONVERGENCE.md) chứng minh ngược lại: Balance_Reloaddead code, bảng thật là mảng trong scene sinh bằng lặp có cắt cụt, ToPrecision cắt. Cookbook luôn dùng phiên bản mới hơn và nói rõ chỗ nào doc cũ chưa cập nhật. Gap: G138a.
  • Đếm Canvas để kiểm kê màn hình. RULES.md R7 nói "25 Canvas"; scene thật có 21 và chỉ 1 là Canvas UI thật, 20 cái còn lại là Canvas lồng để override sorting cho 20 Fish_item. Đơn vị màn hình là con của Canvas/SafeAreaCanvas/Contents_UI (SCREEN_CATALOG §1; G152).
  • Suy hot path từ tên class. BulletShooter chạy 0 lần; Bullet.Update 14 199 lần; class nóng nhất game là thanh máu SlicedFilledImage (169 246 lần/40 s). Đo, đừng đoán (doc 08 §3.5).
  • Kết luận "field không được tham chiếu" từ dump.cs. dump.cs chỉ liệt kê khai báo, không liệt kê truy cập; kết luận sai về Rebirth_Btn_Locked_obj sinh ra từ đó (GAPS G139 METHODOLOGY, UNLOCK_GATES §2.3). Cách đúng: IDA DataRefsTo / CodeRefsTo.

Checklist khi tự làm

  • [ ] Đã đọc 4 trang lõi (01 → 02 → 03 → 10) trước khi viết dòng code kinh tế đầu tiên — và 14 trước khi bật nạp save.
  • [ ] Mỗi con số cân bằng trong game của bạn có một chỗ ghi nguồn (kể cả khi nguồn là "designer chọn").
  • [ ] Danh sách UNKNOWN của dự án bạn được nuôi ngay từ ngày đầu, không đợi cuối.
  • [ ] Đã chạy tools/build_cookbook.sh sau khi sửa bất kỳ .md nào (R10: dashboard cũ = bug).

Điều chưa biết (UNKNOWN)

  • Doc 10 (10-monetization-iaa-iap.md) và doc 11 (11-content-inventory.md) đã landed trong ngày; cookbook 11 và 13 đã được viết lại từ chúng. Khi hai doc đó đổi lớn (đợt sau), hai trang cookbook cần rà lại — cookbook là tổng hợp, không tự cập nhật theo doc.
  • Doc 10 §6.1 (và GAPS G162) đính chính con số "24 IAP product id" trong RULES.md R10 / LIVEOPS_SURFACE §6.1: số đúng là 34 (8 chuỗi trong danh sách 24 là place-string / khoá analytics, không phải product id). Cookbook dùng 34.
  • 90 mục UNKNOWN / negative evidence của framework nằm ở cuối từng doc; danh sách gap toàn dự án ở gap list (nội bộ). Trang này không chép lại — mỗi recipe mang phần của nó.
  • Rủi ro đơn lẻ lớn nhất còn mở: Gun_manager.Request_Sheet (Google Sheet TSV, 65×9) có thực sự chạy lúc boot không (G144 OPEN-HIGH-RISK). Nếu có, kết luận "liveops không đổi được cân bằng" phải sửa. Bằng chứng khoá: hook 0x2B0AB6C + bắt

Đọc thêm

  • docs/framework/00-README.md — chỉ mục và bảng bằng chứng gốc
  • [liveops catalog: SCREEN_CATALOG.md] — kiểm kê màn hình
  • [liveops catalog: UNLOCK_GATES.md] — thang mở khoá
  • [liveops catalog: LIVEOPS_SURFACE.md] — bề mặt điều khiển từ xa
  • [phân tích nội bộ] — hai nhà phân tích độc lập, 0 mâu thuẫn
  • gap list (nội bộ) — gap toàn dự án
  • README của cookbook — cách build và xem dashboard