บทนำ

การอัปเกรดเกมเอนจินกลางคันระหว่างพัฒนาโปรเจกต์ เป็นหนึ่งในการตัดสินใจประจำวันที่น่ากลัวที่สุดในการพัฒนาเกม Godot เวอร์ชันใหม่อาจแก้บั๊กที่กำลังขวางทางคุณอยู่ — หรืออาจทำให้ฉากที่คุณทุ่มเทงานมาหกเดือนพังไปอย่างเงียบ ๆ ก็ได้ นี่คือเหตุผลที่นักพัฒนามากประสบการณ์ในคอมมิวนิตี Godot มองการอัปเกรดเวอร์ชันเป็นการตัดสินใจเชิงความเสี่ยง ไม่ใช่งานประจำธรรมดา

คู่มือนี้ไม่ได้ชวนให้ "อัปเกรดเสมอ" แต่เป็นเช็กลิสต์บริหารความเสี่ยงสำหรับการย้ายจาก Godot 4.x ไป 4.x: วิธีตัดสินใจว่าควรอัปเกรดหรือไม่ตั้งแต่แรก, วิธีเตรียมตัวให้ถอยกลับได้อย่างปลอดภัย, จุดไหนที่รู้กันว่ามักพังระหว่างเวอร์ชัน และ — สำคัญที่สุด — วิธียืนยันจริง ๆ ว่าไม่มีอะไรพัง

ควรอัปเกรดเลยหรือไม่?

ก่อนแตะต้องอะไรทั้งสิ้น ให้ตอบคำถามนี้อย่างตรงไปตรงมา การอัปเกรดมีต้นทุนจริง (งานย้ายระบบ + การทดสอบซ้ำ) ดังนั้นประโยชน์ที่ได้ก็ต้องจริงพอ ๆ กัน

ควรอัปเกรดเมื่อ…

  • บั๊กที่แก้แล้วในต้นทางกำลังขวางทางคุณอยู่ หากปัญหาของคุณถูกแก้ไปแล้วในรีลีสที่ใหม่กว่า การอัปเกรดมักถูกกว่าการเลี่ยงปัญหาไปตลอดกาล
  • ฟีเจอร์ใหม่ให้ประโยชน์กับเกมของคุณอย่างเป็นรูปธรรม ไม่ใช่แค่ "ฟังดูดี" — แต่ต้องเป็นสิ่งที่ประหยัดเวลาพัฒนาจริง หรือปลดล็อกดีไซน์ที่คุณต้องการ
  • ไทม์ไลน์การพัฒนาของคุณยาว หากโปรเจกต์จะกินเวลาหลายปี การกระโดดสั้น ๆ บ่อย ๆ (ทีละหนึ่งเวอร์ชันไมเนอร์) ปลอดภัยกว่าการกระโดดครั้งใหญ่ครั้งเดียวตอนท้ายมาก ช่องว่างมีแต่จะกว้างขึ้นเรื่อย ๆ

ไม่ควรอัปเกรดเมื่อ…

  • ใกล้ถึงกำหนดรีลีส ช่วงไม่กี่สัปดาห์ก่อนวางจำหน่ายคือช่วงเวลาที่แย่ที่สุดในการนำการเปลี่ยนแปลงระดับเอนจินเข้ามา วางจำหน่ายก่อน อัปเกรดทีหลัง
  • คุณต้องใช้ C# + Web export การ export เว็บสำหรับโปรเจกต์ C# ยังใช้ไม่ได้ใน Godot 4.x (ติดตามได้ที่ godot#70796) หากคุณพึ่งพาสิ่งนี้ใน 3.x การย้ายไป 4.x จะทำให้มันหายไป
  • กลุ่มเป้าหมายของคุณใช้ฮาร์ดแวร์เก่า Godot 3.x ทำงานได้บน GPU ระดับ OpenGL 2 ส่วนเรนเดอเรอร์ Compatibility ของ Godot 4 ต้องใช้ OpenGL 3.3 / WebGL 2 หากผู้เล่นของคุณใช้เครื่องเก่า 3.x อาจเป็นเอนจินที่เหมาะสมจริง ๆ
  • แอดออนสำคัญยังไม่ถูกอัปเดต หากปลั๊กอินที่โปรเจกต์พึ่งพายังไม่รองรับเวอร์ชันใหม่ คุณจะต้องแบกปัญหาการย้ายระบบของมันเพิ่มจากของตัวเองอีกชั้น

หลักง่าย ๆ: อัปเกรดเมื่อประโยชน์ที่เป็นรูปธรรมคุ้มกับต้นทุนที่เป็นรูปธรรมที่คุณประเมินไว้แล้ว — ไม่ใช่เพียงเพราะมีเวอร์ชันใหม่ออกมา

ก่อนอัปเกรด — เช็กลิสต์การเตรียมตัว

ทุกขั้นตอนตรงนี้มีไว้เพื่อให้ถ้าการอัปเกรดผิดพลาด สิ่งที่คุณเสียคือช่วงบ่ายหนึ่งวัน ไม่ใช่ทั้งโปรเจกต์

  1. คอมมิตทุกอย่างแล้วสร้างบรานช์สำหรับอัปเกรด อย่าอัปเกรดสำเนาเดียวที่มีของโปรเจกต์เด็ดขาด บรานช์เฉพาะกิจ (หรือสำเนาโฟลเดอร์แบบเต็ม หากไม่ได้ใช้ git) ทำให้การย้อนกลับเป็นเพียงคำสั่งเดียว ไม่ใช่ภารกิจกู้ข้อมูล
  2. จดเวอร์ชันปัจจุบันแบบเป๊ะ ๆ ไว้ (เช่น เป็นบิลด์ 4.x.y ตัวไหน, ตัวมาตรฐานหรือ .NET) คุณจะต้องใช้มันหากต้องย้อนกลับหรือรายงานบั๊ก
  3. เก็บไบนารีตัวแก้ไขเวอร์ชันเก่าไว้ Godot หลายเวอร์ชันติดตั้งคู่กันได้ — ตัวแก้ไขเป็นไฟล์เรียกใช้งานไฟล์เดียว การเก็บไว้ทั้งสองตัวจึงไม่มีต้นทุน แถมยังเปิดบรานช์เก่าด้วยตัวแก้ไขเก่าได้ทุกเมื่อ
  4. ลิสต์รายการแอดออนแล้วตรวจเวอร์ชันที่แต่ละตัวรองรับ ไล่ดูใน addons/ จดว่าแต่ละตัวมาจากไหน แล้วยืนยันบนรีโพหรือหน้า Asset Library ว่ารองรับเวอร์ชันปลายทาง
  5. อ่านบันทึกการอัปเกรดอย่างเป็นทางการของทุกเวอร์ชันที่คุณข้ามผ่าน คู่มือการย้ายเวอร์ชันอย่างเป็นทางการถูกเขียนแยกตามเวอร์ชัน — หากย้ายจาก 4.2 ไป 4.4 ให้อ่านบันทึกทั้งของ 4.3 และ 4.4
  6. เก็บหลักฐานสถานะ "ที่รู้ว่าถูกต้อง" ไว้ ถ่ายสกรีนช็อตฉากสำคัญ อัดคลิปเกมเพลย์สั้น ๆ หรือ — ดีที่สุด — เขียนสถานการณ์ทดสอบอัตโนมัติ (จะพูดถึงเพิ่มเติมในหัวข้อการทดสอบด้านล่าง) หลังอัปเกรด คำถามว่า "หน้าตากับพฤติกรรมยังเหมือนเดิมไหม?" ตอบได้ก็ต่อเมื่อคุณบันทึกไว้ก่อนแล้วว่า "เหมือนเดิม" หมายถึงอะไร

ขั้นตอนการอัปเกรด

  1. เปิดสำเนาฝั่งบรานช์ด้วยตัวแก้ไขเวอร์ชันใหม่ เปิดบรานช์อัปเกรด ไม่ใช่ main ตัวแก้ไขใหม่จะเสนอให้แปลง/นำเข้าใหม่ — ให้ยอมรับ
  2. ปล่อยให้มันนำเข้าใหม่ โฟลเดอร์ .godot จะถูกสร้างขึ้นใหม่จากศูนย์ การนำเข้าครั้งแรกอาจใช้เวลานานในโปรเจกต์ขนาดใหญ่ และคำเตือนที่แสดงระหว่างรอบแรกนั้นมักไม่มีพิษภัย
  3. ตรวจหาข้อผิดพลาดใหม่ในแผง Output และ Debugger เทียบกับข้อผิดพลาดที่มีอยู่ก่อนแล้ว (จดไว้ก่อนแล้วใช่ไหม?) ข้อผิดพลาดใหม่คือรายการงานที่ต้องทำของการย้ายระบบ
  4. เล่นผ่านเส้นทางสำคัญ ๆ ด้วยตัวเอง เริ่มเกมใหม่ โหลดเซฟ รันลูปเกมเพลย์หลัก เปิดเมนูหลัก ๆ ข้อผิดพลาดฝั่งตัวแก้ไขคือของง่าย — พฤติกรรมตอนรันไทม์ต่างหากคือที่ซ่อนของ regression
  5. รันสถานการณ์ทดสอบ (ชุดที่เตรียมไว้ก่อนอัปเกรด) แล้วเปรียบเทียบกับ baseline
  6. ตรวจ diff ของ working tree ใน git ก่อนคอมมิต ตัวแก้ไขจะเขียนไฟล์ทับระหว่างการย้ายระบบ: project.godot ได้ค่าคอนฟิกใหม่, ไฟล์ .tscn ถูกบันทึกซ้ำ และไฟล์ .uid ใหม่อาจโผล่มา ตรวจ diff เพื่อให้รู้แน่ชัดว่าอะไรเปลี่ยนไปบ้าง — จากนั้นคอมมิตเป็นคอมมิตการย้ายระบบเดียวที่ติดป้ายชื่อชัดเจน

จุดพังที่รู้กันระหว่างเวอร์ชัน 4.x

เวอร์ชันไมเนอร์ของ Godot 4 เข้ากันได้ "เกือบทั้งหมด" แต่คำว่า "เกือบ" ในประโยคนี้แหละที่ต้องระวัง ต่อไปนี้คือการเปลี่ยนแปลงที่มีโอกาสกัดคุณมากที่สุด อ้างอิงจากบันทึกอย่างเป็นทางการและรายงานจากคอมมิวนิตี

4.2 → 4.3: TileMap ถูกเลิกใช้ แทนที่ด้วย TileMapLayer

Godot 4.3 เลิกใช้ (deprecated) โหนด TileMap แล้วแทนที่ด้วย TileMapLayer — หนึ่งโหนดต่อหนึ่งเลเยอร์ แทนการมีหลายเลเยอร์อยู่ในโหนดเดียว TileMap ที่มีอยู่ยังใช้งานได้ต่อ แต่โค้ดใหม่และโปรเจกต์ใหม่ควรใช้ TileMapLayer ตัวแก้ไขมีเครื่องมือแยกเลเยอร์ให้: เลือก TileMap ของคุณ เปิดแผง TileMap ด้านล่าง คลิกไอคอนกล่องเครื่องมือที่มุมขวาบน แล้วเลือก "Extract TileMap layers as individual TileMapLayer nodes"

หลุมพรางที่คอมมิวนิตีรายงาน: มีรายงานว่าบิตคอลลิชันของเลเยอร์ฟิสิกส์ใน TileSet ถูกรีเซ็ตกลับเป็นค่าเริ่มต้นหลังการย้ายไป TileMapLayer ไม่ได้เกิดกับทุกคน แต่รูปแบบความเสียหายนั้นร้ายกาจ (สิ่งต่าง ๆ หยุดชนกันโดยไม่มีข้อผิดพลาดใด ๆ) หลังแปลงแล้วให้ตรวจคอลลิชันของกระเบื้องอย่างชัดแจ้ง

4.3 → 4.4: ไฟล์ .uid และส่วนเพิ่มเติมของ GDScript

  • Godot 4.4 เพิ่มไฟล์คู่หู .uid ข้างสคริปต์และเชดเดอร์ ให้คอมมิตไฟล์เหล่านี้เข้า version control — การลบทิ้งอาจทำให้การอ้างอิง uid:// พังในทุกที่ที่ถูกใช้ (บันทึกการอัปเกรด 4.4 อย่างเป็นทางการครอบคลุมการเปลี่ยนแปลงที่เกี่ยวข้อง เช่น พาธของ @export_file ที่กลายเป็น uid://) ดูเหมือนไฟล์ขยะ แต่ไม่ใช่
  • Typed Dictionary และส่วนเพิ่มเติมอื่น ๆ ของ GDScript เข้ากันได้ย้อนหลัง — โค้ดเก่าของคุณยังรันได้ต่อ แต่แอดออนที่รับฟีเจอร์ใหม่ไปใช้จะหยุดทำงานบนเวอร์ชันเก่า พฤติกรรมของแอดออนจึงอาจต่างกันเมื่อข้ามเวอร์ชัน

โดยทั่วไป: ความเปลี่ยนแปลงเล็ก ๆ ระหว่างเวอร์ชันไมเนอร์ใด ๆ

การปรับจูนด้านเรนเดอริงระหว่างเวอร์ชันไมเนอร์อาจเปลี่ยนหน้าตาเกมของคุณอย่างแนบเนียน — แสง, anti-aliasing, การ snap แบบ 2D นอกจากนี้การพูดคุยในคอมมิวนิตียังมีเคส regression เฉพาะฉากที่ไม่เกิดซ้ำในโปรเจกต์ใหม่: ฉากหนึ่งทำงานเพี้ยนหลังอัปเกรด แต่พอสร้างฉากเดียวกันขึ้นใหม่ในโปรเจกต์สะอาดกลับทำงานปกติ หากมีอะไรพังโดยหาสาเหตุไม่ได้ ให้ลองลำดับการแยกปัญหานี้: ปิดตัวแก้ไข ลบโฟลเดอร์ .godot เปิดขึ้นมาใหม่แล้วปล่อยให้นำเข้าทุกอย่างอีกครั้ง; หากปัญหายังอยู่ ให้ทำซ้ำฉากนั้นในโปรเจกต์สะอาดเพื่อชี้ว่าตัวการคือสถานะที่สะสมในโปรเจกต์ของคุณ หรือเป็นการเปลี่ยนแปลงของเอนจินจริง ๆ

3.x → 4.x เป็นคนละเรื่องกันเลย

ทั้งหมดข้างบนเป็นเรื่องการข้ามจาก 4.x ไป 4.x การย้ายจาก Godot 3 ไป Godot 4 เป็นงานคนละหมวดโดยสิ้นเชิง: ไวยากรณ์ GDScript เปลี่ยน, โหนดจำนวนมากถูกเปลี่ยนชื่อ และ TileMap, ฟิสิกส์, เรนเดอริง ถูกรื้อทำใหม่จากฐานราก — แถมแอดออนส่วนใหญ่ต้องมีเวอร์ชันเฉพาะสำหรับ 4.x สำหรับโปรเจกต์ 3.x ขนาดใหญ่ ต้นทุนการย้ายอาจใกล้เคียงกับต้นทุนการสร้างใหม่ทั้งหมด และความคุ้มค่านั้นเป็นการตัดสินใจรายโปรเจกต์จริง ๆ การย้ายแบบนั้นสมควรมี (และก็มี) เอกสารเฉพาะของตัวเอง; บทความนี้จะไม่แสร้งทำเป็นครอบคลุมมัน

การทดสอบหลังอัปเกรด — คอขวดตัวจริง

พูดกันตรง ๆ: เหตุผลอันดับหนึ่งที่นักพัฒนาหลีกเลี่ยงการอัปเกรดไม่ใช่ตัวงานย้ายระบบ — แต่เป็นเพราะการยืนยันว่า "ไม่มีอะไรพัง" ด้วยมือนั้นแพงมาก การไล่ทดสอบ regression แบบแมนวลครบชุดในเกมขนาดกลางกินเวลาสุดสัปดาห์ได้ทั้งอัน และบั๊กรันไทม์ที่ผู้เล่นเจอหลังวางจำหน่าย เลวร้ายกว่าข้อผิดพลาดใด ๆ ในตัวแก้ไขมาก เพราะตอนนั้นมันกลายเป็นปัญหาชื่อเสียง ไม่ใช่แค่รายการงานค้าง

Smoke test แบบแมนวลขั้นต่ำ

  • เริ่มเกมใหม่จากหน้าไตเติล
  • โหลดไฟล์เซฟที่มีอยู่
  • เล่นลูปเกมเพลย์หลักสักสองสามนาที
  • ตรวจ UI ในทุกความละเอียดและโหมดหน้าต่างที่รองรับ

ทำการเปรียบเทียบก่อน/หลังให้เป็นอัตโนมัติ

การไล่ทดสอบด้วยมือขยายขนาดไม่ได้ และบอกคุณไม่ได้ว่าสไปรต์ขยับไปสองพิกเซล นี่คือสิ่งที่ Godot QA ถูกสร้างขึ้นมาเพื่อรับมือโดยเฉพาะ — test runner สำหรับ Godot แบบโอเพนซอร์ส ฟรี สัญญาอนุญาต MIT เวิร์กโฟลว์ของมันเข้ากับการอัปเกรดเวอร์ชันอย่างพอดิบพอดี:

  1. ก่อนอัปเกรด เขียน (หรืออัด) ไฟล์สถานการณ์แบบ JSON ให้ครอบคลุมเส้นทางสำคัญ แล้วเก็บสกรีนช็อต baseline บนเวอร์ชันเก่า
  2. หลังอัปเกรด รันสถานการณ์ชุดเดิมเป๊ะ ๆ พร้อมทำ pixel-diff เทียบกับ baseline บนเวอร์ชันใหม่
  3. จุดที่ล้มเหลวจะชี้ตำแหน่ง regression ให้ภายในไม่กี่นาที แทนการเล่นซ้ำด้วยมือทั้งสุดสัปดาห์

สถานการณ์หนึ่งชุดก็เป็นแค่รายการขั้นตอนในรูปแบบ JSON — อินพุต, การรอ, assertion, สกรีนช็อต:

{
  "name": "core_loop_smoke",
  "steps": [
    {"type": "wait", "seconds": 1.0},
    {"type": "input", "action": "ui_accept", "pressed": true},
    {"type": "wait", "seconds": 0.5},
    {"type": "assert", "node_path": "/root/Main/Player",
     "property": "health", "expected": 100, "operator": "eq"},
    {"type": "input", "action": "move_right", "pressed": true},
    {"type": "wait", "seconds": 2.0},
    {"type": "input", "action": "move_right", "pressed": false},
    {"type": "assert", "node_path": "/root/Main/Player",
     "property": "position:x", "expected": 100.0, "operator": "gt"},
    {"type": "screenshot", "name": "after_move"}
  ]
}

รูปแบบสถานการณ์เดียวกันนี้คือสิ่งที่เครื่องมือ run_test_scenario ของ Godot MCP Pro ใช้ ดังนั้นผู้ช่วย AI ที่เชื่อมต่อกับตัวแก้ไขของคุณจึงเขียนสถานการณ์เหล่านี้แทนคุณได้

ถ้ามีอะไรพัง

  1. ทำ bisect ตามเวอร์ชัน หากคุณข้ามหลายเวอร์ชันไมเนอร์ในครั้งเดียว ให้ลองอัปเกรดใหม่ทีละหนึ่งเวอร์ชันไมเนอร์เพื่อหาว่าพังตรงไหนกันแน่ วิธีนี้ลดขอบเขตการค้นหาจาก "ทุกอย่าง" เหลือ changelog เดียว
  2. ลบโฟลเดอร์ .godot แล้วปล่อยให้โปรเจกต์นำเข้าใหม่ แคชการนำเข้าที่ค้างเก่าเป็นต้นเหตุของอาการแปลก ๆ หลังอัปเกรดในสัดส่วนที่น่าประหลาดใจ
  3. ค้นหาข้อความ error แบบเป๊ะ ๆ ใน GitHub issues ของเอนจิน หากเป็น regression จริง มักมีใครสักคนรายงานไว้แล้ว — บางครั้งพร้อมวิธีเลี่ยงปัญหาด้วย
  4. ตรวจว่าตัวการคือแอดออนหรือไม่ ปิดแอดออนใน Project Settings แล้วทดสอบใหม่ หากปัญหาหายไป ตัวการคือแอดออน — ตรวจหารีลีสอัปเดตก่อนจะโทษเอนจิน
  5. ยอมรับว่าการอยู่กับเวอร์ชันเก่าต่อก็เป็นข้อสรุปที่ชอบธรรม หากต้นทุนการแก้ไขเกินประโยชน์ของการอัปเกรด ให้ revert บรานช์ อยู่ที่เดิมต่อ แล้วตั้งเตือนให้ลองใหม่เมื่อรีลีสถัดไปมาถึง นั่นไม่ใช่ความล้มเหลว — นั่นคือการบริหารความเสี่ยงที่ทำงานตามหน้าที่

เมื่อการอยู่ที่เดิมคือคำตอบที่ถูกต้อง

บางโปรเจกต์ก็ไม่ควรอัปเกรดเลย และเรื่องนี้ควรพูดให้ชัด ๆ: เกมที่วางจำหน่ายแล้วหรือใกล้วางจำหน่าย, โปรเจกต์ C# ที่ต้องใช้ web export, เกมที่มุ่งเป้าฮาร์ดแวร์เก่า และโปรเจกต์บนบิลด์เอนจินแบบกำหนดเองที่ถูกดัดแปลงมาก ในทุกกรณีเหล่านี้ เวอร์ชันที่คุณใช้อยู่กำลังทำหน้าที่ของมันได้ดี การอัปเกรดคือเครื่องมือ ไม่ใช่คุณธรรม — เป้าหมายคือเกมที่เสร็จสมบูรณ์ ไม่ใช่เอนจินป้ายแดง

คำถามที่พบบ่อย

ดาวน์เกรดหลังอัปเกรดได้ไหม?

ทำไม่ได้อย่างน่าเชื่อถือ เมื่อตัวแก้ไขใหม่บันทึกฉากและรีซอร์สของคุณซ้ำแล้ว ไฟล์เหล่านั้นจะไม่เข้ากันย้อนหลังกับตัวแก้ไขรุ่นเก่าอีก ทางกลับที่ปลอดภัยทางเดียวคือกู้คืนจาก version control — นั่นแหละคือเหตุผลที่บรานช์อัปเกรดถูกสร้างขึ้นมา

ควรข้ามหลายเวอร์ชันในครั้งเดียวไหม?

ข้ามทีละก้าวสั้น ๆ ปลอดภัยกว่า บันทึกการอัปเกรดอย่างเป็นทางการเขียนแยกตามเวอร์ชัน แต่ละก้าวจึงมีเช็กลิสต์ที่รู้กันชัดเจน — การกระโดดข้ามหลายเวอร์ชันจะกองทุกอย่างเข้ามาพร้อมกัน และทำให้บอกได้ยากขึ้นว่าการเปลี่ยนแปลงไหนทำอะไรพัง

เวอร์ชันไมเนอร์ทำอะไรพังได้จริงหรือ?

เกิดขึ้นน้อย แต่เกิดจริง โปรเจกต์ส่วนใหญ่ข้ามเวอร์ชันไมเนอร์ได้โดยไม่มีปัญหา แต่เคสขอบที่คอมมิวนิตีรายงานก็มีอยู่ — บิตคอลลิชันถูกรีเซ็ต, regression ด้านเรนเดอริงเฉพาะฉาก นี่แหละคือเหตุผลที่การทดสอบ baseline ก่อนอัปเกรดสำคัญ: มันเปลี่ยนคำถาม "มีอะไรพังหรือเปล่า?" จากความรู้สึกให้กลายเป็นการวัดผล

เช็กลิสต์นี้ใช้กับ 3.x → 4.x ได้ไหม?

ตัวเช็กลิสต์เองใช้ได้ — แตกบรานช์, เก็บไบนารีเก่า, เก็บ baseline, ทดสอบหลังย้าย ส่วนรายการจุดพังนั้นใช้ไม่ได้: การย้ายจาก 3 ไป 4 ใหญ่กว่ามาก (ไวยากรณ์ GDScript, โหนดที่ถูกเปลี่ยนชื่อ, ระบบที่ถูกรื้อใหม่) และมีเอกสารอย่างเป็นทางการเฉพาะของมันเอง