Go Packages we developed for our games

hajimehoshi

Hajime Hoshi

Posted on February 17, 2018

Go Packages we developed for our games

We have released some games in Go like Clock of Atonement and Bluebird of Happiness. Unfortunately, we haven't made them open-source yet for some business reasons. However, we're now splitting the code into some public packages for games gradually so that Go game developers can utilize them, and game developing in Go would get more popular. In this article, I'd like to list the public Go packages we developed and used for the games!

github.com/hajimehoshi/ebiten

A dead simple 2D game library. Basically this is an OpenGL wrapper. This works on multiple platforms, not only desktop but also mobiles and even web browsers by GopherJS! Actually we were able to develop the games on desktops and browsers, and released for mobiles.

Ebiten (海老天) means a tempura of shrimp, which is one of my favorite Japanese food :-)

github.com/hajimehoshi/go-mp3

An MP3 decoder in pure Go. This is a port of PDMP3, an MP3 decoder in Public Domain license. As I just ported this automatically without understanding the spec, I am still struggling to understand what is going on in my lib :-)

The motivation I developed MP3 decoder instead of other decoder like Ogg is that we wanted to make games work on browsers. Now MP3 is supported by most modern browsers but others are not supported well (e.g. Ogg). We could utilize the browser-native decoder on browsers instead of MP3 decoder in Go for performance. MP3 had patent problems, but the patents were expired in 2017.

github.com/hajimehoshi/oto

A lower level audio lib. The great thing of this is portability: this works on Windows, macOS, Linux, Android, iOS and Web browsers. This just offers an io.Writer and you can play any sound by writing bytes to the writer. With go-mp3, you can play an MP3 file with io.Copy (Example)!

func run() error {
    f, err := os.Open("classic.mp3")
    if err != nil {
        return err
    }
    defer f.Close()

    // Decode MP3 stream and the result is an `io.Reader`
    d, err := mp3.NewDecoder(f)
    if err != nil {
        return err
    }
    defer d.Close()

    // Create an oto's player, which is an `io.Writer`
    p, err := oto.NewPlayer(d.SampleRate(), 2, 2, 8192)
    if err != nil {
        return err
    }
    defer p.Close()

    // With `io.Copy`, you can play the decoded MP3 on your machine!
    if _, err := io.Copy(p, d); err != nil {
        return err
    }
    return nil
}
Enter fullscreen mode Exit fullscreen mode

Oto (音) means 'sound' in Japanese.

github.com/hajimehoshi/file2byteslice

Yet another tool to embed binary to Go file, just like go-bindata. file2bytesslice is dead simple compared to other similar packages. This just converts one binary to one byte slice literal. That's it! The motivation I developed this is that there was an incident: go-bindata's original author deleted their GitHub account and another person used the same GitHub account again, and I thought the repository is no longer trusty. Thus, I tried to develop it myself.

Usage of file2byteslice:
  -compress
        use gzip compression
  -input string
        input filename
  -output string
        output filename
  -package string
        package name (default "main")
  -var string
        variable name (default "_")
Enter fullscreen mode Exit fullscreen mode

github.com/hajimehoshi/go-mplusbitmap

A package to offer font.Face object of M+ Bitmap font for 8/16 bitty style Japanese texts. font.Face is a semi-standard interface to represent a font face, and there is a TrueType parser in Go to make font.Face instances. You can draw the text with Ebiten's text package very easily! Of course, this can be used with (semi-)standard rendering package (Example).

const text = `Hello, World!

こんにちは世界!`

func run() error {
    const (
        ox = 16
        oy = 16
    )

    dst := image.NewRGBA(image.Rect(0, 0, 320, 240))

    // Initialize the destination image dst by filling with white.
    draw.Draw(dst, dst.Bounds(), image.NewUniform(color.White), image.ZP, draw.Src)

    f := mplusbitmap.Gothic12r

    // golang.org/x/image/font's Drawer draws a text on a specified image.
    d := font.Drawer{
        Dst:  dst,
        Src:  image.NewUniform(color.Black),
        Face: f,
        Dot:  fixed.P(ox, oy),
    }

    for _, l := range strings.Split(text, "\n") {
        d.DrawString(l)
        d.Dot.X = fixed.I(ox)
        d.Dot.Y += f.Metrics().Height
    }

    // Now the text is drawn to the image dst.

    return nil
}
Enter fullscreen mode Exit fullscreen mode

github.com/hajimehoshi/chinesegamefonts

This offers (compressed) TTF binaries of Noto CJK fonts. This package's fonts are different from original Noto CJK fonts in some points.

  • The fonts are TrueType, not OpenType since there is no actually-usable Go package to parse OpenType fonts so far (golang.org/x/image/font/sfnt is under development).
  • Many glyphs are removed from the originals' and chinesegamefonts fonts include only common CJK glyphs to reduce file size. The original file sizes are 46.1 MB (both Simplified and Traditional), and the reduced ones are 4.4 MB (Simplified) and 7.6 MB (Traditional)!

Our games don't have Chinese support so far, but we're now implementing that with this font package.


Besides above packges, we are now developing packages e.g. for user interface. Stay tuned!

💖 💪 🙅 🚩
hajimehoshi
Hajime Hoshi

Posted on February 17, 2018

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related