1 คะแนน โดย GN⁺ 2023-12-10 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • 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.editor
    • game มี 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 ความคิดเห็น

 
GN⁺ 2023-12-10
ความคิดเห็นจาก Hacker News
  • เห็นว่ามีชื่อ saint11 อยู่ด้วย เลยมั่นใจว่าน่าจะดีมาก บทสอนพิกเซลอาร์ตจัดเรียงไว้ดีจริง ๆ: http://saint11.org/blog/pixel-art-tutorials/

    • เพิ่งเคยเห็นครั้งแรก แต่แค่กวาดตาดูคร่าว ๆ ก็ทำให้มั่นใจได้ว่าเป็น บล็อกที่ดีที่สุด ในอินเทอร์เน็ตทั้งหมด
    • ไม่รู้มาก่อนว่าเป็นคนเดียวกัน เคยดูบทสอนนี้มาก่อน และวิธีการคลี่เนื้อหาให้ดูนั้นยอดเยี่ยมมาก
    • ดูเหมือนว่า saint11 จะเป็นคนทำอาร์ตให้เกม Celeste
    • เขามีส่วนร่วมกับ Celeste และ Towerfall ซึ่งทั้งสองเกมมีพิกเซลอาร์ตที่ยอดเยี่ยม ดูเป็นคนมีพรสวรรค์มากจริง ๆ
  • เอนจินเกมใหม่ ๆ กับ เฟรมเวิร์ก 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 หรือเปล่า

    • ทำได้ค่อนข้างดีด้วยการจัดการออบเจ็กต์แบบง่าย ๆ และเรียก GC.Collect() อย่างชัดเจนทุก ๆ ช่วงที่เป็นตัวคูณเล็ก ๆ ของ simulation latency จุดที่เหมาะที่สุดดูจะขึ้นอยู่กับเนื้อหาในฉากและสไตล์เกมเพลย์ หรือก็คือวัตถุในฉากเปลี่ยนแปลงอย่างไร
      สำหรับฉากและเกมเพลย์สไตล์ 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 ที่ใช้ได้ในบางพื้นที่
    • มี Miguel de Icaza มีงานนำเสนอที่ดีเกี่ยวกับประวัติการเพิ่ม C# เข้าไปในเกมเอนจิน และเหตุผลที่เขาคาดหวังกับการใช้ Swift ใน Godot โดยอ้างว่า reference counting ของ Swift ช่วยหลีกเลี่ยงปัญหา GC pause
      https://youtu.be/tzt36EGKEZo?si=WNxwcTPGFbJABKez
    • ผมมองว่าปัญหา GC แทบจะมีเฉพาะฝั่ง Unity เท่านั้น เกมเอนจินอื่นที่ใช้ .NET ปกติอย่าง Stride ก็ทำงานได้ไม่มีปัญหา
    • มีอยู่ Unity แน่นอน และ Unreal ก็มี GC ด้วย ดังนั้นต้อง allocate ตอนเริ่มต้นและใช้ object pooling
    • C# ก็เขียนให้หลีกเลี่ยงการ allocate ได้เหมือนภาษาส่วนใหญ่
  • อ่านจากลิงก์อย่างเดียวแล้วยังไม่ค่อยรู้ แต่สงสัยว่าการทำ เกม 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”
    ช่วงนี้ผมคิดบ่อยว่าข้อมูลที่ไม่มีพิษภัยเลยแบบนี้จะถูก คู่กรณีที่มุ่งร้ายอย่างดื้อรั้น นำไปใช้ได้อย่างไร

    • ฟังดูฝืน ๆ หน่อย แต่ก็มีคนที่เอาบทความ The Onion มาเชื่อตามตัวอักษรจริง ๆ
      ถึงอย่างนั้น ถ้าเป็นกรณีที่โต้แย้งได้ง่ายแบบนี้ ผมก็ไม่แน่ใจว่าระหว่างการพูดว่า “ผู้คนกำลังคุยกันเรื่อง murder” กับการโกหกโต้ง ๆ จะต่างกันมากแค่ไหน
    • การคิดแบบนี้แต่กลับด้านกัน คือวิธีเดียวในการบริโภค ข่าวจากสื่อมวลชน ทุกวันนี้ทุกอย่างเอนเอียงและไร้สาระจนยากจะเชื่อ
  • ECS คืออะไร?

    • น่าจะหมายถึง Entity Component System เป็นสถาปัตยกรรมที่พบได้บ่อยในเกมเอนจิน
    • เป็นสถาปัตยกรรมประสิทธิภาพสูงที่กำลังเป็นที่นิยม Unity กำลังพยายามผลักดันให้แพร่หลายมากขึ้นในช่วงหลัง