[HN Gopher] Making games in Go for absolute beginners
___________________________________________________________________
Making games in Go for absolute beginners
Author : ingve
Score : 309 points
Date : 2023-11-24 12:04 UTC (1 days ago)
(HTM) web link (threedots.tech)
(TXT) w3m dump (threedots.tech)
| kubanczyk wrote:
| Based on ebitengine.
|
| To fix: a hanging sentence "Here's how an example Sprite
| component can look like"
| m110 wrote:
| Oops, that was a leftover! Thank you :)
| kubanczyk wrote:
| Good luck Milosz, I'm a fan!
| NAHWheatCracker wrote:
| I've been working on a game over the past year in Go using
| https://github.com/g3n/engine. I picked Go because I like the
| language and wanted to learn it. I picked g3n-engine because I
| wanted to work in 3d after making a few 2d games in the past.
|
| Making games is so much more challenging and rewarding than
| almost all of the work I've done for pay. There's always so much
| more to learn that doesn't feel like just relearning how to do
| the same thing except with a different framework of the week.
| mrintegrity wrote:
| This is great, the dificulty goes up rapidly. I only got to
| level 3 before quickly dying (playing on mobile Firefox)
| satellite2 wrote:
| It's really a nice project. It's really too bad that it doesn't
| compile for mobiles.
|
| It's the one point preventing large adoption of go as a gaming
| language I think. I haven't found a 3d lib that supports
| building for mobiles.
|
| And it's really too bad, because go would be perfect for
| writing games.
| uka wrote:
| Doing a game with ebitengine myself. Refreshingly nice
| experience.
| gigafuture wrote:
| Great tutorial. I really enjoyed it and saved it for later.
| dimgl wrote:
| I always wondered if Go would be a good language to make a game
| in due to its concept of goroutines. Maybe one of these days I'll
| give it a shot.
| cdogl wrote:
| Unfortunately, garbage-collected languages have historically
| not been great for real-time action games. Throughput and
| performance can be excellent, but without control over the
| garbage collector pauses can wreck the experience.
|
| For any game that doesn't require smooth frames for the
| experience, the best language is the one you're most
| comfortable with (modulo some base level of game dev community)
|
| Edit: on the other hand, Go is a superb candidate for a back-
| end game server. I'd say the same goes for the network client
| layer, but the language interop story is not ideal.
| pjmlp wrote:
| Didn't stop Notch to become rich, even with some hiccups.
| anthk wrote:
| Also lots of games have been written in C#/XNA.
| pjmlp wrote:
| Indeed, just recently I discovered that Capcom has their
| own .NET fork, and used it on Devil May Cry for the
| PlayStation.
|
| Check their developer channel on YouTube.
| beautron wrote:
| I'm making a game in Go, and it runs perfectly smooth on my
| 240hz monitor (and should run perfectly smooth on 1000hz
| monitors once we get there).
|
| The garbage collector has not been an issue, because I use
| memory the same way as if I were doing it in the C language:
| Allocate all memory used by the game at program launch. I
| find this scheme easier to work with in Go than in C, because
| Go's slice type is a natural fit for partitioning these
| launch-allocated blocks of memory (as they get used and
| reused during the game).
|
| The garbage collector doesn't get called if you don't
| allocate. And for the most part1, it's easy to reason about
| where Go allocates (if you know C). So my rule is: Always
| know where your memory is; never allocate.
|
| This may sound like it's going against the grain of Go, but I
| find Go to be handily amenable to this style. I had my
| concerns going in, but it just hasn't been a problem. My game
| runs silky smooth.
|
| At this point, my only concern about using Go to make a game
| is that bringing the game to consoles does not have a well-
| trodden path.
|
| 1 So far, the only thing that has surprised me is that
| assigning a value type (like an int) to an interface
| allocates! (So another rule is to only assign pointers to
| interfaces [pointers to memory allocated at launch].) And
| while this was a surprise to me, I was pleased with how quick
| the debugging went: I noticed frames were dropping, so I ran
| go's pprof tool, which led me directly to the (freshly coded)
| interface assignment that was stealth allocating. (Also, this
| allocation becomes less surprising the more I think about how
| interfaces are implemented.)
| Xeoncross wrote:
| Thank you for sharing, I've never considered allocating the
| memory for an entire Go program at launch.
|
| One neat thing that Go has is built-in benchmarking (part
| of the built-in test package) which shows you allocations
| per-invocation making it easy to spot the functions which
| need more work.
| nappy-doo wrote:
| Side note: Go's GC will still run without allocations,
| typically every 10 minutes. But, in your case, it might
| never find memory to collect. If you truly want to disable
| the GC, use SetGCPercent or GOGC.
| klabb3 wrote:
| > Unfortunately, garbage-collected languages have
| historically not been great for real-time action games.
|
| I've heard this a lot and even parroted it myself, but in all
| honesty I would be surprised if this is true today. First, GC
| does not mean "no control at all" over GC pauses. Secondly,
| GC pauses are incredibly short in some languages, unless you
| have to deallocate a lot.
|
| Without first-hand experience, I would assume that GC is not
| an issue for games today, given that you are aware of how
| allocations work, and you have access to a good profiler if
| necessary.
|
| As usual, the best language is most likely the one with the
| best ecosystem (libs, tooling, docs) around the domain that
| you're working in.
| d-z-m wrote:
| Much work has gone into making Go GC pauses as quick as
| possible, so it might be in a better position relative to
| other GC'd languages.
|
| Also, you might be able to toggle the GC off, and invoke
| manually with runtime.GC() at opportune moments.
| leetrout wrote:
| The way you have to do math with vectors without operator
| overloading available in Go is quite cumbersome.
|
| I am a huge Go fan and I figured this out working on the
| raytracer in a weekend project using Go.
| angra_mainyu wrote:
| It's extremely good.
|
| Goroutines and channels make it very straightforward to set up
| an ECS engine hence you can actually run a lot of the engine in
| parallel and not have to stick to the "game loop" structure.
| Build your systems similar to the actor model with a mailbox,
| have an event/messaging bus, and you basically have a very
| performant engine.
|
| I've yet to run into issues with the GC. The only bit of tuning
| I had to do was be careful with interfaces in hot paths and
| batch all graphics calls.
| tslocum wrote:
| Speaking of, I created an ECS framework for use with
| Ebitengine:
|
| https://code.rocket9labs.com/tslocum/gohan
| asda22sdasd wrote:
| While ebiten is fun, it absolutely will be limiting for your
| larger project.
|
| Consider options and research properly before choosing tech.
|
| In the case of ebiten + golang, you will suffer greatly from the
| FFI overhead when calling external graphics API:s.
| nehal3m wrote:
| Beware the factory factory factory.
|
| https://factoryfactoryfactory.net/
| endofreach wrote:
| as much as i hate the overhead of frameworks & all the
| tooling that is (seemingly) required for simple things
| nowadays, the analogy that is attempted to be made, doesn't
| really fit well. The author seems to have been too focused on
| writing a "classic analogy" that has it's own URL rather than
| writing a good & fitting one for the case he/she dislikes -
| and especially, putting real thought into the analogy to make
| it a really good one.
| LegibleCrimson wrote:
| > The author seems to have been too focused on writing a
| "classic analogy" that has it's own URL
|
| That doesn't track, given the sources at the beginning. One
| person wrote the essay, then somebody else started hosting
| it at that URL. There doesn't seem to be a direct
| connection between the writer and the URL at all.
| Thaxll wrote:
| This is not true, for 2d game the performance of Ebiten is
| good, you don't suffer from ffi.
|
| Some games have been shiped on that engine, even running on the
| Nintendo switch.
| JoeyJoJoJr wrote:
| At least from my own tests, I also found Ebiten _extremely_
| smooth and performant when building for the WASM target.
| There seems to be some people spouting a bit of nonsense in
| this thread without having actually given Ebiten a chance.
| nikki93 wrote:
| Nice! Ebiten is a super nice API for Go. Lots there to be
| inspired by in API design. Another API I like a lot is Love for
| Lua (which also actually can be used from C++).
|
| Re: the comments on here about the GC etc. -- I've posted about
| this a couple times before but I've been using a custom Go
| (subset / some changes) -> C++ compiler for hobby gamedev, which
| helps with perf, gives access to C/C++ APIs (I've been using
| Raylib and physics engines etc.) and also especially has good
| perf in WebAssembly. Another nice thing is you can add in some
| reflection / metaprogramming stuff for eg. serializing structs or
| inspector UI for game entity properties. I was briefly
| experimenting with generating GLSL from Go code too so you can
| write shaders in Go and pass data to them with shared structs
| etc.
|
| The compiler: https://github.com/nikki93/gx (it uses the Go
| parser and semantic analysis phases from the standard library so
| all it has to do is output C++) (it's a subset / different from
| regular Go -- no coroutines, no GC; just supporting what I've
| needed in practice -- typechecks as regular Go so editor
| autocomplete works etc.)
|
| A game made with it a while ago for raylib game jam along with
| the raylib bindings and other engine stuff:
| https://github.com/nikki93/raylib-5k
|
| Very old video of a longer term game project I'm using it on
| which also shows state-preserving reload on rebuilds and also the
| editor inspector UI: https://youtu.be/8He97Sl9iy0?si=IJaO0wegyu-
| nzDRm (you can see it reload preserving state across null pointer
| crashes too...)
| tjpnz wrote:
| Is size still an issue with Go if you wanted to compile to WASM
| and target the browser?
| pjmlp wrote:
| If the browser is the main target, I would just use browser
| native engines like Pixijs.
| angra_mainyu wrote:
| shout out to babylon.js, incredibly good 3d game engine for
| the browser
| pjmlp wrote:
| Definitely, my example was for 2D games.
|
| Currently the one with best WebGPU support.
| Narishma wrote:
| What would a 2D game need WebGPU for?
| pjmlp wrote:
| BabylonJS is not for 2D games, read the thread properly.
| JoeyJoJoJr wrote:
| I would recommend against anyone using PixiJS. From a code
| perspective it feels dated and inconsistent. It can be very
| difficult finding correct information for the latest version,
| and you will very easily hit performance problems if you want
| to create a full screen game. You will need to apply the
| bitmap caching feature to yield best performance, and to me
| it seemed riddled with rendering and interaction bugs, or at
| the very least highly unintuitive behaviour from its usage. I
| didn't discover these problems until I was too far into
| development of my game.
| pjmlp wrote:
| And the alternative 2D game engine designed for the Web
| with GPU acceleration is?
| JoeyJoJoJr wrote:
| It's not ideal, but I'd go with something non-JavaScript.
| Heaps or Kha in the Haxe ecosystem would be a far more
| worthwhile choice IMO.
| euroderf wrote:
| There's tinygo, which is still missing bits here & there,
| including reflection, which makes encoding/decoding (json, xml)
| problematic.
| bdhcuidbebe wrote:
| There has been work to get ebiten running with tinygo, which
| will yield smaller and maybe faster wasm. Not sure about
| status, just try yourself with tinygo command instead of go.
| tslocum wrote:
| Boxcars[0], a web-based client for playing backgammon powered
| by Ebitengine, compiles to a 20MB WASM binary[1], and as long
| as the server and browser are gzip-enabled, this actual
| transfer size is reduced to a little under a third of this.
|
| 0. https://code.rocketnine.space/tslocum/boxcars
|
| 1. https://play.bgammon.org
| angra_mainyu wrote:
| I've used raylib-go (raylib bindings for Go) and ebiten. Both are
| excellent libraries.
|
| Personally I tend to use raylib-go much more, as it can readily
| supports 3D and has a strong community around it.
| Kiro wrote:
| This is great. I feel it's missing something about delta time
| though.
| m110 wrote:
| Thanks! I had a paragraph about delta time but since Ebitengine
| works based on the TPS, I eventually decided to drop it to not
| make it confusing.
|
| Here's a good summary, I think I'll link it in my post:
| https://ebitencookbook.vercel.app/blog/2022/04/16/TPS
| susam wrote:
| While writing games in any programming language is a very
| rewarding experience, I have found HTML5 Canvas and JavaScript to
| be very effective for writing games as absolute beginners too. If
| sound is needed, there is Web Audio too, all available right
| within the web browser.
|
| It is quite possible to write simple games without using any
| external JS libraries by sticking to first principles only, e.g.,
| drawing simple shapes with fillRect(), simple collision detection
| algorithms, generating simple tones using OscillatorNode, etc.
| Here is one such game I wrote sometime back:
| https://susam.net/invaders.html
|
| Also, if the entire game is written as a single HTML file, the
| game becomes immediately distributable too. All one needs to do
| is host the HTML file somewhere or send the file to someone in
| order to share the game.
| klabb3 wrote:
| Seconded! Especially if you only have keyboard controls. Once
| you have mouse events there is no mapping between mouse
| position and an object in game, which makes it a bit harder. If
| so, you may wanna use svg. It makes it easy to handle mouse
| events, rendering is "free" and you can also do smooth
| animations with CSS. The main downside imo is that svg has more
| browser inconsistencies for some reason.
|
| Example: https://loz.payload.app/
| marcosdumay wrote:
| The web is becoming a really good OS.
|
| We just need make web assembly better for higher level
| languages, because neither javascript not rust are an end-all
| great language for small games.
| capl wrote:
| I am a fan of Go due to the focus on simplicity in the
| language... but why Go for game dev? The purpose of the language
| was to tackle backend services previously written in C++ focusing
| on junior developers, not game dev.
|
| It's not really a popular tool for the job: Python, which is a
| simpler language, has a much larger community of gamedev noobs.
| Or maybe better yet: start with Godot and GDScript
| susam wrote:
| > ... but why Go for game dev? The purpose of the language was
| to tackle backend services previously written in C++ focusing
| on junior developers, not game dev.
|
| I'd say using any language for game development should be
| embraced, not discouraged.
|
| Imagine if William Crowther had thought, "Why Fortran for game
| development? The purpose of the language is to tackle
| scientific computing." Thankfully, he did not think like that.
|
| All Crowther had with him was PDP-10, Fortran, a teletype that
| probably looked like
| https://en.wikipedia.org/wiki/File:ASR-33_at_CHM.agr.jpg, some
| sheets of paper, and a sense of fun! Without being bothered
| about what these tools were really meant for, he went ahead and
| developed Colossal Cave Adventure thereby introducing the genre
| of text-based adventure games into the field of computing. A
| player had to type their input into the teletypewriter and wait
| for the computer to print the output on, well, physical paper!
| Still it was fun. It is nice to have fun and write games with
| whatever technology we have got.
| veqq wrote:
| > Python, which is a simpler language
|
| This seems crazy to me. How so?
| superkuh wrote:
| If you never use anyone elses packages and only stick to
| vanilla python available on your system it's a great learning
| language. Many universities still use it to teach programming
| today. But this is mostly inertia...
|
| ...because python has changed in the last decade so that
| anything ever so slightly complex requires learning all it's
| dependency manager manager setups (conda, pyenv, etc) to set
| up an entire custom python implementation with it's own
| dependency manager (pip, whatever, etc) just to be able to
| run a single python application or use a python lib. Trying
| to do it with the actual python your system runs will always
| end in tragedy.
|
| So yeah... Python is a simple language. But using python
| these days is so complex I actually chose C++ over it to
| _avoid_ complexity. And that 's really saying something. That
| said, there's no such thing as system 'go' at all so it
| brings in plenty of complexity too despite being 'simple' in
| it's own way.
| llm_nerd wrote:
| Using the origin-story* of a language to argue against what the
| language can be used for _now_ is never a good argument.
|
| Go is a powerful, accessible language. It yields highly
| optimized, tight binary output targeting a wide variety of
| platforms and systems. Why _not_ Go?
|
| Python is basically a non-starter in this space. Your other
| example is a scripting language _inside_ an engine. These seem
| orthogonal.
|
| * - Which is oft heavily editorialized and fictitious, such as
| in this case
| appstorelottery wrote:
| I tend to write fireworks or simple particle simulations in a new
| language / graphics api to test for performance as my first step
| (aka learning how to place a pixel on the screen, double buffer
| or whatever, do some simple logic / math, and learn the
| compilation pipeline). It's always a fun task and an easy
| benchmark: how many pixels can I move per frame?
|
| I did this in 2021 in GO and Ebitengine and I was blown away by
| the performance the screen was mostly white with pixels, how easy
| it was to get the context running, and how many pixels I could
| move on the screen at 60fps... I was truly impressed. I've been
| using this approach for the last 30 years I guess ;-) We're a
| long way from moving a few hundred pixels on a 16 bit CPU per
| frame... _greybeard out_
| giancarlostoro wrote:
| I always do a web project because it typically shows you
| language features that you wont see in "Hello World". It also
| shows me what the database drivers look like, if its painful to
| setup, and all that fun stuff.
| mamcx wrote:
| I do the same, but different kinds of projects exercise
| different stacks.
|
| A web project does not prepare you for a bad UI history, for
| example...
| JoeyJoJoJr wrote:
| I also created a performance test with Ebitengine, like I have
| done for many 2d engines/rendering libraries in the past.
| Typically I like to test performance with the web/WASM target.
| More often than not, even just a few rotating sprites will
| result in some dropped frames. I was extremely surprised at
| just how insanely smooth Ebitengine performed. For my purposes
| it was the second most performant engine/rendering library,
| second only to Kha. Being new to Go I was also blown away how
| simple it was to just copy memory around and create Braid-like
| time travel, as well as the exceptionally simple build process.
| Rust and Bevy get a lot of mentions on Hacker News, but I think
| Go and Ebitengine will be my next choice to build my next game.
| tslocum wrote:
| I have been a happy user of Ebitengine for several years. If you
| are interested in seeing the source of some games created with
| it, check out the awesome-ebitengine list.
|
| https://github.com/sedyh/awesome-ebitengine
|
| All of the games listed on my itch.io profile were created using
| Ebitengine, and they are all open source.
|
| https://rocketnine.itch.io
| rTX5CMRXIfFG wrote:
| I'm going to react just to the first part of the article since
| the rest isn't really of interest to me.
|
| If you're experiencing the kind of burnout that the author
| described, I'd suggest an alternative to doubling down and
| "reclaiming" your hobby: make your interests evolve. It could
| very well be your body (specifically your brain) telling you that
| you're stagnating. It doesn't have to be different getting
| programming, but perhaps you've reached a point that it is time
| to go deeper, possibly into CS theory.
| its_kenta wrote:
| Not a Go dev, but a long time viewer of one YouTuber/Twitch
| streamer that makes his games in Go for a long while now. He's
| creating a small MMO in Go which you can test out here:
| https://mythfall.com
|
| UnitOfTime is his YT & Twitch handle
| https://www.youtube.com/@UnitOfTimeYT Uses his own binding to
| OpenGL and WASM to WebGL2 for Web version.
|
| Used to use Go myself, but fell out with it. But I can understand
| why people would enjoy making games with it. Just like SolarLune
| himself uses Golang for his gamedev. A lot of people seem to ask
| the same question tho: "Why make it in Go? Doesn't it have GC?"
| From my understanding Go's GC is quite robust as well.
|
| In a nutshell, nice to see Go having more usage outside the norm
| that devs expect it to only be used in.
| Seb-C wrote:
| Nice to see such a topic come up.
|
| I am the developer of Astral Divide, which is entirely written in
| Go: https://store.steampowered.com/app/2597060/Astral_Divide/
|
| When I started two years ago, I basically had to choose a
| language and a package/framework, so I'd like to share my
| experience about it.
|
| First, about the package, there are two major ones for 2D games,
| which are Ebiten(gine) and Pixel.
|
| I initially chose Pixel, because it seemed more documented at the
| time and had a bigger community. Overall, it was good as long as
| the game was simple, but unfortunately I regretted this choice
| later.
|
| Don't get me wrong, I am not here to discredit the author,
| because there is a phenomenal amount of open source work that was
| done, and I am thankful for it. But as my game grew more complex,
| the engine started to cause big architectural challenges, memory
| leaks (it does not correctly garbage collect OpenGL's objects for
| example), and it's multi-threading model is flawed. I also
| discovered that it was in fact not maintained. Overall it lacks
| too much maturity for a serious game.
|
| In the end, I decided to ditch it, because it was easier, and my
| proposals for help on GitHub never got any answer. It took some
| effort, but having my own engine based on OpenGL was the best
| choice in this case.
|
| When it comes to Ebiten, I have only used the sound library
| called Oto, but overall my opinion of the whole package now is
| that it is well maintained and architected.
|
| Now when it comes to choosing a language, I hesitated between:
|
| - Go, which I had a lot of experience with and seemed good
| enough, even if the typing system is a bit too weak
|
| - Rust, which I was (and still is) interested in, but had no
| experience, and unsure if it was worth it in terms of
| productivity (because of the additional time spent on worrying
| code, and the compilation time itself). Also, it didn't have game
| engines which seemed as mature as in Go at this time (I wish I
| had known that I would end-up with my own engine).
|
| - C++, which is the industry standard, but on which I have very
| limited experience. Also, I just didn't want to bother with the
| header files and the compilation stack.
|
| I chose Go, and too be honest it is a choice that I now regret,
| but also I have to live with it because I cannot afford a rewrite
| at this point.
|
| Go certainly had a lot of productivity benefits, but also major
| flaws when it comes to game development:
|
| - The lack of packages related to data structures. In games, we
| need a lot of specific sets, trees, queues, tries and maps, but
| those are almost non existent in Go. The best one is "gods",
| which still does not support generics. Overall it is always
| difficult to find quality and experienced packages, even for
| broadly used and fundamental algorithms.
|
| - The fact that dependency cycles are handled on a package basis,
| and not per-class or per-file. This is a major source of
| headaches for video games, because contrarily to web servers,
| there are not a limited number of predefined layers: everything
| needs to depend on almost everything else, and Go makes it even
| worse in this case.
|
| - The lack of data structures is made even worse by the native
| map, because it forcefully randomizes the iteration order, which
| causes a lot of bugs and makes it unusable 90% of the time. The
| authors wanted to prevent people from using it as if the key
| order was guaranteed, but their fix also broke the natural
| consistency of iteration order. This means for example that the
| drawing order of objects is different every frame, even when the
| data didn't change at all.
|
| - When it comes to modding, there are not much options, because
| Go does not have a very easy or natural compatibility with FFI
| (cgo is awkward to use, and not really usable with dynamic
| linking), the native plugin package is experimental (and not even
| working in windows), and the support for WebAssembly is still
| quite poor (but getting better).
| mortallywounded wrote:
| I love Go and have been thinking of using it for a game project,
| but I can't help but feel like the web itself is a far better
| stack.
|
| The web browser gives you a rich collection of things you need
| out of the box and fairly "cross platform" by nature. You get
| things like graphics, audio, networking, debugging utilities,
| access to webgl / webgpu, etc.
|
| As much as I hate to admit it.. it seems the web is far more
| suited for it than Go. I'm sure the game dev purists out there
| are pointing and laughing at the idea though :)
| atleastoptimal wrote:
| The question is: is Go a good platform to write big games in? Are
| there enough libraries and performance to justify using it over
| C#?
___________________________________________________________________
(page generated 2023-11-25 23:01 UTC)