Roguelike Tutorial in Rust (2019)
bfnightly.bracketproductions.com
bfnightly.bracketproductions.com
[0] https://youtu.be/TlLIOgWYVpI [1] https://www.roguelike.club/
"Programming Rust, 2-nd edition" by Jim Blandy, Jason Orendorff, Leonora F. S. Tindall [1]
[1] https://www.oreilly.com/library/view/programming-rust-2nd/97...
I need to check this out because as a new programmer, I have a hard time caring about exercise programs whereas a game provides a lot more motivation
At some point the game was spending more time on those things that on the physics simulation.
I have rewritten some code in C++ over time and parallelized as much as I can. However I'm starting to think that scripting languages are a false economy. There is no intrinsic reason you can't have a concise and easy to use language that can be quickly (in debug mode) compiled to the metal and dynamically linked to the project.
I might look at godot-rust at some point although It's a bit late considering the amount of code I have written already.
This might interest you:
* https://reader.tymoon.eu/article/413
* https://github.com/Shinmera/talks/blob/master/gic2021-highly...
and the very recent still front-page discussion on hn:
This is likely more an indictment of Godot's 3D capabilities or GDScript than scripting languages as a whole.
- Counting references. - Variant related conversions. - Resolving methods. - Interpreting the bytecode. - Sorting nodes before calling update functions. - Triggering callbacks etc.
All of these would amount to a good percentage of the time spent in the main thread. I managed to optimize by a combination of parallelism (gladly GDScript has no GIL!) and by rewriting somethings in C++.
I still have some bottlenecks with the rendering but that should be easier to scale back.
Yet, Epic after following the path of deprecating UnrealScript in name of C++ and BluePrints, has decided to hire Simon Peyton Jones from Haskell fame, to design their new scripting language called Verse.
For example if a game engine keeps track of asset references, scripts could be themselves assets like any textures, levels, materials, etc and have asset references as literals in the code that the script compiler understands, allowing automatic and precise extraction of asset dependencies the scripts (and the assets that refer to those scripts) can have. This is, e.g. what Blueprint does (BP is just a visual scripting language that uses a graph with a visual editor instead of parsing text to generate an AST but the same idea applies).
I don't know much about Verse but looking at the preview I already see a type called a type called `<latent>` (async Promise?) and a `race` keyword (seems like a built-in `await Promise.all`?). I bet building these directly into the language fixes much impedance mismatch.
- Fast to compile
- Fast to run
- Memory management that doesn't destroy frame times
- Easy to embed, ideally with a small runtime
- Can target whatever ISAs and OS's that the game runs on, like consoles.
There are not dozens of languages that fit these criteria, particularly memory management, embedding, and toolchain support for consoles when you're using a proper JIT compiler and not a bytecode interpreter.
I think UE is a situation where writing a new language specifically for scripting it is absolutely the correct choice. The user base will be large enough to support it properly, and there are a lot of things that are a lot more ergonomic when the language will be built to support them after the base system is already built, instead of the other way around.
[1]: https://en.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp
I strongly agree this is a superior approach to a custom language. Even better if the games industry standardized a single purpose fit scripting language
But for all intents and purposes it is a scripting language - the blocks are even converted into an AST-like intermediate representation that is then either converted to a bytecode VM or is used to generate C++ (though the BP-to-C++ conversion generates very weird code since BP allows -conceptually- multiple things to run in parallel).
But the Blueprint "front end" can be replaced with another (text based) scripting language that generated the same IR and the rest would work the same. While i haven't seen UE3's source code so i can't be 100% certain, i'd bet that the IR and VM have their roots in UnrealScript - and chances are Verse is also targeting the same IR.
QuakeC was for Quake 1, also compiled, but not to a DLL: https://www.gamers.org/dEngine/quake/spec/quake-spec34/qc-me...
Modern QC compiler: https://www.triptohell.info/moodles/fteqcc/README.html
It points to a few great tips- things like, being very intentional about node type, collision layers, monitoring/monitorable, and other concepts like pooling and the physics server.
I've seen shaders cause problems due to branching logic- I'd try disabling them or making them perform a no-op.
I've focused on 2D with Godot, but often with a very high volume of nodes at once.
Which led me to change many things in the implementation and I also ended up patching the Engine multiple times.
One example is this (which I have patched on my Godot version): https://github.com/godotengine/godot-proposals/issues/4050
I profile my game all the time, but sometimes it's not clear if there is a bottleneck or if there are just too many things at the same time.
Also the bottleneck can change in different parts of the game. Sometimes I have removed a bottleneck on the CPU just to find another in the GPU.
I’m a big fan of interpreted languages like python and the python like godot script. The power of quickly accomplishing tasks because of their fast and loose nature is great, but as I’ve built up some large repos at work written in pure python, I’m starting to regret the loose typing. Bugs caused by a small loss of data because of implicit type casting have been a source of much wasted time. I’m starting to convert to rigidly typed systems of program just for that peace of mind that any calls I make to an API will not compile because I am not passing the right type. It makes sense to switch to a language like CPP/Rust for big projects like a game.
People have built a few games with the Nim Godot bindings:
https://github.com/pragmagic/godot-nim
There’s also an interesting project to do hot reloading using dlls:
The Revenge of Lisp strikes again. Yet another reason for why your program should look like a big ball of mud?
I admit on the few times I played it and managed not to get frustrated I do start to perceive it at least partly in 3 dimensions with immersion, like an interactive cinema in my head, bit like when I played AD&D as a kid (which I admit I miss).
Once you get into them though, they're some of my favorite games. NetHack might be the most absorbing game I've ever played, and there's a few others with that art style that came close.
The ECS pattern became something really interesting to me just because of the highly serializable state.
One of the MUDs my community was involved in had a great developer behind it. It was just so amazing how fast new features were added to the system. The idea that you don't need assets, animations, etc is critical.
I would love for a book series that would cover something like this in multiple languages.
Been using Godot for a year or two and loving it, but I do want to try out the code only workflow, I feel like it'd suit me better being freed of the constraints of an engine, but I'd at very least like to try so I can be sure.
I tried Bevy before and it was fantastic, but its just not production ready. Also tried Raylib, the main problem with that being the sheer number of bindings somewhat segments the community and makes it harder to figure out how to start off with, but it might be worth another go. Might also consider going without a framework and just finding libraries to fill in what I need, but that might not play nice with "not too much of a pain to work with"
But maybe it is worth that extra time investment just for how popular and battle-tested it is
There aren't so many alternatives actually (SDL is a very valid framework, but it isn't a game engine), and the choice depends on what's your real goal (experiment or develop a real game). In my opinion, if the goal is to produce a real game, for somebody who doesn't have significant experience, documentation (including: availability of books) is the top priority.
I'd say my goal is to produce a real game, its really just to experiment, but the experiment is to see if it should replace Godot for me
1. state/stages can't be used together; since plugins may use states (and even baisc funcionality, like the fixed frame step), you can't use stages
2. in order to flush commands, you need stages, but you can't use them due to 1.
The result is that with Bevy itself, writes (commands) become effective only at the end of each frame. There is a plugin written by a 3rd party, but the Bevy developers are treating this as very low priority (it's been open for a very long time, and it's not even scheduled for the next release). Paradoxically, it matters little because there's a lot of hype about Bevy, but there are little (or none) significant projects - only very small ones or demos, which don't require efficiency or precise timing.
Additionally: the Bevy team doesn't write documentation at all. The "cheat book" is written by a 3rd party, with the consequence that it's partial, superficial, and it may be halted at any time (note that I don't fault the book maintainer(s); their contribution is crucial!). This isn't great when one approaches the engine for the first time; it actually sucks because engines like Bevy are (relatively) large beasts.
The scheduling rework that you're complaining about is extremely high priority, and I have personally invested hundreds of hours into redesigning and refactoring this mess (which is now in its third serious iteration). It's a challenging problem, and the volunteer who has taken responsibility for the rewrite has needed to step back for a while as they transition to a new job.
I have also personally invested hundreds of hours writing, editing and reviewing docs for Bevy. That's what got me involved in the first place, and the team has done a great job. A fully revised book is also in the works, but getting the subtle details right are critical.
As for serious projects: I've spoken with about a half-dozen commercial teams, including one with a team size of about 10 and a lifespan of nearly two years. Their feedback is remarkably positive given the immaturity of Bevy and the supporting ecosystem. While there are missing features that they want (hi bevy_ui), and annoying papercuts (yep, those scheduling concerns sure are annoying), they've over all been wildly impressed been how easy to maintain, reliable and performant Bevy has been for them.
I see.
> I have also personally invested hundreds of hours writing, editing and reviewing docs for Bevy
Do you refer to the API docs and/or examples, or something else? I think it's important to have updated and more or less extensive API documentation, but it's not a proper resource for people to learn. AFAIK the only other semi-official learning resource is the cheat book, which is fundamental, but also incomplete.
> As for serious projects: I've spoken with about a half-dozen commercial teams [...] they've over all been wildly impressed been how easy to maintain, reliable and performant Bevy has been for them.
I don't have this clear. Are 5/6 teams actually building commercial games with Bevy, or they just planning to do it in the future? This is a crucial distinction.
Strongly agreed on the need for better introductory material; the existing book is extremely incomplete.
> I don't have this clear. Are 5/6 teams actually building commercial games with Bevy, or they just planning to do it in the future? This is a crucial distinction.
I know of 2 released commercial projects, the CAD team, a few indie devs who have started and 3 or so small studios who are looking to start. There's a little thread in the Discord where I've rounded folks up: [Bevy in production](https://discord.com/channels/691052431525675048/995713618526...).
But the Tool class (which you use to leverage the GUI) is so useful in Godot. You’re probably going to use egui or imgui to build a replacement yourself in any other engine anyway.
The instant feedback of changing key variables and seeing their effect is too useful not to leverage.
As for the tool class, I don't use that much in regular godot to be honest. It always felt a little like variable exports, a bit of a hack for users coming over from Unity to feel more at home but not "standard practice". Not sure why it feels like that to me, but I do alright without it.
For example, i’ve made a script where editing one tilemap updated another, the first being a palette for wave function collapse, generating the other.
When i implemented vector fields, i first had it track the mouse instead of the player and did it all in the editor (not hitting play)
You can always execute via the binary.
https://docs.godotengine.org/en/stable/tutorials/editor/comm...
I am going to suggest the opposite: subject yourself to more constraints. Try programming on a retro-fantasy console like Pico-8 or some of its free alternatives.
I found the (sometimes ridiculous) restrictions very liberating. In exchange you get raw immediacy. I want a game with a chicken on it. I spend doodle something with the 8-bit 8x8 bitmap editor. I draw it with 1 line of code, 4 more lines to control with the arrow keys. Total time: maybe 2 minutes.
This radical immediacy is something I really missed in more unconstrained environments. I would get analysis paralysis "should it be a male or female chicken? what shader should I use to properly render the chicken wings when there's rain".
But if you're more artistically inclined, you will only find frustration where PICO-8 flaunts its "cozyness". It imposes completely arbitrary and unnecessary restrictions where there should be none. These restrictions will become a brick wall you eventually hit, and then you have to start peeking and poking raw memory with hexadecimals like you're programming in fucking C, or just give up trying to make the game you wanted to make.
I also want to say that I think of myself as actually very artistically inclined. An 128x128 screen in 16 colors is just a medium. You prefer other mediums and that’s fine, but the implication of “Pico-8 isn’t for artistic people” is simply not true.
But back on your point, yeh pico-8 is fantastic, like the game dev equivalent of a pocket operator for music. I never quite got the hang of it, but I do want to try it more, it seems like it'd be fantastic for prototyping, and maybe actually itself gives a decent idea of the code-only workflow Im looking for.
I only got to about halfway through section 2, but I think it was going well.
A ~roguelike~ rogue-lite is something where you start from the beginning repeatedly, and each "run" or playthrough you change the game state somehow (varies by game) so that the next run is easier / you have more in-game options for progression. Almost always with randomized game features available each run.
It's worth noting that "rogue-like" is a description for the Game Play Loop, not the look / feel of the game. A roguelike can be top-down, side scroller, 2d, 3D, etc.
Usually this is how the community differentiates between "roguelikes" (i.e., like the original Rogue[1] - with no persistence between runs), and "roguelites" where there is some amount of carryover, like in Hades.
Of course, like any time you have a bunch of dorks arguing about nomenclature, there are a bunch of grey-area examples that people fight over as if it matters more than it actually does.
Anyway, tangent: Hades fucking rules.
You've fallen for the hostile takeover. Roguelike used to mean the exact opposite of that: Each run starts from scratch, independent of all previous runs. Some roguelikes, that is, games like Rogue [0], implemented "player ghosts", monsters based on previously dead player characters, but that's the only persistent progression in a roguelike.
It saddens me that the term has been hijacked by modern indie developers to pretend to mean just about any game that has any amount of randomness in it. Dead Cells is not a roguelike. Hades is not a roguelike. They are action RPGs more like Diablo. Diablo, by the way, is also not a roguelike.
WHAT IS A ROGUELIKE?
As the name suggests, it is a game like Rogue. The genre hasn't evolved a better name yet, kind of how first-person shooters were originally called "Doom clones". So what was Rogue like? First and foremost it was a turn-based tactics game, where you had an unbounded amount of time to ponder your next move. It had highly randomized content, you'd have to make do with what you found. It was a dungeon crawling, exploration, turn-based tactical combat game with permadeath and no persistence of progression. You lose, you start all over.
Hades and Dead Cells are certainly not like diablo. the core game loop is to lose and try again, not build up a strong character over the course of a single playthrough as is typically expected of action-rpgs.
It seems like the definition of rogue-like has expanded due to popularity of the genre (as things do) and you have a purist attitude that rejects the new compromises. Rather than create contention over something you cant control, it might be better to highlight permadeath and no persistence as a subtype of rogue-likes for which the original game falls under.
And yes, it probably does need a better general-purpose name but unfortunately the thing it describes is rather abstract so idk what a concise self-evident phrase could be for it
Saying that it's a feature of the genre is definitely wrong.
good thing I am not saying that then
The point is that if you see "roguelike" then those features could be there, not that they necessarily will be there. We are talking about a genre, which is a pretty general thing
An FPS could have grenades, but it might not. And including grenades does not suddenly mean it is no longer an FPS.
Steam does list Dead Cells as both a roguelike and a roguelite. So yeah, you literally will find these features in this genre.
> each "run" or playthrough you change the game state somehow (varies by game) so that the next run is easier / you have more in-game options for progression.
You didn't say they could have that, you said they did. You can change your comment in a way that it would be correct, yes.
I could describe dogs as "brown animals", then you'd say that's not usually true. I could reply that some modern dogs are brown now so I'm not always wrong, but describing dogs as "brown animals" is definitely an incorrect definition.
I searched for rogue-likes a few years back, played some, enjoyed and continue to enjoy the genre, and commented based on my experience. Pretty much every game I came across had game-state changes. You referenced slay the spire. you unlock new cards and classes in that game, giving you more in-game options for progression as I said.
I think you are misunderstanding where people come from with this: it's not the randomness; it's games where when you lose, you start over from the beginning - not the last save/checkpoint/whatever. What this indicates is that, in the broader gaming scene, this is the defining characteristic of Rogue(likes), not the permadeath.
And in that sense, something like Hades or Everspace or FTL or whatever absolutely fits the bill, even if on your next run - from the beginning - even if you are very slightly stronger the second [third, fourth, hundredth] time around.
I understand that there are still some purists out there who work themselves into a tizzy over splitting these hairs. But it's okay for there to be subgenres. It's okay for colloquial terms like this to have fuzziness to them.
Starting over when you die is exactly how games worked since the arcade days. It only becomes meaningful in a roguelike when coupled with randomness; otherwise you're just replaying the same game over and over again (which is like, exactly the reason Rogue and its likes exist - a different adventure every time).
> from the beginning - even if you are very slightly stronger the second [third, fourth, hundredth] time around.
If you're stronger than before then it isn't the beginning, is it? It's a continuation. It's a save file. Rogue deletes your save file when you die.
So then from a purist viewpoint, starting over from the beginning is not a defining characteristic of a rogue-like. A randomized playthrough is. which means Minecraft is a rogue-like
I think what happened is that some general qualities of early games maintained persistence to modern day gaming in the rogue-like genre (starting over, permadeath) alongside rogues unique features (randomized adventure) because they complimented each other well. So the takeaway for the genre now ends up being those more general qualities, because they've disappeared from everywhere else. they might not be specific to rogue at the time of rogues creation, but rogue-like was effectively hijacked from the beginning.
I only found rogue-likes because i was looking for games with permadeath, for example.
No, it means you don't understand what a roguelike is. (and since you've been fooled, I don't blame you)
> rogue-like was effectively hijacked from the beginning.
Not at all. Rogue came out around 1980, and birthed the genre almost immediately. Hack was released in 1982. NetHack in 1987. Angband in 1990. Ancient Domains of Mystery in 1994. Linley's Dungeon Crawl in 1997. DoomRL since 2002. In 2008, Dungeon Crawl Stone Soup ranked as the #1 roguelike. Brogue started in 2009. Caves of Qud in 2015. And Cogmind has been in development before 2017. These are just the ones I know about, but they clearly represent a descent from Rogue. Play any of them and it's obvious what they have in common - not just randomization and permadeath but also turn-based tactics.
If my memory serves me right, it was Spelunky in 2008 that was really the first game to "borrow concepts from roguelikes" and place them in a decidedly non-roguelike context. Note that Spelunky never advertized itself as a roguelike. It is now tagged as such by users on Steam, but even its creator knew it wasn't in the genre.
I don't know who or why was inspired to start misusing the term roguelike so heavily since then, but it's become a plague.
the minecraft comment was tongue in cheek because you used contradictory wording between your comments. You asserted that the randomization was key to what made rogue different and not the permadeath because all games had permadeath and restart at the beginning mechanics.
If I understand you correctly now, you are asserting that it is a specific set of seemingly generic features that make up the rogue-like genre and that lacking any of them kicks the game out of the genre.
>It is now tagged as such by users on Steam
This is kind of the point I am getting at. There is something captured by rogue-like that is missing from other games enough for users to begin appropriating it out of necessity. "Its a rogue-like except ...." eventually becomes "rogue-like". So if you want to preserve the rogue-like tag, a new tag still needs to be adopted for the kind of game where you start at the beginning repeatedly without the other requirements needing to be met. "rogue-lite" is already kind of the leading effort to patch the problem, but honestly as a tag it makes no goddamn sense without the history lesson.. it's piggy backing off rogue-like which implies some sort of equivalency
I wish games had their specific mechanics tagged in much higher resolution in general tbh
It's fun to get a group of friends together and play a daily seed run... see who gets the most gold, who gets deepest, etc.
No seriously, that's great, and maybe rust monsters will be included eventually. Technically, it has an interesting effect (damages metal items) which may have a place in a tutorial like this.
Sure, game development can be fun. But this looks more like a tutorial for rltk. It quickly gets pretty confusing if you don't already know some rust, gamedev and rougelike.
(I recommend beginners to look at rust by examples instead)
Different tools for different people. Absolutely.
That said, the Venn Diagram of "roguelike enthusiasts" and "game developers" approaches a circle.
It makes separation of concerns very natural. Different parts/layers of the game, like inputs, AI, sounds, graphics, effects and animations can be coded separately. You don't end up with "god class" for player's object that does a bit of everything. You have player entity that has components attached, and each system operates on its own set of components.
I can't really do it justice in a comment. It's a quite different approach, so it's not directly comparable. It's like OOP vs Rust's traits. ECS happens to match Rust's memory model and traits incredibly well.
Here's a more in-depth talk about this: https://www.youtube.com/watch?v=aKLntZcp27M
The classic example is[1]: Instead of having a list of structs, where each struct get some types (int, float, ...), you use one struct, where the fields are list of types (array of int, array of floats, ...)
[0] -- https://en.wikipedia.org/wiki/Data-oriented_design [1] -- https://en.wikipedia.org/wiki/AoS_and_SoA
It's kinda behind the scene ECS.
The SQL reply summed it up quite nicely, basically you perform queries for anything with a class attached and then perform your operations on all of those. It sounds really inefficient, but in terms of raw performance the results usually speak for themselves.
A good example I encountered with Bevy, another Rust ECS framework, is imagine you want your camera to follow your player. Rather than having a script on your camera and a different one on your player, you could just attach a generic class to both, query through anything with that class and update the position of it based on the input.
I followed this one in 2018 and really enjoyed it, and it made a playable and impressive little roguelike! Though I didn't end up learning rust very deeply from the effort, it was a worthwhile experience and I are least gained some familiarity.
Come on.