Android向けFlappy Bird、C言語で記述、100KB未満
(github.com/VadimBoev)- このプロジェクトは、Android向けのFlappy BirdクローンをCで実装し、APKサイズを100KB未満に抑えることを目標としている
- 2021年にrawdrawandroidに触れた後、小さなAPKのゲームを作ろうとし、2024年9月にRaylib DiscordでC# Flappy Birdを見たことがC実装に挑戦するきっかけになった
- 実装は、Cで作成したネイティブライブラリをAPKにパッケージし、OpenGL ES 2、シェーダー、Android Native Activityを組み合わせる方式である
- サウンドはMP3で圧縮してOpenSLESで再生し、PNGデコードにはupngを使用する
- ビルドはWindowsのVisual Studio CodeとLinux/macOSのMakefileをサポートし、ゲームとリソースの権利はDotGEARSにあると明記している
プロジェクトの目標と背景
- Flappy Bird in Cは、Androidで動作するFlappy BirdクローンをCで記述し、APKサイズを100KB未満に維持しようとするプロジェクトである
- 出発点は2021年に触れたrawdrawandroidであり、目標はAPKサイズを最小化しつつ、理解しやすく興味深いゲームを作ることだった
- Flappy Birdはすでに多くの言語に移植された事例があり、クローン実装の対象として自然に選ばれた
以前の試みと問題点
- 2021年にはRaylibを学び、ImGuiを使ってC++でゲームを作ろうとした最初の試みは失敗した
- 当時の問題は次のとおりだった
- APKサイズが約1MBだった
- ゲームがクラッシュした
- APKにarmeabi-v7aライブラリしか含まれていなかった
- Googleの2022年要件ではarm64-v8aライブラリの同梱が必要だった
2024年の再挑戦の動機
- 2024年9月にRaylib DiscordチャンネルでC# Flappy Birdを見た後、Android向けFlappy BirdをCで実装し、APKを100KB未満にする試みを始めた
- 目標は非現実的に見えたが、競争心のような面白さが実装の動機になった
実装方法
- 最初は、Cで記述したHello Worldをコンパイルし、そのライブラリをAPKとしてパッケージする作業から始めた
- サウンドはMP3形式で圧縮し、OpenSLESを使って再生する
- PNGファイルのデコードにはupngを選択した
- グラフィックスとAndroid統合にはOpenGL ES 2、シェーダー、Android Native Activityを組み合わせて使用する
ビルド方法
- WindowsではVisual Studio Code環境を前提としている
.env.exampleから.envを作成する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件のコメント
Hacker Newsの意見
App Storeに10MB未満のアプリだけ表示フィルターがあればいいのに。
いちばん速く、広告や少額課金が少ないアプリは、たいてい小さなアプリ。
150MBの温度計アプリより、3MBの温度計アプリを入れたほうが、はるかに満足できる可能性が高い。
そのアプリ群は全部200KB未満というくらい、本当に小さかった。
採用担当者が、もはや存在しなかったり本番サーバーが落ちていたりするアプリについても、まるでアートのポートフォリオのように見せられる成果物を求めることが多かった。
さらに恣意的な基準として、何か大きなアプリをやったことがあるかを確認しようとするものがあり、有能に見える最適化手法をたくさん使って8〜12MBのパッケージにすると、アプリ・サービス・ユーザーベースが小さいというシグナルのように受け取られた。
実際には数億ダウンロードとユーザーがいてもその基準とは何の関係もなく、この分野には肥大化したアプリを作るインセンティブがものすごく大きい。
たとえば広告込みで、7MBを超える温度計アプリを見つけるまでに9本も探す必要があった。
両方のプラットフォームで数年働いたけれど正確な理由はよく分からない。推測するなら、Androidにはビットマップよりベクターアートの伝統がずっと強く、SwiftライブラリはABI安定性のおかげでOS側の動的リンクを使うようになるまで、数年間アプリに一緒にコンパイルする必要があったからかもしれない。
有料で、広告がなく、場合によってはアプリ内購入もないアプリでフィルタリングできるといい。
少し横道だけれど、以前、人々がなぜFlappy Birdを遊ぶのかについての文献レビューを書いたことがある。
当時はゲーム研究の大学院生で、結局アカデミアには進まなかったけれど、面白半分に共有する。
興味のある人向けにここにある [1]
[1] http://www.fdg2015.org/papers/fdg2015_paper_60.pdf
一方で、ゲーム自体には実際の進行や難易度上昇はない。現在のスコアが0でも10でも100でも、難易度はそのまま。
しかし毎回の新記録が、プレイヤーが越えるべき新しい山になる。最初の、そしておそらく最も腹立たしい山は1点を取ることで、2桁スコアに行くには、正確な物理挙動とタイミングを含む中核操作を基本的に習熟し、さまざまな状況に対処する方法を学ばなければならない。
3桁以上に行くうえでの障害は、ほとんど自分で作り出しているように見え、自己ベストに近づいたときの恐怖と緊張が、記録更新を阻む最大の障害になる。
一度その自己ベストを超えると、次にそこへ近づいたときの手の震えは魔法のように消えるが、新しい自己ベストに近づくとまた現れる。
基本的なゲームプレイの概念はだまされるほど単純だが、掘り下げようとする人には解きほぐすべき層が多い。
https://www.foddy.net/Athletics.html
4千行未満。
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
そこまで複雑なプログラムではないので、正直4千行でも多すぎると思う。
2020年にNimで似たものを作って公開したけれど、グラフィックはそこまできれいではなかった。
違いは、さらに深く入り込んでDalvikバイトコードと.apkファイル用のアセンブラまで実際に書いたこと。
https://www.youtube.com/watch?v=wr9X5NCwPlI&list=PLxLdEZg8DR...
リポジトリのコードは残念ながら時間が経って壊れてしまい、いつか復活させようかと時々考える。
もう少し磨かれていたら、簡単に作れそうなアプリを思いつくことがある。
本当にすばらしい。
1MB未満のAndroidアプリが古いHTCでもどこでも動くのを見るのはいい。
Android APKを作るにはJavaの接続コードが必要だと思っていたので、このプロジェクトを見るといいですね
Javaファイル0個とは素晴らしい
他の人が言っていたrawandroidプロジェクトも見る価値があります
https://github.com/cnlohr/rawdrawandroid/tree/master
何をするにしても実行するにはActivityインスタンスが必要で、Cでも作れますが、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クローンは、ハードウェア構成もソフトウェア構成もばらばらな数え切れないほど多くの端末で動きます
3.5インチフロッピーディスクに収まるのだから、Floppy Birdと名付ける機会を逃しましたね
いちばん目立つのは、鳥の代わりにフロッピーディスクのアイコンを使うだけの単純なスキン変更版です
もちろん「angry birds」は「ongry beards」です
rawdrawandroidでAndroid向けCアプリケーションを作るこの手法は、raylibのような他のCフレームワークにも適用できるのでしょうか?
それからTermux経由でこの開発システムを使い、Android上にAndroid向けC開発環境を作ることもできるのでしょうか?
私のraylibプロジェクトで使っている、少し未完成なビルドスクリプトがあります
当然、署名処理はもっときちんとやる必要がありますし、aarch64以外のターゲットもビルドしたいかもしれません。また、SDKが/home/denisにインストールされているとは限りません
それに、.soファイルをapkに追加する方法が現代のAndroidが好むやり方なのかは確かではありませんが、まだ動きます
https://gist.github.com/deniska/f1ee73e18e1444eb724c01f933b6...
「Android用」ということならJavaを使えるという意味で、バイトコードは非常に高密度にできるので、もっと小さく作れる気がします
とはいえ、この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
頭の中ではもっとずっと低くできるはずに思えますし、10KBでもぼんやり現実的に聞こえます