{"id":13877883,"url":"https://github.com/socketry/flappy-bird","last_synced_at":"2025-04-19T12:57:56.613Z","repository":{"id":239381719,"uuid":"791138388","full_name":"socketry/flappy-bird","owner":"socketry","description":null,"archived":false,"fork":false,"pushed_at":"2024-09-25T22:39:02.000Z","size":11384,"stargazers_count":144,"open_issues_count":1,"forks_count":8,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-22T07:11:39.427Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/socketry.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-24T06:59:01.000Z","updated_at":"2025-01-29T01:04:04.000Z","dependencies_parsed_at":"2024-05-12T01:24:28.263Z","dependency_job_id":"796dcf26-7500-469d-9237-d0c60300d9db","html_url":"https://github.com/socketry/flappy-bird","commit_stats":null,"previous_names":["socketry/flappy-bird"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/socketry%2Fflappy-bird","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/socketry%2Fflappy-bird/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/socketry%2Fflappy-bird/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/socketry%2Fflappy-bird/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/socketry","download_url":"https://codeload.github.com/socketry/flappy-bird/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246156419,"owners_count":20732397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-06T08:01:33.926Z","updated_at":"2025-03-29T08:09:33.138Z","avatar_url":"https://github.com/socketry.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Flappy Bird on Rails\n\nThis is a simple Flappy Bird clone written in Ruby on Rails. It uses Falcon and Live to implement real-time interactivity.\n\n![Flappy Bird Demo](media/Flappy%20Bird%20Demo.gif)\n\n## Usage\n\nTo run the game, clone the repository and run the following commands:\n\n```bash\n$ bundle install\n$ bundle exec rails server\n```\n\nThen, open your browser and navigate to `http://localhost:3000`.\n\n## Overview\n\nThe game is implemented as a server-side rendered view. The game logic is fully implemented in [lib/flappy_view.rb](lib/flappy_view.rb).\n\nThe game uses a standard Rails controller, implemented in [app/controllers/game_controller.rb](app/controllers/game_controller.rb). The controller consists of two actions:\n\n~~~ ruby\nrequire 'async/websocket/adapters/rails'\n\nclass GameController \u003c ApplicationController\n  RESOLVER = Live::Resolver.allow(FlappyView)\n\n  def index\n    @view = FlappyView.new\n  end\n\n  skip_before_action :verify_authenticity_token, only: :live\n\n  def live\n    self.response = Async::WebSocket::Adapters::Rails.open(request) do |connection|\n      Live::Page.new(RESOLVER).run(connection)\n    end\n  end\nend\n~~~\n\nThe `index` action instantiates the game view `FlappyView` which is then rendered by the view template [app/views/game/index.html.xrb](app/views/game/index.html.xrb). The `live` action is used to accept a WebSocket connection from the client browser.\n\nWhen the client connects to the server, it binds the `\u003cdiv class=\"live\" data-class=\"FlappyView\" id=\"...\"\u003e` tag to a server side instance. User interactions generate events which are sent to the server, and the server can send HTML to the client to update the view. In addition, for things like sound effects, the server can send JavaScript to the client to execute.\n\nThe actual implementation of the game logic consists of a main game loop which updates the game physics at 30 FPS (frames per second), and then renders the update to the client browser. As the client browser may be running at something other than 30 FPS, we use CSS transforms with linear interpolation to smooth out the changes in position.\n\n## Compatibility\n\nSurprisingly, this game can run on any Rack 3 compatible server, including both Puma and Falcon. Rack 3 requires support for streaming requests and responses, which is sufficient to support WebSockets. The difference then, between servers, is how they choose to expose concurrency to the application. In the case of Puma, it is one thread per request, while Falcon uses one fiber per request.\n\n## Presentation\n\nThis project was part of my RubyKaigi 2024 Keynote. The \u003ca href=\"https://github.com/ioquatix/presentations/tree/main/2024\"\u003eslides are available here\u003c/a\u003e.\n\n## See Also\n\n- [Async](https://github.com/socketry/async) - The Async library for Ruby, which provides a foundation for scalable concurrency.\n- [Async::HTTP](https://github.com/socketry/async-http) - The HTTP client and server library for Ruby, built on Async, supporting HTTP/1 and HTTP/2.\n- [Falcon](https://github.com/socketry/falcon) - The Ruby web server used to run the game, built on Async.\n- [Async::WebSocket] - The WebSocket library for Ruby, built on Async, supporting both HTTP/1 and HTTP/2 client and server WebSockets.\n- [Live](https://github.com/socketry/live) - The library used to implement real-time interactivity, built on top of Async::WebSocket.\n- [Live.js](https://github.com/socketry/live-js) - The JavaScript library used to interact with the server.\n- [Lively](https://github.com/socketry/lively) - A single-file live programming environment for Ruby, which also uses Live for real-time interactivity. It has a multiplayer example of the Flappy Bird game, using a similar implementation.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsocketry%2Fflappy-bird","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsocketry%2Fflappy-bird","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsocketry%2Fflappy-bird/lists"}