Mobile

TL;DR

Use ebitenmobile command to create a shared library. The generated library includes a complete and easy-to-use view (or view controller) class.

Creating a shared library with ebitenmobile bind

Installing ebitenmobile

Install ebitenmobile command first.

go install github.com/hajimehoshi/ebiten/v2/cmd/ebitenmobile@latest

Creating a binding

Create a package for mobiles to use github.com/hajimehoshi/ebiten/v2/mobile:

package yourgamemobile

import (
    "github.com/hajimehoshi/ebiten/v2"
    "github.com/hajimehoshi/ebiten/v2/mobile"

    "github.com/yourname/yourgame"
)

func init() {
    // yourgame.Game must implement ebiten.Game interface.
    // For more details, see
    // * https://pkg.go.dev/github.com/hajimehoshi/ebiten/v2#Game
    mobile.SetGame(&yourgame.Game{})
}

// Dummy is a dummy exported function.
//
// gomobile doesn't compile a package that doesn't include any exported function.
// Dummy forces gomobile to compile this package.
func Dummy() {}

The key function is SetGame. Do not call RunGame, which you usually use for desktop games.

Android

The minimum required Android SDK version is 16.

Set up these environment variables:

# macOS
export ANDROID_HOME=~/Library/Android/sdk
export PATH=/Applications/Android\ Studio.app/Contents/jbr/Contents/Home/bin:$PATH

(TODO: Environment variables for Windows)

Run ebitenmobile bind command for your package:

cd /path/to/yourgame
ebitenmobile bind -target android -javapkg your.package.name -o path/to/yourgame.aar .

Then your can get a .aar file. This .aar file defines a view class named EbitenView under the specified Java package (-javapkg option + your package name). You can put it on your screen. That's it!

The view class is defined like this:

package your.package.name.yourgamemobile;

import android.view.ViewGroup;

public class EbitenView extends ViewGroup {
    // onErrorOnGameUpdate is called on the main thread when an error happens when updating a game.
    // You can define your own error handler, e.g., using Crashlytics, by overwriting this method.
    protected void onErrorOnGameUpdate(Exception e) {
        // Default error handling implementation.
    }

    // suspendGame suspends the game.
    // It is recommended to call this when the application is being suspended e.g.,
    // Activity's onPause is called.
    public void suspendGame() {
        // ...
    }

    // resumeGame resumes the game.
    // It is recommended to call this when the application is being resumed e.g.,
    // Activity's onResume is called.
    public void resumeGame() {
        // ...
    }
}

Note that you have to call Seq.setContext at the Activity creation like this:

package your.package.name.yourgamemobile;

import androidx.appcompat.app.AppCompatActivity;
import go.Seq;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Seq.setContext(getApplicationContext());
        // ...
    }
}

iOS

The minimum required iOS version is 13.0.

Run ebitenmobile bind command for your package:

cd /path/to/yourgame
ebitenmobile bind -target ios -o path/to/YourGame.xcframework .

This command generates a .xcframework file. This .xcframework defines a view controller class named (Package Name)EbitenViewController.

In order to use this framework at a new Xcode project, you can choose either of these options:

In both ways, you would have to import your game's framework like this to use (Package Name)EbitenViewController.

#import <YourGame/YourGame.h>

The view controller class in the generated xcframework is defined like this:

#import <UIKit/UIKit.h>

@interface YourgamemobileEbitenViewController : UIViewController

// onErrorOnGameUpdate is called on the main thread when an error happens when updating a game.
// You can define your own error handler, e.g., using Crashlytics, by overwriting this method.
- (void)onErrorOnGameUpdate:(NSError*)err;

// suspendGame suspends the game.
// It is recommended to call this when the application is being suspended e.g.,
// UIApplicationDelegate's applicationWillResignActive is called.
- (void)suspendGame;

// resumeGame resumes the game.
// It is recommended to call this when the application is being resumed e.g.,
// UIApplicationDelegate's applicationDidBecomeActive is called.
- (void)resumeGame;

@end

Dependencies

An Ebitengine view controller might require these dependencies:

Example

go-inovation is a complete example to use ebitenmobile bind.

Why ebitenmobile bind?

Why not a complete application instead of a shared library?

It is because it is not feasible to write a mobile application only in Go yet.