Live data from Hacker News

Game Development in Go

j15r.com

21–30 of 60 posts

Re: Game Development in Go

#21
post #14
post #9

Earlier quoted context omitted.

I have worked with GDB and Go before; it's not intractable, just more difficult to interpret. Printf frequently works very well for most debugging, especially server side. I use the regular logging module pointed at stdout instead of printf specifically, and increasing the debugging level works most of the time. Its also nice that with a bit of metaprogramming and goroutines/channels, you can make log printing nearly…

> I once saw a technique where you simply write your really detailed log messages to a ring buffer While this is incredibly cool, my initial concern was mostly this: > I have worked with GDB and Go before; it's not intractable, just more difficult to interpret. > Printf frequently works very well for most debugging, especially server side. The thing about your non-niche dev is that, unless you are debugging prod ( ga…

Yes, this. I've often advocated for the importance of having a good debugger when developing any kind of UI, game, or simulation code. It can be really damned hard to make sense out of subtle bugs that are the result of accumulated state, using log messages alone. When I was writing games in C++, I routinely would just keep the game running in a debugger all the time, so I could break and inspect whenever anything got weird (which could often be difficult to reproduce). I'm writing server code in Go in my day job, and I agree that it's simply a different beast, and doesn't bother me as much.

With respect to the issue brought up elsewhere about debuggers and goroutines, I don't believe it would be as much of an issue with games. In practice, I only have a handful of fixed goroutines -- simulation, rendering, network, etc -- and am only debugging one of them at a time.

Re: Game Development in Go

#22
post #15

Earlier quoted context omitted.

Minecraft seems to be doing okay. The key is to have many small GC pauses instead of few big pauses.

Minecraft's also had a ton of time invested into racing the beam with regards to the JVM GC. Not disagreeing with the viability of it, I personally use the CLR because I'm comfortable with that tradeoff and doing my work there too, but it is worth noting that a sufficiently complicated game will spend a lot of time dealing with memory issues. I'd use either the JVM or the CLR long before Go, though.

I think it's worth it to note that "a sufficiently complicated game will spend a lot of time dealing with memory issues" applies to all games. The memory issues might just be different. Or they could be simpler. Most games (especially large ones) tend to end up with multiple ways of garbage collecting eventually, even if written in pure C++. And that isn't even taking into account cache coherency, NULL pointers, double-freed pointers, etc. At least with something like JVM or CLR, you only have to fight the GC. Whether that's good or bad, that's left up to the developer fighting whatever memory issue is happening at the time.

Re: Game Development in Go

#23
post #14

Earlier quoted context omitted.

> I once saw a technique where you simply write your really detailed log messages to a ring buffer While this is incredibly cool, my initial concern was mostly this: > I have worked with GDB and Go before; it's not intractable, just more difficult to interpret. > Printf frequently works very well for most debugging, especially server side. The thing about your non-niche dev is that, unless you are debugging prod ( ga…

All that makes sense to me. That said, thanks to goroutines and channels, you can be writing out that firehose and not have to worry too much about loosing your 60 FPS (with caveats, of course, but with buffering you can do, say, 6000 log writes a second and not have to worry about overwhelming your disks too much). > and pray that it is still there, 60 times a second is 60 times a second Great thing about memory, mo…

> You could allocate upwards of 600mb to the ring buffer and not feel the pinch.

Touche.

> Ultimately, though, I agree. Full GDB support would be better; logging like this is just a stopgap.

Looks like one of us will need to man up one of these days and make a decent debugging experience. I'm just worried that the people at the helm of Go aren't taking this seriously enough. I've seen one or two quotes with them indicating that they believe printf is enough.

If you want Windows developer mindshare (keeping in mind that a fair amount of gamedevs are Windows/VS users) you're going to need some competitive tooling, they will give you tons of leniency, but if you ask them to printf they will go running back into the arms of the Visual Studio debugger.

Re: Game Development in Go

#24
post #15

Earlier quoted context omitted.

Minecraft seems to be doing okay. The key is to have many small GC pauses instead of few big pauses.

Minecraft's also had a ton of time invested into racing the beam with regards to the JVM GC. Not disagreeing with the viability of it, I personally use the CLR because I'm comfortable with that tradeoff and doing my work there too, but it is worth noting that a sufficiently complicated game will spend a lot of time dealing with memory issues. I'd use either the JVM or the CLR long before Go, though.

> JVM or the CLR long before Go, though.

Possibly only because they have been around for longer. The CLR 1.0 GC was a terrible beast. I'm sure that the earlier Java GCs were horrible things, too.

> sufficiently complicated game will spend a lot of time dealing with memory issues.

This is precisely why gamedevs are going for data oriented design, it all does come down to this at the end of the day. In theory a GC doesn't actually get in the way of DOD, because in the strictest definition it simulates infinite memory (it is, strictly, not a memory reclaiming device). GCs are getting better and better at doing this with less and less overhead. The newest concurrent CLR GC is pretty impressive, it very nearly never has to stop-the-world.

Re: Game Development in Go

#25
post #5

I already asked here before but what is the status of the GC regarding real-time games? ( for a gameserver )

Here's my take on GC in games, FWIW. I'd be very leery of using a VM with a garbage collector for the entirety of a game. They can be fine (and are extremely common) in embedded scripting languages, but it can be far too difficult to control the size of outlier pauses when everything on the heap is subject to GC. As mentioned elsewhere in this thread, the JVM GC has had an enormous amount of effort put into it, and it's still an issue that poses problems for Minecraft, et al.

I'm far from proving this assertion yet, but I believe that Go's memory model allows for a middle way that will avoid big GC pauses. As I touch on briefly in the original post, you can use Go's C-like value types and pointers to field/elements to avoid generating garbage for large numbers of homogenous objects (e.g., by implementing a simple pool allocator), just like you'd do in C[++] to avoid heap fragmentation.

I hope to get more actual data on how this works as I expand my prototype, and will do follow up posts as I learn more.

Re: Game Development in Go

#26
post #20
post #15

Earlier quoted context omitted.

Minecraft's also had a ton of time invested into racing the beam with regards to the JVM GC. Not disagreeing with the viability of it, I personally use the CLR because I'm comfortable with that tradeoff and doing my work there too, but it is worth noting that a sufficiently complicated game will spend a lot of time dealing with memory issues. I'd use either the JVM or the CLR long before Go, though.

The JVM also has probably the most man-years of effort into GC optimization. One thing the CLR has going for it is value types, which make arrays-of-struct possible (instead of arrays-of-refs-to-objects). I assume Go supports this too.

See my earlier comment (and some bits of the original post). Go does indeed support arrays-of-structs, as well as taking pointers to the middle of arrays, and directly to struct fields. This gives you a lot more control over memory layout, and lets you avoid creating garbage if you're willing to put just a bit more work into it.

Re: Game Development in Go

#27
post #5

I already asked here before but what is the status of the GC regarding real-time games? ( for a gameserver )

Java can be okay for soft real-time applications, like games, as long as you're very careful about the lifetime of your objects.

The most recent versions of Hotspot, the most common JVM, has two memory pools for (non-permanent) objects: young and tenured. Objects start off 'young'; when they survive a few collections they become 'tenured'. Young objects are collected with a minor collection, which can happen concurrently with your code and doesn't stop the world. Old objects are collected with a major collection, which does stop the world. If you're writing a game, then minor collections are okay, but you want to avoid major collections at all costs.

This means that it's okay to produce temporary objects that have very limited scopes; e.g., they're allocated while processing a frame/game step and are discarded immediately. It's also okay to produce objects that survive forever, because they won't become garbage. The problem comes in the middle, if you make objects that last a while (significant fractions of a second or longer) but eventually become garbage. They have a chance of becoming tenured, and will build up until they trigger a major collection. At that point your game will stall for a while.

The other thing you'd want to change is to tell the GC to optimize for a maximum pause time with `-XX:MaxGCPauseMillis=` (by default it optimizes for throughput). For a game server, a maximum pause of something like 500ms would probably be unnoticeable by players.

More information:

http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gct...

Re: Game Development in Go

#28

My concern with using go is definitely the GC. I mostly build games in Javascript, which has a nasty GC. But to invest in a new language, I feel like the gains need to be better than that. Java definitely has better perf than JS no doubt, and there's good tooling around it. But I'm happy working in the web space of things. The only thing im considering looking at for gamedev is Rust, but i need to let that grow a bit…

See my comment elsewhere on this thread, about techniques for limiting garbage in Go. I'm far from proving that this is sufficient for avoiding significant GC pauses, but I'm tentatively hopeful. I'll post more as I get more data on large scenes.

I did play with Rust a bit, and I do find a lot to like there. Unfortunately, I quickly found myself dealing with an overwhelming explosion of type parameters (both of the garden variety, and the 'lifetime' variety). Some of this may have been my own naïveté in the language, and some bad library design (the graphics library I was using ended up forcing me to pollute nearly every type with three or for type parameters). But that, coupled with my own Go experience, a slow-ish (though better than C++) compiler, and no better debugging support than Go, led me to stick with the latter for the time being.

Re: Game Development in Go

#29
post #6

I was experimenting with the idea of learning game dev with golang but shortly after starting I realized that there's very little tooling for that and I'll probably drop that project midway. Needing to make my own engine/tools/bindings on every step drained all the enthusiasm. Would love to see something like LÖVE made available for golang

But, but, love + Lua is just beautiful. I've only messed around with it some, but it is really a thing of beauty.

Haxe is one of my biggest current interests, and Snokit + Luxe is looking better every day.

Re: Game Development in Go

#30

My concern with using go is definitely the GC. I mostly build games in Javascript, which has a nasty GC. But to invest in a new language, I feel like the gains need to be better than that. Java definitely has better perf than JS no doubt, and there's good tooling around it. But I'm happy working in the web space of things. The only thing im considering looking at for gamedev is Rust, but i need to let that grow a bit…

See my comment elsewhere on this thread, about techniques for limiting garbage in Go. I'm far from proving that this is sufficient for avoiding significant GC pauses, but I'm tentatively hopeful. I'll post more as I get more data on large scenes. I did play with Rust a bit, and I do find a lot to like there. Unfortunately, I quickly found myself dealing with an overwhelming explosion of type parameters (both of the g…

Generating garbage slowly will reduce the frequency of collections but it won't reduce the amount of time each individual collection takes. If you need to reduce collection times then reduce the amount of data that the garbage collector needs to traverse each time, that is move some of your data off-heap. The concurrent GC in 1.5 should help as long as the STW deadline can be reduced enough (10ms is too long for a game) but going to a generational algorithm may be necessary to get GC overhead as low as you'd want.
Post reply on HN