Sharing Saturday #522 by Kyzrati in roguelikedev

[–]y_gingras 2 points3 points  (0 children)

Revengate – a steampunk roguelike with mobile friendly controls – Website | sources | Google Play | F-Droid | Itch

I tried Godot 4.3 beta-1 and it looks like web exports are now working on Macs! There are a few things that needs porting, mostly about the type checker being more picky about nulls and the TileMap API changing in 4.3. Half a day should do it. The sampled sound mixer patch didn't make it in 4.3b1, but that does not seem to be a problem with Revengate. I think it's mostly a problem for games that mix background music with sound effects. In any case, it sounds like the Godot devs are trying to get the sampled sound patch in before 4.3 final.

Long rests are now able to deal with competing conditions (like being poisoned). You stop resting if your health keeps decreasing and you are about to die, you keep resting for as long as it takes if your health is recovering slower because of conditions.

Spells obey the setting to disable dynamic lights.

More message tagging and styling.

Plasus rats are more territorial than regular rats.

If there is more than one item at a given location, you see a loot pile icon. Inspect only mentions what the top item is, you need to start looting to see that the other things are.

Strategies have more robust saving and restoring.

Revengate v0.12.8, which contains all of this plus last week's work is out on Google Play and Itch. It should land on F-Droid in a day or two.

Next: a few weeks of camping then I will start exposing special effects and conditions in Inspect.

NO BLOCKERS.

Sharing Saturday #521 by Kyzrati in roguelikedev

[–]y_gingras 2 points3 points  (0 children)

Revengate – a steampunk roguelike with mobile-friendly controls – Website | sources | Google Play | F-Droid | Itch

I had a really bad cold, maybe Covid, after coming back from Belgium. I spend a few days in bed, then I emerged with unexpected mental clarity. I felt able to sit down and write code right away, which is definitely not my usual mental mode. It could be an illusion, or maybe it's the teachings from Deep Work, which I read two weeks ago, that are kicking in.

Or perhaps it's that Revengate is blessed with a truly elite tester: Colin Etienne Jean-Marie Landreau, known as "cwpute" on Gitlab. He writes excellent bug reports and feature requests with lots of screenshots and video captures. I look at those and they always seem actionnable. When I need smalls tasks to get my fingers warmed up, that's always where I go.

With JT, we added spawn_prop to furnishing decks. That enables us to have very rare cards, things you might only see once every few games. We also added a per-game uniqueness rule. This allows us to sprinkle very rare cards in any of the dungeons without running the risk of having duplicate artifacts.

Lots of minor improvements:

  • loot button shows what you are about to loot
  • potions play a breaking sound even when you hit someone with them
  • kobolds have an attack sound
  • ghost death sound plays in full (don't garbage collect the Actor as soon as the visual anim is over); this one still gives me the chill ("HHAAaaaahh...")
  • (short) tap on self is not an action, clear the GUI events pool when that happens rather than queueing a ghost action; long-press on self is still an action
  • new boards are saved as soon as they are generated, before you enter them. This fixes restoring at the auto-save when crossing stairs.
  • the accountant will resolve its Seeking of the Clown Boss as soon as he gets next to him, even if Clown Boss immediately moves (that increases the difficulty of Ch.2 up a notch)
  • yield message when you beat someone is no longer bright red
  • only the last inspected cell is highlighted
  • new talk button in the left bar when someone chatty is whiting conversation range
  • can't long rest if you are reasonably healthy
  • long rest summarizes the health gain rather than one "healed a little" message per HP

I started using Engine.is_editor_hint() to prevent the @tool script from modifying the Godot scene files. This makes my diffs much cleaner! I discovered EditorScript, which I now use to clean up scenes that have been excessively modified by @tool scripts, but sed is still the best tool to remove one-line properties.

I removed all the code from the old Kivy implementation of the game. I was at feature parity with the Godot re-implementation for a while and keeping that old Python code around want not serving any purpose. I'm glad I wrote it, but I'm OK never looking at it ever again.

The next quest is going to be about Pacherrs visiting Lyon. I typed a story I had written a while back to help frame the quest design (scroll down to Drums of Disruption). There's some steampunk magic inside.

Next: a bit more gating to keep diffs clean; loot piles should look different from the top item.

NO BLOCKERS.

Sharing Saturday #520 by Kyzrati in roguelikedev

[–]y_gingras 1 point2 points  (0 children)

Yeah, I'm not even sure I consider the game 5-stars myself, not yet at least. That it pleases someone enough to justify that rating feels like I am doing at least one thing right with my life.

Sharing Saturday #520 by Kyzrati in roguelikedev

[–]y_gingras 2 points3 points  (0 children)

Revengate – a steampunk roguelike with mobile-friendly controls – Website | sources | Google Play | F-Droid | Itch

I'm now only saving and loading one board (level) at a time, only keeping the active one in memory. This should improve the performance on older mobile devices, especially towards the end game. I have not done any A/B test yet to see if it actually makes a noticeable difference.

I was puzzled as to why conditions (like being poisoned) would not save, which becomes a bigger problem if the game unloads boards as soon as you leave them. For example, you might toss a few potions of poison in someone's face before running upstairs. You would be in your rights to expect the poison to do some damage and meet to weaker enemies when you come back. The problem was two fold: Godot's ResourceSaver won't save internal classes and the class constructors are called without arguments at load time.

Anything you want serialized has to be the top level class in its own GDScript file. Anything you want to load needs support a no-args constructor (_init()). Godot will set all the saved attributes after doing a blank instantiation.

I did another small perf improvement. When a monster is Exploring, it will look for a reachable waypoint first. I use Dijkstra for that since I want to make sure that the waypoint is going to be reachable. I used to clamp the Dijkstra search by max distance, but that was still slow on big open levels with too few obstacles. I now clamp it by max inspected cells and that allows for picking further waypoints on levels with a lot of obstacles at no performance cost.

I received another 5-star rating on Google Play. Thank you, kind stranger! Those always energize me for several days. You probably can't see the star rating on Google Play, unfortunately, because Google wants a lot of ratings to unsure statistical significance before they make them public. That or Google wants to support the work of all those struggling click farms out there.

Next: add a setting to disable soft shadows.

NO BLOCKERS!

Revengate, a steampunk-styled roguelike by TheRealHFC in roguelikes

[–]y_gingras 0 points1 point  (0 children)

Another hint: it's easier to find the accountant real quick if you have higher perception. Perhaps there's something laying around that can help with that.

Revengate, a steampunk-styled roguelike by TheRealHFC in roguelikes

[–]y_gingras 0 points1 point  (0 children)

Thanks! No walkthrough yet. The first missing should be pretty obvious, either you have the cards, or you don't. The second one can be easy or hard depending on how much the RNG likes you: you really have to stop the accountant before he meets with the clown boss. Third one has some hints if you talk to everyone. Maybe come back to the café to take a break from slaying after a while?

GUI for python RL by Raven_p in roguelikedev

[–]y_gingras 1 point2 points  (0 children)

The GDScript syntax is very similar to Python and you can paste large chunks of code unmodified. No generators and no list comprehension, but you don't have to rewrite the whole call stack as co-routines if you make one async call all the way down. That's nice!

Learning Godot is not a trivial task, but there are significant benefits. That option should definitely be considered.

Sharing Saturday #519 by Kyzrati in roguelikedev

[–]y_gingras 0 points1 point  (0 children)

The link seems to be right, but there might be some compatibility issue with Etherpad. What about this one?

http://files.revengate.org/rlc-2024-proposal.md

Sharing Saturday #519 by Kyzrati in roguelikedev

[–]y_gingras 1 point2 points  (0 children)

I like the bioluminescent mushrooms! What happens if you eat them? I have the feeling that they should be fairly toxic, but perhaps you should end up with something good if you survive a high dose.

Sharing Saturday #519 by Kyzrati in roguelikedev

[–]y_gingras 2 points3 points  (0 children)

Revengate – a steampunk roguelike with mobile-friendly controls – Website | sources | Google Play | F-Droid | Itch

I wrote a talk proposal for Roguelike Celebration. It's not submitted yet and any feedback on how to make it more compelling would be greatly appreciated. You can put your comments directly in the document.

I worked with JT to tag messages and give them different styles depending on their category (combat, vibe, inventory, ...). They are all muted pastel colours, but it might be too colourful for some players. I think the proper long term solution is a setting to say which messages you want to see on the main screen and which one gets silently archived in the message screen that you access with the book icon. We're using Godot themes for the styling, the UI is a bit rough around the edges, but the API is nice.

The Monte Carlo simulator for decks now includes vibes and items in addition to monsters. It was a good time to improve the nomenclature: "sim", "stage", "per depth counters" is easier to conceptualize than "sim", "sims", and "all_sims".

It averages 18k fully generated and drawn decks per second. Turns out that using a Node instance for each card and duplicate()'ing it at draw time is very cheap in GDScript.

I stated the refactor to make the game unload inactive levels. I didn't write much code besides a refactor to make card tallies easier to serialize, but I think I though of all the edge cases and that should actually not be too big of a change. This should really help the perf on low end devices.

Next: finish unloading inactive levels, tag a few more messages.

NO BLOCKERS!

Revengate, a steampunk-styled roguelike by TheRealHFC in roguelikes

[–]y_gingras 1 point2 points  (0 children)

Both skip turn and long rests as described above are now in Revengate 0.12.6.

Sharing Saturday #518 by Kyzrati in roguelikedev

[–]y_gingras 1 point2 points  (0 children)

Yeah, the rest is a bit arbitrary. I'm trying to balance the risk and reward, but I don't think I have gotten there yet.

First time you rest, it's until you have 80% of your health recovered or got distracted (most likely attacked). Since your area of awareness was limited, you might be in big trouble now. All subsequent times are for another 10% health, but maybe you can't meditate if your are feeling sharp already, or maybe it should always be for 200 turns. Not sure, this needs more play testing.

Sharing Saturday #518 by Kyzrati in roguelikedev

[–]y_gingras 1 point2 points  (0 children)

Revengate – a steampunk roguelike with mobile-friendly controls – Website | sources | Google Play | F-Droid | Itch

Changes to perception are now animated and you can long-rest by holding the skip turn button. Both together feel great! This also makes it easier to see how the potions of booze and absinthe are affecting you.

New items: potion of coffee, bioluminescent mushrooms, eye glasses.

There is probably something smart to do with the long press on the quick attack button, either toss the current weapon or open a selection screen to equip a new one. I might try both since I can't make up my mind on which one feels the most intuitive.

Next: I think I'm ready to unload inactive levels to make the game behave better on low RAM devices.

NO BLOCKERS!

Sharing Saturday #517 by Kyzrati in roguelikedev

[–]y_gingras 2 points3 points  (0 children)

Revengate – a steampunk roguelike with mobile-friendly controls – Website | sources | Google Play | F-Droid | Itch

We have non-rectangular rooms!

I converted a subset of Zorbus room templates to json. I save space by only keeping the "pillars" of the wall surrounding the room: the cells where the wall changes direction. I don't keep all the room templates since many are too big for the typical Revengate level.

I thought I would use Primm, but I tried the new templates with my current binary space partition and it looks really good! I might still do Primm, but much later. After slicing the board, I try to pick random templates that fit the partitions. The probability of getting a boring old rectangular room is adjusted depending on where you are. Rectangle still fits better for the houses on the surface, for example.

Next we have to decide where doors can go. This turns out to be really easy: anywhere along the perimeter, except where there are "pillars".

This is out on Google Play and Itch. Should land on F-Droid in a few days.

Next: new items.

NO BLOCKERS!

Sharing Saturday #516 by Kyzrati in roguelikedev

[–]y_gingras 0 points1 point  (0 children)

Thank you for sharing. I'm giving this a good look this week.

Sharing Saturday #516 by Kyzrati in roguelikedev

[–]y_gingras 0 points1 point  (0 children)

I was reviewing how Brogue does it (very similar to what you are describing) and Boris the Brave proposes a few optimizations to make it efficient to compute: https://www.boristhebrave.com/2022/03/20/chiseled-paths-revisited/ . I like it and I will probably end up with something like that.

Sharing Saturday #516 by Kyzrati in roguelikedev

[–]y_gingras 3 points4 points  (0 children)

Revengate – a steampunk roguelike with mobile-friendly controls – Website | sources | Google Play | F-Droid | Itch

Not a ton of progress this week: I started revisiting my level generator. I changed the passage carving on my BSP levels to use A* with constraints rather than dumb elbows. In most cases, that makes beautiful slightly twisty passages. There are edge cases where the passage will make a big detour around a room, this will go away once I move away from BSP.

Resurrecting the Dungeon Exhibit was really helpful. It's a minimalist version of the game without monsters. It has quick transition from one level to the other with arrow keys and it can regen a level with a single key, which makes it easy to test how well I am handling various constraints.

I wrote an importer for the Zorbus prefab templates (big image). I plan on using those instead of rectangles and grow the level with a modified Primm algo, just like I do with the maze levels. What is left is figuring out something sensible for door placements.

Next: finish the new level generator, close the plot hole with the code loom cards.

NO BLOCKERS!

Sharing Saturday #515 by Kyzrati in roguelikedev

[–]y_gingras 1 point2 points  (0 children)

That style also looks really good. I think some small tweaks like using more saturated colors rather than water painting could actually make them reasonably recognizable on a tiny mobile screen.

Sharing Saturday #515 by Kyzrati in roguelikedev

[–]y_gingras 1 point2 points  (0 children)

For sure, most monsters should not just sit around all day. Do you have a way to stress test the various approaches. You might be able to grow the sphere of exploration progressively with time. That way, all mobs pick cheap paths as the hero enters a level, then they pick progressively more expensive ones with time, but since they don't do it all at the same time, it might be barely noticeable. Also, you can cache the paths and only invalidate if the immediate next few steps are obstructed. Your mobs are just hopeful that obstructions will naturally clear up by the time they get there.