CatGunner CookbookBardCat 1.1.59 · L1 ANALYSIS · tài liệu học
Trang chủTài liệu framework › Framework game idle — chưng cất từ bản restore CatGunner
Nguồn: 00-README.md · Cập nhật lần cuối: 2026-09-05 08:45 +07 · sha256 nguồn 750f6217ddbd

Framework game idle — chưng cất từ bản restore CatGunner

Bộ tài liệu này chưng cất các mẫu thiết kế và cơ chế của một game idle đã ship thật (com.Chodun.CatGunner 1.1.59, tên nội bộ BardCat) thành tài liệu tái sử dụng được: vừa là tài liệu học, vừa là hạt giống cho một framework game idle.


Ranh giới (đọc trước)

Đây là gì Bản khái quát hoá, tái sử dụng được, của các mẫu mà bản restore hé lộ.
Đây KHÔNG phải gì Không phải source gốc. Không phải một phần của bản restore 1:1.
Cấp bằng chứng của mọi C# L1 ANALYSIS — dựng lại clean-room từ ARM64 disassembly của libil2cpp.so, metadata IL2CPP đã giải mã, và quan sát runtime trên thiết bị.
Quan hệ với bản restore [restore project: CatGunner] là mục tiêu 1:1 và không bị tài liệu này chạm vào. Chưng cất không bao giờ làm yếu bản restore.

Quy tắc trích dẫn: mọi phát biểu đều kèm nguồn (RVA, đường dẫn file, file trace, scene YAML, hoặc source package). Một phỏng đoán không bao giờ được trình bày như một sự thật — nó được ghi là UNKNOWN.


Các module

# Tài liệu Nội dung
01 Kinh tế & tiền tệ Bignum InfVal, chuỗi nhân thu nhập, cache LRU, 4 loại tiền tệ, ký hiệu hiển thị, đặc tả module chạy độc lập + simulator, mảng balance scene
02 Chiến đấu & đạn Dispatch GunType, pipeline sát thương, nổ AoE, xuyên, missile parabol, bug is_gaming
03 Particle & VFX Pool hạt vs pool GameObject, FXThrottle, FX trúng đích, 7 718 ParticleSystem
04 Âm thanh Sound_manager.PlaySfx, 15 SfxType, chống trùng, mute theo ngữ cảnh, 16 clip
05 Nhân vật, Pet & Kẻ địch Đàn mèo + AI follower, boids pet, Spine 4.1.24, Enemy chung, wave, đặt cây Morton, Game_Win + relic skip, bảng degreeRates
06 Juice & Game Feel Squash-stretch, text nổi, thanh máu 2 tầng, nướng đường cong, knockback
07 Tiến trình & Manager 35 singleton, Balance_Reload, gacha/merge, buff, nhiệm vụ, ranh giới R1, bản đồ save/load 35 field (§2.8), vé + XP Trip (§2.9)
08 Kiến trúc & quy mô Một scene 481 MB và hoá đơn của nó, URP mobile, mã hoá metadata, package, bài học phương pháp khôi phục đợt 3 (§3.6)
09 Prestige / Rebirth Vòng lặp lõi của idle: reset-set/persist-set, đường cong thưởng, tiền tệ meta, công thức designer vs bảng đã ship, kinh tế offline (cửa sổ thời gian đã dựng lại)
10 Kiếm tiền: IAA + IAP 10 AD_Type rewarded, interstitial theo điểm đặt, offerwall, FreeCash/Almedia, IAP + segment máy chủ — (lane khác biên soạn)
11 Kiểm kê nội dung Đếm và dẫn chứng khối lượng nội dung cho hoạ sĩ — (lane khác biên soạn)

Công cụ chạy được: [F001: economy_reference_sim.py] — mô hình tham chiếu Python thuần (0 phụ thuộc) cho tầng kinh tế + prestige, tự kiểm với 70 vector lấy từ SOT thật, gồm việc tái tạo 8 mảng balance serialize trong scene (0/360 lệch).


Đọc theo mục đích

Muốn xây một game idle mới: 01 (kinh tế) → 09 (prestige) → 07 (tiến trình) → 02 (chiến đấu). Bốn tài liệu này chứa toàn bộ vòng lặp cốt lõi.

Muốn game "đã có" nhưng chưa "đã tay": 06 (juice) → 03 (VFX) → 04 (âm thanh).

Muốn hiểu quy mô thật của một game thương mại: 08 → 05.

Muốn học phương pháp reverse-engineering: 08 §3.3 (mô hình mối đe doạ của bảo vệ) và §3.5 (xếp hạng bằng dữ liệu chứ không bằng tên).


Bảng ghi công bằng chứng

Mức Nghĩa
disasm-proven Đọc từ ARM64 / Hex-Rays của libil2cpp.so tại RVA được ghi. Bằng chứng mạnh nhất về logic.
metadata-proven Từ IL2CPP metadata đã giải mã (dump.cs). Tên, kiểu, offset, RVA và giá trị const là chính xác. Không có thân method.
runtime-verified Oracle field-delta trên thiết bị đã xác nhận việc dựng lại dự đoán đúng các phép ghi thật.
runtime-observed Đã thấy chạy trên thiết bị (số lần gọi), giá trị field chưa đối chiếu.
scene-census Đếm từ Main.unity (30 082 tham chiếu m_Script).
asset-census Từ inventory asset (UnityPy / AssetRipper).
package-source Từ package Asset Store / upstream mà user sở hữu.
build-measured Đo được trong quá trình build/import thật.
observed Quan sát trực tiếp trên SOT đang chạy (ảnh chụp màn hình).
runtime-verified (live) Đo trực tiếp trên bản đang chạy trên thiết bị — hook hàm, đọc giá trị trả về / trường bộ nhớ, hoặc đọc trạng thái nút HUD trong một phiên có kiểm soát. Mạnh hơn observed (không chỉ nhìn màn hình) và mạnh hơn runtime-observed (có giá trị, không chỉ số lần gọi). Dùng ở doc 10 và cho các claim từ probe trong 01 / 07 / 09.
scene-YAML Đọc trực tiếp từ Main.unity (số dòng được ghi kèm). Với bảng cân bằng, đây là nguồn sự thật lúc chạy.
VERIFIED Nhãn của [phân tích nội bộ]: đọc trực tiếp từ binary/scene + xrefs IDA.
derived Tính lại từ một công thức đã disasm-proven. Ghi riêng khỏi dữ liệu oracle.
UNKNOWN Chưa biết. Không được thay bằng một con số hợp lý.

Tổng quan số liệu

Tài liệu Claim có bằng chứng UNKNOWN / bằng chứng phủ định
01 — Kinh tế 34 (+1) 18 (1 đóng một phần)
02 — Chiến đấu 25 8
03 — VFX 17 7
04 — Âm thanh 18 9
05 — Nhân vật 65 (+20) 12 (1 đóng một phần, +2 mở)
06 — Juice 46 12
07 — Tiến trình 103 (+32) 20 (1 đóng, +5 mở)
08 — Kiến trúc 66 (+10 bài học §3.6) 12
09 — Prestige 41 (+6) 19 (2 đóng)
10 — Kiếm tiền (lane khác) 177 23 (12 mở · 6 phủ định · 5 đã đóng)
11 — Kiểm kê nội dung (lane khác) (bảng kiểm kê, không đếm claim)
Tổng 770 (+30 đợt 12: Hunt 7, Boss 5, game feel 8, âm thanh 3, nghiệm thu ghi 3, còn lại 4) 143 (đợt 12: 5 đóng [PlaySfx, SfxEntry, FXThrottle, chỉ số hàng Monster, null offline định danh], +3 mở LỖI THẬT [tiền ×300, TotalPlayTime, thưởng Hunt/Boss = 0 (R13)]; đường ghi trên save đã nạp = VERIFIED 122/128)

Tỉ lệ ~3–4 claim trên mỗi UNKNOWN là cố ý. 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.

Đợt 3 (2026-09-05, ledger G290–G353 + G700–G704): +69 claim, 4 UNKNOWN đóng (cấu trúc SaveData; 20 float degreeRates; tên súng StepUp; nơi dùng Relic.Skip_Value), 3 đóng một phần (kinh tế offline; tham số đội hình; Cat), và +7 UNKNOWN mới — đáng chú ý nhất là một mâu thuẫn: bảng XP Trip theo thân hàm Exp_Balance_Reload ((20+3i)·i+50) không bằng mảng scene/bộ nhớ runtime (10, 60, 100…); bảng nào sống sau khi nạp save chưa chốt (07 §2.9). Ghi mâu thuẫn, không chọn bên.

Đợt 4 (ledger G354–G363): mâu thuẫn trên đã giải — mảng scene sống, generator là fallback; Main.unity lưu int[] dạng hex blob nên tìm kiếm dạng danh sách YAML đã bỏ sót (08 §3.6). Thêm: camera iso orthographic + vì sao cây nằm ngoài khung (05 §2.4), auto-move của mèo (05 §3.1b), cụm bắn + pool đạn hai lượt + chuỗi 100 sát thương (02 §2), thứ tự restore đầy đủ của LoadData.Load và bài học nghiệm thu 8/38 field lệch (07 §2.8), bảng relic (07 §2.4), quy tắc R13 (tích luỹ base-100 / factory null là lỗi im lặng). UNKNOWN đóng: Exp_balance, Object_Polling_Smart, nơi đọc is_Shoot_Mute, cây không hiện (G351), đường ghi Rebirth_Value; đóng một phần: số hạng Skin/Pet/Relic (2/3).

Đợt 5 (ledger G364–G371): Cat hoàn tất (65/67; follower = vệt leader 2 s với độ trễ riêng 0.15–0.6 s, hai lớp chống rung, trạm đấu trường; finder quặng mở rộng dần, buffer non-alloc 64 — 05 §2.1/§3.1c); render state 3 shader sprite đọc được, thân hiệu ứng còn placeholder (08 §5); nghiệm thu save thật 37/38 với 4 residual và đường ghi save cố ý tắt (fail-safe, 112 field — 07 §2.8); bắn chạy trên thiết bị nhưng ba lỗi mở (save mới 0 sát thương, đạn trúng vô hiệu trên save nạp, thân mèo thiếu) ghi là MỞ ở doc 02/05/07 §5 — không phải claim.

Đợt 6 (ledger G372–G377): mọi ngày giờ trong save parse UTC (AssumeUniversal|AdjustToUniversal) + guard Phật lịch ±543; khối Adventure có hai nhánh (mới / restore, mốc hỏng ⇒ bắt đầu lại từ bây giờ); hàng 27 nút HUD do tutorial ẩn tới lần nâng Power đầu (HUD tối giản trên save mới là đúng SOT); đường khởi tạo save mới đặt baseline base-100 (Relic_manager.Start, Skin_manager.Start); sổ cái RecordGain (UTC + trust + session + đồng hồ đơn điệu, 32 mục, từ chối dưới Trust.None); đính chính DiaPig (_lastTickTime giữ giá trị file, chỉ kẹp tương lai; _lastTickMono mới được đóng dấu lại). Đóng G423/G425 + residual (1); G424 vẫn mở (giả thuyết is_gaming do tutorial); OfflineProgressSimulator 12 stub → lane riêng; DailyCheck retention đã xong (G378) — bảng 70/200/400/600/800/1000/1500 dia, chuỗi 7 ngày lặp, đồng hồ tin cậy trước, ghi sổ trước khi cấp: 10 §7.6.

Đợt 7 (ledger G379–G382, G1000–G1005) — ĐÍNH CHÍNH LỚN: OfflineProgressSimulator được dựng lại trọn và harness độc lập tái tạo khoản trả của game gốc từ một save thật đúng 17 chữ số (+1 627 259.5021456285). Hệ quả: Skin / Pet / Relic CÓ được áp offline — bản trước của 01 §5.8 / 09 §4b / OFFLINE_ECONOMY.md §(c) ghi "không" là SAI (census bỏ sót lambda); chỉ buff quảng cáo ×3 vắng mặt. 12 luật offline giờ là VERIFIED với ví dụ số thật (01 §5.8). Còn chờ: khoản trả trên thiết bị (9 stub R13). Thêm: G424 — giả thuyết is_gaming bị bác, nghi phạm chuyển sang cài đặt project (ma trận va chạm, thứ tự script — 08 §3.6); G422 đóng (SOT); đường ghi save bàn giao lane riêng với câu hỏi 7 Clone (07 §2.8).

Đợt 8 (ledger G383–G389): đường GHI save dựng xong — 127/128 field, 7 mảng snapshot vs 13 theo tham chiếu, xoay .tmp → .bak — nhưng công tắc vẫn tắt: mô hình round-trip lộ ra 6 getter inline còn stub (trong đó Time_manager.UtcNow = năm 1 đầu độc SanitizeYear = gốc rễ thật của residual ngày tháng và của hồi quy save mới) và các field phía đọc bị bỏ sót trong ContinueLoad (07 §2.8). Ma trận va chạm layer trong export hỏng thật (mã hoá /), đã sửa về SOT — nhưng G424 vẫn mở (sửa xong vẫn 0 sát thương); thứ tự script khớp SOT. Tutorial: SOT chịu được cuộc đua Start-vs-load bằng cách poll level Power mỗi 0.2 s; máy trạng thái đã dựng; bước mua súng nạp 100 dia theo kịch bản (không phải monetisation). 9 blocker offline đã điền, khoản trả trên thiết bị vẫn chưa quan sát. Phương pháp: 08 §3.6 +5 bài học.

Đợt 9 (ledger G391–G397): đồng hồ của game đọc trọn (giờ máy + offset, mốc máy chủ đơn điệu khi đang kiểm, không bao giờ lùi, kẹp trên sàn tin cậy; .cctor thiếu = gốc rễ crash save mới và ngày năm 1 — 07 §2.6); công tắc GHI đã bật trong overlay học (cổng mở 4 trục, round-trip 127/128) nhưng build thiết bị đầu tiên hồi quy cả đọc lẫn ghi — trạng thái "bật, đang sửa", không phải verified; trên thiết bị: nút HUD lần đầu hiện, tutorial tới Challenge, OnTriggerEnter không bao giờ được gọi (0 dòng trace), đường offline chạy nhưng huỷ giữa chừng và làm tiền GIẢM 2.37 M (lỗi thật của bản dựng lại, ghi trung thực), map kẹo ở bước Challenge (chưa giải thích). Kinh tế: dia (_getDia đếm ×3 cho máy chủ, không kẹp 0 khi tiêu), 3 cổng sức mạnh theo chế độ (làm tròn ngân hàng, bảng hệ số súng 1/7/5/pellets/5/5/10), thang mở khoá giờ VERIFIED cả tên (stage 3/4/6/10/12/12/35), bảng máu/tiền cây = seed 250/20 ×3 cắt 2 chữ số (đóng UNKNOWN cũ), hệ cảnh báo round-robin (mọi cảnh báo từng câm), luật chế độ Mine (07 §2.10). Hệ TEXT (ScriptLocalization từ binary, font TMP, cỡ chữ) là hạng mục đang làm — chưa claim. Roadmap quét stub và thứ tự tiếp tục sau giới hạn phiên: nội bộ, 08 §3.6.

Đợt 10 (ledger G398–G400) — VÌ SAO ĐẠN KHÔNG TRÚNG: gốc rễ G424 là một hằng số vector sai một thành phần: CamForward trong static ctor của Cat thiếu pitch 40° ⇒ phép chiếu nòng súng lên mặt phẳng y = 2 chia cho 0 ⇒ mọi viên đạn spawn ở vô cực, không bao giờ chạm trigger (02 §2; bài học ở 08 §3.6) — chờ xác nhận thiết bị batch 20. Cùng đợt: key cache tiền = chuỗi 7 phần liệt kê mọi nguồn multiplier (01 §2); các ngày năm 1 là vì nửa sau của việc nạp chưa hề chạy (ngoại lệ trước continuation); "hồi quy đọc" batch 19 là quy trình test, không phải code; autosave save mới ném vì Shop_manager..cctor thiếu (kèm bảng 23 định dạng tiền tệ + 6 tiền tệ không thập phân KRW/JPY/VND/IDR/CLP/HUF — 10 §6.3); bước Challenge không vào SpeedRun (map kẹo vẫn chưa giải thích).

Đợt 11 (ledger G402–G407) — GAME CHƠI ĐƯỢC: batch 20 xác nhận trên thiết bị: 104/104 va chạm đi trọn chuỗi sát thương, cây đổ, tờ tiền + hạt lá, thanh máu trên xương rồng, hàng nút HUD + bàn tay tutorial; autosave ghi được trên save thật (.json + .bak). G424 ĐÓNG ở mọi doc/bảng. Residual trung thực: autosave save mới còn ném (PlusPack), offline chạy tới cuối rồi còn một null (coroutine), đuôi nạp vẫn chờ, tutorial dừng ở GunOpen. Thêm: throttle số bay (lưới 1.5, X/Y, làm tròn ngân hàng — 06 §2.4); chế độ PlayRaid đọc trọn (07 §2.11–2.12) — map kẹo = chủ đề Stage_Now % 10, không phải bug; hệ text: font giống hệt SOT, lỗi là tài nguyên stock che asset (08 §5); R2: version package phải khớp bề mặt API của binary (ParticleImage.EmitAtWorldPosition). Phương pháp: 08 §3.6 +4 (biên cuối hàm, version package, che khuất Resources, guard bỏ comment).

Đợt 12 (ledger G408–G415): chế độ HuntBoss đọc trọn (07 §2.13–2.14: rào HP 1, 5 level/wave, thưởng PetCoin/dia × gói PlusPack, quét, quirk đĩa HP theo độ, ellipse spawn, skin boss Stage % 9); game feel đọc trọn (06 §2, 04 §5, 03 §5): thứ tự cổng sfx + volume theo hàng, không biến tấu pitch, BGM mute = volume 0, 3 FX trúng/frame, giá trị squash, giật lùi −0.6, dia bay 8 hạt/0.3 s, rung 30 ms — và bằng chứng phủ định: game ship không có camera shake / hit-stop; null offline định danh (ShowAfterFrame) + dự đoán harness 5.4 h chưa xác nhận; che khuất TMP đã gỡ (23 → 3), ParticleImagecode do game sửa vào vendor (quyết định partial + file SOT-authored, 08 §3.6); nghiệm thu batch 20: đường ghi trên save đã nạp VERIFIED 122/128 với xoay .bak và đọc lại sạch — nhưng hai lỗi thật: thu nhập tiền ≈ ×300 SOT (đang điều tra) và TotalPlayTime đứng; nguy cơ đúc lại danh tính khi nửa sau nạp bị bỏ qua. Tự mua offline khớp harness (nhiều khả năng đúng). Phương pháp: R14 (event field-like bị bỏ rơi) ở 08 §3.6.

Trong đợt 2, 9 UNKNOWN được đóng (U1–U4 + bảng cân bằng + hai ô ảnh chụp) và nhiều UNKNOWN mới được mở — chủ yếu quanh mô hình kinh tế offline vừa phát hiện. Đó là dấu hiệu lành mạnh: hiểu sâu hơn thì thấy rõ hơn cái mình chưa biết.


⚠ Đính chính quan trọng (đợt 2)

Một phát hiện đã lật ngược một kết luận trước đó về nền kinh tế, và nó là bài học trung tâm của bộ tài liệu này:

Balance_Reload — hàm sinh bảng cân bằng — là DEAD CODE trong build 1.1.59. Bảng thật lúc chạy là mảng đã serialize trong Main.unity, sinh bằng lặp có CẮT (v[i] = trunc3(v[i-1] × 1.08)), không phải dạng đóng 100·1.08^lv. Sai lệch: −10.2 % ở lv 50, ~6.5 lần ở lv 1 000.

Hệ quả: công thức của designer ≠ bảng mà game ship. Xem 09 §3.201 §5.7. Nguồn: [phân tích nội bộ].

Ba đính chính khác (mỗi cái rút lại hoặc thay thế một phát biểu trước đó):

Từng ghi Sự thật đã VERIFIED
"Đơn vị viết hoa ở text sát thương — đường code UNKNOWN" Là ART CỦA FONT. Chỉ một formatter (InfVal_change, 29 caller); không ToUpper nào; glyph a được vẽ thành "A". Đừng bao giờ thêm ToUpper.
"4 font có m_FontData rỗng — chúng thật sự rỗng" Chúng là BITMAP FONT (bảng 42 ký tự + atlas PNG). Bảng + PNG chính là font; thay bằng TTF đổi cả casing lẫn metrics.
"Thu nhập offline có thể cao hơn ~10 % nếu fallback chạy" RÚT LẠI — fallback không thể chạy (mảng đúng 10 001 phần tử, chỉ số kẹp [0,10000], một scene duy nhất). Giữ chỉ như bẫy khôi phục.

Và một phát hiện lớn: kinh tế OFFLINE là một mô hình thứ hai riêng biệt — không đi qua MoneyValue_return, bỏ qua Skin/Pet/Relic/buff ×3. Xem 01 §5.8.

Bài học phương pháp kèm theo: "field không xuất hiện trong dump.cs" không là bằng chứng rằng nó không được dùng — dump.cs chỉ liệt kê khai báo, không bao giờ liệt kê truy cập. Phải dùng xref của IDA (CodeRefsTo / DataRefsTo).

Đính chính đợt 3 — ba claim đã RÚT LẠI trong ledger (không được xuất hiện ở đây như sự thật)

Claim đã rút Sự thật G-id
"Không có component Gun_manager trong Main.unity" (chẩn đoán NRE trên thiết bị) Sai. Component có (fileID 106); .cs.meta của project bị đúc GUID mới khi dời file ⇒ Missing Script. Lỗi phương pháp: "0 lần xuất hiện của GUID X" khi chưa chứng minh X là GUID SOT G224 → G307, G308, G314
"Tree_manager.Game_Win phải là internalTree.Die_Reload gọi xuyên class" Sai. IDA gộp Tree.Die_Reload với Tree_manager.Tree_Destroyed; người gọi thật cùng class ⇒ Game_Win private như dump.cs G190 → G346
"LoadData.InitNewGame còn 17 call telemetry (15–31) chưa dựng" Sai. Quét quá end_ea sang ServerConfig_manager.LoadFromSaveData; InitNewGame = đúng 14 call, hoàn chỉnh từ batch 5 G208 → G324

Toàn bộ phương pháp đợt 3 (ctor bị bỏ rơi, hàm bị gộp, oracle SHA-256 cho blob, GUID scene, guard singleton) nằm ở 08 §3.6.


Toàn vẹn tệp

docs/framework/hashes.txt giữ sha256 + kích thước của mọi tài liệu trong thư mục này (kể cả docs 10 & 11 do lane khác biên soạn). Sinh lại bằng:

cd docs/framework && shasum -a 256 *.md

Bất kỳ lane nào sửa một tài liệu ở đây phải cập nhật hashes.txt và chạy tools/build_cookbook.sh (R10) — dashboard lệch là một lỗi.


Lane liên quan

  • [liveops catalog: liveops] — danh mục màn hình + cổng mở khoá (đang chạy). Doc 07 và 09 sẽ liên kết tới nó khi bàn giao, không chép lại nội dung.
  • [tài liệu nội bộ: codegen] — lane khôi phục thân method (nguồn của phần lớn bằng chứng disasm).
  • [restore project: CatGunner] — bản restore 1:1. Không bị bộ tài liệu này chạm vào.