AWS |
AWS Government, Education, and Nonprofits Blog |
Last chance to register for the IMAGINE 2022 conference for education, state, and local leaders |
https://aws.amazon.com/blogs/publicsector/register-now-imagine-2022-conference-education-state-local-leaders/
|
Last chance to register for the IMAGINE conference for education state and local leadersThe IMAGINE conference presented by AWS is fast approaching but there s still time to register your spot On Wednesday August at the Seattle Convention Center in Seattle Washington the IMAGINE conference will bring together education state and local leaders for a full day of learning about the latest innovations and best practices in the cloud to help transform communities Join other mission driven leaders for a full day of learning at this in person event that combines thought leadership sessions fireside chats and networking opportunities designed to leave you with inspiration new connections and tangible ideas to take back to your organization or institution |
2022-07-21 16:35:59 |
AWS |
AWS - Webinar Channel |
Build scalable, cost-effective disaster recovery to AWS - AWS Online Tech Talks |
https://www.youtube.com/watch?v=JvzrXmExUO4
|
Build scalable cost effective disaster recovery to AWS AWS Online Tech TalksTechnical and infrastructure failures human error cyberattacks and natural disasters happen These disruptions are inevitable but they do not have to spell disaster for your critical IT systems With AWS Elastic Disaster Recovery organizations of all sizes can build resilience and prepare for fast reliable recovery to AWS In this Tech Talk learn how you can continuously replicate servers to AWS using affordable storage minimal compute and point in time recovery to minimize downtime and data loss meet stringent recovery objectives and significantly reduce costs versus on premises disaster recovery Learning Objectives Objective Deploy a single unified process to test recover and fail back a wide range of applications without specialized skillsets Objective Recover applications within minutes at their most up to date state or from a previous point in time Objective Save costs by removing idle recovery site resources and pay for your full disaster recovery site only when needed To learn more about the services featured in this talk please visit |
2022-07-21 17:00:10 |
python |
Pythonタグが付けられた新着投稿 - Qiita |
webエンジニア界隈で使われる各言語のテンプレートリテラル比較してみた |
https://qiita.com/layzy_glp/items/9e17a24ae2494f0bb34f
|
連結 |
2022-07-22 01:57:41 |
python |
Pythonタグが付けられた新着投稿 - Qiita |
ラズパイのSoC温度を定期的にチェックし閾値を超えたらメール通知する |
https://qiita.com/MashCannu/items/f8f46aaa8247fe3b0e69
|
raspberrypi |
2022-07-22 01:52:11 |
js |
JavaScriptタグが付けられた新着投稿 - Qiita |
webエンジニア界隈で使われる各言語のテンプレートリテラル比較してみた |
https://qiita.com/layzy_glp/items/9e17a24ae2494f0bb34f
|
連結 |
2022-07-22 01:57:41 |
Ruby |
Rubyタグが付けられた新着投稿 - Qiita |
webエンジニア界隈で使われる各言語のテンプレートリテラル比較してみた |
https://qiita.com/layzy_glp/items/9e17a24ae2494f0bb34f
|
連結 |
2022-07-22 01:57:41 |
golang |
Goタグが付けられた新着投稿 - Qiita |
StreamServer Interceptorでコンテキストを上書きしたい時 |
https://qiita.com/kajitack/items/e10b53870d6d282a9aa9
|
interceptor |
2022-07-22 01:50:39 |
海外TECH |
DEV Community |
Building Multiplayer Games with Unity |
https://dev.to/ably/building-multiplayer-games-with-unity-2ki8
|
Building Multiplayer Games with UnitySome of the funnest games are those you can play with your friends Being able to explore worlds defeat monsters and overcome puzzles and challenges together can be amazing experiences Creating multiplayer functionality in games can be a massive challenge however Creating architectures that allow for reliable communication of clients cheat detection handling of networking issues and more requires a lot of thought and planning In this blog we ll be exploring a lot of the considerations required in multiplayer gaming and demonstrating some of the best ways to make things work smoothly and easily IntroductionIn order to best demonstrate multiplayer functionality in Unity rather than creating an entire game from the ground up I got in touch with raywenderlich to see if I could extend their Tower Defense tutorial series with multiplayer functionality It s an incredibly detailed and informative tutorial of a tower defense game and I strongly recommend checking it out to fully understand the context of this blog post With this core single player game we have a solid basis for adding in multiplayer functionality Core features and considerations we ll cover in this blog are How to communicate placement and upgrading of turretsHow to keep clients in sync with an authoritative sourceHow to handle clients falling out of sync with one another be it due to latencies computer issues and moreHow to handle re connection of clients to a gameWe ll be using Unity to develop in and Ably to implement reliable scalable communication between devices Getting startedFirstly you ll need to have Unity installed The best way to do this is to get the Unity Hub from the Unity website and then from that install the most recent version of Unity This was originally created for f With Unity in hand download our base project from GitHub on the starting point branch then load it up in Unity Before starting anything you ll want to adjust the dimensions of the game window so that it renders correctly In the main viewer click the Game tab at the top and then change the aspect ratio to Creating a LobbyOne key thing is that as this game will be multiplayer we will need a way for players to uniquely identify instances of the game to join play and watch To do this we ll create a Scene prior to the actual game in which players can input a unique ID for a game they d like to join and then click a button to load the game In the base template there s already a Scene added in Assets Scenes called Lobby This is a simple Scene with a text input to allow for a player to type the game they wish to join as long as all players input the same ID they ll enter the same game and a button to submit this Currently this button is non functional however What we want is for it to run a script which will load the actual game scene and convey the unique game s ID inputted here for the game to use Persisting the Game StateTo handle the game ID persistence we can create a new C script which we ll call StateManagerBehaviour In this script place the following code using UnityEngine public class StateManagerBehaviour MonoBehaviour public static StateManagerBehaviour Instance public string GameID void Awake if Instance null Instance this DontDestroyOnLoad gameObject else if Instance null Destroy this gameObject Here we have a script that will stop whatever it is attached to from being destroyed between Scenes This means that any variables set such as the current game s ID can be placed here and persisted Within the Lobby Scene create an Empty GameObject and call it StateManager Attach the StateManagerBehaviour script to it This object and the script attached will now persist between scenes Changing scenesNow that we can persist a game ID we need to make the submit button functional The button will need to Update the value of GameID in the StateManagerBehaviour to match what is put into the input boxLoad the game s sceneTo do this create a new script attached to the button called JoinGame and add the following code to it using UnityEngine using UnityEngine SceneManagement using UnityEngine UI using TMPro public class JoinGame MonoBehaviour SerializeField private Button startButton SerializeField public TMP InputField gameIDField void Start startButton onClick AddListener gt if gameIDField text return StateManagerBehaviour Instance GameID gameIDField text SceneManager LoadScene GameScene Select the JoinGameButton in the Hierarchy and drag and drop the InputField into the Game ID Field of the JoinGame script as well as the JoinGameButton itself into the Start Button field The button should now be functional This should now mean we can load up the game scene from this Lobby scene when we build the project Before testing it however we ll need to check that both scenes are added to our build settings Go to File gt Build Settings… and add both scenes to the Scenes in Build section With that you can try running the Lobby scene and if all is well you should be able to input a value for the game ID and hit the button to load in the Tower Defense game Adding in multiplayer capabilitiesWith the lobby added we can start looking at how to include multiplayer functionality As the core user interaction is the placement of monsters to defeat the hordes of enemies we ll look at communicating that first between clients For our communication layer we ll be using Ably Ably s a realtime pub sub platform which is an incredibly powerful paradigm for any form of fan in or fan out messaging From the game each client will send messages to one of Ably s servers and other clients in the game who have subscribed for updates will receive these messages To use Ably you ll need to sign up for a free account Once you have the account you can get an API key from your account dashboard which will allow clients to make use of Ably programmatically For this section we ll be using the API key within our code just to get going but you should eventually replace it with Token Authentication which ensures users only ever have access to short lived tokens which you have full control over in terms of permissions granted Getting the Ably Unity PackageWith an account created and an API key in hand we now need to get one of the client libraries Ably provides in order to easily interact with the system Ably provides a Unity client library as part of their C library If you go to the Ably C GitHub repository you can download the most recent version of the Unity Package from the releases At the time of writing the most up to date version is and can be downloaded here With the unitypackage in hand we need to import it into our Unity project In the top menus select Assets gt Import Package gt Custom Package… and select the unitypackage you just downloaded In the options untick the JsonNet items If you forget to at this step just delete the folder that ll appear in the UnityPackages directory If you get errors about the JsonNet being the wrong version go to Edit Project Settings In here go to the Player tab and then under Configuration Assembly Version Validation untick it Sharing turret upgrades between clientsWith the Ably library added we can now use it to share the addition of monsters between clients As we ll be using Ably in multiple scripts let s create an object to hold a single instance of the Ably client library for us In the GameScene scene add an empty game object called AblyManager and create a script to attach to it called AblyManagerBehaviour Within this script add the following using IO Ably using IO Ably Realtime using UnityEngine public class AblyManagerBehaviour MonoBehaviour private AblyRealtime realtime new AblyRealtime new ClientOptions Key INSERT ABLY API KEY HERE public IRealtimeChannel gameChannel Start is called before the first frame update void Awake gameChannel realtime Channels Get StateManagerBehaviour Instance GameID Make sure to replace the INSERT ABLY API KEY HERE text with the Ably API key you got earlier from your account dashboard Here we are connecting to Ably with the API key to authenticate us and then instantiating an Ably Channel Ably Channels are the means by which clients can indicate the clients they wish to communicate with over Ably They re uniquely identified by a name in this case specified as StateManagerBehaviour Instance GameID We re using the state object we specified earlier to ensure that only clients who wish to participate in a certain game identified by the GameID will be using the Ably Channel Sending and receiving messagesThe Ably instance we ve instantiated will be able to be used by our other scripts to communicate between clients Open up the PlaceMonster script and add in the following to the top of the class private AblyManagerBehaviour ablyManager We can instantiate this reference to the AblyManager within the Start function ablyManager GameObject Find AblyManager GetComponent lt AblyManagerBehaviour gt With this reference to the AblyManager we can now make use of its Ably Channel What we need is to send a message whenever a player clicks to add or upgrade a monster so that clients will be able to subscribe and represent these actions themselves Publish player inputTo do this we ll need to change up the process of adding a monster Instead of adding it as part of a click we will want the click to send a message Replace the contents of the onClick function with the following void OnMouseUp if CanPlaceMonster ablyManager gameChannel Publish spot name “ else if CanUpgradeMonster MonsterData monsterData monster GetComponent lt MonsterData gt Debug Log monsterData levels IndexOf monsterData getNextLevel ablyManager gameChannel Publish spot name monsterData levels IndexOf monsterData getNextLevel ToString Here we are checking on the clientside if we can actually perform the action we re attempting in order to avoid sending unnecessary messages Assuming we can we send a message to the Ably Channel with a name field corresponding to the spot we re interacting with and a data field containing the level we re wanting to set the monster to The name field is useful as the Ably Client library can filter incoming messages by name which will make it easier to only handle messages intended for each monster in each monster s script Subscribe to player inputWith the actions being sent to the Ably Channel we also need to have our clients subscribe to receive these messages To hold messages as they arrived we ll be using a queue The main reason for doing this over just handling messages as they come in is due to the fact the Ably Subscribe functionality will make use of a thread to actively listen for messages This means that when a message is received the handling of that message would occur on this new thread rather than the main thread which means we won t have access to any of Unity s code paths or components from it By using a queue we can handle the messages we receive from the main thread at a later time from the Update function Let s add a queue at the top of the class private Queue actions new Queue Now we have a queue to hold our messages in let s add a subscribe function to listen to the Ably Channel within the Start function just after the ablyManager allocation ablyManager gameChannel Subscribe spot name message gt Need to uniquely identify actions to avoid unintentional upgrade when trying to place etc actions Enqueue message Data Here we re subscribing to the Ably Channel and only acting on messages with the name corresponding to “spot name This means we ll only be running adding messages to the queue if they re intended for this monster with this monster s name Now that we should be receiving messages we need to act upon them Within the Update function we can start to go through the queue Update is called once per framevoid Update if actions Count return PlaceOrUpgradeMonster int Parse string actions Dequeue Here we re checking if the queue has any actions to be performed and if so we ll be calling a new function PlaceOrUpgradeMonster passing the level of monster that s been requested for the location This is important due to the fact we may have multiple clients requesting to upgrade the same tile at the same time so we want to ensure that the intended level of upgrade is considered to avoid unintentional further upgrades to a tile For the contents of PlaceOrUpgradeMonster we can just slightly adjust the old contents of OnMouseUp taking into consideration the intended level of upgrade and if it s still possible or not private void PlaceOrUpgradeMonster int index if CanPlaceMonster amp amp index monster GameObject Instantiate monsterPrefab transform position Quaternion identity AudioSource audioSource gameObject GetComponent lt AudioSource gt audioSource PlayOneShot audioSource clip gameManager Gold monster GetComponent lt MonsterData gt CurrentLevel cost else if CanUpgradeMonster MonsterData monsterData monster GetComponent lt MonsterData gt if monsterData getNextLevel monsterData levels index monster GetComponent lt MonsterData gt increaseLevel AudioSource audioSource gameObject GetComponent lt AudioSource gt audioSource PlayOneShot audioSource clip gameManager Gold monster GetComponent lt MonsterData gt CurrentLevel cost This is a great moment to run the game and see if it works Hopefully with a single client the game should work much the same as before where a click on a tile places a monster If you have two clients running however using the same game ID the actions of each client should now hopefully affect the other client Synchronizing clientsOne useful feature of Ably is that all messages in a channel are guaranteed to be ordered the same way for all subscribers which means that you can be certain that all clients will receive the same messages in the same order ensuring you won t have any desynchronization due to that However there are still various other synchronization issues that we need to address How do we ensure that all clients start the game at the same timeHow do we handle latency which can result in messages being received at different times for different clients Synchronizing start timeEnsuring that all the players start at the same time is a fairly easy one to handle we can add a button to the UI which players can use to start the game This will send a message to all clients indicating to start the game Each message sent through Ably will also have a timestamp attached to it which can be used to ensure all clients are in agreement as to when a game should have started Add a button to the UI of the game and call it StartButton Edit the text element attached to it to have the text Start As this will be an aspect game s flow add the following to the top of the AblyManagerBehaviour script public bool started false public Button startButton public void StartGame startButton enabled false started true Within the Inspector of the button we created select the AblyManager within the On Click section of the Inspector From there go to the AblyManagerBehaviour dropdown for the function dropdown and select the StartGame function The button should now on click set paused to false We will now need to check if the game has started within the SpawnEnemy script Firstly add the Within the SpawnEnemy script s Update function add the following to the top if ablyManager started This doesn t account for any time previously passed lastSpawnTime Time time return If the game hasn t started yet we simply keep the lastSpawnTime set to the current time to avoid enemies eventually instantly spawning and then skip trying to place any enemies We also need to instantiate the ablyManager within SpawnEnemy so at the top add the following line private AblyManagerBehaviour ablyManager Next replace the contents of Start void Start lastSpawnTime Time time gameManager GameObject Find GameManager GetComponent lt GameManagerBehaviour gt ablyManager GameObject Find AblyManager GetComponent lt AblyManagerBehaviour gt If you run the game now locally the game should only start once the player clicks the start button We still need to share this start action with all other players however To do this let s create a function within the AblyManagerBehaviour class which will send a message when the button is clicked and another function which will call the StartGame function once a client receives the message public void SendStartGame gameChannel Publish start Within the Awake function in the AblyManagerBehaviour we can then add a subscribe function to listen for this message much as we did in the PlaceMonster class gameChannel Subscribe start msg gt StartGame If you now change the StartButton s On Click Behaviour to use this new SendStartGame function you should hopefully now have the same Behaviour as you had previously locally but all clients should now react to any client pressing the button Ensuring synchronization is maintainedWhilst the above indicator to start is quite easy to set up ensuring that all clients remain synchronized for the entire game is a much harder challenge There are a few base scenarios you need to consider What if a client lags freezes resulting in it falling behind in terms of gameplay What if a message is delayed in reaching some clients to the point it ll result in different outcomes between clients Both these scenarios can result in different outcomes in a game between clients which isn t something that s acceptable There are a few ways to overcome these issues Full state communicationImagine you have a central server which is responsible for running the true version of the game and is trusted as the defacto truth of what happens Whenever something happens on it it can communicate the new state of the game such as where enemies are where monsters are and the health of both the cookie and the enemies If a client were to fall behind it can then simply check what the most recent version of the state is that was communicated and adjust the local representation of the game to match There will be small periods of time where clients can fall out of sync but the moment the current state of the game is communicated again all clients can quickly adjust to the current state and resync This means that even if there s latencies in communication resulting in some sync states reaching clients out of sync they ll simply be out of sync for a small period but this won t impact what they can do in the game nor the final outcome all clients will see as that s determined and communicated by the server This is however fairly heavy on the communication side of things in comparison to our current approach of only sending messages for players actually interacting with the game Fast forward and delayed inputsOne of the simplest things we can do to ensure a fairly reliable synchronized state is a combination of techniques Firstly if a client falls behind in terms of actions due to their machine freezing momentarily say it can continue to simulate the game as normal up until the point it receives messages which are actions from other players These actions will have a timestamp attached to them indicating when the message was received by Ably If we compare the timestamps of these messages to the timestamp attached to initial start message we can see how much time has passed from our defacto source of truth the Ably servers which is shared by all clients If we re tracking how many times the Update function has been called since the start of the game we can interpret how far behind the local game is behind the true state of the game If we then loop through the ticks of the game rapidly up until we re back to the true state applying the updates received by messages at the appropriate times we should then have our delayed client back in sync To handle the likelihood of a message arriving with a delay for some users we can handle this for the vast majority of cases by simply introducing a delay in the game itself on placing monsters down and them becoming operational aka able to fire If we make this say second then it doesn t matter if a monster s placement message is delayed by any time up to second in reaching a client as all the other clients will already be waiting for second from the timestamp attached to the message before allowing the monster to shoot so they ll all start interacting with enemies at the same time This isn t perfect and if you wanted to ensure for any amount of delay that clients can maintain synchronization you d need to implement some form of rewind mechanism to play back through actions from the last synced point in time storing the exact state of the game at these moments locally to play on from implementing delayed actions at the correct times to ensure they ve happened when they should happen For this blog though we ll be going with the above implementation Allowing clients to catch up with the current stateThe easiest way to allow for clients which have fallen behind the current state to catch up is to make use of the Time timeScale variable that s part of Unity which effects how often Update and FixedUpdate run We can scale this up when we need a client to catch up to quickly run through events until the client has caught up with the current state and then returning back to normal speed To detect if a client has fallen behind though we ll need to start tracking how many ticks have occurred since a game has started locally and also when according to Ably the game started Add the following to the AblyManagerBehaviour class to start tracking the number of ticks since starting public int ticksSinceStart void FixedUpdate if started ticksSinceStart With that added we also can start tracking the start time according to Ably by checking the timestamp attached to the start message all the clients receive Change the StartGame and Awake functions in AblyManagerBehaviour to be the following public DateTimeOffset startTimeAbly Start is called before the first frame updatevoid Awake gameChannel realtime Channels Get StateManagerBehaviour Instance GameID gameChannel Subscribe start msg gt StartGame msg Timestamp public void StartGame DateTimeOffset timestamp if started startTimeAbly timestamp started true With this startTimeAbly should contain the timestamp the game started at Now that the elapsed ticks are being tracked since the start of the game in addition to the time according to Ably the game started we need to start using the timestamps of messages which come in from Ably to the client to determine if our current game state is correct for the elapsed time The first thing we need for that is to start passing the timestamp from messages from Ably that come in to the PlaceMonster class to the queue we consume from Let s create an object within the PlaceMonster file to represent both the existing level of monster to upgrade to in addition to the timestamp public class PlaceMonsterData public int monsterID public DateTimeOffset timestamp Let s replace the subscribe call in the Start function in PlaceMonster to use the new structure ablyManager gameChannel Subscribe spot name message gt PlaceMonsterData pmd new PlaceMonsterData pmd monsterID int Parse string message Data pmd timestamp message Timestamp actions Enqueue pmd Next change the Update function to make use of the new data structure void Update if actions Count return PlaceMonsterData pmd PlaceMonsterData actions Peek DateTimeOffset startTime ablyManager startTimeAbly DateTimeOffset msgTime pmd timestamp TimeSpan diffTime msgTime startTime int ticksSince ablyManager ticksSinceStart float timeFromTicks ticksSince Time fixedDeltaTime if diffTime HasValue PlaceOrUpgradeMonster pmd monsterID return if timeFromTicks lt diffTime Value TotalMilliseconds Time timeScale return else Time timeScale actions Dequeue PlaceOrUpgradeMonster pmd monsterID Let s break down what we re doing here We ll check the start time and current tick from the AblyManagerBehaviour class and compare that to the current next element in the queue We make use of Peek to check the next element as we may not want to consume it if we re out of sync in this current update loop We work out the amount of time that s passed since the start of the game by comparing the start timestamp and the action s timestamp and storing it in diffTime We can then work out how much effective time has elapsed since the start of the game by counting the number of ticks that ve occurred and multiplying it by the amount of time each tick should occur by default once every ms This value is held in Time fixedDeltaTime so we can just use that to calculate timeFromTicks We can then compare the actual time elapsed diffTime and the local game time elapsed timeFromTicks If the game time is behind we can speed up the rate of the game using Time timeScale Here it s set to but you can fiddle with it to match whatever feels best to you If we reach a time elapsed in which the game has caught up with the true state we can finally enact on the message by placing a monster and also ensuring that the timeScale is returned to You should now be able to test this out by running the game Start in the Lobby scene enter a room code and hit the start button You should find that at first the enemies should move at a normal pace and monster placement works the same as usual If you perform an action which causes the game to pause however such as say tasking to another application when you return you should see the game progressing as normal up until you try to place a new monster The game should then pick up pace to catch up with the true state the game should be in This works for ensuring we become eventually consistent with the main state but is dependent on a new action occurring to bring the client back to the real present state As the current only way to invoke an action is with a monster placement this sync could happen right away or not at all before the end of the game An easy fix for this would be to just introduce a fairly regular ping from a client to ensure all the clients are consistently receiving timestamps from Ably to sync on Delaying monster placementWe ve handled the scenario of a client falling behind but we ve yet to address messages being delayed and thus say a monster not existing for one client when it does for another resulting in a desync of damage done to enemies Ideally we d have a foolproof way to handle this scenario such as by making use of checkpoints in the game state locally to rewind to moments which can cause a desync such as a monster being placed and replaying the game quickly from that point forward In this demo however we re going to do something far simpler but which will work for the vast majority of scenarios delaying the placement of a monster from when the action occurs That is to say that if we receive a message to place a monster with timestamp we wouldn t place the turret in the game until say in the local game That means that so long as all the clients receive this message in the second period between the true occurrence of the message and any of them actually enacting on it they should all perform the action at the exact same time in the game To do this we can adjust the shooting logic to not shoot until a second after the timestamp associated with the upgrade placement This should from the player s perspective make the actual placement of monsters still feel smooth and instantaneous with the actual delay in action being hidden by a delay in a monster firing First we ll need to get the timestamp added to the ShootEnemies class Add the following variables to the top of the class private AblyManagerBehaviour ablyManager public DateTimeOffset Timestamp Next add a reference to the AblyManagerBehaviour in the Start function ablyManager gameObject GetComponentInChildren lt AblyManagerBehaviour gt Finally add a consideration for the timestamp to the start of the Update function if timestamp HasValue DateTimeOffset startTime ablyManager startTimeAbly DateTimeOffset msgTime timestamp GetValueOrDefault TimeSpan diffTime msgTime startTime int ticksSince ablyManager ticksSinceStart float timeFromTicks ticksSince Time fixedDeltaTime if timeFromTicks gt diffTime Value TotalMilliseconds timestamp null else return With that added we need a way to pass the timestamp to a monster s ShootEnemies class Update the PlaceOrUpgradeMonster function in PlaceMonster to be the following private void PlaceOrUpgradeMonster int monsterLevel DateTimeOffset timestamp if CanPlaceMonster amp amp monsterLevel monster GameObject Instantiate monsterPrefab transform position Quaternion identity monster GetComponent lt ShootEnemies gt timestamp timestamp AudioSource audioSource gameObject GetComponent lt AudioSource gt audioSource PlayOneShot audioSource clip gameManager Gold monster GetComponent lt MonsterData gt CurrentLevel cost else if CanUpgradeMonster MonsterData monsterData monster GetComponent lt MonsterData gt if monsterData getNextLevel monsterData levels monsterLevel monster GetComponent lt MonsterData gt increaseLevel monster GetComponent lt ShootEnemies gt timestamp timestamp AudioSource audioSource gameObject GetComponent lt AudioSource gt audioSource PlayOneShot audioSource clip gameManager Gold monster GetComponent lt MonsterData gt CurrentLevel cost With this we are allowing for the timestamp to be passed from the Update function and we then use it to assign the timestamp value in the ShootEnemies class Finally change the Update function in PlaceMonster class to pass a the timestamp to the PlaceOrUpgradeMonster function …if diffTime HasValue PlaceOrUpgradeMonster pmd monsterID msgTime return if timeFromTicks lt diffTime Value TotalMilliseconds Time timeScale return else Time timeScale actions Dequeue PlaceOrUpgradeMonster pmd monsterID msgTime With that we should now have decent handling for clients both falling behind the current state in addition to clients receiving delayed messages ConclusionWe have a multiplayer Tower Defence game which can handle network and client instability There s a load of additional features improvements and fixes that can still be applied at this stage but it s a strong starting point to take further and experiment with A few things I d recommend trying out are Making use of Token Authentication for clients to keep authentication details away from untrusted usersHaving a central server to further coordinate users and perform additional validation provide scoreboards and moreExtending the synchronization work to support rewinding the state of a game to a previously known stateGiving clients names so players can uniquely identify themselvesProviding players their own money to buy monsters with rather than a shared bankThere is a version of the game available from the browser if you d like to give it a try If you create anything based on this work I d love to hear about it in the comments on Twitter or even directly via email |
2022-07-21 16:41:00 |
海外TECH |
DEV Community |
Two years of dev.to - let's celebrate with a "Dance Dance Revolution" clone! 💃🕺🎉 |
https://dev.to/thormeier/two-years-of-devto-lets-celebrate-with-a-dance-dance-revolution-clone-4b22
|
Two years of dev to let x s celebrate with a quot Dance Dance Revolution quot clone Time to celebrate Today marks my two year anniversary on dev to With a total of published posts that s roughly one every two weeks And what better way to celebrate than with Dance Dance Revolution The game s rules are explained quickly Boxes come down four different lanes from the topAs soon as the lanes hit a scoring zone or even better the green sweet spot you need to press the correct arrow key to score pointsAny non correct key press or too early or too late will cost you one of livesSome disclaimers though The code is by far not the cleanest The music is royalty freeSometimes the arrow icons take a few seconds to loadWait for all the arrows to disappear before starting a new game It might deduct lives upfront otherwiseThis clone is best played on a computer with a keyboard and in a separate window Have fun What s your high score Leave a comment down below I hope you enjoyed reading this article as much as I enjoyed writing it If so leave a ️or a I write tech articles in my free time and like to drink coffee every once in a while If you want to support my efforts you can offer me a coffee or follow me on Twitter You can also support me directly via Paypal |
2022-07-21 16:19:00 |
Apple |
AppleInsider - Frontpage News |
Flash deal: save $150 on Apple's Mac Studio, plus add AppleCare for $1 today only |
https://appleinsider.com/articles/22/07/21/flash-deal-save-150-on-apples-mac-studio-plus-add-applecare-for-1-today-only?utm_medium=rss
|
Flash deal save on Apple x s Mac Studio plus add AppleCare for today onlyThe cheapest Mac Studio deals are available exclusively for AppleInsider readers with a promo code discounting retail models Plus get AppleCare for savings today only Save on Apple s Mac Studio plus get AppleCare for today only Now through p m PDT save on retail Apple Mac Studio models and get AppleCare year protection plan for only when you shop through this activation link and enter promo code APINSIDER during checkout at Apple Authorized Reseller Adorama Read more |
2022-07-21 16:55:33 |
Apple |
AppleInsider - Frontpage News |
Katy Huberty is no longer covering Apple for Morgan Stanley |
https://appleinsider.com/articles/22/07/21/katy-huberty-is-no-longer-covering-apple-for-morgan-stanley?utm_medium=rss
|
Katy Huberty is no longer covering Apple for Morgan StanleyA new analyst is assuming coverage of Apple for investment bank Morgan Stanley replacing the well known Katy Huberty who has a long track record of correct Apple forecasts Katy HubertyThe bank sent out a note to investors on Thursday penned by analyst Erik Woodring and his team In that note Morgan Stanley said that w ith this report Erik Woodring is assuming coverage of Apple Inc Read more |
2022-07-21 16:18:59 |
Apple |
AppleInsider - Frontpage News |
Documents signed by Steve Jobs, Steve Wozniak set to hit the auction block |
https://appleinsider.com/articles/22/07/21/documents-signed-by-steve-jobs-steve-wozniak-set-to-hit-the-auction-block?utm_medium=rss
|
Documents signed by Steve Jobs Steve Wozniak set to hit the auction blockA number of documents signed by Steve Jobs and other tech pioneers as well as additional collectible Apple memorabilia is set to hit the auction block later in July Apple founder documentsThe items were collected over the years by Charles Mann creator of the educational Powersharing Series and the person who recorded audio of early NeXT computer meetings They re being included in a new Apple Jobs and Computer Hardware lot soon to go up for auction Read more |
2022-07-21 16:32:04 |
海外TECH |
Engadget |
YouTube pulls videos with information on unsafe abortion methods |
https://www.engadget.com/youtube-abortion-misinformation-policy-information-panel-164739943.html?src=rss
|
YouTube pulls videos with information on unsafe abortion methodsYouTube says it will remove content that offers instructions on unsafe abortion methods as well as false claims about abortion safety Such content violates the platform s medical misinformation policies YouTube says it will start taking down those videos today and ramp up its efforts in the coming weeks Additionally YouTube is adding an information panel under abortion related videos and above associated search results The panel includes context and information from local and global health authorities the service said quot Like all of our policies on health medical topics we rely on published guidance from health authorities quot a tweet from the YouTube Insider Twitter account reads quot We prioritize connecting people to content from authoritative sources on health topics and we continuously review our policies amp products as real world events unfold quot YouTube is taking the step after the US Supreme Court overturned Roe v Wade a ruling that ensured the right to abortion in the country Several states immediately moved to ban abortions after the court s decision in late June nbsp The platform banned COVID misinformation following the onset of the pandemic By August it had taken down more than a million videos with dangerous COVID misinformation The following month the platform banned content with vaccine misinformation We re also launching an information panel that provides viewers with context and information from local and global health authorities under abortion related videos and above relevant search results pic twitter com dGzEnbIbーYouTubeInsider YouTubeInsider July |
2022-07-21 16:47:39 |
海外TECH |
Engadget |
Twitch creators can share their banned user lists |
https://www.engadget.com/twitch-shared-ban-lists-creators-163035564.html?src=rss
|
Twitch creators can share their banned user listsTwitch is rolling out a new safety option for streamers They ll be able to share the list of users they have banned with other creators The tool could help to keep serial harassers at bay Twitch suggests particularly those who target creators who are members of marginalized communities The Shared Ban Info function builds on the Suspicious User Controls system Twitch debuted in December nbsp To share a list of banned users with another streamer a creator will need to send them a request from the Shared Ban Info section of the moderation settings When you request ban information from another streamer and they accept you ll share the same information from your channel with them At the outset creators can have up to of these connections You can set a default action for how to treat flagged users that another channel has banned Those users can be monitored meaning they can post in your chat but all of their messages will be flagged for you and your moderators to look at There s an option to restrict flagged users by default ーtheir chat messages will only be visible to a streamer and their mods Otherwise streamers can ban these flagged users or mark them as trusted so they can post chat messages without any limitations In any case the first time a flagged user posts in your chat their message will have a red border and you can see which channel has banned them A Twitch spokesperson said the platform was quot excited about this tool as it s a first step in empowering not just individual streamers to make personalized moderation decisions but communities as a whole quot They added that quot while Shared Ban Info is just the latest customizable tool in the arsenal we offer creators it adds a new level of scalability by expanding the impact of individuals moderation decisions and ultimately helping community members help each other ーsomething they already do organically in a myriad of ways in Twitch s uniquely engaged environment every single day quot Similar efforts to stamp out bad actors have emerged on other platforms Twitter for instance used to allow users to share a list of the accounts they have blocked but the feature is no longer available Third party services that support Twitter block lists are available however Twitch announced the Shared Ban Info feature at TwitchCon Amsterdam this past weekend The company also said it will grant creators more control over who can raid them A raid involves a creator automatically sending all of their viewers to another channel when they end their stream However the feature has been used to harass marginalized creators |
2022-07-21 16:30:35 |
Cisco |
Cisco Blog |
Why Manufacturers duplicate IPv4 addresses and how IE switches help solve the issues |
https://blogs.cisco.com/internet-of-things/why-manufacturers-duplicate-ipv4-addresses-and-how-ie-switches-help-solve-the-issues
|
Why Manufacturers duplicate IPv addresses and how IE switches help solve the issuesIndustrial Automation and manufacturing use sophisticated machines with duplicate IP Addresses Layer NAT on Cisco IE switches can solve this problem |
2022-07-21 16:00:49 |
金融 |
金融庁ホームページ |
金融庁職員の新型コロナウイルス感染について公表しました。 |
https://www.fsa.go.jp/news/r4/sonota/20220721.html
|
新型コロナウイルス |
2022-07-21 17:30:00 |
ニュース |
BBC News - Home |
Conservative leadership: Liz Truss says Tory economic policy choked growth |
https://www.bbc.co.uk/news/uk-politics-62250027?at_medium=RSS&at_campaign=KARANGA
|
minister |
2022-07-21 16:46:23 |
ニュース |
BBC News - Home |
US President Joe Biden 'doing great' after testing positive for Covid |
https://www.bbc.co.uk/news/world-us-canada-62256544?at_medium=RSS&at_campaign=KARANGA
|
house |
2022-07-21 16:26:13 |
ニュース |
BBC News - Home |
Archie Battersbee: Family argue wishes not given 'proper weight' |
https://www.bbc.co.uk/news/uk-england-essex-62257073?at_medium=RSS&at_campaign=KARANGA
|
appeal |
2022-07-21 16:28:52 |
ニュース |
BBC News - Home |
Graham Mansfield: Hale man cleared of terminally ill wife's murder |
https://www.bbc.co.uk/news/uk-england-manchester-62250733?at_medium=RSS&at_campaign=KARANGA
|
mansfield |
2022-07-21 16:42:52 |
ニュース |
BBC News - Home |
Duke of Wellington's sherry sells for £1,500 |
https://www.bbc.co.uk/news/uk-62256613?at_medium=RSS&at_campaign=KARANGA
|
minister |
2022-07-21 16:41:34 |
ニュース |
BBC News - Home |
Tour de France: Jonas Vingegaard extends lead with stage 18 victory |
https://www.bbc.co.uk/sport/cycling/62255650?at_medium=RSS&at_campaign=KARANGA
|
france |
2022-07-21 16:52:06 |
ニュース |
BBC News - Home |
Uwe Seeler: Germany great dies aged 85 |
https://www.bbc.co.uk/sport/football/62258328?at_medium=RSS&at_campaign=KARANGA
|
country |
2022-07-21 16:57:44 |
北海道 |
北海道新聞 |
イタリアで総選挙へ 9月にも、首相の辞表受理 |
https://www.hokkaido-np.co.jp/article/708594/
|
首相 |
2022-07-22 01:10:04 |
北海道 |
北海道新聞 |
列車内で高校生殴った疑い 男を逮捕 森署 |
https://www.hokkaido-np.co.jp/article/708698/
|
鹿部 |
2022-07-22 01:17:35 |
北海道 |
北海道新聞 |
大通ビアガーデン、3年ぶり22日から コロナ急拡大受け対策徹底 |
https://www.hokkaido-np.co.jp/article/708646/
|
大通公園 |
2022-07-22 01:09:51 |
北海道 |
北海道新聞 |
おたる潮まつり、最終24日は道新花火大会 近藤工業が台船無償提供 |
https://www.hokkaido-np.co.jp/article/708610/
|
無償提供 |
2022-07-22 01:08:20 |
GCP |
Cloud Blog |
Standing shoulder to shoulder - building a resilient healthcare ecosystem with Health-ISAC |
https://cloud.google.com/blog/products/identity-security/google-cloud-joins-with-h-isac-to-help-better-secure-healthcare-systems/
|
Standing shoulder to shoulder building a resilient healthcare ecosystem with Health ISACBuilding a resilient healthcare ecosystem is not something done within a vacuum It takes motivated organizations and people working together in a community of trust to build and defend effectively We believe the more diverse these communities are the more effective they can be Last August Google announced its commitment to invest at least billion over the next years to advance cybersecurity We re making good on our commitment to support the security and digital transformation of government critical infrastructure enterprise small business and in time consumers and society overall through community partnerships and other means As part of this initiative Google Cloud is announcing today that it is partnering with Health Information Sharing and Analysis Center Health ISAC as an Ambassador partner Google Cloud is the first and only major cloud provider to join the organization Health ISAC is a trusted community of critical infrastructure owners and operators within the global Healthcare and Public Health sector HPH The community is primarily focused on sharing timely actionable and relevant information with each otherーincluding intelligence on threats incidents vulnerabilities mitigation strategies and best practices Health ISAC also encourages building relationships and networking through worldwide educational events and research papers Working groups and committees focus on topics of importance to the sector and its member vetted Community Services offer enhanced services to leverage the Health ISAC community to help better secure the intersection of healthcare and technology As an Ambassador partner Google Cloud will bring experts and resources including our Threat Horizon Report and Google Cybersecurity Action Team to partner with the healthcare community and its leadership Googlers will work with defenders and leaders in the global health sector sharing knowledge we ve learned building and deploying secure technology at Google “Partnering with Health ISAC just makes sense We share a common vision that building a safe and reliable health ecosystem is our collective responsibility and keeps with values of respecting and protecting each other This partnership should inspire other organizations with skills and capabilities that can contribute to these outcomes to join us said Phil Venables CISO Google Cloud We re excited to be working with organizations like Health ISAC and those on the forefront of building communities and protecting societies On the journey to being resilient one thing is for certain Working together can make all the difference “We re thrilled to have Google Cloud as an Ambassador sponsor with Health ISAC said Errol Weiss Chief Security Officer at Health ISAC “This partnership will help with Health ISAC s expansion in Europe and Asia Pacific while also leveraging Google Cloud s vast resources and data for the benefit of improving the security and resilience of the health and public health sector globally Weiss added Related ArticleHelping global governments and organizations adopt Zero Trust architecturesGoogle details how it helps governments embark on a Zero Trust journey as the anniversary of the Biden Zero Trust Executive Order approac Read Article |
2022-07-21 16:30:00 |
コメント
コメントを投稿