Game Loop simulation in Golang

Issue

I want to create game loop in go(lang), so i tried this:

package main

import (
    "fmt"
    // "runtime"
    "sync"
    "time"
)

var v = 0
var wg sync.WaitGroup
var sec = 5

func main() {
    wg.Add(1)
    gameLoop()
    wg.Wait()
}

func gameLoop() {
    time.AfterFunc(16*time.Millisecond, gameLoop)
    v++
    fmt.Println(v)
    if v == sec*60 {
        // fmt.Println("Goroutines: ", runtime.NumGoroutine())
        panic("err")
        wg.Done()
    }
}

This program running at 62.5Hz (16*time.Millisecond), var sec is used for calling wg.Done() after 5 second and caused var v printed 300 times.

calling panic("err") making the result like this:

panic: err

goroutine 314 [running]:
panic(0x493c60, 0xc420094370)
    /usr/local/go/src/runtime/panic.go:500 +0x1a1
main.gameLoop()
    /home/billyzaelani/Desktop/main.go:26 +0x11f
created by time.goFunc
    /usr/local/go/src/time/sleep.go:154 +0x44
exit status 2

Well what is the meaning of goroutine 314 [running] ? did i use 314 goroutine for 5 second game loop? how if this run for hours?

But, if the program use runtime package and print runtime.NumGoroutine which is return number of goroutine, the result is Goroutines: 2

So, back again what is the meaning of goroutine 314 [running]? while runtime package say different things.

Last one, if anyone can show me the better way to create game loop in golang, i really appreciate that, thankyou

Solution

AfterFunc executes the registered function in a goroutine. https://golang.org/pkg/time/#AfterFunc

While there are only 2 go routines running at a time, there have been 314 (maybe?? Not sure how goroutine ids work) goroutines throughout the program.


i don’t consider it a “better” way, but a different way, and my preferred, could be to model the game loop as a for loop.

func gameLoop()  {
    tick := time.Tick(16 * time.Millisecond)

    for {
        select {
        case <-tick:

        }
    }
}

In addition to concisely registering a case for an interval, selecting over a channel allows you to easily model a timeout, by adding another case for <-time.After, or for cancellation, by adding another case for a <-done channel.

Answered By – dm03514

Answer Checked By – Candace Johnson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.