Convert Figma logo to code with AI

oakmound logooak

A pure Go game engine

1,541
83
1,541
18

Top Related Projects

10,770

Ebitengine - A dead simple 2D game engine for Go

4,448

A hand-crafted 2D game library in Go

2,197

SDL2 binding for Go

Go bindings for raylib, a simple and easy-to-use library to enjoy videogames programming.

1,744

Engo is an open-source 2D game engine written in Go.

Quick Overview

Oak is a pure Go game engine, designed to provide a simple yet powerful framework for 2D game development. It offers a comprehensive set of tools and utilities for creating games, including rendering, input handling, collision detection, and audio support, all while leveraging Go's concurrency features.

Pros

  • Pure Go implementation, ensuring cross-platform compatibility and easy integration with Go projects
  • Comprehensive feature set, including rendering, input handling, collision detection, and audio support
  • Built-in support for entity-component systems, simplifying game object management
  • Active development and community support

Cons

  • Limited documentation and learning resources compared to more established game engines
  • Primarily focused on 2D game development, lacking robust 3D support
  • Smaller ecosystem and community compared to popular game engines like Unity or Godot
  • May require more low-level programming compared to engines with visual editors

Code Examples

Creating a basic game window:

package main

import (
    "github.com/oakmound/oak/v4"
    "github.com/oakmound/oak/v4/scene"
)

func main() {
    oak.AddScene("game", scene.Scene{
        Start: func(*scene.Context) {
            // Initialize game objects and logic here
        },
    })
    oak.Init("game")
}

Adding a movable character:

package main

import (
    "github.com/oakmound/oak/v4"
    "github.com/oakmound/oak/v4/entities"
    "github.com/oakmound/oak/v4/key"
    "github.com/oakmound/oak/v4/scene"
)

func main() {
    oak.AddScene("game", scene.Scene{
        Start: func(ctx *scene.Context) {
            player := entities.New(ctx, entities.WithRect(100, 100, 32, 32))
            
            ctx.OnKeyDown(key.W, func(e key.Event) {
                player.ShiftY(-5)
            })
            ctx.OnKeyDown(key.S, func(e key.Event) {
                player.ShiftY(5)
            })
        },
    })
    oak.Init("game")
}

Handling collisions:

package main

import (
    "github.com/oakmound/oak/v4"
    "github.com/oakmound/oak/v4/collision"
    "github.com/oakmound/oak/v4/entities"
    "github.com/oakmound/oak/v4/scene"
)

func main() {
    oak.AddScene("game", scene.Scene{
        Start: func(ctx *scene.Context) {
            player := entities.New(ctx, entities.WithRect(100, 100, 32, 32))
            obstacle := entities.New(ctx, entities.WithRect(200, 200, 64, 64))
            
            collision.Add(player.Space, obstacle.Space)
            
            ctx.OnCollision(player.Space.CID, obstacle.Space.CID, func(a, b *collision.Space) {
                // Handle collision between player and obstacle
            })
        },
    })
    oak.Init("game")
}

Getting Started

  1. Install Oak:

    go get -u github.com/oakmound/oak/v4
    
  2. Create a new Go file (e.g., main.go) and import Oak:

    package main
    
    import (
        "github.com/oakmound/oak/v4"
        "github.com/oakmound/oak/v4/scene"
    )
    
  3. Set up a basic game structure:

    func main() {
        oak.AddScene("game", scene.Scene{
            Start: func(ctx *scene.Context) {
                // Initialize your game here
            },
        })
        oak.Init("game")
    }
    
  4. Run your game:

    go run main.go
    

Competitor Comparisons

10,770

Ebitengine - A dead simple 2D game engine for Go

Pros of Ebiten

  • More mature and widely adopted, with a larger community and ecosystem
  • Better performance, especially for mobile and web platforms
  • More comprehensive documentation and examples

Cons of Ebiten

  • Steeper learning curve for beginners
  • Less built-in functionality for common game development tasks
  • Requires more low-level implementation for certain features

Code Comparison

Oak example:

type player struct {
    oak.Entity
}

func (p *player) Init() {
    p.SetDimensions(32, 32)
}

Ebiten example:

type Game struct{}

func (g *Game) Update() error {
    // Update game logic
    return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
    // Draw game elements
}

Oak provides a more high-level, entity-based approach, while Ebiten offers a lower-level, more flexible structure. Oak's entity system simplifies object management, whereas Ebiten requires manual implementation of game objects and their behaviors.

Both libraries have their strengths, with Oak being more beginner-friendly and Ebiten offering greater performance and flexibility for experienced developers.

4,448

A hand-crafted 2D game library in Go

Pros of Pixel

  • Simpler API with a focus on 2D graphics and game development
  • More active community and frequent updates
  • Better documentation and examples for beginners

Cons of Pixel

  • Less comprehensive feature set compared to Oak
  • Limited built-in audio support
  • Fewer high-level game development abstractions

Code Comparison

Pixel:

win, err := pixelgl.NewWindow(pixelgl.WindowConfig{
    Title:  "Pixel Rocks!",
    Bounds: pixel.R(0, 0, 1024, 768),
})

Oak:

oak.Add("scene",
    func(string, interface{}) {
        oak.SetViewportBounds(0, 0, 1024, 768)
    },
    func() bool { return true },
    func() (string, *scene.Result) { return "scene", nil },
)

Summary

Pixel is a lightweight 2D game library focused on simplicity and ease of use, making it ideal for beginners and small projects. Oak, on the other hand, offers a more comprehensive set of features and abstractions for game development, including built-in scene management and entity-component systems. While Pixel has a more active community and better documentation, Oak provides more advanced tools for larger and more complex game projects.

2,197

SDL2 binding for Go

Pros of go-sdl2

  • Direct bindings to SDL2, providing low-level access and control
  • Wider range of multimedia capabilities, including audio and input handling
  • More mature and established project with a larger community

Cons of go-sdl2

  • Steeper learning curve due to lower-level API
  • Requires more boilerplate code for basic functionality
  • Less Go-idiomatic, as it closely mirrors the C SDL2 API

Code Comparison

oak:

window, err := oak.SetupWindow(640, 480, "My Game")
if err != nil {
    log.Fatal(err)
}

go-sdl2:

if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil {
    log.Fatal(err)
}
defer sdl.Quit()
window, err := sdl.CreateWindow("My Game", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 640, 480, sdl.WINDOW_SHOWN)
if err != nil {
    log.Fatal(err)
}
defer window.Destroy()

Go bindings for raylib, a simple and easy-to-use library to enjoy videogames programming.

Pros of raylib-go

  • Bindings for the popular raylib C library, providing access to a well-established and optimized graphics framework
  • Extensive documentation and examples available due to raylib's mature ecosystem
  • Cross-platform support for desktop and web (via WebAssembly)

Cons of raylib-go

  • Requires C dependencies, which may complicate setup and deployment
  • Less idiomatic Go code due to being a wrapper around a C library
  • Limited to raylib's feature set and design decisions

Code Comparison

raylib-go:

rl.InitWindow(800, 450, "raylib [core] example - basic window")
defer rl.CloseWindow()

for !rl.WindowShouldClose() {
    rl.BeginDrawing()
    rl.ClearBackground(rl.RayWhite)
    rl.DrawText("Congrats! You created your first window!", 190, 200, 20, rl.LightGray)
    rl.EndDrawing()
}

oak:

func main() {
    oak.Add("scene",
        func(*scene.Context) {
            render.Draw(text.New("Hello World", 0, 0))
        },
        func(*scene.Context) bool {
            return true
        },
    )
    oak.Init("scene")
}
1,744

Engo is an open-source 2D game engine written in Go.

Pros of engo

  • More comprehensive ECS (Entity Component System) architecture
  • Better support for 3D game development
  • Larger and more active community, potentially leading to more resources and support

Cons of engo

  • Steeper learning curve due to its more complex architecture
  • Less frequent updates and maintenance compared to oak
  • Potentially overkill for simple 2D games or prototypes

Code Comparison

oak:

type Player struct {
    oak.Entity
    speed float64
}

func (p *Player) Init() {
    p.SetDimensions(16, 16)
}

engo:

type Player struct {
    ecs.BasicEntity
    common.RenderComponent
    common.SpaceComponent
}

func NewPlayer(world *ecs.World) {
    player := Player{BasicEntity: ecs.NewBasic()}
    player.RenderComponent = common.RenderComponent{...}
    player.SpaceComponent = common.SpaceComponent{...}
    world.AddEntity(&player)
}

The code comparison shows that engo uses a more explicit ECS structure, while oak provides a simpler entity setup. engo requires more boilerplate code but offers greater flexibility and separation of concerns. oak's approach is more straightforward and may be easier for beginners or smaller projects.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Oak

A Pure Go game engine

Go Reference Code Coverage Mentioned in Awesome Go

Table of Contents

  1. Installation

  2. Features

  3. Support

  4. Quick Start

  5. Examples

  6. Finished Games


Installation

go get -u github.com/oakmound/oak/v4

Features and Systems

  1. Window Management
    • Windows and key events forked from shiny
    • Support for multiple windows running at the same time
  2. Image Rendering
    • Manipulation
      • render.Modifiable interface
      • Integrated with optimized image manipulation via gift
    • Built in Renderable types covering common use cases
      • Sprite, Sequence, Switch, Composite
      • Primitive builders, ColorBox, Line, Bezier
      • History-tracking Reverting
    • Primarily 2D
  3. Particle System
  4. Mouse Handling
  5. Joystick Support
  6. Audio Support
  7. Collision
    • Collision R-Tree forked from rtreego
    • 2D Raycasting
    • Collision Spaces
      • Attachable to Objects
      • Auto React to collisions through events
  8. 2D Physics System
  9. Event Handler

Support

For discussions not significant enough to be an Issue or PR, feel free to ping us in the #oak channel on the gophers slack. For insight into what is happening in oak see the blog.

Quick Start

This is an example of the most basic oak program:

package main

import (
    "github.com/oakmound/oak/v4"
    "github.com/oakmound/oak/v4/scene"
)

func main() {
    oak.AddScene("firstScene", scene.Scene{
        Start: func(*scene.Context) {
            // ... draw entities, bind callbacks ... 
        }, 
    })
    oak.Init("firstScene")
}

See below or navigate to the examples folder for demos. For more examples and documentation checkout godoc for reference documentation, the wiki, or our extended features in grove.

Examples

<img width="200" src="examples/platformer/example.gif" a=examples/platformer> Platformer Top down shooter Flappy Bird
Bezier Curves Joysticks Piano
Screen Options Multi Window Particles

Games using Oak

To kick off a larger game project you can get started with game-template.

<img width="200" src="https://img.itch.zone/aW1hZ2UvMTk4MjIxLzkyNzUyOC5wbmc=/original/aRusLc.png" a=examples/platformer-tutorial> Agent Blue Fantastic Doctor
Hiring Now: Looters Jeremy The Clam
Diamond Deck Championship SokoPic

On Pure Go

Oak has recently brought in dependencies that include C code, but we still describe the engine as a Pure Go engine, which at face value seems contradictory. Oak's goal is that, by default, a user can pull down the engine and create a fully functional game or GUI application on a machine with no C compiler installed, so when we say Pure Go we mean that, by default, the library is configured so no C compilation is required, and that no major features are locked behind C compliation.

We anticipate in the immediate future needing to introduce alternate drivers that include C dependencies for performance improvements in some scasenarios, and currently we have no OSX solution that lacks objective C code.