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.
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=<nnn>` (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...
I'd use either the JVM or the CLR long before Go, though.
The only thing im considering looking at for gamedev is Rust, but i need to let that grow a bit first.
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.
I do want to learn Go at some point though, as i'd like to do some web back end experiments with it.
In the meantime, I've gotten pretty good at printf() debugging (I worked on embedded systems in a past life, so it's a skill I've had to develop). I'm also considering adding some more structured log/trace/metrics stuff (perhaps exposed via a simple web UI) that would allow me to escape the "tyranny of the ever-scrolling console".
But in the end, I'll consider Go dead for game development (at least for me) if the debugger situation doesn't get fixed. I'm just betting that it will.
Not as good as debugger, but invaluable when you need to see the specific value (position, etc) of an object right next to the object on screen.
I'd also usually have a key bound to spit out a frequently change buffer of debug information that I could call up at any time.
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 free. I once saw a technique where you simply write your really detailed log messages to a ring buffer (using a lockfree algorithm), and spit them out when you fail. This is even easier to do in Go, since you can just send the messages over a channel and not have to worry about properly implementing a lock free algorithm, and spit them out in a `recover()` function surrounding your main (or look at them in GDB).
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 (gasp), you can control the influx of data/output of data. E.g. If you want to debug a specific webpage you can simply hit that webpage in the browser yourself, and you are guaranteed to only see code executing that has to do with that request.
The problem with gamedev is that things are happening 60 times a second. There is a firehose of data and there is nothing you can do about that. Logging is definitely used, but it is more useful on client machines once you have actually shipped a working product.
I guess what you could do is force a fail once a condition is met, to access the last data in the ringbuffer (and pray that it is still there, 60 times a second is 60 times a second).
Do you know of a library that facilitates this?
Would love to see something like LÖVE made available for golang
Haxe is one of my biggest current interests, and Snokit + Luxe is looking better every day.
Programming a LÖVE-like lib is an excellent way of learning a language. I did a javascript one some time ago, and it worked very well. You can find it at https://github.com/kikito/luv.js
To sum up I was 1) on the move, 2) in a new language, 3) in a domain I only superficially know. Not precisely the best conditions to say the least, but I managed to read and map keyboard and mouse input, draw sprites, animated water (screenshot missing), and (almost) working point physics. Were I not aiming for the realistic physics but some crude old skool implementation, I'd definitely have a (very basic) platform game out as the last screenshot.
So, even at the lowest levels and using a few techniques I gleaned from watching Notch's Twitch stream on LD48 #28 it was loads of fun and extremely productive, even without support libraries or a dedicated engine. Hint: binding a reload hack thingy[1] to cmd+R[2] was the best thing I did, being stubborn about the Real physics thing was the worst.
[0]: https://github.com/lloeki/ld48-29/blob/master/log.mdown
[1]: https://github.com/lloeki/ld48-29/blob/master/ld48-29.go#L31
[2]: https://github.com/lloeki/ld48-29/blob/master/ld48-29.go#L65
I think it shouldn't be too much trouble to get to the point where we have a set of basic composable libraries for loading and rendering meshes and other graphics, as well as sound/input/etc. that doesn't require so much wiring. I haven't done the exercise yet, but I'm also hopeful that SWIG will provide good enough bindings to Bullet Physics, so that you won't stub your toe on "real physics" again :)
Lol, last time i have seen such a message was ten years ago ;-)
Edit: Or at least it should be. Might take a couple of minutes to clear up.
Incidentally do you find that compiling is actually disappointingly slow? My current project takes about 2.5 seconds to build and that feels very long.
Anyone that isn't aware of that will assume C# in Unity == other runtimes.