Bevy 0.12 - เอนจินเกมแบบขับเคลื่อนด้วยข้อมูลที่สร้างด้วย Rust
(bevyengine.org)- เรนเดอเรอร์รองรับ Deferred Rendering แบบเลือกใช้ได้ โดยสามารถเลือกเส้นทาง forward หรือ deferred แยกตาม material และตั้งค่าเริ่มต้นแบบ global ได้ด้วย
DefaultOpaqueRendererMethod - สำหรับแอปหรือปลั๊กอิน Bevy เดิม ควรตรวจสอบขั้นตอน migration ผ่าน 0.11 to 0.12 Migration Guide
- Bevy Asset V2 รองรับการ preprocess asset, การตั้งค่าบนพื้นฐานไฟล์
.meta,AssetSourceหลายตัว, อีเวนต์โหลด dependency แบบ recursive, asset I/O แบบ asynchronous และ handle ที่ปรับปรุงดีขึ้น - การ preprocess asset เปิดใช้งานได้ด้วย
AssetPlugin { mode: AssetMode::Processed }และ Cargo featurebevy/asset_processorแต่ตอนนี้ยังไม่แนะนำสำหรับกรณีการใช้งานส่วนใหญ่ - บน Android แอปจะไม่ crash อีกต่อไปเมื่อถูก suspend และจะหยุดการทำงานของระบบไว้จนกว่าจะ resume พร้อมมีอีเวนต์
ApplicationLifetime::SuspendedและApplicationLifetime::Resumed - มีการเพิ่ม
specular_transmission,diffuse_transmission,thickness,ior,attenuation_color,attenuation_distanceให้กับ StandardMaterial เพื่อรองรับการแสดงผล material โปร่งผ่านอย่างแก้ว น้ำ พลาสติก ใบไม้ และกระดาษ - ตัวโหลด glTF รองรับส่วนขยาย
KHR_materials_transmission,KHR_materials_ior,KHR_materials_volume,KHR_materials_emissive_strengthและสามารถนำเข้า UV map ตัวที่สองจากTEXCOORD1หรือUV1ได้ - รองรับ batching/instancing อัตโนมัติสำหรับ draw command แล้ว โดยขณะนี้สามารถ batch entity ที่ใช้ material และ mesh เดียวกันได้ และสามารถยกเว้นด้วยคอมโพเนนต์
NoAutomaticBatching - เงาเพิ่ม PCF Shadow Filtering เพื่อรองรับเงาที่นุ่มขึ้นใน
DirectionalLightและSpotLightโดยวิธีค่าเริ่มต้นคือShadowMapFilter::Castano13 - ECS เพิ่ม one-shot systems ทำให้สามารถลงทะเบียน system แล้วเรียกใช้เมื่อจำเป็นผ่าน
SystemIdได้ แต่ยังไม่รองรับ exclusive system, system สำหรับ system piping, การเรียกตัวเอง หรือการประเมินผลแบบขนาน FixedTimeถูกถอดออกแล้ว และTimeจะคืนค่าที่สอดคล้องกับบริบทแม้ในFixedUpdateพร้อมป้องกัน “death spiral” ที่เกิดจากFixedUpdateสะสมมากเกินไปจนแอปค้าง- ใน
AnimationPlayer,set_elapsedถูกแทนที่ด้วยseek_to,stop_repeatingถูกแทนที่ด้วยset_repeat(RepeatAnimation::Never)และelapsedจะคืนค่าเวลาที่ผ่านไปจริงซึ่งไม่ขึ้นกับความเร็วแอนิเมชัน - การ import shader ของ Bevy เปลี่ยนเป็นไวยากรณ์สไตล์ Rust รองรับ
#import bevy_pbr::forward_io::VertexOutput, การ import หลายรายการด้วยวงเล็บปีกกา, partial path import และ fully qualified path - UI สามารถใช้ custom material shader กับโหนด UI ได้ผ่าน
UiMaterialและรองรับเส้นขอบรอบโหนดที่ไม่กินพื้นที่ layout ด้วยคอมโพเนนต์Outline - การผสานรวมด้านการเข้าถึงเพิ่ม resource
ManageAccessibilityUpdatesทำให้เมื่อค่าของมันเป็นfalseจะสามารถหยุดการอัปเดต accessibility tree อัตโนมัติของเอนจินได้
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
เมื่อเทียบกับเอนจินแบบดั้งเดิมอย่าง Unity หรือ Godot แล้ว Bevy มี วิธีสร้างเกมที่แตกต่างไปโดยสิ้นเชิง
มันจัดการทุกอย่างด้วยโค้ด Rust โดยไม่มี UI หรือสคริปต์ จึงใกล้เคียงกับ libGDX หรือ Cocos2D-x มากกว่า แต่เพราะใช้ ECS และ Rust วิธีเขียนโค้ดจึงต่างออกไปมากอีกที ให้ความรู้สึกเหมือนอยู่บนเกาะของตัวเองโดยแท้
อยากเห็นเกมอินดี้ที่ประสบความสำเร็จด้วย Bevy แต่มีแนวโน้มว่านักพัฒนาเกมส่วนใหญ่จะชอบเครื่องมือแบบดั้งเดิมที่ตนเรียนมาแล้วและคนรอบข้างก็ใช้กันอยู่มากกว่า จุดร่วมของคนที่อยากทำเกมและชอบ Rust ด้วยนั้นไม่ได้ใหญ่ และแม้ในกลุ่มนั้นก็ดูเหมือนจะมีหลายคนที่เลือกเครื่องมือที่มีความน่าเชื่อถือและมีแหล่งข้อมูลสะสมแล้ว มากกว่าจะทุ่มเวลาและแรงอย่างมากไปเรียนเอนจินใหม่ที่ยังเป็นเชิงทดลอง
โดยส่วนตัวคิดว่า Bevy ต้องมี IDE และภาษาสคริปต์ ที่อิง Bevy และ Rust แม้มันจะไม่ทำให้กำแพงที่ต้องลงแรงมากกับโปรเจกต์ใหม่หายไป แต่จะทำให้เป็นมิตรกับผู้ใช้ใหม่ที่ไม่มีประสบการณ์ Rust และรู้สึกหนักใจกับการเริ่มจากกำแพงของโค้ดมากขึ้นมาก ซึ่งต่างจากแนวทางของ Unity หรือ Godot ที่สามารถทำโปรโตไทป์พื้นฐานมาก ๆ บนแคนวาสได้ภายในไม่กี่ชั่วโมง
เท่าที่รู้ ผู้พัฒนาไม่เห็นด้วยกับภาษาสคริปต์ แต่คิดว่าจำเป็นต้องมี hot reload และการดีบักที่ลึกขึ้น และทำให้มีประสิทธิภาพด้วย Rust ล้วน ๆ ได้ยาก นักพัฒนาเกมจำนวนมากอาจรู้สึกหนักใจกับ Rust และ borrow checker ด้วย อย่างไรก็ตาม ตอนนี้ไม่มีเวลา ทรัพยากร และความตั้งใจที่จะลงมือทำเอง
เคยลองเล่น Bevy นิดหน่อยและตรวจดูรีโพซิทอรีแล้ว พบว่ามีการระบุ lifetime อยู่ 0 แห่ง
ภาษาสคริปต์อาจช่วยได้บ้าง แต่คนที่ใช้ Bevy ตอนนี้มีแนวโน้มทางเทคนิคสูงมาก และหลายครั้งก็ไม่ใช่นักออกแบบเต็มเวลา จึงดูเหมือนยังไม่มีความต้องการเร่งด่วนมากนัก
คาดหวังว่า community ของ Rust จะส่งผลต่อการพัฒนาเกม และอยากมีส่วนร่วมสักวัน แต่ตอนนี้ด้วยเหตุผลที่กล่าวมา คิดว่าจะคง pipeline C++/C# ไว้ก่อน จะเรียน Rust ให้จริงจังควบคู่ไป และเมื่อเครื่องมือเติบโตเต็มที่แล้วค่อยพิจารณาใช้ในโปรเจกต์ถัดไป
hot reload มักเป็นมาตรการชั่วคราวเมื่อเวลา compile เริ่มรับมือได้ยาก หากโดยเฉลี่ยอยู่ที่ 4 วินาที และ recompile ทั้งหมดราว 20 วินาที ความจำเป็นในการทุ่มทรัพยากรจำนวนมากเพื่อหลีกเลี่ยงการ compile ทั้งหมดก็จะลดลง
แต่ได้ยินว่า Rust โดยรวมมีเวลา compile ที่ยาวกว่า ดังนั้นความจำเป็นของ scripting หรือ hot reload อาจมาถึงเร็วกว่าที่คิด ถึงอย่างนั้นโปรเจกต์อินดี้ที่กำลังทำอยู่ในตอนนี้ก็น่าจะยังไม่ชนกำแพงนั้น
Cart ผู้ก่อตั้ง Bevy มองว่า Bevy ควรให้ความสำคัญกับ Rust เป็นอันดับแรก และส่วนตัวก็เห็นด้วย แต่นั่นไม่ได้หมายความว่าจะสร้างปลั๊กอินสำหรับภาษาสคริปต์หลาย ๆ ภาษาไม่ได้ และจริง ๆ ก็มีอยู่แล้วหลายตัว
เป็นผู้ก่อตั้ง Bevy และหัวหน้าโปรเจกต์ ถามอะไรก็ได้
Bevy และ community ยอดเยี่ยมมาก มี ticket บางอย่างที่ต้องทำ และการหาหนึ่งใน contributor หลักมาสนับสนุนแล้วผลักดันคำขอจนเสร็จเป็นเรื่องง่ายมาก ตัวอย่างเช่น morph target
Carter กำลังสร้างสิ่งที่สำคัญจริง ๆ และมีแรงผลักดันที่ยอดเยี่ยมอยู่เบื้องหลัง Bevy deploy บนเว็บได้ง่ายมาก และควรค่าให้คนจำนวนมากขึ้นลองดู community ก็ดี และขอความช่วยเหลือได้ง่าย
เอกสารจะปรับปรุงเมื่อไร? ถ้าดูจาก release notes ตามอุดมคติแล้วแต่ละฟีเจอร์ควรมีเอกสารหลายหน้า เข้าใจว่างานเยอะ และเอกสารครบทั้งชุดอาจเป็นไปได้หลังจากเสถียรแล้วเท่านั้น
Bevy เป็น เอนจินที่มีแนวทางชัดเจน แค่ไหน? อยากรู้ว่าเคยต้องประนีประนอมระหว่างฟีเจอร์กับการเข้าถึงได้ของนักพัฒนาหรือไม่
ตอนนี้โปรเจกต์แบบไหนที่เหมาะกับ Bevy ที่สุด?
มีปลั๊กอินสคริปต์อยู่หลายตัว และตอนนี้ดูเหมือนจะเน้นที่ rhai เป็นหลัก แต่รู้สึกว่ายังติดอยู่เพราะขาดการสนับสนุน Bevy ที่เหมาะสม
ไม่ว่าโฟกัสปัจจุบันของ Bevy จะเป็นเกมที่ใช้ Rust ล้วนหรือไม่ ก็มีความต้องการด้านสคริปต์อยู่ และมีคนที่ยุ่งอยู่กับการหาโซลูชัน third-party แล้ว ไม่ได้คาดหวัง official Bevy scripting ทันที แต่คิดว่า Bevy ควรยอมรับพื้นฐานที่ทำให้ crate ของ third-party ทำงานได้
ในบทความบอกว่า deferred rendering ไม่รองรับ MSAA แต่นั่นเป็นจริงเฉพาะกับ implementation แบบตรงไปตรงมาเท่านั้น
ตัวอย่างเช่น สามารถสร้าง stencil mask ของพิกเซลที่ซับซ้อนใน pre-pass แล้วใช้ hierarchical early stencil reject เพื่อรัน pass แบบ per-sample กับพิกเซลที่ซับซ้อน และรัน pass แบบ per-pixel กับพิกเซลอื่น ๆ ได้ การใช้ SIMD lane จะไม่สมบูรณ์แบบ
อีกวิธีคือมี pass สำหรับจัดการ mask ของพิกเซลที่ซับซ้อนและรวบรวมบัฟเฟอร์พิกัด
(x, y, sample)จากนั้นใน pass compute shader แบบ hybrid per-pixel/per-sample เดียวถัดไป ก็สามารถใช้ SIMD lane ได้อย่างสมบูรณ์ช่วงนี้กำลังทำเกมด้วย Bevy อยู่ ดูโค้ดได้และถามคำถามได้
https://ant.care/
https://github.com/MeoMix/symbiants
ปัญหาที่เจอมาจนถึงตอนนี้คือ ระบบ UI มันยืดยาวเกินไปสำหรับการทำวิดเจ็ตให้สะดวก เลยเปลี่ยนไปใช้ egui แต่คิดว่าภายใน 1 ปีน่าจะกลับมาใช้ Bevy แบบเนทีฟ เพราะ egui เองก็มีข้อจำกัดใหญ่เหมือนกัน
การรองรับความสัมพันธ์แบบพ่อแม่/ลูกมีไม่มาก และ ECS ก็มีโครงสร้างที่ค่อนข้างไม่ชอบเรื่องนี้อยู่ระดับหนึ่ง การติดป้ายกำกับให้สไปรต์ แล้วขยับ/หมุนสไปรต์โดยให้ป้ายกำกับตามแค่ตำแหน่งแต่ไม่หมุนตามนั้นยากกว่าที่คาดไว้
ยังไม่มีการรองรับการคงอยู่ของเอนทิตีข้ามเซสชันเป็นค่าเริ่มต้น Entity มีไว้สำหรับความเป็นเอกลักษณ์เฉพาะฝั่งไคลเอนต์ และการสร้างความสัมพันธ์พ่อแม่/ลูกที่บันทึกไว้ขึ้นมาใหม่อย่างง่ายก็ไม่ได้ทำให้อัตโนมัติ
ตอนนี้ยังไม่รองรับ WASM parallelism แต่สถาปัตยกรรมของ Bevy ออกแบบหลายส่วนให้จัดลำดับระบบได้ยืดหยุ่น เพื่อให้ได้ประโยชน์ด้านประสิทธิภาพจากการทำงานแบบขนาน
การ query เชิงพื้นที่รู้สึกเหมือนขัดกับเป้าหมายของ ECS พออยากค้นหาด้วยค่า Position แทนที่จะค้นหาตามประเภท เช่น เอนทิตีมี Position หรือไม่ ก็จะเกิดแคชเสริมจำนวนมากที่ต้องซิงก์กับเอนจิน query
เมื่อเปลี่ยนแปลง world ด้วย
commandsการทำงานจะถูกหน่วงไว้เพื่อให้ประมวลผลเป็นชุดเพื่อประสิทธิภาพ แต่ถ้ามีพฤติกรรมแบบหน่วงจำนวนมาก ก็ทำให้สร้างระบบที่เปลี่ยน world อย่างจริงจังได้ยาก เลยต้องเรียกapply_deferredบ่อย ๆ และต้องใช้คำสั่งแบบกำหนดเองเพื่อแก้ปัญหา race conditionWASM บน Android โดยเฉพาะชุด Pixel 6 กับ Chrome ตอนนี้ยังใช้งานไม่ได้ แต่เป็นปัญหาของ dependency ระดับล่าง จึงมีกำหนดจะแก้ใน Bevy 13
ข้อดีคือการผสมกันระหว่างเอนจิน Rust กับเกม Rust ทำงานด้วยดีมาก และ Rust+WASM ก็แทบไม่รู้สึกว่าเทคโนโลยีเป็นตัวฉุดเลย เมื่อสมองเริ่มคิดแบบ ECS แล้วก็ยากจะย้อนกลับ และมันยืดหยุ่นมาก อาจจะยืดหยุ่นเกินไปด้วยซ้ำ
ชุมชนคึกคัก ทำให้หาคนคุยเรื่องปัญหาได้ง่าย เอกสารมีไม่มากแต่มีตัวอย่างเยอะ มองอนาคตในแง่ดีได้มาก อัตราการพัฒนาเร็ว และแต่ละรีลีสก็ผลักดันประเด็นกังวลหลัก ๆ ไปได้มาก
บันทึกประจำรีลีส ยอดเยี่ยมมาก
สำหรับนักพัฒนาเกม/เอนจินที่มีประสบการณ์ บางส่วนอาจพื้นฐานเกินไป แต่จากมุมมองของคนที่ไม่ได้อยู่ในโลกนั้นตลอดเวลา สมดุลระหว่างการอธิบายการเปลี่ยนแปลงกับการอธิบายหัวข้อทำได้ดีมาก
เคยเห็นมุกว่า เกมที่เขียนด้วย Rust มี 5 เกม แต่เอนจินเกมมี 50 ตัว
จริง ๆ แล้วมี รายชื่อเกมที่เขียนด้วย Bevy ไหม?
Tiny Glade (https://pouncelight.games/tiny-glade) ได้รับความนิยมมากและปรากฏบนโซเชียลมีเดียเยอะ ใช้ Bevy ECS / Bevy App กับเรนเดอเรอร์แบบคัสตอม https://store.steampowered.com/app/2198150/Tiny_Glade/
tunnet (https://puzzled-squid.itch.io/tunnet), Noumenal (https://noumenal.app/), Foresight Mining (https://www.foresightmining.com/) ก็มีเช่นกัน Foresight Mining เป็นซอฟต์แวร์ “CAD” สำหรับการทำเหมือง และจ้างนักพัฒนา Bevy หลายคน
Axie Infinity: Homeland (https://app.axieinfinity.com/games/homeland-alpha/) ใช้ Bevy ECS กับ Unity นอกจากนี้ยังมี Shifting Chamber (https://maciekglowka.itch.io/shifting-chamber), Hytopia (https://hytopia.com/)
Titleless Comfy City Builder (https://twitter.com/i_am_feenster/status/1710714877231186323), Molecoole (https://store.steampowered.com/app/1792170/Molecoole/), Titleless industrial revolution builder (https://twitter.com/ElmoSampedro/status/1684920884811698176) ก็มีด้วย
Jarl Game (https://twitter.com/jarl_game) เป็นเกมแนว Dwarf Fortress ที่มีแสงแบบไดนามิกสวยงาม
ในแท็ก “bevy” ของ itch.io มีเกมหลายร้อยเกม: https://itch.io/games/tag-bevy
ช่อง #showcase ใน Bevy Discord ก็มีกิจกรรมมาก
เฟรมเวิร์กทุกตัวมักเริ่มต้นด้วยการบอกว่าจะทำสิ่งที่มีอยู่เดิมให้ เรียบง่าย สะอาด และเร็วขึ้น แต่ก็ขาดฟีเจอร์หวือหวา
แล้วพอไล่เติมฟีเจอร์ให้ทัน ก็กลายเป็นสัตว์ประหลาดที่ซับซ้อนไม่ต่างกัน และวัฏจักรก็วนซ้ำ
ข้อสรุปฟังดูเหมือน “ซอฟต์แวร์ที่ใช้ง่ายทุกตัวที่เพิ่มฟีเจอร์เข้าไปย่อมล้มเหลว” ซึ่งออกจะดราม่าไปหน่อย
อยากรู้ว่ามีความคิดหรือความกังวลที่เฉพาะเจาะจงเกี่ยวกับสถาปัตยกรรมของ Bevy หรือวิธีเพิ่มฟีเจอร์ของ Bevy ไหม เรากำลังพยายามอย่างเต็มที่เพื่อหลีกเลี่ยงชะตากรรมนั้น
Tiny Glade ใช้ bevy_ecs แต่ไม่ได้ใช้ crate สำหรับเรนเดอร์ของ Bevy เลย ส่วนตัวผมเองก็มี PR อยู่หลายอันที่เกี่ยวกับการทำเส้นทางเรนเดอร์ทางเลือก เช่น ray tracing หรือการเรนเดอร์แบบ GPU-driven meshlet + visibility buffer ซึ่งแทบไม่ต้องเปลี่ยนภายในของ Bevy เลย
จากมุมผู้ใช้ก็แทบไม่ต่างกัน เพิ่ม FeatureFooPlugin เข้าไปในแอป แล้วใช้สิ่งอย่าง FooComponent ก็ทำงานได้
crate หรือปลั๊กอินแต่ละตัวอาจบวมได้ แต่ Bevy โดยรวมจะยังโอเค ผู้ใช้ก็แค่ไม่สนใจปลั๊กอินเหล่านั้น แล้วใช้อย่างอื่นที่เหมาะกับตัวเองกว่า
อีกอย่าง นี่คือเกมเอนจิน โดยนิยามแล้วมันเป็นสัตว์ประหลาดที่บวมและซับซ้อน และเพราะบางฟีเจอร์อาจมีประโยชน์กับบางเกม มันจึงดูดซับฟีเจอร์สารพัดเข้ามา ประเด็นสำคัญคือความบวมของฟีเจอร์ส่งผลต่อการใช้งานอย่างไร ต่อให้มีฟีเจอร์ 1,000 อย่าง แต่ถ้าไม่จำเป็นต้องไปปฏิสัมพันธ์กับส่วนใหญ่เลย ก็ไม่เป็นปัญหา
ที่บอกว่าโปรเจกต์ใหม่ที่ไม่ต้องกังวลเรื่องความเข้ากันได้ย้อนหลังทำได้ง่ายกว่านั้นก็ถูก จากที่ผมเห็น Bevy มีวัฒนธรรมที่ให้ความสำคัญกับประสบการณ์ใช้งานที่ดีสำหรับผู้ใช้ และพยายามลดพื้นผิวของ API ลง อาจเป็นเพราะระบบแพ็กเกจของ Rust ด้วยก็ได้ แต่ผมมองในแง่ดี เพราะค่อนข้างพร้อมจะแตกหักกับอดีตเพื่อสิ่งนี้
ข้อดีของ cargo คือแม้จะตัดสินใจพึ่งพา Bevy ต่อให้เวอร์ชันในอนาคตมี breaking change คุณก็ไม่จำเป็นต้องไล่ตามเป้าหมายที่ขยับไปเรื่อย ๆ แค่อยู่กับเวอร์ชันของตัวเองก็พอ ถึงอย่างนั้นก็ยังมีไกด์ให้ย้ายไปเวอร์ชันล่าสุดได้ง่ายด้วย อย่างน้อยจากประสบการณ์ที่ผมเคยลองแตะ Bevy มาบ้างก็เป็นแบบนั้น
ตอนอัปจาก 0.10 เป็น 0.11 ต้องแก้แอปค่อนข้างเยอะ แต่ครั้งนี้ คอมไพล์ผ่านทันที
Bevy เป็นหนึ่งในเกมเอนจินที่ผมชอบ โดยเฉพาะกับโปรเจกต์ใหญ่ ๆ การประมวลผลล่วงหน้า Asset V2 และไฟล์
.metaดูมีประโยชน์มากรอคอยการรองรับ lightmap ในรีลีสถัด ๆ ไปด้วย
ระหว่างดูตัวอย่างเว็บ ผมไปดูส่วน UI แล้วเหมือนทุกอย่างถูกจัดการอยู่ใน canvas
จะสร้าง UI ด้วย DOM แทน แล้วเชื่อมกับ WASM ได้ไหม?
ฝั่ง Rust หรือก็คือฝั่ง WASM มีวิธีอย่าง web_sys ส่วนฝั่ง JavaScript ก็มีวิธีเรียกฟังก์ชัน WASM จึงมีตัวเลือกเยอะ