4 คะแนน โดย GN⁺ 2024-09-23 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • โปรเจกต์นี้มีเป้าหมายสร้าง Flappy Bird โคลนสำหรับ Android ด้วย C พร้อมลดขนาด APK ให้ ต่ำกว่า 100KB
  • หลังจากได้รู้จัก rawdrawandroid ในปี 2021 ผู้พัฒนาต้องการสร้างเกมที่มี APK ขนาดเล็ก และการได้เห็น C# Flappy Bird ใน Raylib Discord เมื่อเดือนกันยายน 2024 ก็เป็นจุดเริ่มต้นให้ลองทำเวอร์ชัน C
  • วิธีการพัฒนาคือแพ็กเกจไลบรารีเนทีฟที่เขียนด้วย C ลงใน APK และผสานการทำงานของ OpenGL ES 2, เชดเดอร์ และ Android Native Activity
  • เสียงถูก บีบอัดเป็น MP3 และเล่นผ่าน OpenSLES ส่วนการถอดรหัส PNG ใช้ upng
  • รองรับการบิลด์ด้วย Visual Studio Code บน Windows และ Makefile บน Linux/macOS พร้อมระบุว่าสิทธิ์ในเกมและทรัพยากรเป็นของ DotGEARS

เป้าหมายและที่มาของโปรเจกต์

  • Flappy Bird in C คือโปรเจกต์ที่ต้องการเขียน Flappy Bird โคลนที่ทำงานบน Android ด้วย C และคงขนาด APK ให้ ต่ำกว่า 100KB
  • จุดเริ่มต้นมาจาก rawdrawandroid ที่ได้รู้จักในปี 2021 โดยเป้าหมายคือทำเกมที่ทั้งเข้าใจได้และน่าสนใจ พร้อมลดขนาด APK ให้เล็กที่สุด
  • Flappy Bird มีตัวอย่างการพอร์ตไปหลายภาษาอยู่แล้ว จึงถูกเลือกเป็นเป้าหมายในการทำโคลนอย่างเป็นธรรมชาติ

ความพยายามก่อนหน้าและปัญหา

  • ในปี 2021 ผู้พัฒนาได้ศึกษา Raylib และความพยายามครั้งแรกในการสร้างเกมด้วย C++ โดยใช้ ImGui ก็ล้มเหลว
  • ปัญหาในตอนนั้นมีหลายอย่าง
    • ขนาด APK อยู่ที่ประมาณ 1MB
    • เกมเกิดการแครช
    • ภายใน APK มีเพียงไลบรารี armeabi-v7a
    • ตามข้อกำหนดของ Google ในปี 2022 จำเป็นต้องมีไลบรารี arm64-v8a ด้วย

แรงจูงใจในการลองใหม่ปี 2024

  • หลังจากเห็น C# Flappy Bird ในช่อง Raylib Discord เมื่อเดือนกันยายน 2024 ผู้พัฒนาจึงเริ่มลองสร้าง Flappy Bird สำหรับ Android ด้วย C และทำให้ APK มีขนาดต่ำกว่า 100KB
  • แม้เป้าหมายจะดูไม่สมจริง แต่ความท้าทายเชิงแข่งขันก็กลายเป็นแรงผลักดันในการลงมือทำ

วิธีการพัฒนา

  • จุดเริ่มต้นคือการคอมไพล์ Hello World ที่เขียนด้วย C และแพ็กเกจไลบรารีนั้นลงใน APK
  • เสียงถูกบีบอัดเป็น ไฟล์ MP3 และเล่นด้วย OpenSLES
  • สำหรับการถอดรหัสไฟล์ PNG เลือกใช้ upng
  • งานกราฟิกและการเชื่อมต่อกับ Android ใช้ OpenGL ES 2, เชดเดอร์ และ Android Native Activity ร่วมกัน

วิธีบิลด์

  • บน Windows ใช้สภาพแวดล้อม Visual Studio Code เป็นหลัก
    • สร้าง .env จาก .env.example
    • รัน build.bat
  • บน Linux และ macOS สามารถบิลด์ได้ด้วย Makefile ที่ให้มา
    • จำเป็นต้องติดตั้ง Android command-line tools
    • ตั้งค่าตัวแปรสภาพแวดล้อมในไฟล์ .env ที่รากโปรเจกต์
    • เข้า cd FlappyBird แล้วรัน make
  • ขั้นตอนการบิลด์แบบละเอียดเพิ่มเติมให้ดูที่ BUILDING.md
  • APK ที่เซ็นแล้วจะถูกสร้างไว้ที่ FlappyBird/app/build/outputs/apk/FlappyBird-signed.apk

ลิขสิทธิ์และโปรเจกต์อ้างอิง

  • ผู้เขียนโปรเจกต์ระบุว่าไม่ได้อ้างสิทธิ์ลิขสิทธิ์ และสิทธิ์ในตัวเกมกับทรัพยากรเป็นของ DotGEARS
  • โปรเจกต์ที่เป็นแรงบันดาลใจมีดังนี้

1 ความคิดเห็น

 
GN⁺ 2024-09-23
ความคิดเห็นจาก Hacker News
  • อยากให้ App Store มีตัวกรอง ดูเฉพาะแอปต่ำกว่า 10MB
    แอปที่เร็วที่สุดและมีโฆษณา/ไมโครทรานแซกชันน้อย มักจะเป็นแอปขนาดเล็ก
    มีโอกาสสูงมากที่จะพอใจกับแอปเทอร์โมมิเตอร์ขนาด 3MB มากกว่าแอปเทอร์โมมิเตอร์ขนาด 150MB

    • เมื่อก่อนใน Play Store เคยมีผู้เผยแพร่ที่ลงแอปเล็กมาก ๆ อย่าง ไฟฉาย, ซูโดกุ, ปฏิทิน ขนาดหลัก KB หลักเดียว แต่ตอนนี้หาไม่เจอแล้ว
      แอปพวกนั้นเล็กจริง ๆ ถึงขั้นทั้งหมดต่ำกว่า 200KB
    • นึกถึงเหตุผลหนึ่งที่เลิกทำงานพัฒนาแอปมือถือ
      นายหน้าจัดหางานมักเรียกร้องผลงานให้โชว์ราวกับเป็นพอร์ตโฟลิโองานศิลป์ แม้กับแอปที่ไม่มีอยู่แล้วหรือเซิร์ฟเวอร์โปรดักชันปิดไปแล้วก็ตาม
      เกณฑ์ที่ยิ่งตามอำเภอใจไปกว่านั้นคือการตรวจว่าเคยทำ แอปใหญ่ ไหม และถ้าคุณใช้เทคนิคปรับแต่งประสิทธิภาพดูมีฝีมือจำนวนมากจนทำเป็นแพ็กเกจ 8–12MB ได้ มันกลับถูกมองเหมือนเป็นสัญญาณว่าแอป/บริการ/ฐานผู้ใช้มีขนาดเล็ก
      ในความเป็นจริง ต่อให้มียอดดาวน์โหลดและผู้ใช้นับร้อยล้านก็ไม่เกี่ยวอะไรกับเกณฑ์นั้นเลย และวงการนี้มีแรงจูงใจมหาศาลให้สร้าง แอปที่บวมเทอะทะ
    • ยังรู้สึกแปลกใจอยู่เลยที่แอป Android มักจะเล็กกว่ามาก
      เช่น ต้องค้นหาไปตั้ง 9 รอบรวมโฆษณาด้วย กว่าจะเจอแอปเทอร์โมมิเตอร์ที่เกิน 7MB
      เคยทำงานบนทั้งสองแพลตฟอร์มมาหลายปี แต่ก็ไม่แน่ใจเหตุผลที่แท้จริง เดาว่าอาจเป็นเพราะ Android มีธรรมเนียมใช้ เวกเตอร์อาร์ต แข็งแรงกว่าบิตแมปมาก และไลบรารี Swift เคยต้องคอมไพล์รวมไปกับแอปอยู่หลายปี ก่อนจะใช้การลิงก์แบบไดนามิกฝั่งระบบปฏิบัติการได้ด้วยความเสถียรของ ABI
    • สำหรับผม สัญญาณเตือนคือแอปพวกนั้นทั้งหมดเป็น ฟรี
      อยากให้กรองหาแอปที่เป็นแบบเสียเงิน ไม่มีโฆษณา และบางทีก็ไม่มีการซื้อในแอปได้
    • Aurora Store อย่างน้อยก็กรองตาม เสียเงินหรือไม่, มีการซื้อในแอป, มีโฆษณาหรือไม่ ได้
  • ออกนอกเรื่องนิดหน่อย แต่เมื่อก่อนเคยเขียน การทบทวนวรรณกรรม ว่าทำไมผู้คนถึงเล่น Flappy Bird
    ตอนนั้นเป็นนักศึกษาปริญญาโทด้านเกมศึกษา และสุดท้ายไม่ได้ไปสายวิชาการ แต่เอามาแชร์สนุก ๆ
    สำหรับคนที่สนใจ อยู่ที่นี่ [1]
    [1] http://www.fdg2015.org/papers/fdg2015_paper_60.pdf

    • ผมรู้สึกเสมอว่าหลัง เส้นโค้งความยาก อันโด่งดังของ Flappy Bird มีบางอย่างที่น่าสนใจและควรศึกษาลึกกว่านี้
      ในอีกด้านหนึ่ง ตัวเกมเองไม่มีความคืบหน้าจริง ๆ หรือการเพิ่มระดับความยากเลย ไม่ว่าคะแนนปัจจุบันจะเป็น 0, 10 หรือ 100 ความยากก็เหมือนเดิม
      แต่ทุกครั้งที่ทำสถิติใหม่ มันจะกลายเป็นยอดเขาลูกใหม่ที่ผู้เล่นต้องข้ามให้ได้ ยอดแรก และอาจเป็นยอดที่น่าหงุดหงิดที่สุด คือการทำให้ได้ 1 คะแนน และการไปถึงคะแนนสองหลักนั้นโดยพื้นฐานแล้วต้องเชี่ยวชาญการควบคุมหลัก ๆ รวมถึงฟิสิกส์และจังหวะที่แม่นยำ และต้องเรียนรู้วิธีรับมือกับหลายสถานการณ์
      อุปสรรคที่จะไปถึงสามหลักขึ้นไปดูแทบจะเหมือนเป็นสิ่งที่สร้างขึ้นเอง และความกลัวกับความตึงเครียดเมื่อเข้าใกล้สถิติส่วนตัวมักเป็นอุปสรรคใหญ่ที่สุดที่ขวางการทำสถิติใหม่
      พอข้ามสถิตินั้นได้สักครั้ง ครั้งต่อไปที่เข้าใกล้จุดนั้น อาการมือสั่นจะหายไปอย่างมหัศจรรย์ แต่เมื่อเข้าใกล้สถิติใหม่ มันก็กลับมาอีก
      แนวคิดเกมเพลย์พื้นฐานนั้นเรียบง่ายจนน่าหลอกตา แต่สำหรับคนที่อยากมองลึกลงไป มีหลายชั้นให้แกะออกมา
    • “คาดว่าการวางเงื่อนไขถูกเสริมแรงผ่าน อคติทางความคิด หลายอย่างที่หลอกให้ผู้เล่นคาดหวังความสุข หรือเส้นทาง liking ทั้งที่จริง ๆ แล้วสิ่งที่ได้รับคือความคับข้องใจ เมื่อการวางเงื่อนไขเกิดซ้ำ ผู้เล่นจะถูกปรับจูนให้โต้ตอบกับเกมแทบจะในระดับสัญชาตญาณ เราเห็นว่าการกระตุ้นเส้นทาง wanting เช่นนี้อาจทำให้ผู้เล่นโต้ตอบกับเกมโดยที่ไม่เพียงแต่ไม่ได้ชอบเกมจริง ๆ แต่ยังไม่รู้ด้วยซ้ำว่าทำไมจึงเล่นเกมนั้น อันที่จริง สิ่งนี้ชี้ว่าจำเป็นต้องลากเส้นขนานอีกเส้นระหว่างการติดยาเสพติดกับพฤติกรรมการเล่นที่แทบไม่แสดง liking ออกมา”
    • ถ้ามีพื้นฐานเรื่องนั้น ก็น่าจะเคยเห็นแล้วสูงมาก แต่ถึงอย่างนั้น เพื่อ ผู้โชคดี 10,000 คน ก็ต้องแนะนำ QWOP
      https://www.foddy.net/Athletics.html
    • ในฐานะผู้เชี่ยวชาญ Flappy Bird ขอบอกว่าเป็นเพราะผู้คนชอบ การประมาณด้วยพหุนาม
  • มี ไม่ถึง 4,000 บรรทัด
    457 android_native_app_glue.c
    360 audio.c
    802 game.c
    201 init.c
    93 main.c
    39 mouse.c
    38 shaders.c
    229 texture.c
    1377 upng.c
    27 utils.c
    3623 total

    • นักเรียนของผมได้รับงานให้ทำเกมด้วย SFML และเขียนโคลน Flappy Bird ออกมาได้ในไม่กี่ร้อยบรรทัด
      มันไม่ได้เป็นโปรแกรมที่ซับซ้อนขนาดนั้น พูดตรง ๆ ผมว่า 4,000 บรรทัด ยังเยอะเกินไปด้วยซ้ำ
    • น่าเสียดายที่โค้ด 4,000 บรรทัดพอคอมไพล์แล้วกลายเป็น ไบนารีเกิน 100KB
  • ในปี 2020 ผมเคยทำของคล้าย ๆ กันด้วย Nim แล้วปล่อยสาธารณะ แต่กราฟิกสวยน้อยกว่า
    ความต่างคือผมลงลึกกว่านั้น ถึงขั้นเขียน แอสเซมเบลอร์สำหรับ Dalvik bytecode และไฟล์ .apk จริง ๆ
    https://www.youtube.com/watch?v=wr9X5NCwPlI&list=PLxLdEZg8DR...
    น่าเสียดายที่โค้ดในรีโพพังไปตามกาลเวลา และบางครั้งก็คิดว่าสักวันจะลองกู้มันกลับมา
    บางทีก็นึกถึงแอปที่ถ้ามันถูกขัดเกลาอีกนิดคงทำขึ้นมาได้ง่าย ๆ

  • เจ๋งมากจริง ๆ
    ดีที่ได้เห็น แอป Android ต่ำกว่า 1MB รันได้ทุกที่ แม้แต่บน HTC รุ่นเก่า

    • อยากให้มีการประเมินด้วยว่าความเร็วดีขึ้นประมาณไหน
  • ผมเคยคิดว่าการสร้าง Android APK จำเป็นต้องมีโค้ดเชื่อมต่อฝั่ง Java พอเห็นโปรเจกต์นี้แล้วรู้สึกดีมาก
    ไม่มีไฟล์ Java เลยสักไฟล์ ถือว่ายอดเยี่ยม
    โปรเจกต์ rawandroid ที่คนอื่นพูดถึงก็น่าดูเช่นกัน
    https://github.com/cnlohr/rawdrawandroid/tree/master

    • ในกรณีส่วนใหญ่ เหตุผลที่ใช้โค้ดเชื่อมต่อฝั่ง Java แทนโค้ดเชื่อมต่อฝั่ง C คือ ฝั่ง Java เขียนได้ง่ายกว่า
      ไม่ว่าจะทำอะไรก็ตาม หากจะรันได้ก็ต้องมีอินสแตนซ์ของ Activity และถึงจะสร้างใน C ได้ แต่ก็ต้องใช้โค้ด boilerplate จำนวนมากที่ใน Java ส่วนใหญ่จัดการได้ด้วยการสืบทอดคลาส
      ใน C ล้วน ๆ จะทำแบบนี้: https://github.com/VadimBoev/FlappyBird/blob/master/FlappyBi... https://github.com/VadimBoev/FlappyBird/blob/master/FlappyBi...
  • Super Mario Bros มีขนาดเพียง 40KB เท่านั้น
    https://news.ycombinator.com/item?id=21213421

    • นั่นก็ถูกสร้างมาให้ทำงานบนสเปกฮาร์ดแวร์เพียงแบบเดียว และแทบไม่มีระบบปฏิบัติการด้วย
      ส่วนโคลน Flappy Bird ตัวนี้รันได้บน อุปกรณ์นับไม่ถ้วน ที่มีการจัดวางฮาร์ดแวร์และซอฟต์แวร์แตกต่างกันไป
  • พลาดโอกาสตั้งชื่อว่า Floppy Bird ไปแล้ว เพราะมันใส่ลงในฟลอปปีดิสก์ 3.5 นิ้วได้

    • ผมก็คิดแบบนั้นเหมือนกัน แต่น่าเสียดายที่มีโคลนบางตัวเอาชื่อนั้นไปใช้แล้ว
      ตัวที่เด่นที่สุดเป็นแค่เวอร์ชันเปลี่ยนสกินง่าย ๆ ที่ใช้ไอคอนฟลอปปีดิสก์แทนนก
    • ที่อาร์เจนตินา ทุกคนเรียกมันว่า ‘floppy beard’
      แน่นอนว่า ‘angry birds’ ก็เป็น ‘ongry beards’
  • เทคนิคการสร้างแอป C สำหรับ Android ด้วย rawdrawandroid แบบนี้ จะนำไปใช้กับเฟรมเวิร์ก C อื่น ๆ อย่าง raylib ได้ไหม?
    แล้วจะใช้ระบบพัฒนานี้ผ่าน Termux เพื่อสร้างสภาพแวดล้อมพัฒนา C สำหรับ Android บน Android เองได้ไหม?

    • ได้ raylib รองรับ Android
      ผมมีสคริปต์ build ที่ยังไม่สมบูรณ์นักซึ่งใช้กับโปรเจกต์ raylib ของผม
      แน่นอนว่าควรจัดการเรื่องการเซ็นให้ดีกว่านี้ และอาจอยาก build สำหรับเป้าหมายอื่นนอกจาก aarch64 ด้วย อีกทั้ง SDK ของคุณก็อาจไม่ได้ติดตั้งอยู่ที่ /home/denis
      นอกจากนี้ยังไม่แน่ใจว่าการเพิ่มไฟล์ .so เข้าไปใน apk ด้วยวิธีนี้เป็นแนวทางที่ Android สมัยใหม่ชอบหรือไม่ แต่ตอนนี้ยังใช้งานได้
      https://gist.github.com/deniska/f1ee73e18e1444eb724c01f933b6...
  • ถ้าบอกว่า “สำหรับ Android” ก็แปลว่าใช้ Java ได้ และ bytecode อาจมีความหนาแน่นมาก จึงน่าจะทำให้เล็กกว่านี้ได้อีก

    • มีโคลน Flappy Bird สำหรับ GameBoy ด้วย และอยู่ในรูปแบบ ROM 32KB [0][1][2]
      ไม่ได้ตั้งใจจะลดคุณค่าโปรเจกต์บน Android นี้นะ เพราะเขาก็ไม่ได้อ้างว่าสร้างโคลน Flappy Bird ที่เล็กที่สุด
      [0] https://laroldsjubilantjunkyard.itch.io/flappy-bird-gameboy/...
      [1] https://laroldsjubilantjunkyard.itch.io/flappy-bird-gameboy
      [2] https://www.youtube.com/watch?v=m839Vg_qXzM
    • พูดตรง ๆ ตัวเลข 100KB นี่น่าทึ่งมาก
      ในหัวผมรู้สึกว่าน่าจะลดลงไปได้มากกว่านี้อีก และ 10KB ก็ฟังดูพอเป็นจริงได้แบบลาง ๆ