For context, i am making a multi-player game using nodejs and my db is postgres.
players play one by one, and i save everything in the db.
when first user plays, they can't play again, until the other player played too.
what i am doing now is having a boolean on each player in the db that says "ableToPlay" which is true, then turns to false if it's not the user's turn.
issue is when user spams the "play button" and my db is in a remote server, it takes time to update from true to false, making the user play multiple times then causes the app to crash.
I am using aws Microservices architecture so the server must be stateless.
is there any way i can save the game progress in a way where the progress is accessible to all my micro-services?
How do you check the turn? Is it something:
select turn from db
if turn == X then
//allow the turn
do all the logic
update the turn to Y
endif
So the "do all the logic" may be called several times as several requests will get turn=X.
This is a very common problem in programming, there are several approaches you could do.
Two key observations to address:
the same player should not do a turn twice in a row
while one player is making the turn, the other player must wait
Easiest way it to use a transaction in the DB while the turn is happening. For example, when player X making the turn:
start transaction
update turn=X where turn=Y (Y is the other player)
if update done (one record is updates)
do all the logic
commit the transaction
In that approach, update will wait for the previous one to finish, and the WHERE clause will make sure the same player won't do two or more turns in a row. And the transaction isolation will avoid running turn logic at the same time.
If you don't want to use the transaction, you could build a state machine, with states:
waitingForTurnX
makingTurnX
waitingForTurnY
makingTurnY
this would be a nice model to code and these transitions could be handled without transactions:
update state=makingTurnX where state=waitingForTurnX
This approach will also eliminate race condition, because in vast majority of databases, updates are atomic when it comes to a single record.
I have a plugin for Homebridge that operates shades, i.e. WindowCovering Services. It basically imitates the remote for the shades. The remote has 16 channels and one of them, 0, operates all shades. Each shade/channel is an Accessory on a Dynamic Platform. As the shades move I am updating the CurrentPosition and PositionState Characteristics. This seems to work fine now. However, some updates never seem to reach Homekit.
When multiple shade/channels are moving at the same time, this shows in the Home app as "Opening" or "Closing". When the PositionState is updated to Stopped, the icons show the current %age open. However the updates on some shades will get lost.
I thought perhaps a delay between update calls is required, so I implemented a scheme that prevents calls being made close together with a configurable delay. That seemed to improve things, but updates are still lost and I don't really know if the delay is required.
All PositionState updates go through this code. I have been debugging this issue for quite a while and am convinced the code is executed, but I can't figure out why the Home app does not see the Stop.
updateStateCB() {
this.service.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.positionState);
this.logTimeCh('Update state:' + this.positionState);
}
Where might I be going wrong here? Is the delay between calls required? Is there a bug in Homekit somewhere?
Thanks
Is there a way to reset a quest or area in Azerothcore such that the quest giver or quest objectives are at their initial states?
I've encountered some problems when a player completes a quest that is not resetting, thereby preventing other players from doing the quest. One such quest is Torek's Assault in Ashenvale. After quest completion, the quest NPCs do not respawn at their starting positions to enable other players to perform the same quest.
Another type of problem is when a player completes the Hellfire Fortifications quest by capturing the three outposts in Hellfire Peninsula. In a server where all players are playing the same faction, only the first one gets to complete the quest. Is there any way to put the outposts back to neutral as a GM? If not, could it be done by modifying the database?
You don't reset the quest zone to achieve what you wish.
All of your issues seem to be related with creature scripting instead of zone bugs.
Each of your issues can be broken down into these 2 points:
Torek's Assault in Ashenvale. After quest completion, the quest NPCs do not respawn at their starting positions to enable other players to perform the same quest.
Your problem is that you need to despawn your desired NPCs. You need to get the closest creature entry within a certain radius and start despawning out of combat every x seconds if this is done via SmartAI. With core scripts you would need to iterate through all the found creatures and despawn them.
Another type of problem is when a player completes the Hellfire
Fortifications quest by capturing the three outposts in Hellfire
Peninsula. In a server where all players are playing the same faction,
only the first one gets to complete the quest
Is this creature's script Smart AI or core script? Is the event on repeat? Is the creature correctly scripted?
Look at the command table and our wiki, maybe there is a command for that.
Otherwise you could delete something in the Db probably but again I'm not really versed in the subject, just trying to give you some hints.
What you should do is try to do the quest alone on a dev server, see before and after, what data has been inserted, then delete it to reset it.
Create a SAI for that creature. Make him to respawn at location where you want ( With the timer, or on quest taken/complete
I had a question related to performances.
Here's the context :
Imagine a TempleRun-like game in which the player only moves in 1 direction and is allowed to switch between 3 lanes (all of them going in the same direction).
Unlike temple run, there are no turns.
I wish to make the level generate dynamically and therefore we placed colliders on the ground. When triggered, the level loads the next (random) part of the path and unloads the old one.
Since the player is moving at a constant speed in 1 direction, I was wondering if it wouldn't be better to use a timer to load and unload game parts?
Also, I was wondering how colliders were handled by Unity? Do they work with a thread constantly watching for a collision to happen?
Personally I would not use time in case I want to change the speed of the player through a boost or some other reason.
Here's some information on colliders:
https://docs.unity3d.com/Manual/CollidersOverview.html
https://forum.unity3d.com/threads/collision-detection-at-high-speed.3353/
From what I read, it feels like there is a separate thread that has a fixed time step and fires events to alert when a collision happens.
Can anyone give me a scenario where they think busy cursors are justified? I feel like they're always a bad idea from a user's perspective. Clarification: by busy cursors, I mean when the user can no longer interact with the application, they can only move their hourglass mouse pointer around and whistle a tune.
In summary, I think that the user should be blocked from doing stuff in your app only when the wait interval is very short (2 seconds or less) and the cognitive overhead of doing multi-threading is likely to result in a less stable app. For more detail, see below.
For an operation lasting less than 0.1 second, you don't usually need to go asynchronous or even show an hourglass.
For an operation lasting between 0.1 and 2 seconds, you usually don't need to go asynchronous. Just switch the cursor to the hourglass, then do the work inline. The visual cue is enough to keep the end-user happy.
If the end-user initiates an operation that is going to take just a couple of seconds, he's in a "focused" mode of thinking in which he's subconsciously waiting for the results of his action, and he hasn’t switched his conscious brain out of that particular focus. So blocking the UI - with a visual indicator that this has happened - is perfectly acceptable for such a short period of time.
For an operation lasting more than 2 seconds, you should usually go asynchronous. But even then, you should provide some sort of progress indicator. People find it difficult to concentrate in the absence of stimulation, and 2 seconds is long enough that the end-user is naturally going to move from conscious ‘focused’ activity to conscious ‘waiting’ activity.
The progress indicator gives them something to occupy them while they are in that waiting mode, and also gives the means of determining when they are going to switch back into their ‘focused’ context. The visual cues give the brain something around which to structure those context switches, without demanding too much conscious thought.
Where it gets messy is where you have an operation that usually completes in X time, but occasionally takes Y, where Y is much greater than X. This can happen for remote actions such as reaching across a network. That's when you might need a combination of the above actions. For example, consider displaying an egg-timer for the first 2 seconds and only then bringing in your progress indicator. This avoids wrenching the end-user from the 'focused' context directly to the 'waiting' context without an intermediate step.
It's not specifically the busy cursor that is important, but it IS important, absolutely, always to give feedback to the user that something is happening in response to their input. It is important to realize that without a busy cursor, progress bar, throbber, flashing button, swirling baton, dancing clown.. it doesn't matter ANYTHING- if you don't have it, and the computer just sits there doing nothing, the computer looks broken to the user.
immediate feedback for every user action is incredibly important.
I think you may well be right: in a decent asynchronous app, you never need to show a busy cursor. The user can always do something even if the big last operation is completing.
That said, sometimes Java apps like Netbeans or Eclipse, or even Visual Studio, hang with no busy cursor and no hope. But in that case, a busy cursor probably wouldn't help much either...but I think you're right: busy cursors are from a non-multithreading era for apps. In Flex apps, for instance, EVERYTHING is automatically event-driven callbacks, so setting a busy cursor would just be meaningless (though possible, of course).
You show a busy cursor when the user can not do anything until the operation is completed - including exiting the application.
I find it interesting that you don't see busy cursors in Web Browsers - perhaps that why people like them so much.
No, wait, I have a better answer. You show a busy cursor when the computer is thinking.
When one hits the Refresh button on a web browser, busy cursor must appear immediately to tell the user to let them know that a page is being loaded.
I think it was Don't Make Me Think that said that the tolerable loading time for human is zero second.
Google says:
Responsive
It's possible to write code that wins
every performance test in the world,
but that still sends users in a fiery
rage when they try to use it. These
are the applications that aren't
responsive enough — the ones that feel
sluggish, hang or freeze for
significant periods, or take too long
to process input.
There are two purposes for it:
Indicate for the user that something is happening.
Indicate for the user that nothing can't be done right now.
Busy cursor is better signal about the operation than nothing. For longer lasting operations something better should be used. For example browsers is still operational when a page is being retrieved and there is even a button to stop the operation. As the user interface is fully functional, there is no need to use busy cursor. However busy cursor can be used even in this kind of situations in the transition phases like when starting the operation or when stopping it.
I try to use them on any action that may take from 0.5 to 3 seconds, for longer actions I think progress indicators with enough information should be used.
I noticed with Fedora 8 at least that when an app sets the "busy" cursor, the "busy interactive" one is actually displayed. I guess this is because the system is still responsive to mouse input (like dragging the window etc.). As an aside, selecting the "busy interactive" cursor explicitly on linux is tricky:
http://www.pixelbeat.org/programming/x_cursors/
The only thing I believe the busy cursor does is it informs the user that ...
I'm not outright ignoring you, I'm just doing something else that may take awhile
While it is absolutely necessary to alert the user that your application is doing something, a busy cursor is only useful for the first few seconds of processing. For a delay of more than about 15-20 seconds, something else must be presented such as a progress bar, status message, message box, whatever. People assume your software has locked up after a minute or so and will try to terminate it. Sometimes, overall visual cues are just as important as a busy cursor.
For example, applications with tabs that do not respond with appropriate highlighting until the operation in the tab completes can be fixed up by updating the tab temporarily until all operations are complete. Sometimes, just a little optimization or refactoring will clean up horrible user interface responsiveness such as this.
I would use them only for quick completing things, like say under half a second. If anything takes longer than that then a progress dialog should popup, or a progress bar should appear in the status bar or somewhere else in the interface.
The user should always be able to cancel the action if it is taking too long to complete.
In response to the comment, the busy cursor would only be visible for the half second or so, as once the progress dialog is up it should change to being one of those "half busy" cursors, or just the normal arrow cursor.
You should avoid having a busy cursor up except in extreme circumstances, and if you think you need one, then think again and redesign.
For example, to indicate that you've clicked on a button, even though it's not done processing the event. If there were not some indication, the user might try to click the button again, causing all manner of badness.