Flutter + Flame · MIT

Mini games for your Flutter app.
One call away.

Fruit Slice, an endless runner, a match-3 puzzle and a rhythm game, ready to drop into any app. Brand them with your colors, art and texts; get the score back for coupons, points or analytics.

final result = await FlameGallery.show( context, game: const FruitSlice(), );

The gallery

Four classic 2D mechanics, each its own package, all sharing menus, pause handling and results.

⚡

One call

FlameGallery.show opens a full screen game with start, pause and game over menus and completes with a GameResult.

🎨

Your brand

Color scheme, font, logo, background (color, gradient or image), every text, sprites and rules are config. No colors given? The game follows your app theme.

🎯

Campaign ready

Timers, lives, move limits, target scores and seeded "daily" boards, plus stats in every result.

🪶

Light

Library packages depend only on flutter and flame. No state management or codegen forced on your app.

🧪

Testable

Stable Semantics ids on every button and HUD value. A Maestro suite plays every game on iOS and Android.

🧩

Extensible

Build your own game on flame_gallery_core; menus, theming, pause and results come for free.

Get started

Add the package, call show, use the result.

1 · Install

flutter pub add flame_gallery

2 · Open a game

import 'package:flame_gallery/flame_gallery.dart';

final result = await FlameGallery.show(
  context,
  game: const SweetSwap(
    config: MatchConfig(moveLimit: 15, targetScore: 1000),
  ),
  onEvent: (event) => analytics.log('$event'),
);

3 · Reward the player

if (result case GameResult(
  isCompleted: true,
  :final score,
) when score >= 1000) {
  grantCoupon();
}

// result.toJson()
// {gameId: sweet_swap, score: 1040, reason: completed,
//  playTimeMs: 48210, stats: {movesUsed: 12, maxCascade: 3,
//  endedBy: target}}

Events: GameStarted, GameScoreChanged, GamePaused, GameResumed, GameFinished.

Make it yours

Every game takes a theme, texts and its own rules. Swap the fruit for your products.

FruitSlice(
  theme: GameTheme(
    colorScheme: ColorScheme.fromSeed(
      seedColor: brandTeal,
      brightness: Brightness.dark,
    ),
    logo: const AssetImage('assets/logo.png'),
  ),
  strings: FruitSlice.stringsTr.copyWith(
    title: 'Yaz Kampanyası',
  ),
  config: SliceConfig(
    timeLimit: const Duration(seconds: 30),
    items: [
      SliceItem(
        sprite: const GameAsset('assets/can.png'),
        juiceColor: brandRed,
        points: 2,
      ),
    ],
    bomb: null,
  ),
)
GameConfig highlights
FruitSlicetimeLimit, lives, items, bomb, difficulty
EndlessRunnertimeLimit, lives, coinValue, sprites
SweetSwaprows, columns, moveLimit, targetScore, seed
NoteRushsong, difficulty, missLimit, pluggable RhythmAudio

All games ship English and Turkish texts. Your art goes in with GameAsset('assets/...').

Beyond colors

Backgrounds, your own dialogs and HUD, animated characters and sound effects, all without forking a game.

FlameGallery.show(
  context,
  game: FruitSlice(
    theme: GameTheme(
      background: const GameBackground.gradient(
        LinearGradient(colors: [teal900, teal500]),
      ),
      themeData: myAppTheme,
    ),
  ),
  // replace any built-in overlay
  overlays: GameOverlayBuilders(
    start: (context, ui) => MyBrandDialog(onStart: ui.start),
    gameOver: (context, ui) => MyResultSheet(onClose: ui.close),
  ),
  // your audio package plays the cues
  sounds: CallbackSounds((cue) => player.play(cue.name)),
);
You wantYou use
Color, gradient or image behind the gameGameTheme(background:)
Your design system in menusGameTheme(themeData:), GameOverlayBuilders
Animated runner or coinGameAnimation via RunnerSprites
Sound effectsGameSounds / GameSoundCue (no audio dependency)
Custom difficulty numbersSliceDifficulty.normal.copyWith(...)

Try every game now

The demo app runs in your browser: default games, a branded campaign and a seeded daily puzzle.

▶ Open the playground