4P by GN⁺ | ★ favorite | 댓글 1개
  • 이 프로젝트는 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 FlappyBirdmake를 실행함
  • 더 자세한 빌드 절차는 BUILDING.md를 참조하도록 안내함
  • 서명된 APK는 FlappyBird/app/build/outputs/apk/FlappyBird-signed.apk에 생성됨

저작권과 참고 프로젝트

  • 프로젝트 작성자는 저작권을 주장하지 않으며, 게임과 리소스 권리는 DotGEARS에 있다고 명시함
  • 영감이 된 프로젝트는 다음과 같음

댓글과 토론

Hacker News 의견들
  • 앱스토어에 10MB 미만 앱만 보기 필터가 있었으면 좋겠음
    가장 빠르고 광고·소액결제가 적은 앱은 보통 작은 앱임
    150MB짜리 온도계 앱보다 3MB짜리 온도계 앱을 받는 편이 훨씬 만족스러울 가능성이 큼

    • 예전에 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이 거의 드러나지 않는 놀이 행동 사이의 또 다른 평행선을 그을 필요가 있음을 시사한다”
    • 그 배경이라면 이미 봤을 가능성이 매우 높겠지만, 그래도 운 좋은 1만 명을 위해 QWOP을 소개해야겠음
      https://www.foddy.net/Athletics.html
    • Flappy Bird 전문가로서 말하자면, 사람들이 다항식 근사를 좋아하기 때문임
  • 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

    • 내 학생이 SFML로 게임을 만드는 과제를 받았고, Flappy Bird 복제판을 몇백 줄 정도로 작성했음
      그렇게 복잡한 프로그램은 아니라서 솔직히 4천 줄도 너무 많다고 봄
    • 4천 줄 코드가 컴파일되면 100KB 넘는 바이너리가 된다는 게 아쉬움
  • 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

  • Super Mario Bros는 40KB에 불과했음
    https://news.ycombinator.com/item?id=21213421

    • 그건 정확히 하나의 하드웨어 사양에서, 사실상 운영체제 없이 동작하도록 만든 것이기도 함
      이 Flappy Bird 복제판은 하드웨어와 소프트웨어 구성이 제각각인 셀 수 없이 많은 기기에서 돌아감
  • 3.5인치 플로피 디스크에 들어가니 Floppy Bird라고 이름 붙일 기회를 놓쳤음

    • 나도 그 생각을 했지만 안타깝게도 이미 몇몇 복제판이 그 이름을 가져갔음
      가장 눈에 띄는 건 새 대신 플로피 디스크 아이콘을 쓰는 단순한 스킨 변경 버전임
    • 아르헨티나에서는 다들 ‘floppy beard’라고 부름
      물론 ‘angry birds’는 ‘ongry beards’임
  • rawdrawandroid로 Android용 C 애플리케이션을 만드는 이 기법이 raylib 같은 다른 C 프레임워크에도 적용될 수 있을까?
    그리고 Termux를 통해 이 개발 시스템을 써서, Android 위에서 Android용 C 개발 환경을 만들 수도 있을까?

    • 가능함. raylib는 Android를 지원함
      내 raylib 프로젝트에 쓰는 약간 미완성 빌드 스크립트가 있음
      당연히 서명 처리는 더 제대로 해야 하고, aarch64 외의 대상도 빌드하고 싶을 수 있으며, SDK가 /home/denis에 설치되어 있지도 않을 수 있음
      또 .so 파일을 apk에 추가하는 방식이 현대 Android가 선호하는 방식인지는 확실치 않지만 아직 동작함
      https://gist.github.com/deniska/f1ee73e18e1444eb724c01f933b6...
  • “Android용”이라면 Java를 쓸 수 있다는 뜻이고, 바이트코드는 매우 조밀할 수 있으니 더 작게 만들 수도 있을 것 같음