Category: Flutter

Linux challenges with the Flutter game

Linux challenges with the Flutter game

Tux and Flutter having a tussle
Generated by Gemini

The architecture of this is all Flutter and Dart running on a Ubuntu Linux box. There are two pure Dart programs- one to create the game setup and one to do the processing. The first is run manually, the second by crontab. Then there’s the Flutter web app.

The Flutter web app has to read and write files from the file system which of course it can’t do directly. I’ve created a backend of sorts using PHP.  There’s an API; it works but not without issues. If you’re calling a PHP script from a Flutter app, what is the URL?  It depends.

Say the URL is /file?params where I’ve modified .htaccess to pass /file urls onto a PHP script.

If I want to test this on the box in a browser I have to call localhost/file?params but in a Dart program running on the box it just calls /file?params.

The next problem is where are the game files stored. The setup program doesn’t really care. Any location will do so long as it doesn’t need to run elevated.  But the web app is limited to /var/www/html – it’s running under Apache on a linux box. In the end I created a folder under /var/www/game and each game is stored under there. PHP can read mostly anywhere, not just in /var/www/html and this provide a little extra security.

However there’s the not-so slight issue of permissions. The setup program runs under my login – call it user. So files are created owned by user user. The web app runs under www-data so to keep things simple, I’ve set permissions to user:www-data so both can access it. It’s a bit of a faff.

Here’s a tip. If you are developing a Flutter web app, develop it on Linux and do development as a Linux app. It’s far quicker building and launching a Linux app than it is the web app.

 

 

 

A silly bug in Flutter/Dart

A silly bug in Flutter/Dart

Robot postman
Generated by Gemini

So I’m developing a web postal* game client which is loaded from a Linux server as a Flutter web app. When I run it on the Linux box from Chromium, no problems, it loads a binary file ok. When I try to run it from a networked Windows box, the binary file fails to load. It’s loaded by calling a PHP endpoint, passing the path of the file to a PHP script.

It was my fault. Because the game client is loaded from the Linux server and the path is a Linux path to the binary file, I’d missed that it runs on the Windows box (where the browser launches from). I’d used Platform.isLinux and Platform.Windows calls to figure out the path when I initially tested it on a Windows box.  The path to the binary file was being sent as if the file was on the Windows box because the Flutter app runs as JavaScript in the browser there. D’oh!

*Postal means a game where the game client sends orders to the server. Those are processed once an hour and the results file is picked up when the client next runs. It’s how games used to be played through the post back 30 or 40 years ago hence the name. 

 

Fun with Flutter

Fun with Flutter

So I upgraded Flutter to 3.35 and tried building an app for the Web. It failed with a weird error about the js package being deprecated. Errors a bit like this:

Target dart2js failed: ProcessException: Process exited abnormally with exit code 1:
Error: Couldn’t resolve the package ‘libphonenumber_web’ in ‘package:libphonenumber_web/libphonenumber_web.dart’.
.dart_tool/flutter_build/6872c759b3585597f59b4a698a13ca94/web_plugin_registrant.dart:9:8:
Error: Not found: ‘package:libphonenumber_web/libphonenumber_web.dart’
import ‘package:libphonenumber_web/libphonenumber_web.dart’;

I’d been experimenting with flutter_login package and it was in the projects pubspec.yaml.  I found this out by using this command:

flutter pub deps

Which provides a full and detailed tree of all package dependencies. Like this but 260 lines in total!

turfwar 1.0.0+1
|– badges 3.1.2
| ‘– flutter…
|– cupertino_icons 1.0.8
|– flutter 0.0.0
| |– characters 1.4.0
| |– collection 1.19.1
| |– material_color_utilities 0.11.1
| | ‘– collection…
| |– meta 1.16.0
| |– sky_engine 0.0.0
| ‘– vector_math 2.2.0
|– flutter_lints 6.0.0
| ‘– lints 6.0.0
|– flutter_test 0.0.0

js was used by libphonenumber which was part of flutter_login.  However despite removing that from pubspec.yaml and removing the package files, the flutter build web command was still complaining about it.

The trick to solving that is just to delete the .dart_tool folder. It’s regenerated by the flutter build command so is safe to delete.

Flutter project screenshot

There’s a new feature now, you can add –wasm on the end of the flutter build web command to have it use wasm. More on this official flutter wasm page which includes a link to a neat demo project called wonderous that is worth a look; the source to that is available on GitHub as well..

Don’t get Flutter and Dart mixed up

Don’t get Flutter and Dart mixed up

A bird a Flutter and Darts

I’m working on a game with a Flutter web client and two Dart terminal programs hence the visual pun. Annoyingly, you can’t compile a Dart exe for Linux on a Windows PC. You can do that in C# but I prefer to use Dart.

I have all the classes in two files (one is called classes.dart) and because I’m using JSON to persist game data, I use the build_runner package from pub.dev. Just add this before any classes:

@JsonSerializable()

Make sure if you have enums that every enum value has

@JsonValue('houses')

before it and add functions like this for each class you want to persist; in this case a Location class:

factory Location.fromJson(Map<String, dynamic> json) =>
    _$LocationFromJson(json);

Map<String, dynamic> toJson() => _$LocationToJson(this);

Then when it’s all done, do this to generate a file that handles loading and saving the specified classes.

dart run build_runner build

Along the way though I managed to get Flutter into a Dart program. I’m using SQLite but only in Dart, not in the Flutter app. Unfortunately I used the kIsWeb constant to exclude some calls (when the classes are used by the Flutter app) in my classes file.  But you can’t do that in a pure Dart program, it will not compile. Instead I wrote my own function.

bool isWeb() {
  return !Platform.isWindows && !Platform.isLinux;
}

Interestingly, the definition of kIsWeb in the API is this below, so it might be worth trying that out.

const bool kIsWeb = bool.fromEnvironment(‘dart.library.js_util’);