A dead simple 2D game library for Go

Ebiten (v2)

PkgGoDev Build Status Build Status Go Report Card

A dead simple 2D game library for Go

Ebiten is an open source game library for the Go programming language. Ebiten's simple API allows you to quickly and easily develop 2D games that can be deployed across multiple platforms.

Overview

Platforms

Note: Gamepad and keyboard are not available on Android/iOS.

For installation on desktops, see the installation instruction.

Features

  • 2D Graphics (Geometry/Color matrix transformation, Various composition modes, Offscreen rendering, Fullscreen, Text rendering, Automatic batches, Automatic texture atlas)
  • Input (Mouse, Keyboard, Gamepads, Touches)
  • Audio (Ogg/Vorbis, MP3, WAV, PCM)

Packages

Community

Slack

#ebiten channel in Gophers Slack

License

Ebiten is licensed under Apache license version 2.0. See LICENSE file.

Owner
Comments
  • internal/graphicsdriver/directx: low performance

    internal/graphicsdriver/directx: low performance

    Easiest way to reproduce for now is with my game AAAAXY, which currently (for this reason) defaults to OpenGL rather than DirectX:

    • Download AAAAXY from https://github.com/divVerent/aaaaxy/ (latest release will do)
    • Also download the file "benchmark.dem" from the github repository, and put it next to the exe file.

    In PowerShell, run:

    $Env:EBITEN_GRAPHICS_LIBRARY = "opengl"
    Measure-Command { .\aaaaxy-windows-amd64.exe -load_config=false -demo_play="benchmark.dem" -demo_timedemo -vsync=false }
    ...
    TotalMilliseconds : 23103.9543
    $Env:EBITEN_GRAPHICS_LIBRARY = "directx"
    Measure-Command { .\aaaaxy-windows-amd64.exe -load_config=false -demo_play="benchmark.dem" -demo_timedemo -vsync=false }
    ...
    TotalMilliseconds : 39587.4662
    

    (to view runtime fps, can run .\aaaaxy-windows-amd64.exe -load_config=false -vsync=false -show_fps, which shows me 110fps at the start of the game in OpenGL, and 19fps in DirectX - the lower difference in TotalMilliseconds is primarily due to loading time "equalizing" things somewhat)

    Issue may be GPU specific though - I have this issue on one of these: https://www.amazon.com/2019office%E3%80%91-Ultra-Light-High-Speed-High-Performance-Notebook/dp/B09CQ22335/ref=sr_1_3?keywords=7+inch+laptop&qid=1657310835&sr=8-3 - according to Device Manager I have an Intel(R) HD Graphics 500.

    -vsync=false is most certainly not at fault - with vsync on, I can't reach 60fps either, which is very noticeable.

  • Add event API to allow low-level events (e.g. input)

    Add event API to allow low-level events (e.g. input)

    As per our discussion on Slack I'd like to propose that Ebiten exposes the low level events it receives from the underlying platform (key presses, joystick, etc) in a separate package "event".

    Arguments in favor:

    1. It's more efficient than converting the state based API.
    2. It's easier to use for certain applications, such as GUI's.
    3. In some cases it's more correct.

    The API could be something like it is in Allegro, https://liballeg.org/a5docs/trunk/events.html, but without the C-ism like unions and an event queue, which could be replaced simply with a Go channel.

  • internal/gamepaddb: standard layout is not correctly detected on Android

    internal/gamepaddb: standard layout is not correctly detected on Android

    I am connecting a generic X-Box gamepad (this one: https://github.com/gabomdq/SDL_GameControllerDB/pull/452) but am getting:

    09-06 07:34:08.860 25521 25559 I GoLog   : 2022/09/06 11:34:08.860469 [INFO] gamepad Generic X-Box pad added
    09-06 07:34:08.860 25521 25559 I GoLog   : 2022/09/06 11:34:08.860534 [ERROR] gamepad Generic X-Box pad has no standard layout - cannot use
    

    This can't be right - it doesn't get much more standard layout than this.

    However, on Android, Ebitengine always returns false to hasOwnStandardLayoutMapping, and for some reason we don't match the gamecontrollerdb entry either (not sure if that'd even work, as it depends on the order the OS returns buttons in, which likely differs between Android and Linux).

    In addition, the Java code in cmd/ebitenmobile/gobind.go very much looks like Android does usually provide the standard layout mapping internally (see names like KEYCODE_BUTTON_SELECT).

  • Fullscreen broken on X11 with HiDPI

    Fullscreen broken on X11 with HiDPI

    Repro:

    • Set display DPI to something other than 96: echo Xft.dpi: 144 | xrdb -merge
    • Run examples/windowsize
    • Press F

    Observe that a large part of the screen is cut off (see screenshots).

    20210820-100222 20210820-100226

    Note how Xft.dpi does not influence the Device Scale Factor, but it does change the initial window size and causes this weird fullscreen scale up.

    Reproduced on:

    • X11/i3
    • Wayland/Sway/Xwayland

    Does NOT reproduce on:

    • Cinnamon

    Most likely because ebiten has its own support for querying device scale that is specific to Cinnamon and GNOME, while not supporting anything else; at the same time, glfw has its different support and these two disagree.

    Maybe we should just always use glfw's content scale?

    Note though:

    // deviceScaleFactor() is a scale by desktop environment (e.g., Cinnamon), while GetContentScale() is X's scale.
    

    I do not quite understand this - when do these two ever differ, except when there simply is no desktop environment managing this at all? In fact, do we ever handle the case of these two differing right?

  • Regression: invisible window, wrong fullscreen size

    Regression: invisible window, wrong fullscreen size

    On my system (Linux/Sway/XWayland), 77664ff0575c8f51e1ba5cd3604a57808fbf95f4 causes a regression:

    • Before the commit, Ebiten windows get created on the correct screen and get centered correctly.
    • After the commit, I don't get any visible window, and in fullscreen it displays too small in the bottom left corner.

    Commenting out the initializeWindowAfterCreation(window) in createWindow() fixes it, although I do not yet know why. What the function does looks reasonable to me (other than the window being way too small, 16x16).

    Checking with xwininfo reveals that the window actually gets created but outside the visible area of my dual screen setup. Fullscreen oddly uses the wrong size.

    I suggest backing out the commit for now, unless it fixes similar issues on other systems. Or maybe have it temporarily controlled by an environment variable until fixed for good?

  • Immediate crash when running gamepad example locally

    Immediate crash when running gamepad example locally

    I'm running Void Linux. I copied the code for the gamepad example and removed the // +build example jsgo. It compiles, but upon running it immediately crashes.

    Error Log

    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    GLFW: An uncaught error has occurred: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    GLFW: Please report this bug in the Go package immediately.
    panic: InvalidValue: Invalid button in gamepad mapping 030000004c050000cc09000011810000 (PS4 Controller)
    
    goroutine 1 [running]:
    github.com/go-gl/glfw/v3.3/glfw.acceptError(0xc00015de58, 0x1, 0x1, 0xc00016a120, 0xc00000e160)
    	/home/semi/go/src/github.com/go-gl/glfw/v3.3/glfw/error.go:174 +0x216
    github.com/go-gl/glfw/v3.3/glfw.Init(0xddf27cfb, 0xb94fc6b71120b9e0)
    	/home/semi/go/src/github.com/go-gl/glfw/v3.3/glfw/glfw.go:37 +0x54
    github.com/hajimehoshi/ebiten/internal/glfw.Init(...)
    	/home/semi/go/src/github.com/hajimehoshi/ebiten/internal/glfw/glfw_notwindows.go:291
    github.com/hajimehoshi/ebiten/internal/uidriver/glfw.initialize(0xc0001005a0, 0xc000100570)
    	/home/semi/go/src/github.com/hajimehoshi/ebiten/internal/uidriver/glfw/ui.go:129 +0x26
    github.com/hajimehoshi/ebiten/internal/uidriver/glfw.init.1()
    	/home/semi/go/src/github.com/hajimehoshi/ebiten/internal/uidriver/glfw/ui.go:119 +0x22
    
  • ebiten: deprecate `FPSMode`, undeprecate `SetVsyncEnable`, and add more APIs to control TPS/FPS

    ebiten: deprecate `FPSMode`, undeprecate `SetVsyncEnable`, and add more APIs to control TPS/FPS

    FPSModeVsyncOffMinimum is quite odd since a) this affects TPS and b) this consumes GPU power unnecessarily (e.g. when a mouse is dragged).

    To solve these issues, we have discussed at the Discord server and came up with these ideas, instead of introducing a new FPS mode like FPSModeVsyncOnMinimum:

    1. Undeprecate SetVsyncEnabled and deprecate FPSMode to make the API orthogonal with new APIs
    2. Add a new TPS mode SyncWithInput, with which Update is called only when inputting occurs. Draw's timing is also adjusted. When vsync is on, Draw is also called only when inputting occurs, but the maximum is limited by vsync. When vsync is off, Draw is not limited by vsync. This should be the same as FPSModeVsyncOffMinimum. As SetTPS affects Draw, this might be odd, but basically we cannot control the timings of Draw directly in the first place. This solves the problem a) by the clearner APIs and also b) partially by SyncWithInput with vsync-on.
    3. Add a new error value SkipDraw, which skips Draw (and the previous framebuffer is used for swapping framebuffers). This solves the problem b) by suppressing Draw (e.g. when a mouse is dragged).

    @tinne26 @Zyko0 Any thoughts?

  • cmd/ebitenmobile: support current NDK

    cmd/ebitenmobile: support current NDK

    Hi,

    I've installed a fresh Android Studio with NDK 24.0.8215888. When trying to use ebitenmobile, I get:

    $ export ANDROID_HOME=$HOME/Android/Sdk
    $ export ANDROID_NDK_HOME=$HOME/Android/Sdk/ndk/24.0.8215888
    $ go run github.com/hajimehoshi/ebiten/v2/cmd/ebitenmobile \
    	bind -target android -javapkg io.github.divverent.aaaaxy.android \
    	-androidapi 21 \
    	-o aaaaxy.aar \
    	github.com/divVerent/aaaaxy/internal/mobile
    2022/05/02 09:20:33 gomobile [init] failed: gomobile: No compiler for 386 was found in the NDK (tried /home/rpolzer/Android/Sdk/ndk/24.0.8215888/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android16-clang). Make sure your NDK version is >= r19c. Use `sdkmanager --update` to update it.
    

    I do not know why it tries to search SDK 16 binaries (and for x86 even, which is an odd platform for Android); this NDK comes with versions 21 to 32 for aarch64 and x86_64, as well as 19 to 32 for armv7a and i686.

    I would assume that passing -androidapi sets which NDK binaries it'll use, but to no avail.

    In general, the ebitenmobile instructions could be a LOT clearer - many things in there I just do not understand and will have to figure out by trial and error, not being an Android developer myself.

  • graphics: Shader API

    graphics: Shader API

    EDIT: There is a proposal document for the shader language:

    https://docs.google.com/document/d/1yVfqWY6B-yF0H3NOVff3r791_n2zUu8BUWdW9TuEorw/edit?usp=sharing


    In Unity, there is a converter from HLSL to GLSL for portability

    https://docs.unity3d.com/Manual/SL-ShadingLanguage.html

  • graphics: HTML5-Canvas-like API

    graphics: HTML5-Canvas-like API

    Random note

    How to implement

    For simple primitives, GLSL would work. For complex things like filling polygon, GLSL would also work but stencil buffers might be better.

    Or, how about implementing scan-line algorithm on GLSL without vertices?

    What kind of features there are in HTML5 Canvas

    Ref: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D

    • Shapes / Paths

      • Line
      • Rectangle
      • Polygon
      • Arc
        • Circle
        • Ellipse
      • Bezier Curve
      • Quadratic Curve
    • Line style

      • Width
      • Cap
      • Join
      • Miter Limit
      • Dash
    • Fill/Stroke Style

      • Solid
      • Gradient
      • Pattern
    • Shadow

      • Blur
      • Color
      • Offset
    • Paths

      • Fill (non-zero / even-odd) (NanoVG supports only even-odd)
      • Stroke
      • Clip
    • Others

      • imageSmoothingEnabled (Anti alias)

    I don't think we need all the above items though...

    Text

    As for text rendering, we already have github.com/hajimehoshi/ebiten/text and that's fine. For true type fonts, using bezier curves might be more effective, but the text package accepts more general font.Face interface, that can be any rasterized data.

    Filling pattern / Clip

    We already have composition modes, so I don't think we need API to specify complex filling pattern and clipping. Just filling with a solid color might be enough.

    Actual use cases

    I need actual use cases before considering API. This is similar way to Go2 language change.

    • Prototyping
    • Graphs or charts
    • UI
  • Add a single-thread mode by introducing a new build tag

    Add a single-thread mode by introducing a new build tag

    This project is super cool so I finally started porting the cp-examples over to ebiten. With vsync off I noticed the ebiten tumble ran much slower than the cp-example tumble that builds the triangles every single frame.

    The cp-example was getting ~1600 FPS and ebiten was at ~600 FPS.

    So I did some profiling and noticed some channel related locks. From what I understand most game engines are single threaded, so I removed the threading and the ebiten version is now getting ~2100 FPS.

    Is there a specific design decision that lead to threading in the GLFW code? If there's a good reason maybe add an option to disable threading to unlock peak performance?

  • Option to allow cursor to pass through window

    Option to allow cursor to pass through window

    Operating System

    • [X] Windows
    • [X] macOS
    • [X] Linux
    • [X] FreeBSD
    • [X] OpenBSD
    • [ ] Android
    • [ ] iOS
    • [ ] Nintendo Switch
    • [ ] Xbox
    • [ ] Web Browsers

    What feature would you like to be added?

    An option to allow cursor clicks to pass through the game window and not take focus. My idea was another cursor mode such as CursorModePassThrough as it would be exclusive of the existing modes.

    This would of course only apply to desktop and probably only before Run.

    Why is this needed?

    Creating a transparent overlay window like: mascot or neko but where the screen is large or where clicking, dragging or keys have no effects and we want to just use the window behind it. This would be especially required if the window was a full screen window displaying some sort of full screen effect such as the weather or whatever.

  • ebiten: add a function to call it on the main thread for native OS APIs

    ebiten: add a function to call it on the main thread for native OS APIs

    Operating System

    • [ ] Windows
    • [ ] macOS
    • [ ] Linux
    • [ ] FreeBSD
    • [ ] OpenBSD
    • [ ] Android
    • [ ] iOS
    • [ ] Nintendo Switch
    • [ ] Xbox
    • [ ] Web Browsers

    What feature would you like to be added?

    When I tackled #1029, I realized that it would be very useful to call something on the OS's main thread. Many OS native APIs have to be called on the main thread. With this, everyone can implement OS-dependent features as they like.

    Why is this needed?

    This is needed to touch the OS native APIs.

  • ebiten: make `KeyName` consistent for one tick

    ebiten: make `KeyName` consistent for one tick

    Ebitengine Version

    dd7e125d9c1414679ae9500976f9d51d2f6dac46

    Operating System

    • [X] Windows
    • [X] macOS
    • [X] Linux
    • [X] FreeBSD
    • [ ] OpenBSD
    • [ ] Android
    • [ ] iOS
    • [ ] Nintendo Switch
    • [ ] Xbox
    • [ ] Web Browsers

    Go Version (go version)

    go version go1.19.2 darwin/amd64

    What steps will reproduce the problem?

    Actually it is almost impossible to reproduce this in an usual program, but probably this can reproduce this:

    func (g *Game) Update() error {
        println(ebiten.KeyName(ebiten.KeyQ)) // prints q
        time.Sleep(5 * time.Second) // Switch the keyboard from QUERTY to AZERTY
        println(ebiten.KeyName(ebiten.KeyQ)) // prints a?
        return nil
    }
    

    These KeyName calls should return an consistent (same) results to avoid confusions. During one tick, the input state should be frozen. See #2496.

    What is the expected result?

    'q' and 'q' are printed.

    For one tick, KeyName should return a consistent result.

    What happens instead?

    'q' and 'a' are printed.

    Anything else you feel useful to add?

    This requires rewriting GLFW.

  • ebiten: support `KeyName` for Android and iOS

    ebiten: support `KeyName` for Android and iOS

    Operating System

    • [ ] Windows
    • [ ] macOS
    • [ ] Linux
    • [ ] FreeBSD
    • [ ] OpenBSD
    • [X] Android
    • [X] iOS
    • [ ] Nintendo Switch
    • [ ] Xbox
    • [ ] Web Browsers

    What feature would you like to be added?

    See #1904.

    KeyName is a function to get a physical key name for the current keyboard layout. Let's support this for mobiles.

    Why is this needed?

    n/a

  • internal/graphicsdriver/directx: unstable performance (sometimes suspending) with DirectX

    internal/graphicsdriver/directx: unstable performance (sometimes suspending) with DirectX

    Ebitengine Version

    760e6b9ebd228554bed191410ce47d8a93a329dd

    Operating System

    • [X] Windows
    • [ ] macOS
    • [ ] Linux
    • [ ] FreeBSD
    • [ ] OpenBSD
    • [ ] Android
    • [ ] iOS
    • [ ] Nintendo Switch
    • [ ] Xbox
    • [ ] Web Browsers

    Go Version (go version)

    1.19.1

    What steps will reproduce the problem?

    Note: This is a developing Issue that I will try to update when I gather more information.

    One of my players (and probably more) are experiencing "unpleasant" experience on DirectX, that is low FPS, lags between frames, and most importantly white screen (not responding state). Given that this player's machine is quite good, and on OpenGL everything is perfectly normal (2 white screens during 4 hours on dx, and no white screens on opengl for 15+hours and counting). His dxdiag: image image

    DirectX having observable worse performance than OpenGL on this particular machine is repeatable, and there is no shadow of a doubt that OpenGL is much better for this particular player. I have no evidence that this not responding state is because of ebitengine's DirectX, there are more players who reported this issue but I did not ask about details, I will from now on and I'll update this Issue to gather as many informations as possible.

    What is the expected result?

    No "not responding" state, better DirectX performance.

    What happens instead?

    Measurably worse DirectX performance on Windows.

    Anything else you feel useful to add?

    I don't really expect anyone to do something with this case right now, as I already mentioned I'll treat this Issue as a documenting page for my observations regarding those issues, especially the "not responding" state since there are a couple of players who reported that and I don't think that this is my game's fault since most of the players are doing the same activities, and only a handful of them are reporting such scenario.

Simple 2D game to teach myself various things about game development and ECS, etc

2d-grass-game I really don't know what to name this game. Its a big grass field, and its in 2d so....2D Grass game This is a simple 2D game to teach m

Jan 17, 2022
Arkanoid game in Go using Ebiten game engine with ECS.
Arkanoid game in Go using Ebiten game engine with ECS.

Arkanoid-go Arkanoid game in Go using Ebiten game engine with ECS. You must have Git LFS installed when cloning the repository to download assets. See

Oct 9, 2022
AircraftWar - a game powered by Go+ spx game engine
AircraftWar - a game powered by Go+ spx game engine

AircraftWar - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download thi

Jan 5, 2022
FlappyCalf - a game powered by Go+ spx game engine
FlappyCalf - a game powered by Go+ spx game engine

FlappyCalf - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this

Nov 6, 2022
FlappyCalf - a game powered by Go+ spx game engine
FlappyCalf - a game powered by Go+ spx game engine

FlappyCalf - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this

Nov 6, 2022
MazePlay - a game powered by Go+ spx game engine
MazePlay - a game powered by Go+ spx game engine

MazePlay - a game powered by Go+ spx game engine How to run Download Go+ and build it. See https://github.com/goplus/gop#how-to-build. Download this g

Dec 16, 2021
RundQuiz-Game - This is a Go exercise that implements and builds a quiz game from a list of math questions in a CSV file.

Go RundQuiz Game Exercise details This exercise is broken into two parts to help simplify the process of explaining it as well as to make it easier to

Jan 5, 2022
A hand-crafted 2D game library in Go
A hand-crafted 2D game library in Go

Pixel A hand-crafted 2D game library in Go. Take a look into the features to see what it can do. go get github.com/faiface/pixel If you are using Mod

Dec 31, 2022
Rock-paper-scissors game library
Rock-paper-scissors game library

jankensheep Rock-paper-scissors game library Examples Play with two players:

May 13, 2022
Golang writen 3D render library and some game-relative concepts

Golang writen 3D render library and some game-relative concepts.

Jun 6, 2022
Battleblips - Work in progress multiplayer terminal base battleship game written in Go (with mouse support!) using tcell library
Battleblips - Work in progress multiplayer terminal base battleship game written in Go (with mouse support!) using tcell library

battleblips Work in progress multiplayer terminal base battleship game written in Go (with mouse support!) using tcell library (see https://github.com

Apr 26, 2022
Spaceshooter - A port to go of the pygame Space Shooter game using the ebiten library
Spaceshooter - A port to go of the pygame Space Shooter game using the ebiten library

Space Shooter This is a port to go of the pygame Space Shooter (https://github.c

Sep 29, 2022
Simple 2D game prototyping framework.
Simple 2D game prototyping framework.

prototype Simply prototype 2D games using an easy, minimal interface that lets you draw simple primitives and images on the screen, easily handle mous

Dec 17, 2022
Bampf is a simple 3D arcade style game. Collect Energy Cores in order to finish a level. Teleport (bampf) to safety or use cloaking abilities to avoid Sentinels.

Bampf Bampf is a simple 3D arcade style game. Collect energy cores in order to finish a level. Teleport (bampf) to safety or use cloaking abilities to

Dec 12, 2022
This is a "simple" game server. Main functionalities are matching and establishing a connection between players
This is a

Game Server This is a "simple" game server. Main functionalities are matching and establishing a connection between players How to Run? run the server

Aug 28, 2022
Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol.
 Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol.

Simple Matchmaking Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol. 1- Simple Match Rule Easiest usage of sys

Jan 4, 2023
A simple desktop snake game

A simple desktop snake game that's supposed to run on Linux and Mac OS (maybe eventually on Windows). Work on the game is currently in progress - so i

Oct 12, 2021
Simple word guessing game written in golang.
Simple word guessing game written in golang.

Word Guessing Game Simple word guessing game written in golang. successTexts := []string{ "You guessed right! ????????", "Correct! ✅", "Horray!

Oct 19, 2021
Simple moonlander like game with some new mechanics
Simple moonlander like game with some new mechanics

Space Crane game Controls Arrows - control ship engines Q/A - wind/unwind crane chain Tab - capture cargo Screenshots Features Levels Levels are simpl

Aug 24, 2022