00-bat-dau-tu-dau.md · Cập nhật lần cuối: 2026-09-05 03:34 +07 · sha256 nguồn c0d8ea3888f800 — 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:
- Mọi con số đều có nguồn (RVA trong
libil2cpp.so, dòng trongdump.cs, dòng trongMain.unity, số lần gọi trong trace, ảnh chụp). Không có nguồn thì không có số. - 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ố ý). - 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õi → 02 Kinh tế & số lớn → 03 Prestige → 10 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 Juice → 09 VFX & pooling → 08 Â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ật → 05 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 & offline → 10 | 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 content → 05 → 06 → 07 | 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
ToPrecisionlàm tròn vàBalance_Reloadsinh 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_Reloadlà dead code, bảng thật là mảng trong scene sinh bằng lặp có cắt cụt,ToPrecisioncắ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.mdR7 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 20Fish_item. Đơn vị màn hình là con củaCanvas/SafeAreavàCanvas/Contents_UI(SCREEN_CATALOG §1; G152). - Suy hot path từ tên class.
BulletShooterchạy 0 lần;Bullet.Update14 199 lần; class nóng nhất game là thanh máuSlicedFilledImage(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.cschỉ liệt kê khai báo, không liệt kê truy cập; kết luận sai vềRebirth_Btn_Locked_objsinh ra từ đó (GAPS G139 METHODOLOGY, UNLOCK_GATES §2.3). Cách đúng: IDADataRefsTo/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.shsau khi sửa bất kỳ.mdnà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.mdR10 / 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á: hook0x2B0AB6C+ 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ẫngap list (nội bộ)— gap toàn dự án- README của cookbook — cách build và xem dashboard