Replies: 2 comments
-
Certainly sounds possible, and it also sounds like a very good idea! From the little I do know about Bevy, I think it should suit your use case pretty well. The core requirement for this type of project is the ability to run the same underlying game logic on both the client and server application. Luckily, the way Bevy apps are built up allows you to exclude whatever bits you don't need. And you can manually control the event loop too, that'll be helpful for the server side of things. Rambling About of the Challenges of NetworkingGetting this project to work well could come with a fair number of challenges. I'm not sure what level of experience you have writing networked applications, but in general, it's challenging, because determinism is hard to achieve. If you run game logic on both the client and the server, you have to make sure that they are in agreement. There are many things that, if you don't consider how to deal with them, could result in them disagreeing:
Even if you do the best you can at trying to eliminate sources of non-determinism, often it's impossible to eliminate them all. For this reason, most networked games execute the client-side game logic optimistically and the server communicates the authoritative game state to the client(s) so they can correct their state (you'll be intimately familiar with this if you've ever "rubber-banded" in an online game). There's a fantastic GDC talk from the Rocket League development team describing how they solved the problem of deterministic physics for a multiplayer game: https://www.youtube.com/watch?v=ueEmiDM94IE&ab_channel=GDC However, if you make your game server authoritative, you can diminish the player's experience. Most people who play online games accept the fact that there may be rubber-banding, but somebody playing a platformer might not have any idea that their game is connected to a server and get annoyed if there character rubber-bands, or worse, if a network disruption causes the server to think that an honest player is cheating. Actual AdviceIf it were me, here's the approach I would take. You may have already thought the exact same things, but here goes anyway: Make the client authoritative There should be no need for full server authority like in multiplayer games. All you need is for the server to do some additional checks as the game progresses and provide the final answer as to whether it thinks a player is legit. This comes with the benefit of never having to adjust the client's state. No rubber bands! Make the cheat-checking best-effort Treat every player as innocent until provably guilty. You really don't want to mistakenly label someone as cheating. This means only labeling a cheater if you know the server has seen every single frame of input/state from the client (you can make optimizations to avoid sending lots of redundant data, e.g., format your data like Run game logic on a fixed timestep. Otherwise, send the deltaTime of every frame to the server. Be very cognizant of 1-frame delays. I think the parallelized nature of Bevy makes it easy to write game logic that doesn't exactly flow from system to system as you might hope or expect. I'm not familiar enough with good Bevy practices to know how to best deal with that. Maybe you need multiple explicit stages in your application loop. Maybe you can guarantee everything you need with just events and system ordering. Buffer and resend data If you can only cheat check by getting every single frame from the client, then a packet drop could totally screw you up. You'll want to make sure that the client continues to resend input/state until the server acknowledges that it has seen it. The easiest way to do this would be to use TCP as your networking protocol, rather than UDP. It'll handle all the dirty details of buffering and resending dropped packets. You could also roll your own solution using UDP. IMO that'd be fun but certainly not everyone's cup of gfuel. Send inputs and game state to the server. This is to solve the (potentially non-existent) problem of floating-point drift. I say potentially non-existent because, in theory, the same game logic run on the same inputs on the same timestep should produce the exact same results. But if you want to be overly paranoid like me, then every frame (or every couple of frames), you can do the following:
I'm actually really enjoying thinking through this problem, I certainly wouldn't mind chatting more about it on Discord :) |
Beta Was this translation helpful? Give feedback.
-
Hey @BGR360, I think I wasn’t clear enough with my intentions however. I didn’t want to establish a server connection. Instead I would want to have exactly one HTTP call that verifies the user input whether it would be possible to beat the level with it. I know that determinism is very important. Otherwise it wouldn’t work. I use the Rapier physics engine, which has an enhanced-determinism feature, so as long as I keep the rest deterministic as well, it should work. Let me give more details about my idea with this single HTTP call. The call should be completely stateless. I want it to run in a serverless function on Cloudflare Workers. CF Workers uses v8, but it’s not using Nodejs. It is capable of running WASM code, which is where I will export a My takeaway from your response was that I have not yet thought about timestep. I could either make it a fixed timestep, which should make it easier or I would also have to send every timestep for every tick and not just the player inputs. I already have a running client prototype here, but it does not yet include any code of the actual jump and run game itself. I only made a poc for the tech stack I want to use. |
Beta Was this translation helpful? Give feedback.
-
Hey,
i want to develop a jump and run game and I want my server to validate whether a player actually beat a level without cheating.
My idea is that the client would track what inputs have been given at what game tick. The server should then play through the level via these inputs in a time lapse.
Does this sound possible and could you give me a little guidance how I would do this?
Beta Was this translation helpful? Give feedback.
All reactions