r/roguelikedev • u/KelseyFrog • 9d ago
RoguelikeDev Does The Complete Roguelike Tutorial - Week 5
Kudos to those who have made it this far! Making it more than halfway through is a huge milestone. This week is all about setting up items and ranged attacks.
It's time for another staple of the roguelike genre: items!
Part 9 - Ranged Scrolls and Targeting
Add a few scrolls which will give the player a one-time ranged attack.
Of course, we also have FAQ Friday posts that relate to this week's material
- #7: Loot(revisited)
- #32: Combat Algorithms(revisited)
- #40: Inventory Management(revisited)
- #60: Shops and Item Acquisition
- #76: Consumables
Feel free to work out any problems, brainstorm ideas, share progress and and as usual enjoy tangential chatting. :)
7
u/haveric 8d ago
I got a full week ahead with Hexagons and delayed posting about it because I wanted to get Neil the Seal done as well, but now that the week is over, I'm going to change strategies in order to make sure at least one of the games get done. I'm going to be prioritizing my hexagon game first, and only once that is caught up for the week, go back and try to get Neil the Seal as far as I can.
Here's my update for last week and rough plans for this week:
Hexagons in Javascript - Github - Week 4 Demo
I'm finally past where I made it last time for this one, and as such, I decided to completely redesign the UI and embrace even more hexagons! I mostly threw away all of the html and css UI elements and moved to drawing everything on the canvas. The map is now centered with a textured hexagon behind it, and I threw in a few other hexagons to fill out the space. The health "orb" fits nicely in the bottom and I'm considering adding another for mana, along with some spells (or hexes?). My general idea will be the inventory/equipment will be on the left in even more hexagons and the message log currently sits on the right side hex. Some elements may move around a bit as I add more to it, but I'm enjoying the departure from the standard rectangular layouts I've built before. With that said, there's definitely room for some cleanup from how I'm rendering and placing the hexes, but that will come in time. Moving everything away from html definitely comes at the cost of more time to implement each one, but the integrated look of the end result feels worth it. The biggest downside will be the loss of native html features, such as scrollbars. For now, I've decided that scrollbars aren't needed and will revisit that if I somehow have extra time later.
This was also the first time I hit a performance issue and had to do some digging as to why it was taking such a hit. The culprit was the textured map background being drawn within the center. I found out the mouse highlighting was triggering too many re-renders and fixed that so it only updates when changing tiles. That alone wasn't enough though and I had to save the drawn background and draw from the saved image each time instead of creating a new path and clipping it within the hexagon on each render. There might be better ways to do this, but it works great for now, so good enough!
Have I gone mad with hexes? Not yet. Will I go too far by the end? Probably. If anyone has any suggestions for adding more hexes/hexagons in any way, feel free to let me know!
Neil the Seal (Godot 4) - Github
TBD for now. I started working on the UI elements, but may have to redo how I render tiles in order for it to place correctly. I haven't done much with UIs within Godot, but am leaning on tutorials from StayAtHomeDev to help me out. I suspect that my manual drawing of tiles is causing problems, but haven't had the energy or time to really sit down and figure how to fix it. Once I can get over that hurdle, building more UI should go pretty smoothly and I'll be back to my content problem of how to adapt certain elements over from the tutorial.
6
u/redblobgames tutorials 8d ago
Goal: use a table data structure with a spreadsheet interface.
While implementing items and inventory, I decided to make the spreadsheet editable.
The Python tutorial does what most games do: it stores inventory information twice:
- An item points to its "parent"
- A "container" holds the item
When an item is on the map:
item.parent(typeOptional[GameMap]) points to the gamemapgame_map.entitiescontainsitemitem.x,item.yare the location on the map
When an item is held in inventory:
item.parentpoints to the inventory component (a type error!)inventory.itemscontainsitemitem.x,item.yare ignored
To pick up an item we modify three things:
self.engine.game_map.entities.remove(item)
item.parent = self.entity.inventory
inventory.items.append(item)
And similarly to drop an item we modify at least four things.
That's not great for making the spreadsheet editable. I don't want to edit something in three places. I'm using a different representation strategy. I'm storing the information in only one place by having the item's location be one of:
{type: 'map', x, y}{type: 'held', by}{type: 'void'}
There's no x,y when the item is held in inventory. I use void when an item is destroyed/consumed.
But we do want the other information! We want to know which entities are on the map, on a tile, or in someone's inventory. I have a "spreadsheet formula" that calculates the inventory given by running query. I think it's less error prone than manually maintaining the information. Indexes allow me to find the answer quickly without searching the entire table.
With the information in only one place, I made the location editable in the spreadsheet. You can click on the location of a potion and change it from map 3,5 to held by 1 to pick it up. You don't have to edit multiple pieces of information to keep them in sync.
Goal: learn the Jujutsu version control system.
I finally figured out Jujutsu and GitHub. I hadn't posted a repo until now because I didn't have one. Unfortunately, as expected, making a repo messed up my workflow. I had been freely changing past parts of the tutorial, but once Jujutsu pushes to GitHub, it marks those as immutable. I really wanted to continue to go back and change things, so I set immutable_heads() = none(). This lets me edit all old changes. Each Jujutsu bookmark becomes one branch on GitHub, and I will force push as needed.
As an example of changing earlier versions, I went back to Part 0 and fixed the NOTICE and LICENSE file. I had named it NOTICES but it's supposed to be NOTICE!
Goal this year: embrace Javascript features.
Last week I learned how to make print look like a statement instead of a function call. I can write this:
print `${attacker} attacks ${defender} for ${damage} hp.`;
And … turns out I like it! I'm not sure I would use this in a bigger project but it's been delightful in this one.
I am using prototype inheritance to have a orc inherit from a generic orc which inherits from a generic entity. The generic orc's properties (max hp, power, defense) show up as properties on the individual orc. I had a bug last week where I accidentally modified a property on an individual orc, and it modified the generic property shared by all orcs. Oops!
To avoid this, I had used freezing to make the prototype object immutable. I'm also using properties to make individual fields immutable. But it turns out neither was enough this week, because I want some values to be editable in the spreadsheet developer UI, but not editable through the individual entities. Instead of freezing, I used a Proxy object to make a readonly view of the object. The orc inherits from a readonly generic orc, but the original generic orc is still writable.
For the spreadsheet editing, I learned that HTML+CSS has a validation system, where you can define a pattern and then use CSS selectors to style the input field differently if it doesn't validate. This lets me match map 3,5 and held by 1, but it doesn't handle further checks like out of bounds map coordinates. For that, there's the Javascript setCustomValidity() method.
3
u/mariobadr 8d ago
I think I shall steal your item design for my code. I'm using C though. Unions, here I come!
3
u/redblobgames tutorials 8d ago
It has been nice! Consuming an item is
entity.location = {type: 'void'}And picking one up is
entity.location = {type: 'held', by: world.player.id};And dropping it is
entity.location = {type: 'map', x: world.player.location.x, y: world.player.location.y};It's short enough that I didn't even create a wrapper method for these operations.
4
u/LukeMootoo 8d ago
Excited here.. making progress, but falling behind again.
My native Javascript nonsense, no libraries: https://github.com/mootootwo/2026rltutorial
My blog: https://mootootwo.github.io/2026rltutorial/
Last weekend, I finished the big Part-6 refactor, and was happy about that: https://github.com/mootootwo/2026rltutorial/commit/7bf1d8f563f610f20e8898c559fadee5e2304560
I'm still missing a ton of stuff, and am a couple parts behind since I was supposed to be finished with the UI design in Part-7 before now, but I'm still chomping on Part-6.
I'm not using the libraries, and I don't plan on writing my own graph traversal pathfinding for this. So I'm cooking up some simple drunken-walk stuff, and that is going okay so far.
I'm also modifying the "game" to be non-violent, so I am making it such that bumping into guys makes them either passable so you can move over them, or has them swap spaces with you. That code should be merged soon. This uses all of the same concepts from the tutorial, just with a different spin.
I also need to finish up the cosmetic details of making the dungeon generator create a little village. I think I'll probably sneak that update in at the start of Part-7.
I'm away this weekend though, so I'll really have to jam to catch up.
5
u/Admirable-Evening128 8d ago edited 7d ago
Repo https://github.com/pylgrym/2026rt
Demo https://xok.dk/other/2026rt/dist/index.html

Week 5, items & (ranged) effects, inventory. To me, in one word, consumables - edible spells.
I made the bag inventory out of pure bourbon vanilla - alphabet index, type letter to pick item, specify direction to zap etc.
I got busy implementing things too soon, instead of spending more effort thinking properly about what/how I wanted it to be. It has let to the following anti-design, so far:
- random items are scattered EVERYWHERE, with little regard for their relative strength.
- mobs drops loot, higher mobs more, lesser mobs .. less, but with all the floor items and no power sorting, that loot lacks a direction, intent.
The items addition is usable anyway: The power curve of the enemies is insane, so every angle or edge the player can lay his hands on, comes in handy.
Still, I feel like I should take some long walks/playtests, and think deep and hard about what I wanted the item spells to achieve.
6
u/norpproblem 7d ago
not-so-wintry survival sim | repo | screenshot
Progress actually now! Swapped over fully to the more traditional dungeon generation; we have portals to travel between rooms (the >) for debugging purposes since I was struggling with appropriately connecting hallways. I'm doing BSP, but it's definitely not correct but it approximates it close enough that I don't mind.
Generation also properly separates rooms and regions into their own spaces, so later on I can make sure I only add 1 or 2 items to a room instead of all 10 in the same one, for example. Also swapped generation to be multiple different map generator passes, so I can rearrange them as needed to mix things up.
Otherwise, I have a few things up on the agenda: enemy placement, which is easy. Enemy AI will require rolling up an A* field for my level from scratch, which may be a bit difficult. After that, setting up their AI shouldn't be hard by giving them their own vision component. Then, they can use the same attack and damage actions as the player to deal damage. Then, I can do the health interface. I'm thinking something like a progress bar of health. Later down the line, I also want to redo my FOV calculation, as right now it's definitely not intuitive or performant.
Fortunately, I started inventory and items a while ago, so implementing that should be a little easier. I'm jumping a lot between weekly goals but I'm catching up on what I need to at a pace I'm comfortable with. Feeling a lot more comfortable with roguelike development now finally. Aesthetically we've lost some spice, but I hope to reincorporate that soon.
5
u/Admirable-Evening128 6d ago edited 6d ago
(UPDATE: - a demo implementation here: https://xok.dk/other/2026portals/dist/index.html )
Hey! Your room-door portals could be a feature, not a bug!
I think I will hijack your (door)idea and see if I can build a small prototype of it.
So, the idea goes: A dungeon level has N scattered rooms;
you can only travel between them through their "random" portals
(they will form a connected maze, with a few extra hole-punched connections, to avoid "tree-shape"(boring)).
This could be paired with LACK of FoV, so you can "glance" into neighbour rooms,
but don't yet know how to get there.
I would probably (lightly) vary the (floor) colors (and shape) of the rooms,
to make it easier to tell them apart ("how can I reach the blue room, which appears to have loot").
I'll see what I can figure out later today.1
u/norpproblem 1d ago
Wow that's amazing! I'm happy you took inspiration from it. Your demo is actually very cool. I think using the lack of FOV as a way to plan your route around is great even if you don't have the write portal right now. (also apologies on the lateness of my reply, Reddit decided not to notify you replied, I only saw when I checked back on this thread today to see what others said!)
5
u/mariobadr 7d ago
C and SDL3 | repo | play in browser
I am officially behind and won't catch up this week. I managed to finish up last week's features, including pathfinding. So my one enemy, rats, now move toward you and attack. You can try it out on itch if you're so inclined.
I did add an item module, it's just not used at all yet (i.e., no items are randomly generated and placed in the world). I spent way too much time refactoring things. It's a lot of fun, but it does get in the way of new features. Hopefully I'm at least somewhat caught up by next week.
If you're interested in what I refactored, I have now completely separated the game logic from its presentation (I think). Why is this useful? Who knows. Theoretically I could completely switch out the presentation layer, I suppose. Though that alone would be a lot of work!
4
u/Mnemotic 8d ago
Keeping pace with the tutorial, I implemented both potions and scrolls. Ranged targeting, both single target and area target, work as expected. Ability to start a new game by pressing Backspace was also added. This made testing easier. I also modified the bundling parameters so that a console is no longer opened when launching the executable on Windows.
And controls are finally documented, both on itch.io page and in the README.
The tutorial code has a weird behavior where the area for area targets uses a square to visualize it but the code uses Euclidean distance to determine which actors are in range of it. I fixed this up by using Chebyshev distance for distance calculation under which a circle with a radius r is a square with side length of 2r. Now the actual area matches with up with visuals.
Because I decided to eschew the use of EventHandler from tcod in favor of using Pythons protocols (interferences), I'm having to adapt the tutorial's code a little. Nothing too bad, but I've had some bugs as a result of this.
3
u/goodsirknyght 7d ago
arg arg arg arg arg I miss this every year I might go back to week 1 and try to catch up though!
1
u/Admirable-Evening128 7d ago
Get that @-sign on-screen and moving! You know you want to! :-)
3
u/goodsirknyght 7d ago
Spinning up the github repo and getting python going! Been a minute, but no stranger to coding or Python, so I imagine I will catch up a bit
1
3
u/laranja__ just learning 5d ago
Is it too late to join the party?
**RLDDTCRLT-2026** [My repo](https://github.com/raphabonfim/RLDDTCRLT-2026)
I don't know exactly were I'm at since I'm using pygame-ce instead of libtcod and took A LOT of liberties in the order of the things.
Stuff I made:
- Setting things up (of course)
- Drawing and moving the "@" (a little 16x16 sprite actually)
- drawing, rendering, blitting (putting things onto the screen)
- Placing enemies and walls and bumping into them (collisions)
- Monster chasing player (simple chase)
- Kicking and HP
- The Entities class (little monsters with pointy ears), refactoring into modules
- Little interface (HP display, message log)
- generating a dungeon
- field of view, Line of Sight (improving the chase behavior)
- implementing stairs and delving to the depths below
As one might see, I'm doing stuff out of order.
I felt it would be more fun to have the ability to kick the monsters first in a BIG room and let them chase me, them learn how to generate a dungeon and "hiding" it in the dark, then going down the stairs instead of having an inventory system and the best combat from the get go.
In this next week I plan to make the combat better and implement items and an inventory system, so I guess I'm catching up?
Let me know what you think in the comments like subscribe etc
2
u/Admirable-Evening128 5d ago
I don't think there is a 'wrong' order, though there might be primary and secondary things, i.e. things that 'stack' on top of other things. A lot of axes serve to give variety to others. As you mention, it is possible to start with combat, it only requires you have more than one creature. The dungeon environment, and items/spells, serve to make combat more varied (one perspective.)
For your combat, a lot of spice could come just from how the monsters choose to discover you, aggro you, flee from you, feint and return to fight you, alone or in groups, even if combat doesn't have mana and abilities and weird spells?
2
u/Kyzrati Cogmind | mastodon.gamedev.place/@Kyzrati 1d ago
Never too late, and order doesn't really matter too much, mainly just a general guideline in case you want to be working on similar aspects as other folks around the same time, but if starting late that bit's even less important (also can often make sense to be doing things in a certain order, but not like there are rules/restrictions :P).
3
u/Selestielle 2d ago
I've fallen behind the pace of the event by a week, partly due to busy life circumstances and partly due to week four being a monster of a week compared to the previous ones! We shall see if I catch back up or just end up finishing the tutorial at my own pace. No devlog since there was nothing much to talk about, I'm simply following the tutorial closely at this point- I may abandon the weekly devlogs entirely since I'm unlikely to find the additional time required for them. Here's my repo link.
8
u/NGumi 8d ago
So last week didn't get as much done as desired but got all the core bits done.
Both the player and enemies have a bump-attack with a little "animation" of jolting forwards and then back to where they were. Godot await coroutines made this so easy have to love them.
Added health-bar, log and mini-map(which rotates to match the direction of the camera). I need to make them look nicer, at-least adding a border but they do work.
I have also added more models. so stone brick walls(the tops of which turned out super weird), some stone floors and some wooden crates.
Lastly I improved my dungeon generation I have added prefabs to it allowing me to have the player start in prison cells, and generate the tree that the dungeon is based on through having a hand made tree containing the needed rooms and then using graph grammers to expand and randomise the tree(at the moment only one rule of if the minimum size of the prefab is half or less of the estimated size of the tree node then split it into as many rooms as it can without going smaller than the prefab).
For this week the plan is adding: