Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Writing space invaders with Go (sausheong.github.io)
179 points by dcu on Feb 2, 2018 | hide | past | favorite | 58 comments


Looks cool but really should mention early on that it doesn't use SDL or OpenGL to render the game but uses a specific feature of iTerm2 to render a series of images in the terminal, on other terminals it just shows a black screen.


Ouch. Not so interesting after all then.

Does Go even have some "standard" SDL bindings? I was googling the other day (with the aim of learning Go through doing something fun) and I found like 6 results only on the first page. Didn't go and try any of them because to be honest that's depressing... i bet that if there are 6 different bindings none is feature complete.

Is Go useful just for server side stuff then?


Go has an excellent set of SDL2 bindings: https://github.com/veandco/go-sdl2

They do a very good job of making the API relatively idiomatic to Go without adding overhead, and I haven't run into any bugs yet.

I have been using them as part of a twitch series that teaches programming via small game projects. I go through how to get SDL2 up and running in episode 6:

https://www.twitch.tv/jackmott42/videos/all

There are aspects of Go that should make it better for game related programming. The low latency GC is a very good thing, compiling to native binaries means quicker start up time, and better responsiveness than a JIT, and easier distribution. Fast compile times are also very nice for many game programming workflows.


Awesome. Thanks for the link to those videos, I plan to watch them all.


There's nothing about Go that makes GUI programming hard, it just hasn't taken off. Probably because maintaining bindings isn't fun, and bindings are rarely pleasant to use (impedance between C and the host language). And writing a decent GUI toolkit from scratch is a huge amount of work. Besides, competition from web apps and things like electron is eating GUI apps' lunch, regardless of programming language.

Go is a general purpose programming language, so it's suitable for basically anything in the Java/Python/.Net world modulo availability of libraries.


https://github.com/go-gl has opengl and glfw bindings which would serve many of the same purposes.


See? That's the problem. Two different bindings recommended already. Better than 6 tbh, i might look at those 2.

And to the twitch guy I'm sorry, I'm old enough to prefer written documentation :)


opengl and SDL are different things.

glfw and SDL are similar things, in that one may use one or the other to do basic operating system tasks like "get a window" which you can then draw to with opengl (or vulkan or whatever)

Even if you were programming in C++ you would have the choice between glfw or SDL for that kind of thing (or directly talking to your operating system's API!), so Go is not adding any confusion here that doesn't exist already.

I talk a bit about this in the EP 6 stream that you are too old for =) (I prefer written docs too! EDIT here: https://www.khronos.org/opengl/wiki/Related_toolkits_and_API... )


I know, except SDL also has OpenGL support ;) Plus enough stuff to handle the rest of your game.

My main confusion is I know some SDL and OpenGL, but no Go. Thus, I don't know how to choose a SDL binding. Fighting with the binding is not a good thing when you want to learn a new language by doing a space invaders clone :)


https://github.com/veandco/go-sdl2 is the SDL binding most people are using. It is solid.


Replying to myself because I can't reply to my reply - guess too many reply levels.

Thank you mr/mrs/whatever gameswithgo! That's what I wanted to hear!


>See? That's the problem. Two different bindings recommended already.

You were recommended one binding for SDL and one for GL. Obviously they're different.


Ah sorry, my bad. I thought that since i asked about SDL bindings i got recommendations for SDL bindings ;)


Flappy Gopher[1] uses SDL and comes with an instructional video for the beginners.

[1] https://github.com/campoy/flappy-gopher



Terminals can display images?

Wow.

I'd consider that pretty amazing and useful for displaying visual information like charts, flame graphs, latency plots etc.

Is this a (de-facto) standard? If not, it should be!


Nope, just an iTerm2 feature.

Surprisingly there's nothing similar for Linux distributions - iTerm is for Mac only.


Well there is HTerm which is available for Linux.

http://41j.com/hterm/


Not just graphics, iTerm2 has a whole bunch of other features that you can't find in one terminal on Linux.


Sure but I was responding specifically in the context of GP.

>> Terminals can display images?


xterm supports some graphics through Sixel rendering. Never saw a real use of this. On X11, some text browsers, like w3m render images on xterm by painting directly in the xterm window.


This is a major annoyance for me, a former OS X user (stopped using it turned to shit in all other regards). I have had to work really hard to get text to render well in Linux terminal emulators -- iTerm2 had good typography out or the box, modulo the default typeface.


xterm has a Tek 4014 mode. Here's an older comment with some examples: https://news.ycombinator.com/item?id=7776904


notty [1], although I believe it's dead currently.

[1] https://github.com/withoutboats/notty


You know we live in strange times when Linux falls behind Mac OS on terminal support.


DEC Sixel has been around since the '80s, although I'm not sure how many modern terminal applications support it.


It may be worth noting that the sprites are registered trademarks of Taito. So be careful…

(I learned this the hard way: I once had a rather poplar 404 page featuring a variant of the game [1], until I received a cease and desist letter from Taito…)

[1] Compare: https://gizmodo.com/this-space-invaders-404-page-is-the-funn...


What year did you receive the cease and desist and was it from Brinks Hofer / Brinks Gilson & Lione?


So, I just had a look: Oct 2013, processed by a local attorney (Vienna/Austria). This was following to the page gaining some traction and popular attention in Japan. (Without intending any interpretation of this: I believe, in principle, you have to defend a trademark in order to uphold the rights – and at this point it was well in their radar.)


The invaders positions shouldn't all be updated every cycle, they should be updated one at a time, or in a separate thread, this is what the arcade machine does and due to its limited processing speed this naturally leads to the aliens speeding up as fewer aliens remain.

This implementation starts with the aliens going at what might be considered "full speed", and is probably much more difficult.

https://www.giantbomb.com/space-invaders/3030-5099/


For anyone interested in making little games in Golang, Termloop[1] is a terminal-based engine (though it uses text to render rather than this iTerm-specific feature).

[1] https://github.com/joelotter/termloop


Also, for non terminal-based things, Raylib is really nice. It's originally a C-based games-library, but the bindings work well for playing around in Golang.

https://github.com/gen2brain/raylib-go


My understanding is that Go's ffi overhead[1] makes game development impractical at a certain level, due to the amount of opengl calls you have to make. Is this still the case?

[1] https://github.com/dyu/ffi-overhead/blob/master/README.md


That test was using Go 1.8, did 1.9 introduce any improvement?

There appear to be improvements coming for 1.10 and 1.11: https://github.com/golang/go/issues/14939

You don't necessarily have to make a large number of calls into C per frame when using opengl though, I'm not sure it would be a deal breaker.


I re-tested with 1.9 and got:

  # Go 500000000 in 53058 ms

  # C 500000000 in 1989 ms


grab the 1.10 beta and try?? =)


Looks like no, no substantive improvement in 1.9


Maybe if you are doing deprecated GL_BEGIN stuff -- but that is ridiculously inefficient even in languages with native bindings!

I don't see how FFI overhed would be a big deal for modern GL code. Most of the bindings happen only once. Then, sure, you update some buffers and ask the shaders to draw, but the buffer updates are likely limited by available bandwidth between primary memory and GPU, and the actual drawing is done in-GPU by shaders -- the single FFI call to start that process does not seem like a big deal in comparison.


Just doing some napkin math.

It would be about 13,000 calls into C per frame, to waste 1 ms with call overhead.

1ms would still be a lot when you only have ~16ms to work with,but I don't think even AAA games make within an order of magnitude of that many opengl calls per frame? Even writing in pure C you want to batch things as much as possible. I think typical is well under 1000 calls per frame, but I've only got experience with small hobbyist projects.



Wouldn't that only be an issue for high-end AAA games though?


This is awesome, and something I was doing as well for fun! Go's image package has some pretty nice primitives. One thing I think would make this even simpler is you could simply sequence the individual sprites using image.NewRGBA and simply setting the Pix slice to the values to draw the appropriate images, then you can avoid going to the os at all!


FWIW, here's a single-file terminal snake in Go: https://github.com/hoffa/snake


Neat. This one works on Linux too.


Here's also a cool example of a game written in go, although using JS to display GUI: http://blog.u2i.com/we-made-a-multiplayer-browser-game-in-go...


As someone who is just learning Go, this is a really cool bite-size project to read and learn from.

Very cool!


Cool, and a great programming tutorial!

I was thinking I might see Go in a device-control application, but alas not. The program uses a modern computer's video system. The original Space Invaders code likely had to shift pixels out to the video display in realtime. So a different programming feat entirely, but still cool!


I have used go in an embedded application (raspberrypi) in a soft realtime manner controlling and LCD over I2C and staying under a 1.5ms looptime. The hardest part is to undo all the things the kernel does and get access to memory so you can do memory based io, but luckily the go stdlib has everything you need to make it happen.


Nice! I have a project of my own [1] in a similar vein although not as low level as yours. Using an RPi3 with the official TFT LCD and touchscreen and rendering graphics via OpenVG. Getting about 45fps (~22ms per frame) on the Pi itself to render an 800x480 UI filled with some round-rect buttons, rotary dials, and text. Rolled my own very basic UI controls library and cross-platform host isolation library [2] to achieve this. Tested and working on darwin, win64, and raspberry pi 3.

[1] https://github.com/JamesDunne/axewitcher-ovg [2] https://github.com/JamesDunne/golang-openvg


Well for this kind of things, bare metal and C are hard to beat. Is bare metal go possible?


There are projects which modify Go to allow it to run on bare metal. I don't recall any of the names though and I can't speak to their quality.


Even for soft realtime I'd much sooner reach for Ada than C...


Interesting, can you develop why ?


Sure! There are a few major reasons:

- The built-in concurrency primitives are designed with real time systems in mind, freeing you from the need of constructing a cyclic executive and scheduling manually.

- The tools to deal with time constraints and diagnose why deadlines were not met are very high quality. The Ravenscar profile essentially guarantees that all scheduling decisions are known statically.

- Not strictly real time related, but since real time systems are often safety priority systems I'll mention it anyway: Ada makes memory management hard to get wrong.

If you're interested, I think Programming Real-time with Ada 2005 over at Embedded.com[1] provides a really good overview. Many of those features are meant for safety critical hard deadline systems and are consequently overkill for bedroom experiments, but for those projects you can just take the default basics and get 98% of the way there.

(If the article seems outdated in some aspects, recall that there were some further imptovements to the standard in 2012.)

[1]: https://www.embedded.com/design/prototyping-and-development/...


The Sinclair ZX80 worked like that. As a result of which if you pressed a key the video would blank.


..only in fast mode iirc



Dupe - posted yesterday by the original project author, but with only two comments[0]

I think a moderator should consider merging this thread with the original, if possible.

[0]https://news.ycombinator.com/item?id=16287030




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: