Are there any resources for developing 2D game graphics, especially for hobbyists? It seems like game development articles focus so much on frameworks and just assume everyone knows where to find / how to make graphics, audio, etc. I would be especially interested in a high level "how to make a game" that didn't go so in-depth into the programming details but which did include procuring the assets and perhaps some standard patterns/strategies for managing them in your code. Also, even the general approach for game development--presumably there's some white boarding phase followed by a wireframe phase etc like you have with app dev? What does that look like in game dev land, what are some reasonable tools for hobbyists for each stage, etc?
I used it to master how to write a basic video game, without falling into the intricacies of C++ to hack out a video game.
I mastered all the mechanics of 2D video games, similar to the Nintendo and PlayStation games of the 1980s and 1990s.
I finished it in a weekend. Well, I put in 16 hour days, so it was more like a week’s work. Granted, I did have other development experience, but this was my first foray into video games.
I was driven to complete it, when I realized it was possible to actually make money as an independent video games developer. Still difficult, but possible.
I was thinking of turning this into a book or a video tutorial series. It would be helpful to crack the mysteries of game development for the new programmer.
I wonder if anybody would be interested in such a book? Or such knowledge.
Writing high level game logic in Rust is not fun, you spend more time waiting for compilation and dealing with language problems than real game dev fun.
Bevy is the nicest ECS I've tried yet you can prototype something much faster in JS. And prototyping is the fun part.
After 2ys doing rust all I can say is that it is nice as long as you know exactly what you want to do. And you often hit the wall because rust is still very young and there are not many libraries.
And more you know rust and do advanced stuff the more you hit bugs & unfinished things in rust itself. And I can tell you it's really hard to swallow when you need to redo something for the third time just because you are ahead (and nightly doesn't really help, sometimes it just opens another bag of bugs because those new features do not work together)
Try doing some GUI in rust, there's literally nothing complete right now, druid & iced are the most promising ones but still far from production-ready.
I don't know -- Pico-8 seems to be the perfect answer to what the author is asking for: it's a great environment to learn about these things, and there is a large and useful community and pool of resources around it which will tell you exactly how to develop 2D games (including the pico-zines, https://sectordub.itch.io/pico-8-fanzine-1, wiki etc). The0 "cartverse" and the already included games also provide plenty of examples of games that are both easy to learn from and actually fun.
> Also, even the general approach for game development--presumably there's some white boarding phase followed by a wireframe phase etc like you have with app dev? What does that look like in game dev land, what are some reasonable tools for hobbyists for each stage, etc?
If you're interested in learning more about this, I can't recommend enough The Art of Game Design: A Book of Lenses. The gist is that it's hard to make an actually fun game by working "from first principles", you need to iterate tens if not hundreds of times just to get a solid game idea down (more subtle aspects like balance may require thousands of iterations). So a lot of the work of a game designer is coming up with ways to iterate extremely fast, e.g. by making a prototype of the game using paper figurines and writing the rules in a google doc.
A zillion years ago I used to do hobby games as a solo dev, and it took me a long time to understand this. I was always interested in game engine elements (sprites, tilemaps, input, menus, audio, pathfinding, etc), and I could put those elements together to make halfway decent games (usually by copying existing genres). But assembling those elements is a skill of its own, and this is easy to overlook if you're a programmer who thinks programming is the only challenge to making a game (or making anything :)).
I didn't truly appreciate game design as a skill until I worked with a separate game designer on a project. He made decisions on things that would have never crossed my mind. From that point on, I started seeing game design everywhere. Notably, I started seeing it in older games, ones I had played many times and that inspired me to get into game dev in the first place. I hadn't realized how well thought out the classics were.
I've gotta say though as a beginner, I found ECS more approachable than the Actor/Object systems common in engines. Granted, I do a lot of FP and digesting data, so a series of systems to operate on data is sort of home turf. In the end though, I've been using the traditional OO systems in Unity because most educational resources + documentation are so focused around that
Interesting, the idea of ECS is intuitive to me but actually doing it is kinda hard, mainly because the scope of ECS is kinda vague there're some stuff that you aren't supposed to do with ECS, if you try to do every single aspect of your game in ECS that might result in some messier code. I actually think the Unity way is not bad, it's also a series of components compose an entity, the only difference is not separating data and logic which I found easy to work with and not bad at all.
The basic OOP solution relies on mutable aliasing being available, where any entity can reference any other entity.
Rust won't let you have arbitrary mutable aliasing or risk dangling pointers, so you'd end up fighting the language. In Rust ECS is actually easier, and it's a better fit for the single ownership, shared XOR mutable model.
That's also why I don't recommend Rust for game dev beginners, I think the most important thing for beginner is to experience the fun of game dev, which is making game logic and making the actual game, even if you go Rust with ECS, you'll still spend most of the time learning ECS, solving compile errors and waiting compilation, stuff that does not have any game dev fun.
I contend that ECS is overengineering in any game that isn't an immersive sim. It is certainly overengineering for beginners working on relatively simple 2D games.
I just started playing around with it and honestly, I like it a lot.
I've never used Pico-8 before, but from what I understand the Tic80 is pretty much the same, but with about twice the 'specs' of the pico-8.
The community is a lot smaller, but it'd be awesome to see it get more support.
It gives you a nice integrated environment for code, art, SFX and music, with limitations that make it more likely to avoid feature creep and actually letting a solo dev finish a full game in a reasonable time frame.
I'm a mobile app (not game) perspective. For many years, I always want to make cool 3D game like GTA, unfortunately due to it's complexity it's impossible to write such game alone.
The thing that's been nice working on the tic80 is being able to work on both my phone and the computer it's kind of a hassle copying the cart back and forth, but it's cool being able to program features on the go.
For 2d gamedev, I recommend raylib, GMS2, or Godot
If I had to pick one, I'd say go with raylib. Free, open source, lightweight, portable, friendly and helpful Discord community, super helpful and friendly and engaged lead dev, bindings to tons of languages, builds for many platforms, straightforward high-level API that is sufficiently documented by a simple cheatsheet, a great set of related gamedev tools taht are also developed and maintained by the same lead dev, and it's just a (C99) library, not an inverted-control framework. So you just have a while loop in main() that checks for whether the window should be closed and lets you do whatever updates in whatever order you want.
If you ultimately develop commercial indie aspirations, you may want to move to GMS2 as it makes it easier to do things like publish to consoles and integrate Steam APIs. Tons of commercial indie hit have been made and continue to be made with GMS2.
Stay away from Unity....2d is a second-class citizen in Unity.
This is hard to do in a one-size-fits-all fashion because there's a wide range of 2d techniques, tools, and processes available, depending on a multitude of factors, some example ones being:
- Game genre / mechanics
- Your team size/skill sets/experience
- Game engine
- Target platform(s)
- Monetization strategy
2d games in particular support a wide variety possibilities.
If you narrow it down I can more easily point you in the direction of specific helpful resources.
Yeah, I guess I'm thinking "hobbyist", so team size of 1 and no monetization strategy. Simple game engine (preferably in Go or Rust or some similarly approachable language; my hobby time is to precious to be writing C/C++ again), but maybe getting into the nitty gritty of game engine is too low-level for the write-up that I'm thinking about. I don't have a specific idea for a game, but I'd probably like to putz around with top-down tilers a la Pokemon or Zelda.
So, for that, I can easily recommend Godot/GDScript and using Asperite for Pixel art, if that's the aesthetic you're going for.
Godot has a little bit of a learning curve, but easily justifies it. I've made some games in it: https://yumaikas.itch.io/. Godot, for 2D games, for me, has been a force multiplier in terms of what I can get done in X hours. For Hobbyist work, that just means you can take on more ambitious projects without having to do as much groundwork.
Barring that, you could look into bindings in your language of choice to Raylib. I've used a tiny bit of it with Janet via Jaylib.
If Lua or Fennel aren't hateful to you, there's always Love2D, TIC-80, or PICO-8. But, tbh, I really recommend learning Godot.
If you goal is to work on a top down Rpg-style game, as a single developer I would HIGHLY recommend using a tool like RPG Maker (https://www.rpgmakerweb.com/)
Games like Pokemon/Zelda are very content driven and usually don't have any sort of complex systems that require deep access to game engine internals.
As someone working solo, you are going to want to spend most of your time creating fun/interesting content. Tools for this genre have been built many times before by people with far more experience building them. If you spend your time rebuilding them yourself, it's a recipe for stalling out without having much to show.
If your goal is really to just have fun building out gameplay systems as a programming challenge, I recommend using a lightweight code-oriented scripting language engine. Some good examples in this space are LÖVE (Lua, https://love2d.org/) or Phaser (Javascript, https://phaser.io/). These will allow you to jump right in to building games without needing to learn a graphical UI and are usually more agnostic about how you build your game than fully featured environments.
If you prefer the latter, but still want to end up with a finished game at the end, I recommend scoping down from an RPG to something like a Sokoban-style puzzler (https://en.wikipedia.org/wiki/Sokoban). Use a tool like Puzzlescript (https://www.puzzlescript.net/) to prototype your mechanics. Once you've finalized your mechanics you can then recreate it in the engine of your choice and add any polish. Having a playable prototype will make it much clearer what systems you will need to build.
For me, I'm interested in static typing, ECS-ish, fast feedback loops, and 2D games.
I've used Unity in the past and mostly liked it, but it is infuriating that they haven't fully solved the problem of feedback loops (slow refresh times in the Unity editor with a small project after code changes) given that they're operating in a fully managed context.
The book Game Engine Architecture by Jason Gregory might be more detailed than you'd like, but it still covers a lot of those issues (for both 2D and 3D). As a programmer-but-not-a-game-programmer, I was fascinated to read about the different modules within a game and how they interact. Before reading, if I ever did write a game, I probably would have ignored the "don't write your own engine" advice. Maybe I still would. :-) But at least I have a taste of the awesome amount an engine gives you.
Their YouTube channel is an immense resource, and IIRC all their talks are made public after 2 years (many also before that). So there's plenty to listen before you need to pay for the most recent stuff.
> Also, even the general approach for game development--presumably there's some white boarding phase followed by a wireframe phase etc like you have with app dev? What does that look like in game dev land, what are some reasonable tools for hobbyists for each stage, etc?
This is called "greyboxing" in game dev, where you build functionality (often levels) with plain grey boxes rather than actual art assets to test whether a concept is fun, playable, etc.
They're often not literally grey. You're kit-bashing for form rather than aesthetics. As such you need some ability to differentiate things. Similarly there's a minimum amount of FX feedback and UI you also need to make a game understandable.
For 2D art https://2dgameartguru.com/ might be good. It started as a set of tutorials for game programmers struggling with making art. It specifically focuses on vector art, and pixel art might be more suitable, for that https://lospec.com/ links to many tutorials.
For game design process Game Design Workshop and Challenges for Game Designers are good books that cover process comprehensively (TLDR is quick concept, prototype, play test, refine).
Tangentially related - if anyone is new to Rust and wants to see some simple mini text game examples, I've been working on a bunch [0]. It also includes some more complicated text games:
Asylum - Choose your own adventure style interactive narrative
Knights and Barbarians - Simple turned based strategy game
Legend of the Rusty Dragon - Simple adventure game inspired by Legend of the Red Dragon
Neat! I used these as an excuse to play with / work on WASM build tools / WASI interop. I've uploaded a built version to github so you can play them directly in your browser:
If you’re looking for a simple project to start with, adding new Items or Leaders to Shotcaller (my game) should be quite straightforward after perusing some of the above resources.
https://github.com/amethyst/shotcaller
Aren’t these websites manually created though? In which case, a simple check every month for “new issues with responses, and if so, are they not abandoned” would be nice
They are, but information about if a project is still actively maintained or if it's simply feature complete (data structures come to mind), should be automated in some way, otherwise information becomes stale if the maintainer of that site isn't actively maintaining it (ironically).
From what I've experienced, these sites largely go via passive maintainance, ie, based on pull requests and issues, not actively developing or updating things.
I'd love to see some kind of metric on crates.io to designate the quality of a crate. I appreciate that creating such a metric could lead to freak economics, so this is obviously not a trivial task, and the metric(s) may have to be mixed up every now and then to avoid to much gaming. Also it might be useful if such metrics are a geometric mean of the crates own score and all its dependencies.
Hardly a thing that 99% of crates are even viable for. What company would pay me 3k$ a month to full-time (or 1k$ for part-time) maintain some crate that barely anyone uses?
Only popular crates would have a chance to have support contracts like this.
The important metrics I'd be interested in is the Bus Factor, the Active Maintenance and Passive Maintenance activity as well as when the last release tag was created.
Bus Factor could be a bucketed 90-percentile count on the contributors. Active Maintenance and Passive Maintenance could be established by looking at PRs and Issues and how many commits aren't directly related to them. Last Release Tag is easy.
I agree that there be dragons, but maybe simpler metrics would be better? As an example; what if I could easily filter by crates supported by a team rather than a individual included in all its dependencies. That could be a way of doing risk mitigation. The metric would also work as incentive to create a more connected community.
It'd be very interesting to read real-world experiences of experienced game programmers with the language itself; all the discussions around the net are purely academic.
Long ago I've read on Reddit a programmer posted his detailed experience of the problems they've found on a non-trivial game, but I can't find it. I also wonder if anything changed.
... because Catherine West left for personal reasons and so it was easier to shift the project over to their existing and already working C++ engine (that they were continuously developing and using, so they didn't really 'go back').
I'm not sure if it was that first video or i saw/read about this approach somewhere else (i'm almost certain that i heard about it years before that video though), but my reaction was pretty much the same as Jon Blow's (though not so long winded :-P): aren't you just working around the borrow checker and making your own allocator with its own faux pointers via indices? Sure, it wont crash the game if your index is invalid, but you'll still access the wrong data - which can end up with hard or weird bugs and corrupted state (e.g. in savegames and/or editor).
Yeah, that's pretty much working as intended. The first priority of Rust's safety is crashes and security. Any other bugs that get squashed are a bonus, and you can't expect it to get all of them (whatever any overly enthusiastic evangelists might say).
I've just watched the first 20 minutes of that video. So far, it's all "yeah, she's basically right". When does he get to the point? I.e., what does he actually object to?
Her talk is basically "Introduction to Entity Component Systems for Rust Programmers," and it has an implicit secondary thesis that implementing the ECS in Rust adds value vs implementing it in e.g. C++.
He seems to disagree with that secondary thesis. He thinks she did a good job implementing a toy ECS, but that Rust itself wasn't particularly helpful to her.
An issue that Jonathan Blow had was that one of the touted benefits of Rust is it's ownership semantics, yet the ECS (Entity Component System) that the talk demonstrated was effectively bypassing that.
> ownership semantics, yet the ECS (Entity Component System) that the talk demonstrated was effectively bypassing that.
I don't see how that's the case [1]. The entities are owned by the ECS (or the game state, or whatever), not by each other. Entities can conceptually reference each other, but not own each other. The only time this is problematic, is when one entity is destroyed while another one is still holding a reference to it. At the beginning of the video, he discussed basically all approaches to solve that problem:
1) Raw pointers. Bad for obvious reasons.
2) Smart pointers which keep the referenced object alive. No good, he says, because one entity should not keep another one alive, if the game logic says it should be removed.
3) Weak pointers which are safely invalidated when the referenced entity is removed. No good, he says, because keeping track of back-references is inefficient.
4) Weak pointers which check whether the referenced entity is still alive before accessing it. Which is exactly what the ECS does. Rust's ownership semantics still help here, because entities are unambiguously owned by the ECS, which returns a type-safe None value when you try to access a deleted entity.
[1] I'm not arguing against you, indy; I understand that you paraphrased Blow's argument.
Yeah the confusion comes because entities are no longer a concrete element of the program but a concept tying components together. It’s just as valid to look at a subset of the components that are referenced by an entity id as a view as it is to look at them all. Like a relational database.
And by breaking things into components the granularity of ownership is increased compared with the equivalent concrete representation of the same data. So whilst you can’t reason about ownership of an entity as it primarily exists conceptually the ownership of its constituent parts is well defined.
tldnr is that Rust guides the programmer only halfway to the solid engineering solution, the programmer is on their own to make the arena solution safe.
its a pedantic nitpick, as is his way. also keep in mind that of late Blows focus has been single player video games made by very small very talented teams. A domain where the benefits of Rust are very small, possibly even a net loss compared to the fast compiling language they use now.
You might be thinking of Chucklefish who’ve done some talks and write ups about using Rust for their projects. IIRC they’ve since stopped. Catherine West their TD did a talk a few years ago.
I assume most game development (or, at least, game engine development) is still in C++? How easy would it be to start moving parts of it to Rust?
For example, if I were to write a library (e.g. a physics engine) in Rust, how easy is it for game developers to incorporate it into their C++ games? Would they need to set up a separate Rust toolchain alongside their existing C++ one? It seems it would be much harder to for them to include my library compared to a competing one that’s written in C++ - especially if the competing library is available as a single header file.
The rise of Unity (C#) and Godot (GDScript or C#) would make me think that most game code is starting to move away from raw C++ — but of course the core engine code is still C++ indeed.
"would make me think that most game code is starting to move away from raw C++"
Godot is talked about on Hacker News but it's nowhere in the industry, as for C++ it's the default language for games and it will be the case for the foreseeable future.
I feel that there is a real disconnect between hacker news and people working in the industry.
Most people here don't seem to understand how different it is from your regular CRUD app compagny.
While the disconnect is true, specially in what concerns FOSS views of the world and how real studios work, middleware like Unity and WaveEngine are indeed being picked up by major studios.
On the Switch alone, a very big chunk are all based on Unity, more than 50% as per Unity official statement.
Also although the engine is still mostly C++, they have been porting the rendering pipeline into HPC#.
Engine development and game development are two different things. For gameplay/scripting, even in 90s there were alternative languages. The way Unreal uses C++ (i.e. as scripting) is not different to how Unity uses C#.
cxx [1] is a relatively recent effort to enable safe interop with C++.
Mozilla has also published information on how they are rewriting components in Rust and integrating them into the Firefox codebase, though they were using C apis - exposing Rust to C and vice versa is relatively straight-forward.
I don't think there's anything official about it? Anyone can create bindings from their language of choice to GDNative.
Unless the maintainer is directly involved in godot or something (I couldn't see any evidence of this from quickly checking their profile), it looks like a community effort to me.
Rust has good C interoperability. So from C++ it’d look like a C library. You can either write your own glue code or use something like cbindgen to autogen the header file.
Many interesting SDKs come with C++ APIs that aren't necessarily translatable to C. Choosing Rust for engine development has the potential of severely hamstringing the team. It is the same tough uphill battle for all languages that aren't C++. Even more so now that the smoke is slowly rising from the battlefield of licensed engines and only a few contenders remain standing. And all of them have a massive C++ codebase and litttle incentive to toss that out.
If there will be a transition to any other language in that space, it'll take a decade or two.
There is an effort to automate generating mid-level C bindings for C++ code automagically, to enable easier wrapping in high level Rust APIs, by an unofficial Academy [of Motion Pictures] Software Foundation group.
It is called C++-- [1].
At this time we only target the VFX C++ ecosystem but I'd be surprised if people wouldn't use (and extend) this to cover a broader set of C++ libs.
Maybe you can give an example of a C++ API that you deem not "translatable to C"?
For example, OpenVDB uses templates with user provided arguments at the very heart of its tree structure. Similar things happen in PCL and CGAL. They are template-heavy libraries by design.
OpenCV on the other hand seems to instantiate all possible variants of cv::Mat for their Python bindings. They don't such a big space of valid and useful template parameters and IIRC the specifics are abstracted away from the algorithms working on them.
That's kind of hilarious given the role that C++ to C compiler had in the early development of the language [1]. But sounds useful, thanks for the link.
There is also this, [1], which wasn't on my radar until today:
"Corrosion, formerly known as cmake-cargo, is a tool for integrating Rust into an existing CMake project. Corrosion is capable of importing executables, static libraries, and dynamic libraries from a crate."
Interestingly, somebody pointed out in a previous discussion that a potentially significant interoperability hurdle (which is the case for the Qt libraries) is that, if a library makes use of multiple inheritance levels, it translates poorly into any language not supporting inheritance.
The vast majority of games are indeed developed in other languages than C++. The native languages of the most widely used game platforms are C# for anything done with Unity, Java/Kotlin for Android, and Swift/Objective-C for iOS.
The C ABI is the lingua franca still, you can call it from all of the above. And you can expose a C ABI for your Rust library.
Since I haven't seen it mentioned in the comments, Veloren is a FOSS cube world inspired game that's developed entirely in Rust. Looks simply stunning and I have high hopes for it.
Part of me worries about all of the awesome speedrunning people do in games written in more memory unsafe languages(like doom 2) and it makes me a bit sad that there could potentially be less broken games that people can take advantage of for speedrunning.
I'm gonna guess 90% those are physics errors either in logic (bunny hopping) or issues with floating point/bad geometry/overlooked design (doors that push you out of the world) if you stand behind them as they ope
That just has allocation, but no way to reset the arena & reclaim its memory. But then again, you'd have to make it so no allocations from the arena are alive & in use when you reset the arena.
Definitely a downside :/ On a side-note: I'm fairly sure the ST trick + -XLinearTypes will allow a better & still type-safe arena allocator to be written in Haskell than is currently possible in Rust.
Borrows are scope based, so if you limit arena usage to a scope (e.g. inside your frame loop), then it should be fairly trivial to reset it.
Reclaiming should theoretically be possible too via a method that takes ownership of the arena (the borrow checker prevents moves while an object is borrowed).
hm interesting - so basically, the blocks you borrow from the arena can be scoped to be <= the scope of the arena itself, which will then make them respect a reset?
> but no way to reset the arena & reclaim its memory. But then again, you'd have to make it so no allocations from the arena are alive & in use when you reset the arena
Looks like that implementation doesn't, but the borrow checker can definitely specify that sort of constraint (it looks `fn foo(self) -> Self`). I think it's not exposed because the code assumes that all but the last chunk are completely filled - but it could also just be that no one asked for that.
Strictly speaking rustc has a dependency on LLVM, which is in C++, but you could use the rustc_codegen_cranelift backend [1] and get pretty much everything to be pure Rust. Unless you count the libc dependency, in which case, um, I guess you could use relibc [2]? And if you think relying on OS syscalls implemented in not-Rust is cheating, then you could just use Redox directly ;)
> And if you think relying on OS syscalls implemented in not-Rust is cheating, then you could just use Redox directly ;)
There's a problem though, the hard-drive firmware isn't written in rust, which is definitely cheating :P
I mean someone even managed to run linux on the harddrive, it's practically a whole extra computer we are using to build rust and it is undoubtedly programmed in C.