‘Murder’ เอนจินเกม ECS สำหรับพิกเซลอาร์ตที่สร้างด้วย C#
(github.com/isadorasophia)- Murder Engine คือ เอนจินเกม ECS สำหรับพิกเซลอาร์ตที่สร้างอยู่บน FNA ขณะนี้ยังอยู่ระหว่างการพัฒนา จึงมีการเปลี่ยนแปลงบ่อยและคาดว่าจะมี breaking changes
- ตัวอย่างสำหรับเริ่มต้นมีโปรเจกต์เกมแจม neocityexpress และ hellomurder ซึ่งแสดงลำดับการสร้างเวิลด์ เอนทิตี และคอมโพเนนต์
- โครงสร้างโปรเจกต์แยก
gameกับgame.editorออกจากกัน และเลือกแนวทางที่ให้ผู้ใช้ ควบคุมเอดิเตอร์โดยตรง ภายในโปรเจกต์ของตนเอง โดยไม่มีeditor.exeแยกต่างหาก - สภาพแวดล้อมสำหรับพัฒนารองรับ Linux, MacOS, Windows, Steam Deck สิ่งที่ต้องมีคือ .NET 8 SDK ส่วนเป้าหมายของเกมรองรับ Linux, MacOS, Windows
- ขณะนี้ยังไม่มี แพ็กเกจ NuGet จึงแนะนำให้ใช้อ้างอิงใน
.csprojผ่าน git submodule และปัจจุบันยังไม่มีแผนรองรับเว็บและมือถืออย่างเป็นทางการ
ลักษณะและสถานะของ Murder Engine
- Murder Engine คือ เอนจินเกม ECS สำหรับพิกเซลอาร์ตที่ใช้ FNA เป็นพื้นฐาน
- เป็นเอนจินที่อยู่ระหว่างการพัฒนา แม้จะพยายามรักษา release branch ให้เสถียร แต่ควรคาดว่าจะมีการเปลี่ยนแปลงจำนวนมากและมีส่วนที่ยังไม่เสร็จสมบูรณ์
- README เตือนว่า “Proceed at your own risk” และระบุไว้อย่างชัดเจนว่าอาจมี breaking changes
ตัวอย่างเริ่มต้นและเส้นทางการเรียนรู้ ECS
- สำหรับผู้ใช้ที่ต้องการดูตัวอย่างอย่างรวดเร็วเพื่อทำความเข้าใจ แนะนำให้เริ่มจากโปรเจกต์ต่อไปนี้
- game jam project: โปรเจกต์เกมแจมที่ช่วยให้ดูสถาปัตยกรรมของ Murder ได้
- Hello World project: ตัวอย่างที่แสดงวิธีสร้างเวิลด์ เอนทิตี และคอมโพเนนต์
- สำหรับวิธีที่ ECS ถูกนำมาใช้ใน Murder มีคำแนะนำให้อ่านเอกสารของ Bang
- Bang คือ เฟรมเวิร์ก ECS ที่ Murder ใช้
โครงสร้างโปรเจกต์และรูปแบบเอดิเตอร์
- โครงสร้างโปรเจกต์ Murder แบ่งเป็น
resources,src/game,src/game.editorgameมีbin,packed,resourcesสำหรับเกมตัวสุดท้ายgame.editorมีbinและresourcesสำหรับเอดิเตอร์เกม
- ไม่มี
editor.exeภายนอก มีเพียงโปรเจกต์ของผู้ใช้เองเท่านั้น - โครงสร้างนี้เป็นตัวเลือกเพื่อให้สามารถควบคุมทั้งโปรเจกต์ได้โดยตรง คล้ายกับวิธีพัฒนาโปรเจกต์ MonoGame หรือ FNA
- เหตุผลที่แยกเอดิเตอร์เป็นโปรเจกต์ต่างหากคือเพื่อ ไม่ให้โค้ดของเอดิเตอร์แตะต้องโค้ดของเกม และให้ฝั่งเอดิเตอร์สามารถทำงานที่ต้องการได้อย่างอิสระ
การบิลด์และรูปแบบ dependency
- ขณะนี้ยังไม่มี แพ็กเกจ NuGet สำหรับ Murder
- แนวทางที่แนะนำคือวาง Murder ไว้เป็น git submodule แล้วอ้างอิงจาก
.csproj - ตัวอย่างการอ้างอิงอยู่ใน HelloMurder.csproj
ข้อกำหนดและแพลตฟอร์มที่รองรับ
- สภาพแวดล้อมสำหรับพัฒนาที่ใช้รันเอดิเตอร์รองรับ Linux, MacOS, Windows, Steam Deck
- ข้อกำหนดที่ต้องมีคือการติดตั้ง .NET 8 SDK
- แพลตฟอร์มเป้าหมายของเกมรองรับ Linux, MacOS, Windows
- Linux รวมถึง Steam Deck ด้วย
- การรองรับคอนโซลกำลังอยู่ระหว่างดำเนินการ
- เว็บและมือถือ iOS·Android ปัจจุบันยังไม่มีแผนรองรับอย่างเป็นทางการ
การมีส่วนร่วมและฟีดแบ็ก
- โปรเจกต์นี้ยังอยู่ในช่วงเริ่มต้นอย่างมาก
- สามารถติดต่อผู้สร้างเพื่อเสนอแนะหรือให้ฟีดแบ็กได้ และมีการระบุว่าสนใจการใช้งานจริงและฟีดแบ็ก
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เห็นว่ามีชื่อ saint11 อยู่ด้วย เลยมั่นใจว่าน่าจะดีมาก บทสอนพิกเซลอาร์ตจัดเรียงไว้ดีจริง ๆ: http://saint11.org/blog/pixel-art-tutorials/
เอนจินเกมใหม่ ๆ กับ เฟรมเวิร์ก ECS นี่ดูเพลินดี พอดู Bang ซึ่งเป็นส่วน ECS จะมีตัวอย่างคอมโพเนนต์อย่าง
CarComponentและระบบอย่างCarMoverSystemและดูเหมือนว่าระบบจะเป็นคลาส โดยอินเทอร์เฟซที่ implement จะเป็นตัวกำหนดว่ามันถูกรันเมื่อไรคล้าย DOTS อยู่เล็กน้อย แต่ยังหาไม่เจอว่าระบบถูกเพิ่มเข้าไปในเกมตรงไหน และระบบประเภทเดียวกันถูกจัดเรียงอย่างไร ก็อยากรู้ด้วยว่าระบบที่ทำหลาย query ต่างกัน เช่น รถกับสิ่งกีดขวาง จะมีหน้าตาแบบไหน
Bang ดูเหมือนจะใช้ ตัวสร้างซอร์สโค้ด อยู่ เมื่อเทียบกับ
GetComponentแล้วTryGetVelocity,RemoveFriction,SetVelocityน่าจะถูกสร้างขึ้นจากการมีอยู่ของคอมโพเนนต์Velocity,Frictionและยังไม่แน่ใจว่าอาจเป็นเพราะการแคช component ID หรือไม่มันไม่ได้อิง archetype แต่แต่ละ entity จะเก็บพจนานุกรม
component id => componentไว้ และแต่ละระบบจะติดตามว่า entity ใดตรงกับฟิลเตอร์ของตัวเอง ประสิทธิภาพจะดีแค่ไหนก็ไม่รู้ แต่สำหรับหลาย ๆ เกม ความสะดวกในการพัฒนาอาจสำคัญกว่าประสิทธิภาพการเปลี่ยนแปลงก็ดูเหมือนจะมีผลทันทีด้วย ถ้าอย่างนั้นเวลาระบบเพิ่ม/ลบคอมโพเนนต์ใน entity จนทำให้สถานะการตรงกับฟิลเตอร์เปลี่ยน ก็สงสัยว่าจะถูกประมวลผลใน tick เดียวกันหรือไม่ และจะขึ้นอยู่กับ entity ID หรือเปล่า
จากที่เปิดเอกสารดูคร่าว ๆ ยังไม่เห็นวิธีระบุ dependency หรือ order แบบชัดเจน เลยสงสัยว่าเอนจินนี้จัดการเรื่องนั้นอย่างไร
หน้า Itch และดาวน์โหลดเกมแจมที่สร้างด้วยเฟรมเวิร์กนี้: https://saint11.itch.io/neo-city-express
น่าประทับใจสำหรับเกมแจม 72 ชั่วโมง อาร์ตกับงานเขียนดี และยังมีความสนุกเชิงกลไกในแบบที่คาดไม่ถึงด้วย
ดีมาก ตัว editor ดูมีสไตล์สุด ๆ ชอบเลย ผมชอบ MonoGame มาตลอดเพราะประสิทธิภาพดีและข้ามแพลตฟอร์มได้ แต่ไม่เคยทำเกมใหญ่ ๆ มีแค่ทำเดโมเป็นครั้งคราว
ดูดีนะ สงสัยว่าในการพัฒนาเกมด้วย C# จะมีปัญหา GC pause หรือเปล่า
สำหรับฉากและเกมเพลย์สไตล์ Q3A นั้นเสถียรมาก มีองค์ประกอบในฉากที่เปลี่ยนทุก tick น้อยมากจน GC pause ส่วนใหญ่แทบมองข้ามได้
ใน .NET 6+ เมื่อเรียกซ้ำอย่างรวดเร็วแบบมีกลยุทธ์ในเอนจิน DIY วัด GC pause ได้ประมาณ 1–5ms การปิด concurrent/server/background GC ในการตั้งค่าโปรเจกต์ แล้วใช้ foreground + workstation GC ให้ jitter ต่ำที่สุด
ดูเหมือนทางเลือกจะมีแค่จัดการหน่วยความจำเอง 100% หรือเก็บขยะให้บ่อยที่สุดเท่าที่ทำได้ ใน .NET รุ่นใหม่ แทบเป็นไปไม่ได้ที่จะปิด GC โดยสิ้นเชิงโดยไม่ใช้มนตร์ดำอย่างการแฮก DLL ระดับต่ำ ถ้าสามารถรีสตาร์ตโปรเซสระหว่าง event งานหรือรอบเกมได้
Process.Exit()ก็ถือเป็นเทคนิค GC ที่ใช้ได้ในบางพื้นที่https://youtu.be/tzt36EGKEZo?si=WNxwcTPGFbJABKez
อ่านจากลิงก์อย่างเดียวแล้วยังไม่ค่อยรู้ แต่สงสัยว่าการทำ เกม F# ด้วย Murder game engine จะยากแค่ไหน
เคยลองใช้ ECS ใน Unity มานิดหน่อย แต่ ECS ของ Murder ง่ายกว่ามาก นักพัฒนาทำออกมาได้ดีจริง ๆ
ผมทำโปรเจกต์เกมอาร์เคดเล็ก ๆ ด้วย Murder และเล่นได้ที่นี่: https://nopetrides.itch.io/bombs-away
ในหน้าแนะนำตัวของ saint11 เขียนไว้แบบนี้: “Murder Engine: 2D Pixel art C# ECS Game Engine made by Isa! I usually help on the render and physics side of it.”
Isa: https://isadorasophia.com/projects/
ไม่เกี่ยวกับเกมเอนจิน แต่ตลกดีที่คนไม่หวังดีสามารถพูดได้ว่า “พวกเว็บไซต์แฮ็กเกอร์กำลังคุยกันเรื่อง murder”
ช่วงนี้ผมคิดบ่อยว่าข้อมูลที่ไม่มีพิษภัยเลยแบบนี้จะถูก คู่กรณีที่มุ่งร้ายอย่างดื้อรั้น นำไปใช้ได้อย่างไร
ถึงอย่างนั้น ถ้าเป็นกรณีที่โต้แย้งได้ง่ายแบบนี้ ผมก็ไม่แน่ใจว่าระหว่างการพูดว่า “ผู้คนกำลังคุยกันเรื่อง murder” กับการโกหกโต้ง ๆ จะต่างกันมากแค่ไหน
ECS คืออะไร?