diff --git a/AGENTS.md b/AGENTS.md index 00a4e4d..18b8c33 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,76 +1,51 @@ -# 📜 G-Launcher Development Rules & Engineering Guidelines -> กฎและแนวทางการพัฒนา G-Launcher จากบทเรียนโปรเจกต์เดิมและคำแนะนำของ Horoyoi-san +# Repository rules ---- +## ห้าม hardcode ค่าที่เปลี่ยนตามสภาพแวดล้อมหรือการใช้งาน -### 1. 🏗️ แก้ที่ระบบหลังบ้านก่อน UI เสมอ (System-First Architecture) -* **คำแนะนำจาก Horoyoi:** *"ระบบมันรองรับ build zig แนะนำตอนแก้ ให้แก้ที่ระบบก่อน แล้วค่อยไปแก้ UI หน้าต่างต่างๆ ของ launcher ไม่งั้นเดี๋ยวพัง"* -* **แนวปฏิบัติ:** - 1. ทุกครั้งที่เพิ่มฟีเจอร์หรือแก้ไข logic ให้เริ่มที่ **Go Backend** (`internal/`, `pkg/`, `main.go`) ให้เสร็จสิ้น - 2. รัน `go vet ./...` เพื่อให้แน่ใจว่าไม่มี type error หรือ compilation error - 3. Generate หรืออัปเดต TypeScript Bindings (`@bindings/...`) - 4. จากนั้นจึงค่อยไปแก้ที่ **Frontend UI** (`frontend/src/`) เพื่อเชื่อมต่อกับ API / Event ของ Backend - 5. **เหตุผล:** Wails v3 มี Bindings และ Event IPC ที่ผูกกันแน่น หากแก้ UI ก่อนโดยที่ Backend ยังไม่พร้อม หน้าต่าง Launcher จะ crash หรือเกิด runtime exception ทันที +- ห้ามใส่ path ของเครื่อง, ชื่อผู้ใช้, Desktop, ไดรฟ์ติดตั้ง (`C:\...`), path ของเกม/Proxy/Server/Go/Node, IP, port, URL ของ deployment หรือ endpoint ลงใน source code, logic หรือ startup scripts +- ค่า URL, endpoint, และ repository config ต้องรวมศูนย์อยู่ที่ `pkg/constant/constant.go` หรือ config file กลางเท่านั้น ห้ามกระจายค่าคงที่หรือซ่อน hardcode ไว้ตาม service +- การเข้าถึง filesystem ภายในเครื่องต้องใช้ `filepath.Join(...)` เสมอ และโฟลเดอร์ข้อมูลผู้ใช้ต้องอ้างอิงผ่าน `os.UserConfigDir()` (`%APPDATA%`) เท่านั้น ห้ามเดาพาธจากไดรฟ์หรือชื่อโฟลเดอร์ +- ค่าเฉพาะเครื่องต้องอยู่ในไฟล์ local ที่ถูก ignore หรือ environment ห้าม commit ข้อมูลเฉพาะเครื่องเข้า Git +- ห้ามอ้างว่าเอา hardcode ออกหมดทั้ง repository หากตรวจหรือแก้เพียงบางส่วน ต้องระบุขอบเขตและส่วนที่ยังเหลือจริงตามความเป็นจริง ---- +## สถาปัตยกรรม System-First และลำดับการพัฒนา -### 2. 🚫 ห้าม Hardcode เด็ดขาด (Strict No-Hardcoding Rule) -* **ห้ามฝังค่าต่อไปนี้ในโค้ด logic โดยตรง:** - * URL, Domain, IP Address, หรือ Port (เช่น API Endpoint, Git Release URLs, Proxy URLs) - * File Path สัมบูรณ์ (ห้ามใส่ `C:\...` หรือ Drive Letter ใดๆ) - * ชื่อไฟล์หรือโฟลเดอร์เฉพาะทางที่อาจเปลี่ยนแปลงได้ -* **แนวปฏิบัติ:** - * รวมศูนย์ค่า Configuration ไว้ที่ [`pkg/constant/constant.go`](file:///c:/Users/Phitchayut/Desktop/G%20Launcher/pkg/constant/constant.go) หรือไฟล์ Configuration กลาง - * สำหรับ Path ให้ใช้ `filepath.Join(...)` เสมอ และเก็บข้อมูลผู้ใช้ไว้ที่ `os.UserConfigDir()` (`%APPDATA%`) - * เปิดช่องให้ผู้ใช้สามารถปรับแต่ง URL เซิร์ฟเวอร์, พร็อกซี หรือพารามิเตอร์ของเกมได้ผ่าน UI Settings หรือ Config File +- ทุกครั้งที่เพิ่มฟีเจอร์ ปรับแต่ง logic หรือแก้ schema ให้ทำที่ **Go Backend** (`internal/`, `pkg/`, `main.go`) ให้เสร็จสิ้นและรัน `go vet ./...` ผ่าน 100% ก่อนแตะ Frontend UI ทุกครั้ง +- เมื่อ Go Backend เปลี่ยนแปลง ต้องรัน `wails3 generate bindings` เพื่อซิงก์ TypeScript Bindings ลง `frontend/bindings/` ก่อนเริ่มเขียนหรือแก้ไข UI ใน `frontend/src/` +- ห้ามแก้ Frontend UI ให้เรียก method หรือ property ที่ยังไม่มีใน Go Backend เด็ดขาด เพราะจะทำให้ Wails v3 เกิด Unhandled Exception จนหน้าต่าง Launcher ขาวสนิทหรือ crash ทันที +- ห้ามอ้างว่าแค่ build ผ่านหรือไม่มี type error แปลว่าหน้าต่าง Launcher ทำงานถูกต้อง ต้องเปิดตรวจสอบการตอบสนองจริงหรือรายงานว่ายังรอการยืนยัน ---- +## กฎของระบบอัปเดตและบิลด์ท้องถิ่น (Updater Lifecycle Contract) -### 3. 🏷️ การเปลี่ยนชื่อและ References (Refactoring & Naming Rule) -* **คำแนะนำจาก Horoyoi:** *"ส่วนชื่อที่เป็น sunbringer หรือชื่อผมค่อยไปเปลี่ยนทีหลังนะ"* -* **แนวปฏิบัติ:** - * ห้ามใช้วิธี Find-and-Replace ชื่อโปรเจกต์เดิม (เช่น `sunbringer`, `firefly`) แบบสุ่มสี่สุ่มห้าทั่วทั้งโปรเจกต์ เพราะอาจกระทบ internal protocol, protobuf identifier, build manifest หรือ package bindings - * แยก User-Facing Branding (เช่น ชื่อหน้าต่าง, Title, Tooltip, Config metadata) ออกจาก System/Package naming ให้ชัดเจน - * เปลี่ยนชื่อส่วนที่จำเป็นเมื่อระบบ core นิ่งแล้วเท่านั้น +- ระบบอัปเดตทั้งในสคริปต์และในแอป ต้องทำงานตามลำดับ 4 ขั้นตอนอย่างเคร่งครัด: **ดาวน์โหลดลง Temp -> Build ใหม่ใน Temp -> นำมาสลับแทนที่ของเก่า -> ลบ Temp ทิ้ง 100%** +- ห้าม git pull หรือรัน compiler ทับโฟลเดอร์หลักของ Launcher ขณะที่ตัว Launcher รันอยู่โดยตรง เพราะจะติด Windows Executable File Lock (`Access is denied`) และทำให้โฟลเดอร์ทำงานเสียหาย +- การสลับไฟล์ `.exe` บน Windows ต้องใช้วิธี Rename ไฟล์เดิมที่กำลังรันอยู่เป็น `.old` ก่อน แล้วจึงย้ายไฟล์ใหม่เข้ามาแทนที่ หากเกิดข้อผิดพลาดระหว่างย้าย ต้อง Rollback นำไฟล์ `.old` กลับคืนมาทันที ห้ามทิ้งไฟล์ให้อยู่ในสถานะเสียหาย +- โฟลเดอร์ชั่วคราว (`temp/build_workspace` หรือ `os.MkdirTemp`) ต้องถูกลบทิ้ง 100% ผ่านบล็อก `finally` หรือ `defer os.RemoveAll` เสมอ ห้ามทิ้งไฟล์ขยะตกค้าง ---- +## ความปลอดภัยของข้อมูลและการแก้ไขไฟล์ตัวเกม (Data Safety & Atomic Operations) -### 4. 🛡️ ความปลอดภัยของข้อมูลและการ Rollback (Data Safety & Rollback) -* **บทเรียนจาก GaC-hkrpg-go / Ananta:** - * ไฟล์ตัวเกม Hoyoverse / Unity มีขนาดใหญ่มากและเสียหายได้ง่าย - * **Safe Backup:** ก่อนจะ Patch, แก้ไข หรือเขียนทับไฟล์ใดๆ ของเกม (เช่น `.dll`, `.exe`, asset binaries) จะต้องสำรองไฟล์เดิมไว้เป็นนามสกุล `.backup` เสมอ - * **Atomic Rollback:** หากการ Copy, Verify หรือ Download เกิดความล้มเหลว ระบบจะต้อง Rollback นำไฟล์สำรองกลับคืนมาทันที ห้ามทิ้งไฟล์เกมให้อยู่ในสภาพเสียหาย - * **Atomic Write สำหรับ Config:** การบันทึกไฟล์คอนฟิก (เช่น `game-selection.json`) ให้เขียนเป็น `.tmp` ก่อน แล้วใช้ Windows API `MoveFileEx` เพื่อป้องกันไฟล์เสียหายจากไฟดับหรือ crash +- ไฟล์ตัวเกมและไฟล์เซฟเป็นข้อมูลที่มีขนาดใหญ่และเสียหายง่าย ก่อนจะ patch, แก้ไข หรือเขียนทับไฟล์ใดๆ (เช่น `.dll`, `.exe`, `ExcelData`) ต้องคัดลอกไฟล์เดิมไว้เป็นนามสกุล `.backup` เสมอ +- หากการ patch, verify hash, หรือ download เกิดข้อผิดพลาด ต้องทำ Atomic Rollback กู้คืนไฟล์ `.backup` กลับมาทันที ห้ามทิ้งไฟล์เกมในสภาพเสียหาย +- การบันทึกไฟล์คอนฟิก (เช่น `game-selection.json`) ห้ามใช้ `os.WriteFile` ธรรมดา เพราะไฟดับหรือ crash จะทำให้ไฟล์กลายเป็น 0 ไบต์ ต้องเขียนลง `.tmp` พร้อม `file.Sync()` แล้วสลับด้วย Windows API `MoveFileEx` (`MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH`) เท่านั้น ---- +## การจัดการเครื่องมือและ Zero-Dependency -### 5. 🧰 Zero-Dependency & Portability First -* ไม่สมมติว่าเครื่องผู้ใช้ปลายทางมี Git, Zig หรือ 7-Zip อยู่ใน PATH -* ต้องมี Toolchain Helper และ Portable Runtimes ในตัว: - * **MinGit:** ใช้ระบบ Auto-download MinGit portable หากตรวจไม่พบ Git ในระบบ - * **Tools Extraction:** ดึง binary tools (`7za.exe`, `hpatchz.exe`, `zift.exe`) ออกจาก embed assets อัตโนมัติเมื่อเริ่มโปรแกรม +- ห้ามสมมติว่าเครื่องผู้ใช้มี Git, Go, Node.js หรือ 7-Zip อยู่ใน PATH สคริปต์ bootstrap ต้องมีระบบดาวน์โหลด portable runtime อัตโนมัติลงใน `tools/` +- ฝั่ง Launcher ต้องแตก binary tools (`7za.exe`, `hpatchz.exe`, `zift.exe`) ออกจาก embed assets ลง `bin/` อัตโนมัติเมื่อเริ่มโปรแกรม +- สคริปต์ PowerShell ทั้งหมดที่มีอักขระสองไบต์หรือภาษาไทย ต้องบันทึกเป็น UTF-8 with BOM (`[System.Text.Encoding]::UTF8`) เสมอ เพื่อป้องกัน Windows PowerShell 5.1 ตีความไบต์ผิด +- คำสั่ง Git ในสคริปต์และในโค้ด ต้องกำหนด `GIT_TERMINAL_PROMPT=0` เสมอ เพื่อป้องกันโปรเซสค้างจากการรอ interactive credentials prompt ---- +## การอนุรักษ์ Naming และการ Refactor -### 6. 🌿 Git Workflow & Code Hygiene -* **Active Branch:** ทำงานและ Commit บน branch **`Dev`** เท่านั้น -* **Pre-commit Verification:** - * ฝั่ง Go: `go vet ./...` ต้องผ่าน 100% - * ฝั่ง Frontend: `npm run build` ต้องผ่าน 100% -* **Clean Repository:** รักษาความสะอาดของ `.gitignore` ห้าม commit ไฟล์ `_references/`, `dist/`, `node_modules/`, `bin/`, `temp/`, หรือ `server/` เข้าสู่ Git +- ห้ามใช้วิธี Find-and-Replace ชื่อโปรเจกต์เดิม (เช่น `sunbringer`, `firefly`) สุ่มสี่สุ่มห้าทั่วทั้งโปรเจกต์ เพราะจะทำให้ internal protocol, protobuf serialization, หรือ build manifest พัง +- ให้แยก User-Facing Branding (เช่น ชื่อหน้าต่าง, Title, Tooltip) ออกจาก System/Package Identifier ภายในให้ชัดเจน เปลี่ยนเฉพาะส่วนที่จำเป็นเมื่อระบบ core นิ่งแล้วเท่านั้น ---- +## Git Workflow และความสะอาดของ Repository -### 7. 🚀 สถาปัตยกรรมระบบอัปเดต (Updater Rule) -* **กลไก 4 ขั้นตอน:** - 1. ดาวน์โหลด/Clone โค้ดลงโฟลเดอร์ชั่วคราว (`temp/build_workspace` หรือ `os.MkdirTemp`) - 2. คอมไพล์ Frontend และ Go Backend ภายในโฟลเดอร์ Temp - 3. นำไฟล์ใหม่มาแทนที่ตัวเดิม (`bin/G-Launcher.exe`) พร้อมระบบสำรอง `.old` และ Rollback - 4. ทำลายและลบโฟลเดอร์ Temp ทิ้ง 100% ผ่านบล็อก `finally` / `defer` ห้ามทิ้งไฟล์ขยะตกค้าง +- ทำงานและ Commit บน branch **`Dev`** เท่านั้น ห้ามแตะต้องหรือ push เข้า main โดยตรง +- ก่อน Commit ทุกครั้ง: Go ต้องผ่าน `go vet ./...` 100% และ Frontend ต้องผ่าน `npm run build` 100% +- รักษาความสะอาดของ `.gitignore` ห้าม commit ไฟล์ `_references/`, `dist/`, `node_modules/`, `bin/`, `temp/`, `tools/`, `server/`, หรือ `*.old` เข้า Git ---- +## การฟื้นตัวของ AI หลัง Compact บริบท -### 8. 📚 เอกสารความจำโครงการสำหรับ AI (Persistent Context & Compaction Recovery) -* โฟลเดอร์ [`Doc/`](file:///c:/Users/Phitchayut/Desktop/G%20Launcher/Doc/README.md) ถูกสร้างขึ้นเพื่อเก็บรายละเอียดทั้งหมดของโปรเจกต์ -* **เมื่อใดก็ตามที่ AI ฟื้นตัวหลังจากการทำ Compact บริบท หรือเริ่มเซสชันใหม่:** - * **ให้ AI อ่านไฟล์ในโฟลเดอร์ `Doc/` ทันที** เพื่อคืนความจำและทำความเข้าใจกฎ สถาปัตยกรรม และประวัติของระบบก่อนเริ่มทำงานเสมอ +- เมื่อ AI เริ่มเซสชันใหม่หรือฟื้นตัวหลังจากการทำ Compact บริบท ให้เปิดอ่านไฟล์ในโฟลเดอร์ `Doc/` (โดยเฉพาะ `Doc/G-LAUNCHER-HANDOFF.md`) ทันทีเพื่อคืนบริบทและทำความเข้าใจสถานะจริงก่อนเริ่มงานเสมอ diff --git a/Doc/DEVELOPMENT_RULES.md b/Doc/DEVELOPMENT_RULES.md index 29fd95d..01d9b9a 100644 --- a/Doc/DEVELOPMENT_RULES.md +++ b/Doc/DEVELOPMENT_RULES.md @@ -1,62 +1,68 @@ -# 📜 G-Launcher Development Rules & Engineering Guidelines -> กฎเหล็ก 6 ข้อและแนวทางปฏิบัติที่ต้องปฏิบัติตามอย่างเคร่งครัด โดยไม่มีข้อยกเว้น +# Repository rules (G-Launcher Development Rules) +> เอกสารกฎเกณฑ์การพัฒนา G-Launcher ฉบับทางการ อ้างอิงมาตรฐานเดียวกับ `AGENTS.md` --- -### 1. 🏗️ แก้ที่ระบบหลังบ้านก่อน UI เสมอ (System-First Architecture) -* **คำแนะนำจาก Horoyoi:** *"ระบบมันรองรับ build zig แนะนำตอนแก้ ให้แก้ที่ระบบก่อน แล้วค่อยไปแก้ UI หน้าต่างต่างๆ ของ launcher ไม่งั้นเดี๋ยวพัง"* -* **แนวปฏิบัติ:** - 1. ทุกครั้งที่เพิ่มฟีเจอร์หรือแก้ไข logic ให้เริ่มที่ **Go Backend** (`internal/`, `pkg/`, `main.go`) ให้เสร็จสิ้น - 2. รัน `go vet ./...` เพื่อให้แน่ใจว่าไม่มี type error หรือ compilation error - 3. Generate หรืออัปเดต TypeScript Bindings ด้วย `wails3 generate bindings` - 4. จากนั้นจึงค่อยไปแก้ที่ **Frontend UI** (`frontend/src/`) เพื่อเชื่อมต่อกับ API / Event ของ Backend - 5. **เหตุผล:** Wails v3 มี Bindings และ Event IPC ที่ผูกกันแน่น หากแก้ UI ก่อนโดยที่ Backend ยังไม่พร้อม หน้าต่าง Launcher จะ crash หรือเกิด runtime exception ทันที +## ห้าม hardcode ค่าที่เปลี่ยนตามสภาพแวดล้อมหรือการใช้งาน + +- ห้ามใส่ path ของเครื่อง, ชื่อผู้ใช้, Desktop, ไดรฟ์ติดตั้ง (`C:\...`), path ของเกม/Proxy/Server/Go/Node, IP, port, URL ของ deployment หรือ endpoint ลงใน source code, logic หรือ startup scripts +- ค่า URL, endpoint, และ repository config ต้องรวมศูนย์อยู่ที่ [`pkg/constant/constant.go`](../pkg/constant/constant.go) หรือ config file กลางเท่านั้น ห้ามกระจายค่าคงที่หรือซ่อน hardcode ไว้ตาม service +- การเข้าถึง filesystem ภายในเครื่องต้องใช้ `filepath.Join(...)` เสมอ และโฟลเดอร์ข้อมูลผู้ใช้ต้องอ้างอิงผ่าน `os.UserConfigDir()` (`%APPDATA%`) เท่านั้น ห้ามเดาพาธจากไดรฟ์หรือชื่อโฟลเดอร์ +- ค่าเฉพาะเครื่องต้องอยู่ในไฟล์ local ที่ถูก ignore หรือ environment ห้าม commit ข้อมูลเฉพาะเครื่องเข้า Git +- ห้ามอ้างว่าเอา hardcode ออกหมดทั้ง repository หากตรวจหรือแก้เพียงบางส่วน ต้องระบุขอบเขตและส่วนที่ยังเหลือจริงตามความเป็นจริง --- -### 2. 🚫 ห้าม Hardcode เด็ดขาด (Strict No-Hardcoding Rule) -* **ห้ามฝังค่าต่อไปนี้ในโค้ด logic โดยตรง:** - * URL, Domain, IP Address, หรือ Port (เช่น API Endpoint, Git Release URLs, Proxy URLs) - * File Path สัมบูรณ์ (ห้ามใส่ `C:\...` หรือ Drive Letter ใดๆ) - * ชื่อไฟล์หรือโฟลเดอร์เฉพาะทางที่อาจเปลี่ยนแปลงได้ -* **แนวปฏิบัติ:** - * รวมศูนย์ค่า Configuration ไว้ที่ [`pkg/constant/constant.go`](../pkg/constant/constant.go) - * สำหรับ Path ให้ใช้ `filepath.Join(...)` เสมอ และเก็บข้อมูลผู้ใช้ไว้ที่ `os.UserConfigDir()` (`%APPDATA%`) - * เปิดช่องให้ผู้ใช้สามารถปรับแต่ง URL เซิร์ฟเวอร์, พร็อกซี หรือพารามิเตอร์ของเกมได้ผ่าน UI Settings หรือ Config File +## สถาปัตยกรรม System-First และลำดับการพัฒนา + +- ทุกครั้งที่เพิ่มฟีเจอร์ ปรับแต่ง logic หรือแก้ schema ให้ทำที่ **Go Backend** (`internal/`, `pkg/`, `main.go`) ให้เสร็จสิ้นและรัน `go vet ./...` ผ่าน 100% ก่อนแตะ Frontend UI ทุกครั้ง +- เมื่อ Go Backend เปลี่ยนแปลง ต้องรัน `wails3 generate bindings` เพื่อซิงก์ TypeScript Bindings ลง `frontend/bindings/` ก่อนเริ่มเขียนหรือแก้ไข UI ใน `frontend/src/` +- ห้ามแก้ Frontend UI ให้เรียก method หรือ property ที่ยังไม่มีใน Go Backend เด็ดขาด เพราะจะทำให้ Wails v3 เกิด Unhandled Exception จนหน้าต่าง Launcher ขาวสนิทหรือ crash ทันที +- ห้ามอ้างว่าแค่ build ผ่านหรือไม่มี type error แปลว่าหน้าต่าง Launcher ทำงานถูกต้อง ต้องเปิดตรวจสอบการตอบสนองจริงหรือรายงานว่ายังรอการยืนยัน --- -### 3. 🏷️ การเปลี่ยนชื่อและ References (Refactoring & Naming Rule) -* **คำแนะนำจาก Horoyoi:** *"ส่วนชื่อที่เป็น sunbringer หรือชื่อผมค่อยไปเปลี่ยนทีหลังนะ"* -* **แนวปฏิบัติ:** - * ห้ามใช้วิธี Find-and-Replace ชื่อโปรเจกต์เดิม (เช่น `sunbringer`, `firefly`) แบบสุ่มสี่สุ่มห้าทั่วทั้งโปรเจกต์ เพราะอาจกระทบ internal protocol, protobuf identifier, build manifest หรือ package bindings - * แยก User-Facing Branding (เช่น ชื่อหน้าต่าง, Title, Tooltip, Config metadata) ออกจาก System/Package naming ให้ชัดเจน - * เปลี่ยนชื่อส่วนที่จำเป็นเมื่อระบบ core นิ่งแล้วเท่านั้น +## กฎของระบบอัปเดตและบิลด์ท้องถิ่น (Updater Lifecycle Contract) + +- ระบบอัปเดตทั้งในสคริปต์และในแอป ต้องทำงานตามลำดับ 4 ขั้นตอนอย่างเคร่งครัด: **ดาวน์โหลดลง Temp -> Build ใหม่ใน Temp -> นำมาสลับแทนที่ของเก่า -> ลบ Temp ทิ้ง 100%** +- ห้าม git pull หรือรัน compiler ทับโฟลเดอร์หลักของ Launcher ขณะที่ตัว Launcher รันอยู่โดยตรง เพราะจะติด Windows Executable File Lock (`Access is denied`) และทำให้โฟลเดอร์ทำงานเสียหาย +- การสลับไฟล์ `.exe` บน Windows ต้องใช้วิธี Rename ไฟล์เดิมที่กำลังรันอยู่เป็น `.old` ก่อน แล้วจึงย้ายไฟล์ใหม่เข้ามาแทนที่ หากเกิดข้อผิดพลาดระหว่างย้าย ต้อง Rollback นำไฟล์ `.old` กลับคืนมาทันที ห้ามทิ้งไฟล์ให้อยู่ในสถานะเสียหาย +- โฟลเดอร์ชั่วคราว (`temp/build_workspace` หรือ `os.MkdirTemp`) ต้องถูกลบทิ้ง 100% ผ่านบล็อก `finally` หรือ `defer os.RemoveAll` เสมอ ห้ามทิ้งไฟล์ขยะตกค้าง --- -### 4. 🛡️ ความปลอดภัยของข้อมูลและการ Rollback (Data Safety & Rollback) -* **บทเรียนจาก GaC-hkrpg-go / Ananta:** - * ไฟล์ตัวเกม Hoyoverse / Unity มีขนาดใหญ่มากและเสียหายได้ง่าย - * **Safe Backup:** ก่อนจะ Patch, แก้ไข หรือเขียนทับไฟล์ใดๆ ของเกม (เช่น `.dll`, `.exe`, asset binaries) จะต้องสำรองไฟล์เดิมไว้เป็นนามสกุล `.backup` เสมอ - * **Atomic Rollback:** หากการ Copy, Verify หรือ Download เกิดความล้มเหลว ระบบจะต้อง Rollback นำไฟล์สำรองกลับคืนมาทันที ห้ามทิ้งไฟล์เกมให้อยู่ในสภาพเสียหาย - * **Atomic Write สำหรับ Config:** การบันทึกไฟล์คอนฟิก (เช่น `game-selection.json`) ให้เขียนเป็น `.tmp` ก่อน แล้วใช้ Windows API `MoveFileEx` เพื่อป้องกันไฟล์เสียหายจากไฟดับหรือ crash - * **Binary Replacement Safety:** การอัปเดตไฟล์ `.exe` ของ Launcher ต้องเปลี่ยนชื่อตัวเก่าเป็น `.old` ก่อนสลับไฟล์ใหม่เข้ามา หากล้มเหลวต้อง Rollback คืนค่าเดิมทันที +## ความปลอดภัยของข้อมูลและการแก้ไขไฟล์ตัวเกม (Data Safety & Atomic Operations) + +- ไฟล์ตัวเกมและไฟล์เซฟเป็นข้อมูลที่มีขนาดใหญ่และเสียหายง่าย ก่อนจะ patch, แก้ไข หรือเขียนทับไฟล์ใดๆ (เช่น `.dll`, `.exe`, `ExcelData`) ต้องคัดลอกไฟล์เดิมไว้เป็นนามสกุล `.backup` เสมอ +- หากการ patch, verify hash, หรือ download เกิดข้อผิดพลาด ต้องทำ Atomic Rollback กู้คืนไฟล์ `.backup` กลับมาทันที ห้ามทิ้งไฟล์เกมในสภาพเสียหาย +- การบันทึกไฟล์คอนฟิก (เช่น `game-selection.json`) ห้ามใช้ `os.WriteFile` ธรรมดา เพราะไฟดับหรือ crash จะทำให้ไฟล์กลายเป็น 0 ไบต์ ต้องเขียนลง `.tmp` พร้อม `file.Sync()` แล้วสลับด้วย Windows API `MoveFileEx` (`MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH`) เท่านั้น --- -### 5. 🧰 Zero-Dependency & Portability First -* ไม่สมมติว่าเครื่องผู้ใช้ปลายทางมี Git, Go, Node.js หรือ 7-Zip อยู่ใน PATH -* ต้องมี Toolchain Helper และ Portable Runtimes ในตัว: - * **MinGit:** ใช้ระบบ Auto-download MinGit portable หากตรวจไม่พบ Git ในระบบ - * **Go & Node.js:** หากรันสคริปต์คอมไพล์ในเครื่องที่ไม่มีสภาพแวดล้อม สคริปต์จะดาวน์โหลด Portable Go 1.24 และ Portable Node.js v22 มาไว้ในโฟลเดอร์ `tools/` อัตโนมัติ - * **Tools Extraction:** ดึง binary tools (`7za.exe`, `hpatchz.exe`, `zift.exe`) ออกจาก embed assets อัตโนมัติเมื่อเริ่มโปรแกรม +## การจัดการเครื่องมือและ Zero-Dependency + +- ห้ามสมมติว่าเครื่องผู้ใช้มี Git, Go, Node.js หรือ 7-Zip อยู่ใน PATH สคริปต์ bootstrap ต้องมีระบบดาวน์โหลด portable runtime อัตโนมัติลงใน `tools/` +- ฝั่ง Launcher ต้องแตก binary tools (`7za.exe`, `hpatchz.exe`, `zift.exe`) ออกจาก embed assets ลง `bin/` อัตโนมัติเมื่อเริ่มโปรแกรม +- สคริปต์ PowerShell ทั้งหมดที่มีอักขระสองไบต์หรือภาษาไทย ต้องบันทึกเป็น UTF-8 with BOM (`[System.Text.Encoding]::UTF8`) เสมอ เพื่อป้องกัน Windows PowerShell 5.1 ตีความไบต์ผิด +- คำสั่ง Git ในสคริปต์และในโค้ด ต้องกำหนด `GIT_TERMINAL_PROMPT=0` เสมอ เพื่อป้องกันโปรเซสค้างจากการรอ interactive credentials prompt --- -### 6. 🌿 Git Workflow & Code Hygiene -* **Active Branch:** ทำงานและ Commit บน branch **`Dev`** เท่านั้น (ห้าม push สู่ main โดยตรง) -* **Pre-commit Verification:** - * ฝั่ง Go: `go vet ./...` ต้องผ่าน 100% - * ฝั่ง Frontend: `npm run build` ต้องผ่าน 100% -* **Clean Repository:** รักษาความสะอาดของ [`.gitignore`](../.gitignore) ห้าม commit ไฟล์ `_references/`, `dist/`, `node_modules/`, `bin/`, `temp/`, `tools/`, หรือ `server/` เข้าสู่ Git +## การอนุรักษ์ Naming และการ Refactor + +- ห้ามใช้วิธี Find-and-Replace ชื่อโปรเจกต์เดิม (เช่น `sunbringer`, `firefly`) สุ่มสี่สุ่มห้าทั่วทั้งโปรเจกต์ เพราะจะทำให้ internal protocol, protobuf serialization, หรือ build manifest พัง +- ให้แยก User-Facing Branding (เช่น ชื่อหน้าต่าง, Title, Tooltip) ออกจาก System/Package Identifier ภายในให้ชัดเจน เปลี่ยนเฉพาะส่วนที่จำเป็นเมื่อระบบ core นิ่งแล้วเท่านั้น + +--- + +## Git Workflow และความสะอาดของ Repository + +- ทำงานและ Commit บน branch **`Dev`** เท่านั้น ห้ามแตะต้องหรือ push เข้า main โดยตรง +- ก่อน Commit ทุกครั้ง: Go ต้องผ่าน `go vet ./...` 100% และ Frontend ต้องผ่าน `npm run build` 100% +- รักษาความสะอาดของ [`.gitignore`](../.gitignore) ห้าม commit ไฟล์ `_references/`, `dist/`, `node_modules/`, `bin/`, `temp/`, `tools/`, `server/`, หรือ `*.old` เข้า Git + +--- + +## การฟื้นตัวของ AI หลัง Compact บริบท + +- เมื่อ AI เริ่มเซสชันใหม่หรือฟื้นตัวหลังจากการทำ Compact บริบท ให้เปิดอ่านไฟล์ในโฟลเดอร์ [`Doc/`](./README.md) (โดยเฉพาะ [`Doc/G-LAUNCHER-HANDOFF.md`](./G-LAUNCHER-HANDOFF.md)) ทันทีเพื่อคืนบริบทและทำความเข้าใจสถานะจริงก่อนเริ่มงานเสมอ