{"id":16441682,"url":"https://github.com/misha/flame_fuse","last_synced_at":"2026-04-16T22:31:26.333Z","repository":{"id":249222737,"uuid":"814929387","full_name":"misha/flame_fuse","owner":"misha","description":"Hook-like behavior composition for Flame components.","archived":false,"fork":false,"pushed_at":"2026-03-11T00:52:25.000Z","size":3508,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-11T06:25:36.870Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/misha.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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-06-14T02:24:12.000Z","updated_at":"2026-03-11T00:52:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"0feacd67-0905-4bd3-8ac0-453074425c29","html_url":"https://github.com/misha/flame_fuse","commit_stats":null,"previous_names":["misha/flame_fuse"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/misha/flame_fuse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misha%2Fflame_fuse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misha%2Fflame_fuse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misha%2Fflame_fuse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misha%2Fflame_fuse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/misha","download_url":"https://codeload.github.com/misha/flame_fuse/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/misha%2Fflame_fuse/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31907429,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"ssl_error","status_checked_at":"2026-04-16T18:21:47.142Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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-10-11T09:15:04.032Z","updated_at":"2026-04-16T22:31:26.019Z","avatar_url":"https://github.com/misha.png","language":"Dart","funding_links":[],"categories":["Plugins \u0026 Libraries"],"sub_categories":["Examples"],"readme":"# Fuse\n\nFuse is a library for writing [Flame](https://github.com/flame-engine/flame) component behavior in a composable way.\n\n\u003e :warning: This project is not affiliated with Blue Fire or the official Flame project in any way.\n\n## Installation\n\n```bash\ndart pub add flame_fuse\n```\n\n## Usage\n\nInstead of implementing callbacks, all behavior is added in the `fuse` method at load time.\n\n```dart\nclass SpinningSquare extends RectangleComponent with Fuse {\n  @override\n  FutureOr\u003cvoid\u003e fuse() {\n    fuseUpdate((dt) {\n      angle += (pi / 2) * dt;\n    });\n  }\n}\n```\n\nAny Flame component may use the `Fuse` mixin to gain access to this special method. All functions that add behavior inside the `fuse` method are prefixed with the word `fuse`.\n\nAdditional `fuse*` functions become available if you also apply feature-specific mixins. Here is the master list of available fuses:\n\n| Mixin            | Fuses                                                                                            | Description                   |\n|------------------|--------------------------------------------------------------------------------------------------|-------------------------------|\n| `Fuse`           | `fuseComponent`, `fuseGame`, `fuseCamera`, `fuseUpdate`, `fuseRemove`, `fuseResize`, `fuseTimer` | Core fuses.                   |\n| `FuseCollisions` | `fuseCollision`, `fuseCollisionPoints`, `fuseCollisionStart`, `fuseCollisionEnd`                 | Fuses related to collisions.  |\n| `FuseHovers`     | `fuseHoverEnter`, `fuseHoverExit`, `fuseHoverUpdate`                                             | Fuses related to hovers.      |\n| `FuseKeys`       | `fuseKeyEvent`                                                                                   | Fuses related to keys.        |\n| `FusePointers`   | `fusePointerMove`, `fusePointerMoveStop`                                                         | Fuses related to pointers.    |\n| `FuseTaps`       | `fuseTapDown`, `fuseTapUp`, `fuseTapCancel`, `fuseLongTapDown`                                   | Fuses related to taps.        |\n| `FuseDoubleTaps` | `fuseDoubleTapDown`, `fuseDoubleTapUp`, `fuseDoubleTapCancel`                                    | Fuses related to double taps. |\n\nOf course, the true power of fuses is unlocked by building your own, game-specific behaviors from the core fuses.\n\n## Why Fuse?\n\nThere are a few advantages to writing Flame components using this library.\n\n### Without Fuse\n\nTo illustrate these advantages, consider the following `Ball` component. The component has two behaviors:\n\n1. Bouncing off walls, which affects its velocity.\n2. Randomly changing colors when colliding with other balls.\n\n```dart\nclass Ball extends CircleComponent with CollisionCallbacks {\n  final velocity = Vector2.all(250) //\n    ..rotate(2 * pi * _RANDOM.nextDouble());\n\n  @override\n  Future\u003cvoid\u003e onLoad() async {\n    await super.onLoad();\n    anchor = Anchor.center;\n    size = Vector2.all(33);\n    paint.color = randomColor();\n    add(CircleHitbox());\n  }\n\n  @override\n  void update(double dt) {\n    position += velocity * dt;\n  }\n\n  @override\n  void onCollisionStart(\n    Set\u003cVector2\u003e intersectionPoints, \n    PositionComponent other,\n  ) {\n    super.onCollisionStart(intersectionPoints, other);\n\n    switch (other) {\n      case Wall():\n        velocity.reflect(other.normal);\n        break;\n      case Ball():\n        paint.color = randomColor();\n        break;\n    }\n  }\n}\n```\n\nThere are two major issues with this implementation:\n\n1. The code for each behavior (position and color) is interwoven throughout the component. To understand what a particular behavior ultimately does, you *must* read the entire component.\n2. It is not easy or obvious how to extract the behavior to \"bounce when colliding with walls\" or \"change colors when colliding with balls\" for reuse in other components.\n\n### With Fuse\n\nThis library resolves both these issues directly.\n\nHere is the exact same ball component rewritten using fuses instead:\n\n```dart\nclass Ball extends CircleComponent \n    with Fuse, CollisionCallbacks, FuseCollisions {\n\n  @override\n  FutureOr\u003cvoid\u003e fuse() {\n    anchor = Anchor.center;\n    size = Vector2.all(33);\n    add(CircleHitbox(collisionType: CollisionType.active));\n\n    final velocity = Vector2.all(250) //\n      ..rotate(2 * pi * _RANDOM.nextDouble());\n\n    fuseUpdate((dt) {\n      position += velocity * dt;\n    });\n\n    fuseCollisionStart\u003cWall\u003e((wall) {\n      velocity.reflect(wall.normal);\n    });\n\n    paint.color = randomColor();\n\n    fuseCollisionStart\u003cBall\u003e((_) {\n      paint.color = randomColor();\n    });\n  }\n}\n```\n\n#### Advantage #1: Locality of Behavior\n\nIn the version written with fuses, the position behavior code and the color behavior code are **no longer interspersed**. In order to understand a single behavior in its entirety, you need only look at that particular section of the component. In short, it accomplishes locality of behavior.\n\nThis advantage is shared with frontend frameworks that use hooks, like React and `flutter_hooks`. The following GIF from a popular Tweet on React Hooks exemplifies the shift in code organization, where colored parts represent parts of the same feature or behavior:\n\n![react hooks locality](assets/react-hooks.gif)\n\n##### Advantage #2: Composability\n\nIn the version written with fuses, it's trivial to extract *either* behavior into a standalone, reusable fuse. Here is how you might write a fuse that allows any component to \"bounce when hitting a wall\":\n\n```dart\nvoid fuseBallMovement(Vector2 velocity) {\n  final component = fuseComponent\u003cPositionComponent\u003e();\n\n  fuseUpdate((dt) {\n    component.position += velocity * dt;\n  });\n\n  fuseCollisionStart\u003cWall\u003e((wall) {\n    velocity.reflect(wall.normal);\n  });\n}\n```\n\nSimilarly, here's how you could easily extract the color behavior:\n\n```dart\nvoid fuseBallRecolor() {\n  final component = fuseComponent\u003cHasPaint\u003e();\n  component.paint.color = randomColor();\n\n  fuseCollisionStart\u003cBall\u003e((_) {\n    component.paint.color = randomColor();\n  });\n}\n```\n\nNow anything with a velocity vector or a `Paint` object can trivially share either of those behaviors with the `Ball` component.\n\n## Development\n\nThe main Fuse project is stored in the top-level directory.\n\nThe tests are written in a Storybook located in the `fuse_test` package. Unfortunately, the top-level project is a package-type project and cannot have a platform attached to it. As a result, I have opted to have a separate, application-type project to host the Storybook instead.\n\nIf you have any problems or suggestions, please open an issue on GitHub.\n\n## Naming\n\nThe name \"Fuse\" was selected because this method of functional composition is shared with React and Flutter hooks. With hooks, you `use` functions. With Flame hooks, you `fuse` functions instead.\n\nI also like that the verb \"to fuse\" reminds me of welding together parts in a secure way, similar to what the library tries to do with component behavior.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmisha%2Fflame_fuse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmisha%2Fflame_fuse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmisha%2Fflame_fuse/lists"}