Bitcoin Forum
May 03, 2024, 04:09:51 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: [1]
1  Economy / Gambling / Re: bustabit – The original crash game on: August 01, 2021, 01:17:05 AM
Why is it necessary to correct the start time on each heartbeat? How does the start time change?

Well, it's not necessary. But it's better to do, and it's easy. So why not?

Basically it handles this situation:
Client receives a "game started" event. Client records the time it got the game started.  5ms later, the server says "the game has been running for 150ms".

With this information, the client can know that the "game started" event was lagged out (e.g. network problems). It can safely update the "game started" time to be 145ms earlier than it previously had it.


Quote
"So the client basically has two options..." Could you perhaps elaborate more on this? I don't really understand what you ment.

What part of my explanation didn't you get?
So if I understand correctly the only purpose of the game tick is telling the client the game is still running, esentially a heartbeat.
In case the client does not receive a game tick it can show a 'reconnecting' animation or something similair. I completely understand that and it makes much sense to me. However why is the including elapsed time necessary in this event?

Earlier you said this is used for correcting the start time, why not just send a unix timestamp when game emits the start event? This way desync can never happen since the client has the start time of the game and does not calculate this time itself. If the game start event is emitted 5 second later, the client will still receive the correct unix timestamp when the game started since this does not change in the backend.

So instead of sending: game_tick: 1041, why not send game_tick: true (assuming this is only used as a heartbeat you explained earlier).
I don't see the need of the elapsed time here.
2  Economy / Gambling / Re: bustabit – The original crash game on: July 31, 2021, 10:09:27 PM
Hey, good question!

So starting from first principles, the server needs to let the client know these events:

a) The game starting
b) When cash outs happen
c) When the game ends


And let's remember, there is a certain amount of time it takes for the server to communicate with the client (latency).


So the most naive solution is simply to broadcast all the events in real time. That will work fine, but the first issue you'll run into is when there's a network connection the client won't (immediately) realize and it'll look like the multiplier is going super high. When the network connection issues resolve, the user will be disappointed to learn that it didn't really go that high.

So we're going to need to broadcast a "heartbeat" (or game tick). Ideally multiple times per second, so if the client doesn't get the heart-beat it knows immediately something is up.

That's going to work fine now, and we're in business. But each message we send/process incurs overhead, and with a lot of events it's going to cause issues on both the server and client. Bustabit v1 was notorious for this. So there's a whole slew of optimizations we can make.

So let's go through a few that bustabit v2 employs:

A) Sends the client the (auto) cashout of the other players. That way the client can "predict" other players cashing out, and there's no need for the server to say the player cashed out at that point. This way the server only tells clients when a player manually cashed out.

B) Batch cash out events. If people cash out at the same time (or close to it), just send it in a big message.

c) Combine heart-beats with cashout events. If the server sends a cashout event, obviously the network connection is fine. No need for a heartbeat in that time.


---

And your question regarding synchronization is a little tricky. So two things to remember: there is always latency between the server and client. It's not possible for the server to tell the client the exact time the game will crash (until it actually crashes) or people would hack the client to easily cheat.

So the client basically has two options. One is to try show the multiplier that is CURRENTLY on the server. The other is to show the multiplier that the player would get if they hit the cashout button. The first solution is better for when you lose (it shows a lot smoother). The second solution is better for when you win (players are a lot less affected by latency. But the multiplier will overshoot the actual crash, i.e. the player will see 1.92x and then see "busted at 1.90x").

So bustabit tries to go more with the first approach. And each heartbeat it tells the client how much time has elapsed, which the client can use to correct its idea of when the game started (i.e. latency is not necessarily constant. It might get better and worse ). You can see how bustabit v1 did this:

https://github.com/kungfuant/webserver/blob/master/client_new/scripts/game-logic/GameEngineStore.js#L192-L195

--

Hope that makes sense!




Hey Ryan, thanks a lot for your answer!

"So bustabit tries to go more with the first approach. And each heartbeat it tells the client how much time has elapsed, which the client can use to correct its idea of when the game started "
Why is it necessary to correct the start time on each heartbeat? How does the start time change? Lets say the client somehow decided the start time to be 5000 but the server actually started at 5001 it will correct this start time on the very first tick it receives, where can it go wrong from there? Why would the client suddenly change the start time?

"So the client basically has two options..." Could you perhaps elaborate more on this? I don't really understand what you ment.
3  Economy / Gambling / Re: bustabit – The original crash game on: July 31, 2021, 02:13:58 PM
One reason is indeed ensuring that clients stay in sync. While most devices' clocks don't have much drift, we can't expect every device to be accurate, so it's safer to not entirely rely on the client like that.

But I suppose the bigger reason is simplicity and efficiency. Oftentimes there are lots of cash-outs happening simultaneously and broadcasting each of these events individually isn't fast enough, so bustabit broadcasts cash-out events in batches on every tick instead. We could skip the broadcast if there weren't any cash-outs since the last tick, but it's simpler to just broadcast every tick, regardless of whether it contains cash-outs or not.

Finally, the broadcast tick also serves as a kind of heartbeat, allowing the client to assume that the connection has been lost if they haven't received any events from the server in n seconds.

Thanks for your answer!
How can the client and server get out of sync though? They only need two variables, the start time of the game and the current time. Both of these can not change since its a simply subtraction.
Even if one of the two variables is subject to change (I dont know how) then I don't see how the game tick of 150ms which gives back the elapsed time can help in correcting this.
I understand emitting back the elapsed time can be used to check if the elapsed time on the client is the same, but as far as I know start time and current time are always the same regardless of where it is called from so there shouldn't be a difference.

About your second point, why is exactly broadcasting cash out events individually not fast enough? If you broadcast them only on ticks wouldn't that result in a delay (not a delay for actually cashing out but a slight delay in updating the bets for other users)? if I cash out at timestamp 3000 and the next tick is at 3150 it will show my cashout of timestamp 3000 'happening' at 3150 for other users.

Lastly the third point you gave, this is the only reason why I could see the purpose of emitting the backend ticks to the client. But lets say a game lasts 3000ms, a user laggs for around 8000ms, when the user resumes it will for instance receive game tick 4000, what useful information can it get from this? I understand it can ensure that the game is alive but it can't conclude from that '4000' that its still the current game or the next one. In my eyes emitting the game id would just be enough if its purpose is only for sending heartbeats.

Perhaps I'm missing something here, which I probably am I guess haha. Just correct me if I'm wrong


4  Economy / Gambling / Re: bustabit – The original crash game on: July 31, 2021, 01:31:39 PM
Hey everyone,

I have some questions about crash games in general and I think this topic is the right place to ask.
Lately I've been wondering about a few things:

Most crash games send game ticks (every 150ms or so) to the client. I'm having a hard time understanding why they do this. Bustabit (and also the old v1 src) does this as well. I know the backend has to loop/tick every 150ms to do cashouts and such, but why would you emit that back to the client. If the client just keeps track of the start time of the current game and updates the counter according to the same formula the backend does then it is always in sync with the backend whatsoever since both sides do a simple subtraction (current time - start time) and pass this onto a function which gives you back the multiplier/point it should be at.

So what is exactly the purpose of the backend emitting the current tick/elapsed time to the client? If the client receives the crash event then it knows the game crashed and can show the crash animation or something similair. I've been looking around in the chrome devtools network tab (filter on WebSockets) and almost every crash gambling site seems to send ticks back to the client, except for one site (https://www.csgoroll.com/) which just sends the start and crash event and nothing else which seems to work fine.

Initially I sent the above (a little adjusted) to Ryan but he forwarded me to this topic so others can also benefit from potential answers Smiley

If someone can enlighten me on this specific question I would greatly appreciate it!

- sharpness
Pages: [1]
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!