Top Related Projects
Ebitengine - A dead simple 2D game engine for Go
A hand-crafted 2D game library in Go
SDL2 binding for Go
Go bindings for raylib, a simple and easy-to-use library to enjoy videogames programming.
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
-
Install Oak:
go get -u github.com/oakmound/oak/v4
-
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" )
-
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") }
-
Run your game:
go run main.go
Competitor Comparisons
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.
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.
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")
}
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 designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Oak
A Pure Go game engine
Table of Contents
Installation
go get -u github.com/oakmound/oak/v4
Features and Systems
- Window Management
- Windows and key events forked from shiny
- Support for multiple windows running at the same time
- Image Rendering
- Manipulation
render.Modifiable
interface- Integrated with optimized image manipulation via gift
- Built in
Renderable
types covering common use casesSprite
,Sequence
,Switch
,Composite
- Primitive builders,
ColorBox
,Line
,Bezier
- History-tracking
Reverting
- Primarily 2D
- Manipulation
- Particle System
- Mouse Handling
- Joystick Support
- Audio Support
- Collision
- Collision R-Tree forked from rtreego
- 2D Raycasting
- Collision Spaces
- Attachable to Objects
- Auto React to collisions through events
- 2D Physics System
- 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.
Top Related Projects
Ebitengine - A dead simple 2D game engine for Go
A hand-crafted 2D game library in Go
SDL2 binding for Go
Go bindings for raylib, a simple and easy-to-use library to enjoy videogames programming.
Engo is an open-source 2D game engine written in Go.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot