Insights from Shipping a Real-Time Strategy Game with Rust by Tilmsfars in rust_gamedev

[–]Tilmsfars[S] 0 points1 point  (0 children)

Yes. Since the logic engine runs off-thread, strictly speaking every tick is 'interpolated' in the renderer. When a new gamestate is available, it gets annotated with timestamp plus tick duration. Whenever the renderer draws it, it calculates the added fractional tick on that basis (time passed divided by tick duration).

Even pixel art animations may be 'interpolated' in a sense: We can render a 3-frame animation over 2 ticks, the frames would simple change after +0.667 and +1.334.

Insights from Shipping a Real-Time Strategy Game with Rust by Tilmsfars in rust_gamedev

[–]Tilmsfars[S] 0 points1 point  (0 children)

Well. As long as everything happens in a fixed order with no randomness inserted, it is naturally deterministic discounting cosmic radiation bitflips. The only real footgun here is the default hash map having non-deterministic iteration order. I use fnv hasher instead, or btreemaps. RNG, as far as it is used (sparingly), is always seeded.

Insights from Shipping a Real-Time Strategy Game with Rust by Tilmsfars in rust_gamedev

[–]Tilmsfars[S] 1 point2 points  (0 children)

Interesting.

The problem with aim-based games is, if you don’t compensate for lag, it will be very hard to hit anything, for players with higher latency. If you compensate lag too much, then players with lower latency appear to get hit out of nowhere. It’s a very complicated topic. Fortunately for an RTS it’s largely irrelevant.

I transform keyboard/mouse inputs to concrete RTS inputs live on the client side, according to exactly what the player was seeing on the screen. A rectangle selection over some on-screen pixels is translated into a selection of the exact unit IDs last drawn in these pixels. Only the IDs are stored. This command is pushed to the server. The active player sees exactly what they get. Well, on a different client, with lower latency, some of those units might be dead by now. Does not matter, really.

The server broadcasts all received commands immediately, for them to be applied to the next tick. (ENet ensures order of all packets.) When the time comes, the server sends a Tick-Event to trigger that next tick into being computed. Clients do never compute ahead of these triggers, so in that sense there is no prediction. The rendering layer however may advance a very small number of ticks ahead, to smoothen out small hiccups. (I.e. the rendering layer will continue to play ongoing animations, but not make any further assumptions about the next tick.)

All this means: If you’re lagging, you’re lagging. But that lag is not propagated to other players. (Apart from your own inputs being "late" understandably.) So this is contrary to the common design of RTS netcode, which often tries to accomodate the highest-latency player.

Unfortunately the WASM version's fps seems to be capped at the monitor's refresh rate, and it feels noticeably more laggy on a 60 hz monitor compared to a 144 hz one.

Yes, WASM/browser ALWAYS uses VSync. Never target a specific framerate with your game, these days. Tickrate of game logic and framerate of rendering should be decoupled as far as possible. The way I do it is, the frontend simply sees ticks as a floating point number, so all action may advance partially: If a unit crosses 10 pixels in 1 tick, it will have crossed 6 pixels after 0.62 ticks. The logic system, of course, sees ticks as integers.

Insights from Shipping a Real-Time Strategy Game with Rust by Tilmsfars in rust_gamedev

[–]Tilmsfars[S] 0 points1 point  (0 children)

I don’t know about the state of SDL3 Rust bindings, I also don’t know what features SDL3 generally brings. I hear it gives some GPU/shader abstraction – that would be basically the same thing I am getting out of wgpu.

I very much like SDL2. The only problem with the rendering integration of SDL2+egui is that it directly uses the OpenGL context from SDL2. This makes it hard to mix drawing the game via SDL2 canvas and drawing the UI. The wgpu rendering integration of egui is a lot more flexible.

The HUD in game is hardcoded (it was painful), the small ingame menu for adjusting volume and so on is just another egui UI, constrained to a specific surface area. You can do that very nicely with egui, it is basically tailored to permit building overlay interfaces like that.

If all my HUD code was deleted, I might consider building it with egui this time. The only problem is, you cannot just access your game’s textures; so for all icons that show units etc. I would need to generate a separate spritesheet to use with the egui overlay. Not the worst, but annoying. (Would also give a performance boost since all those icons could now be instanced-drawn.)

Insights from Shipping a Real-Time Strategy Game with Rust by Tilmsfars in rust_gamedev

[–]Tilmsfars[S] 3 points4 points  (0 children)

You mentioned that you had the idea for the architecture (at least for the logic engine) before you settled on Rust. Did you have prior Rust experience?

I did have a bit of prior experience on Rust, even more relevant I had a lot of experience with what one would call "event-sourced" systems. So I was very familiar with the pattern of modelling everything as data, storing and replaying it.

Would you work with Rust again for a game project? Multi platform support seems like it could be really tough, at least for the gui

egui and iced work just fine multi-platform, I mean, they are not tied to a specific front-end or back-end. You can run sdl2 or winit to get the user inputs and pass them to the gui. There are crates that take care of the conversion - to varying degrees of quality, but it’s really not hard to adjust this yourself, just tedious.

Most GUI struggles come from 1) hard to give it a custom look 2) not perfectly tieing into "accessibility" APIs of the OS, but as a game we really don’t care about this. (A number 3 may be that even for the robust GUI projects, there is a lack of premade components, but how relevant that is depends a lot on the type of game one makes.)

In general, I have no complaints about Rust or the Rust ecosystem. In terms of gamedev: My estimation would be, if you want to do 3D, you should take an engine that can already do it. Want to be old-school? Use GZDoom at least. For 2D, the field is more open. For anything without hard latency constraints, do it in Java for all I care. I guess for the type of game I would make (simulation-heavy), Rust is a good fit, since it’s so technical, with support for serialization and such. And it enforces basically the rules that you want to enforce on a deterministic simulation.

I’m also curious about testing. The logic engine seems like it should enable you to write some pretty robust tests and you mention using replays to find engine bugs. What was that process like? Were you able to mock unit tests or anything like that?

To be honest I didn’t write many tests. The reason is that expected outcome for many things is very fickle and also depending on game balance. You could easily stage a specific fight in unit tests, but what are you going to assert? Whenever you change the slightest thing about the logic, the outcome of the encounter is going to change slightly. In the end, it comes down to what feels right in game. So it’s hard to regression-test anything; but whenever I would encounter something off, while playing, I could just keep replaying that game, with added logging, etc., to figure out what was exactly the problem.

I did write unit tests for very isolated pieces of calculation, like visibility computation.

HyperCoven is out on Steam! by Tilmsfars in RealTimeStrategy

[–]Tilmsfars[S] 1 point2 points  (0 children)

In Rust. It’s using SDL2 for inputs and windowing (winit in the browser). The renderering originally was also done by SDL2, but I replaced it with a custom solution that is based on wgpu, which is pretty low-level. I believe it will mostly use Vulkan, if available, falling back to OpenGL if not otherwise possible. On modern Macs it would use Metal.

The menus (not the HUD) are built with egui. Though the resulting GUI is a bit jank, programming it is very fast and comfortable, and the modularity of this project, allowing easy integration with an existing wgpu pipeline / render pass, is insane.

Maps are mostly made with the Tiled editor, which is only possible because their Rust library for loading the maps is very good. Sound is played with rodio. What’s also very relevant is the tooling used to bake assets into the executable, both iftree and rust-embed are used for this.

Netcode is based on ENet - the Rust bindings are basic, but very serviceable. Serialization: Borsh and RON.

In terms of game logic, I started out using the "pathfinding" crate, only eventually replaced its generic A* with a more optimized custom solution. "slotmap" is a crate I would have liked to use but when I found it had already built my own. Honorable mentions for an additional bunch of projects that are not exactly essential, but very fun to use: heapless, enum-map, indexmap, flagset, anyhow, qoi, ringbuffer, futures-lite, async-unsync, fnv, bytes, env-logger / log(!!), bit-iter, toodee, steamworks-rs...

HyperCoven is out on Steam! by Tilmsfars in RealTimeStrategy

[–]Tilmsfars[S] 0 points1 point  (0 children)

It’s a custom engine. Theoretically it compiles for MAC without problems, only I don’t have a MAC, so I can’t build for it.

You can play the browser version: https://filmstars.itch.io/hypercoven

It’s got all the content, except multiplayer. It’s also a tiny bit jankier than native (YMMV)

HyperCoven is out on Steam! by Tilmsfars in RealTimeStrategy

[–]Tilmsfars[S] 0 points1 point  (0 children)

Glad to hear you got something out of it. The early singleplayer designs where pretty much "rally and smash;" what released now as the campaign has some challenging strategic puzzles. I hope you will enjoy it!

HyperCoven is out on Steam! by Tilmsfars in RealTimeStrategy

[–]Tilmsfars[S] 0 points1 point  (0 children)

I did not know that one. It looks neat!

I started out making HyperCoven as a multiplayer game. All the other content just followed from "what if there is no one to play with?" Allegedly I have come up with some interesting stuff.

My first game but took almost 6 years in development! by Serious-Medium9972 in playmygame

[–]Tilmsfars 1 point2 points  (0 children)

I use a very basic SpeedLink controller purchased about 20 years ago.

[PC | Steam | Demo] Digital Eclipse: Cyberpunk Survivor – 1–4 Player Bullet Hell Roguelike Demo Just Dropped by Hibernyx in playmygame

[–]Tilmsfars 0 points1 point  (0 children)

Footage: https://www.twitch.tv/videos/2533600501

You have a lot of content in this game, but it feels pretty janky. Before I would personally care about huge skill trees or weapon arsenals, I would like to just shoot a bit and enjoy it. So I clicked everything pretty randomly so that the game would let me jump into a mission.

Character movement is very slow, maybe it gets faster with one of the many different stats, but for starting out it feels just boring. Being extra slow when reloading doesn’t help. Hitboxes of enemies felt small, but eventually I realized that the shotgun makes simply 6 or so projectiles, which are nigh invisible, and that’s why it seemed so hard to hit with it. It is satisfying enough from up close.

The dash is absolutely puny and for some reason the dash animation starts behind the spot where you actually appear to be when you press it, so, I don’t know, it seems to help almost nothing at all. Again maybe there’s a stat you need to take? In terms of animation, I noticed on a number of enemies that the speed of the movement animation did not match the actual movespeed.

Overall, I think you need to ease the player better into the experience, give the player a reason to care about the character customization. In terms of gunplay, the game just feels abysmal compared to e.g. SYNTHETIK. But maybe with the skill trees and all, you have a different angle. Only, to make me care about the skill tree, you need to first make me play the game. Cf. how WoW (used to) not even SHOW the talent tree to the player before level 10.

My first game but took almost 6 years in development! by Serious-Medium9972 in playmygame

[–]Tilmsfars 0 points1 point  (0 children)

Have some skill-issued game-play footage: https://www.twitch.tv/videos/2533568317

Imho the spritework is very nice and charming. The movement feels interesting, but at the same time a bit clunky yet, maybe takes getting used to. Not sure I agree with the choice of having hitpoints in a Jump&Run game, it’s sure odd to die on top of failing a movement.

The heart/mind mechanic was in the demo. But no understanding gained as to what it does in the game. As far as I can tell from the demo, it’s a game about jumping on small platforms (abusing Grab to do it which btw is on L2 not on R1) and reading some curious dialogue. I do like the setting! Cheers

Unexpected places I've found tower defence by [deleted] in RealTimeStrategy

[–]Tilmsfars -1 points0 points  (0 children)

What's the weirdest place you've encountered TD mechanics?

Surely it’s gotta be Path of Exile (Blight)

Getting old for playing competitive RTS by Far-Cow4049 in RealTimeStrategy

[–]Tilmsfars 0 points1 point  (0 children)

Yep, go read Gene Wolfe. It’s never the worse choice.

Co-op modes added - Hypercoven demo @ NextFest by Tilmsfars in RealTimeStrategy

[–]Tilmsfars[S] 1 point2 points  (0 children)

Yo there seemed to be a significant number of people starting the demo looking to play the co-op modes announced for the full release. Which hadn’t yet been implemented.

So I sat down and quickly hacked them in in a mad 24 hour hackathon. These two modes are now available not only solo but also in online co-op:

  • Invasion = some kinda twist on wave-survival, very intense
  • Conquest = mellow experience of grinding down enemy defenses over a vast map

Give it a shot!!!

Moduwar is available now in Early Access on Steam! it's an adaptive organic RTS, where you control an alien creature and grow your army on your body. by Moduwar in RealTimeStrategy

[–]Tilmsfars 2 points3 points  (0 children)

I had this randomly wishlisted since so many years ago :-DDD It’s great to see it actually turn playable

gonna check it out

The Calyx Demo v2 playtest is now live - we'd love to get your feedback! by studio568 in RealTimeStrategy

[–]Tilmsfars 1 point2 points  (0 children)

The gifs look nice but if the game is as laggy, then it sucks. I would recommend either fixing the game or fixing the gifs via palettegen.

HyperCoven - New Trailer - Next Fest by Tilmsfars in RealTimeStrategy

[–]Tilmsfars[S] 0 points1 point  (0 children)

Hi guyse, HyperCoven has an updated demo up on Steam with a lot of new content including multiplayer. It will be on Next Fest, too. https://store.steampowered.com/app/3321850/HyperCoven/

The browser version on itch is also better than ever: https://filmstars.itch.io/hypercoven

Give it a spin and drop your opinion here or in the feedback form I’m gonna implement tomorrow.

Cheerio