av

Writing game with Flutter and Flame

What I Learned Developing Games from Scratch on Flutter

"Dart engineers exploring Stack Overflow 'Flutter gamedev' section", Photo by Elena Zhuravleva.
Once upon a time every software engineer thinks of writing their own game. Being a card-scattering solitaire or zombie-mmo-survival-crafting madness, sometimes it could drive you crazy, how much you want to actually write that thing straight away right now.
And the way human brains are wired, oh this awfully brilliant optimization machine, we often tend to start that project of ours with either something we already familiar with, or whatever everyone uses. The former was my choice, and it was exactly the period of my utter excitement with Flutter. Long story short, I've started writing a game with it and here's what I learned.

#1: Dart community loves library names starting with "F".

I understand that it seems like a far-fetched statement, but here's some numbers from pub.dev:
And, in particular, there are 907 (more than 74%) of packages which name starts with flutter in particular. So there's a good chance that if you're missing something in dart ecosystem, try looking for the "f" word :)
Data was collected with the following Puppeteer 🙌 script:
const puppeteer = require('puppeteer');
const alphabet = 'poiuytrewqlkjhgfdsamnbvcxz'.split('');

(async () => {
  let results = {};
  const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
  const page = await browser.newPage();

  await page.setViewport({ width: 1024, height: 768 });
  
  for (let char of alphabet) {
    await page.goto(`https://pub.dev/packages?q=package%3A${char}`);
    const el = await page.$('.package-count span');
    const count = await (await el.getProperty('textContent')).jsonValue();

    results[char] = parseInt(count);
    await page.screenshot({path: `pub/${char}.png`});
  }

  console.log(JSON.stringify(results, null, 2));

  await browser.close();
})();

#2: Flutter's top game engine is Flame 🔥

Another proof to statement above, Flame is Flutter's top game engine as for September 2019. It is a great library with convenient APIs allowing you to avoid implementing game loop and component abstractions by yourself, as well as allowing to conveniently embed itself somewhere within your widgets tree. However, Flame is still far way from even the engines considered "small" (like Phaser, Pixi.js or Babylon.js) and light years behind from monsters like Unreal Engine or Unity.
On the good side, Flame's simplicity is great in a way that allows you to simply read its sources and quickly modify your code to do what it supposed to do, instead of spending half of a day on a documentation and community portals to find thatMethodWhichDoesWhatYouNeeded. And their "Getting Started" guide does not invoke thoughts about black boxes and magic. At the same time, if you need something specific, be almost sure, it's not there yet.
Disclaimer: i am not related to Flame game engine, opinion above is subjective.

#3: Write it yourself

Yes, this could be quite a paradigm shift, especially if you're coming from a fruitful lands of modern Javascript with NPM's more than a million of packages readily available. Dart is not there yet and you will end up in a situation where things you need are not yet written by anyone else in the entire world.
Good side of this would be that it would allow you to expand your engineering expertise in ways you would never expect. One thing to note is that if you're exploring Flutter for game development, you're probably already not afraid of unknown, so WIY all the way!
So be ready to write systems for level progression, inventory, settings persistence, and much more on your own.

#4: Flutter gives you full control over what's displayed on the screen

This is true, and a not at the same time, so sort of a quantum statement.
Collapsing the wave function of this statement, you'd observe yourself in a situation where you're really controlling each and every pixel on the screen, but there's not much Dart code left which uses common Flutter APIs, or Widgets. But at the same time, utilizing the framework's abilities for rendering, limits you in a multiple ways, so you will not get same level of control if stayed within the widgets framework. But, as in any quantum phenomena, reality would end up being in both states. Flutter and widgets for in-game UI and Canvas and custom painters for places where you actually need _full_ control. So you still get amazing convenience of Flutter APIs for actual interfaces, but get full access to a canvas for actual game view.

#5: Full control is not full

Yes, yes, i am sorry for such a stereotypical twist in the article plot, but if you're really considering using Flutter for game development because of its "Full control" over what's going on the screen, there are a few limitations you should be aware of.
First of all, if you're seeking true power, you will likely end up working with Flutter at dart:ui layer. You could find more information on Flutter's layered architecture in Flutter: Through the abstractions forest 🌲 article. And oh boy, that layer is Dart. Between us, i wasn't ready for some of things which are happening there. Some of the limitations are:
- Canvas contents could only be accessed asynchronously and only via bound PictureRecorder. It means you can't copy whole contents of your game image after each frame, apply some transformation to each pixel and then render it back, i tried.
- You don't have access to full Skia API with dart:ui Canvas. So if you would like to do write some shaders for your game, it's not possible yet.
- dart:ui Path object doesn't allow you to access points data within the path, despite clearly having it available.
- If you want 3D scenes in your game, you will need to write all the projection logic yourself. It's possible, but it'll run purely on CPU, so it's not a great idea both in terms performance and time investment point of view.
Overall, working with Flutter on that level it felt that there are API and implementation gaps where it's not directly applicable to 2D UI rendering, but at the same time, if your niche is a sprite 2D game, you will probably not be constrained too much.

So should i even consider using Flutter for mobile games?

Writing games with flutter is an adventure, writing an adventure game with it would be adventure squared. For me personally, i am enjoying both Dart and Flutter ecosystem as well as i'm not afraid to do a bit of geeky coding, like writing BMP encoder, or interpolator for transformation matrices. But that might not be applicable for you, so if you're looking for an answer if Flutter is feasible for writing mobile games, just like in hundreds of other blogposts, the answer would be quantum.
Yes if at least two of these are true:
  • You're doing it as a side-project for fun and experience
  • You're enjoying Dart and Flutter ecosystem
  • You don't mind programming some basic things from scratch
No if any of these is true:
  • You're looking for quickest possible way to market for your next product
  • You don't have any prior experience with game development in other technology stacks
So, in plain English, it's not ready for prime time yet, but it's definitely an interesting technology combo to explore and to track.
Thank you for making it here! If you have any interesting story about writing game with Flutter, please drop a few lines in comments or write me to av@av.codes, i think we'll have something to talk about!
And yeah, you won't see any shameless plugs in this post about my own game or anything :)
Have a great time with Flutter (and Flame, probably)!

Tags

Comments

Topics of interest