Game Framework
Troubleshooting

Debugging

Tools and techniques for diagnosing and resolving issues with the Game Framework CLI, Flutter SDK, and game engine integration.

CLI Verbose Output

All CLI commands support a --verbose flag that prints detailed logs including file paths, engine commands, and API requests.

# Verbose export
game export unity --platform android --verbose

# Verbose sync
game sync unity --platform android --verbose

# Verbose build (export + sync + flutter build)
game build android --engine unity --verbose

# Verbose publish
game publish --verbose

The verbose output includes:

  • Resolved .game.yml configuration values
  • Unity/Unreal batch mode command and arguments
  • File copy operations during sync
  • API request and response details during publish
  • Timing information for each step

Pipe verbose output to a file for easier review: game build android --engine unity --verbose 2>&1 | tee build.log

Checking Configuration

Validate .game.yml

Use the built-in validation command to check for configuration errors:

# Validate configuration
game config validate

# View resolved configuration
game config show

Common configuration issues:

  • Missing or incorrect project_path - Verify the Unity/Unreal project directory exists at the specified relative path
  • Missing export_path - Ensure the export directory exists or will be created by the engine
  • Disabled platforms - Check that the platforms you are targeting have enabled: true
  • Incorrect target_path - Verify the sync destination matches your Flutter project structure

Verify Environment

# Check game-cli is installed and accessible
game --version

# Check Flutter version (3.3.0+ required)
flutter --version

# Check Unity installation
# macOS
ls /Applications/Unity/Hub/Editor/

# Check authentication status
game workspace list

Verify Authentication

# Check if GAME_API_KEY is set (for CI/CD)
echo "$GAME_API_KEY"

# Test authentication by listing workspaces
game workspace list

# Re-authenticate if needed
game login

Debugging the Flutter SDK

GameWidget Logging

Add logging to your GameWidget callbacks to trace the engine lifecycle and message flow:

GameWidget(
  engineType: GameEngineType.unity,
  config: GameEngineConfig(runImmediately: true),
  onEngineCreated: (controller) {
    print('[GameFramework] Engine created');

    // Log all incoming messages
    controller.messageStream.listen(
      (message) {
        print('[GameFramework] Message: ${message.target}.${message.method} = ${message.data}');
      },
      onError: (error) {
        print('[GameFramework] Message stream error: $error');
      },
      onDone: () {
        print('[GameFramework] Message stream closed');
      },
    );
  },
  onSceneLoaded: (scene) {
    print('[GameFramework] Scene loaded: ${scene.name}');
  },
  onEngineUnloaded: () {
    print('[GameFramework] Engine unloaded');
  },
)

Lifecycle Event Monitoring

Use the eventStream on the controller to observe all lifecycle transitions:

controller.eventStream.listen((event) {
  print('[GameFramework] Lifecycle event: ${event.type}');
});

Checking Engine State

Query the engine state to understand what is happening:

Future<void> _printEngineState() async {
  if (_controller == null) {
    print('Controller is null - engine not created yet');
    return;
  }

  final ready = await _controller!.isReady();
  final paused = await _controller!.isPaused();
  final loaded = await _controller!.isLoaded();
  final background = await _controller!.isInBackground();

  print('Engine state:');
  print('  ready: $ready');
  print('  paused: $paused');
  print('  loaded: $loaded');
  print('  inBackground: $background');
}

Debugging Unity Communication

Verifying Messages Are Sent

Wrap your send calls with logging to confirm messages leave Flutter:

Future<void> _sendMessage(String target, String method, String data) async {
  print('[Flutter -> Unity] $target.$method = $data');
  try {
    await _controller!.sendMessage(target, method, data);
    print('[Flutter -> Unity] Sent successfully');
  } catch (e) {
    print('[Flutter -> Unity] Send failed: $e');
  }
}

Verifying Messages Are Received in Unity

On the Unity side, add logging in your C# message handler to confirm messages arrive:

// In your Unity C# script
public void OnMessageFromFlutter(string message)
{
    Debug.Log($"[Unity] Received from Flutter: {message}");
}

Common Communication Pitfalls

  1. Target name mismatch - The target parameter in sendMessage must match the GameObject name in Unity exactly (case-sensitive)
  2. Method name mismatch - The method parameter must match the C# method name exactly
  3. Sending before engine is ready - Always wait for onEngineCreated before sending messages
  4. JSON parsing errors - Validate JSON structure on both sides when using sendJsonMessage
  5. Message ordering - Messages are delivered asynchronously; do not assume immediate processing

Platform-Specific Debugging

iOS - Xcode Console

  1. Open ios/Runner.xcworkspace in Xcode
  2. Run the app on a device or simulator
  3. Check the Xcode console output for:
    • [GameFramework] prefixed logs from the SDK
    • Unity framework loading messages
    • Native crash logs and stack traces
# Or view device logs from the command line
xcrun simctl spawn booted log stream --predicate 'process == "Runner"'

On iOS, the engine is automatically paused when the app enters the background. If messages are not arriving after returning to the foreground, verify that resume() is being called.

Android - Logcat

Use adb logcat to view Android runtime logs:

# Filter for Game Framework and Unity logs
adb logcat -s Flutter Unity GameFramework

# Filter for crashes
adb logcat -s AndroidRuntime

# Save to file for analysis
adb logcat -s Flutter Unity GameFramework > logcat.txt

Common Android issues to watch for:

  • minSdkVersion conflicts between Flutter and Unity library
  • NDK-related native library loading failures
  • Memory pressure on low-end devices

WebGL - Browser Console

For Unity WebGL builds running in Flutter Web:

  1. Open your browser's Developer Tools (F12 or Cmd+Option+I)
  2. Check the Console tab for JavaScript errors and Unity log output
  3. Check the Network tab for failed asset loads
  4. Check the Memory tab if you suspect out-of-memory issues

Common WebGL issues:

  • CORS errors when loading assets from a different origin
  • Memory allocation failures (increase Unity WebGL memory size in Player Settings)
  • Shader compilation errors on certain GPUs

Desktop (macOS, Windows, Linux)

Desktop builds output logs to stdout/stderr by default:

# Run Flutter desktop app with visible console output
flutter run -d macos --verbose

# On Windows, check the Output window in Visual Studio
# On Linux, check terminal output or journalctl

Diagnosing Export and Sync Issues

Checking Export Output

After running game export, verify the exported files exist:

# Check the export directory (path from .game.yml)
ls -la ../MyUnityProject/Exports/android/
ls -la ../MyUnityProject/Exports/ios/

Checking Sync Results

After running game sync, verify files were copied correctly:

# Android - check unityLibrary exists
ls android/unityLibrary/

# iOS - check framework exists
ls ios/UnityFramework.framework/

Comparing Versions

If you suspect a version mismatch between exported and synced files:

# View current project configuration
game config show

# Check what version is published
game workspace list

Collecting Debug Information

When reporting an issue, collect this information:

# CLI and environment versions
game --version
flutter --version
dart --version

# Current configuration
game config show

# System information
uname -a

# Run the failing command with verbose output
game build android --engine unity --verbose 2>&1 | tee debug-output.log

Include the full verbose output when filing a bug report. Partial logs make it much harder to diagnose the issue.

Getting Help

If you cannot resolve the issue:

  1. Search GitHub Issues for similar reports
  2. Ask on GitHub Discussions
  3. Email support@gameframework.dev with your debug output and a description of the problem