{"id":439,"date":"2021-11-05T03:25:56","date_gmt":"2021-11-05T03:25:56","guid":{"rendered":"https:\/\/globalgoodplay.com\/?p=439"},"modified":"2022-11-07T09:58:05","modified_gmt":"2022-11-07T09:58:05","slug":"optimize-your-games-in-unity-the-ultimate-guide","status":"publish","type":"post","link":"https:\/\/globalgoodplay.com\/?p=439","title":{"rendered":"Optimize Your Games In Unity \u2013 The Ultimate Guide"},"content":{"rendered":"<div class=\"elementor elementor-17336\" data-elementor-type=\"wp-post\" data-elementor-id=\"17336\">\n<section class=\"elementor-section elementor-top-section elementor-element elementor-element-19ff91c1 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"19ff91c1\" data-element_type=\"section\">\n<div class=\"elementor-container elementor-column-gap-default\">\n<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1b1c150\" data-id=\"1b1c150\" data-element_type=\"column\">\n<div class=\"elementor-widget-wrap elementor-element-populated\">\n<div class=\"elementor-element elementor-element-3cc661f9 elementor-widget elementor-widget-text-editor\" data-id=\"3cc661f9\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>When developing your game, one of the hardest things to do is optimization, no matter if you are creating a mobile, desktop or a console game.<\/div>\n<div><\/div>\n<div>And we all know that if your game is not well optimized, it will result in downloads lost, refunds requested, and ultimately labeling your game and your game development company as the ones who create poor games.<\/div>\n<div><\/div>\n<div>In this post, I will go over everything I learned over the course of 8 years developing games in Unity. I will share with you the wrong way and the right way to do things and I will explain everything I am using in the examples.<\/div>\n<div><\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-21c63fd9 elementor-widget elementor-widget-heading\" data-id=\"21c63fd9\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Important Information Before We Start<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-5723de79 elementor-widget elementor-widget-text-editor\" data-id=\"5723de79\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>When it comes to optimization the Profiler is your best friend. Always profile your games on the platform you are creating them, especially mobile games.<\/div>\n<div><\/div>\n<div>The Profiler will give you information about the performance of your game and any spikes that are causing low performance.<\/div>\n<div><\/div>\n<div>That being said, everything that I am going to talk about in this post are things that will help you write better and more optimized code and use optimized options for your game which will help you boost your game to &gt; 60 FPS.<\/div>\n<div><\/div>\n<div>The order by which I will write every tip doesn\u2019t matter, I will write everything I know how I remember it and I will add new things as I learn them. You can use the menu navigation on the left side to directly navigate to the part you want to learn.<\/div>\n<div><\/div>\n<div>Now let\u2019s get started.<\/div>\n<div><\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-278c0110 elementor-widget elementor-widget-heading\" data-id=\"278c0110\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Always Cache Your Components<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-66593a9e elementor-widget elementor-widget-text-editor\" data-id=\"66593a9e\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>A good practice that you need to get used to is to always cache your variables. Code like<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-3e327c05 elementor-widget elementor-widget-text-editor\" data-id=\"3e327c05\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>is very costly for your game performance, especially on mobile devices. If you need to access any component of any game object, always declare the type of the component you need<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-48a7c122 elementor-widget elementor-widget-text-editor\" data-id=\"48a7c122\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>and then in Awake get a reference to that variable<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-5fe29643 elementor-widget elementor-widget-text-editor\" data-id=\"5fe29643\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>I know that we can also use the Start function for this purpose, even the OnEnable function, but I used the Awake function for this example because the Awake function is the first initialization function that is called when the game starts, and if I want to get a reference to variables or initialize variables I always do it in the Awake function as that will be the first thing that will be executed and then the game can start normally.<\/p>\n<p>After that you can safely apply force to your Rigidbody variable:<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-14edc499 elementor-widget elementor-widget-heading\" data-id=\"14edc499\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Caching Components VS SerializeField<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-61d36bf9 elementor-widget elementor-widget-text-editor\" data-id=\"61d36bf9\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>There is another way how we can get a reference to cached variables and that is by adding the SerializeField keyword above the variable declaration:<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-1d01426a elementor-widget elementor-widget-text-editor\" data-id=\"1d01426a\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>This will expose the variable in the Inspector tab and we can now drag the game object itself providing that it has the desired component attached on it, in the exposed variable field to get a reference to it:<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-1cb6c960 elementor-widget elementor-widget-image\" data-id=\"1cb6c960\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n<div class=\"elementor-widget-container\"><img decoding=\"async\" title=\"Img-1-2.jpg\" src=\"https:\/\/glossingdress.com\/lib\/img\/all\/551\/db29f4ccc794a0e52119263a283fa6a9bb2ecccfc2c0f0ef63eab52f7be48d47\/8fa16aa67b5e93af600b01e0b2abe26d42efd18ba4af6c4e8d47f84f26e61038.jpeg\" alt=\"Img-1-2.jpg\" \/><\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-63c5acd7 elementor-widget elementor-widget-text-editor\" data-id=\"63c5acd7\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>Now which of the two methods is more optimized, the answer is SerializeField. Because you don\u2019t need to use code to get a reference to the desired component, and this is very effective especially if you have a lot of game objects such as enemies or collectable items that need to get a certain component when they are spawned.<\/p>\n<p>Now there will be times where you need to get a reference to a component via code, but whenever you can, try to get a reference to the component of a game object by using SerializeField and attaching the desired component in the appropriate slot in the Inspector tab.<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-1cb5d278 elementor-widget elementor-widget-heading\" data-id=\"1cb5d278\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Cache Your Non-Component Variables As Well<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-e98800a elementor-widget elementor-widget-text-editor\" data-id=\"e98800a\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>One of the things that I see A LOT in tutorials and courses online are the following:<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-4b433631 elementor-widget elementor-widget-text-editor\" data-id=\"4b433631\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>Once I profiled a mobile game that I was currently working on, and I found out that by creating a new Vector3 variable in the Update function like you see in the example above, it was taking my code 0.02 ms more to execute the code.<\/div>\n<div><\/div>\n<div>Given the fact that to get to 60 FPS and above, all of your code needs to execute at 16 ms tops, you can imagine how unoptimized this one simple line of code is.<\/div>\n<div><\/div>\n<div>The solution is to cache the variable before you use it:<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-57095983 elementor-widget elementor-widget-text-editor\" data-id=\"57095983\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>This is also a rule for any other variable types. It is always better to do<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-6f005085 elementor-widget elementor-widget-text-editor\" data-id=\"6f005085\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>than<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-3cd71f63 elementor-widget elementor-widget-text-editor\" data-id=\"3cd71f63\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>So get in a habit to do this with all of your variables especially object type variables like vectors, components and custom classes you create, but also do this with floats, ints, booleans, and strings.<\/div>\n<div><\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-7f51e18c elementor-widget elementor-widget-heading\" data-id=\"7f51e18c\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Don\u2019t Use Camera.main<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-11b12459 elementor-widget elementor-widget-text-editor\" data-id=\"11b12459\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>This is also something that I see a lot in online tutorials and course which is killing your performance. Accessing the camera by using<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-7bb9efb2 elementor-widget elementor-widget-text-editor\" data-id=\"7bb9efb2\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>especially if you use this a lot will slow down your game. This is in a way connected to caching that we talked about above, but the solution for this, again, is to cache the camera variable before using i<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-126bd5b1 elementor-widget elementor-widget-heading\" data-id=\"126bd5b1\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Avoid Repeated Access to MonoBehaviour Transform<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-2e3fd5f7 elementor-widget elementor-widget-text-editor\" data-id=\"2e3fd5f7\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>Another thing that you need to be careful of is reusing the transform property of MonoBehaviour. This internally calls GetComponent to get the Transform component attached on the game object.<\/p>\n<p>Again, the solution for this is to cache the transform variable:<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-7cbdfe83 elementor-widget elementor-widget-heading\" data-id=\"7cbdfe83\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Optimizing Strings<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-3236faf8 elementor-widget elementor-widget-text-editor\" data-id=\"3236faf8\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>One of the heaviest performances in your Unity game are the strings that you are using. Yeah, you read it right, STRINGS.<\/div>\n<div><\/div>\n<div>The first mistake you will see everything online is when collision check is performed:<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-61855740 elementor-widget elementor-widget-text-editor\" data-id=\"61855740\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>This is not the way to go. When you are checking the tag of the collided game object it is better to use CompareTag function<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-5aa3bd8c elementor-widget elementor-widget-text-editor\" data-id=\"5aa3bd8c\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>Another common mistake is when declaring an empty string people usually write:<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-f94dd76 elementor-widget elementor-widget-text-editor\" data-id=\"f94dd76\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>A better way is to use string.Empty:<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-2aef9ca3 elementor-widget elementor-widget-heading\" data-id=\"2aef9ca3\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Strings And Text UI<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-4e05378e elementor-widget elementor-widget-text-editor\" data-id=\"4e05378e\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>When using strings and text UI you need to be careful when you are updating the text often, especially if that happens in the Update function.<\/p>\n<p>This is something a lot of people do with timers, the usually write code that looks like this:<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-22adb47 elementor-widget elementor-widget-text-editor\" data-id=\"22adb47\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>While this looks like a very simple operation, it is going to slow down your game significantly, especially a mobile.<\/p>\n<p>The reason for that is because a string is an object type variable. Every time you concatenate a string like you see in the line 9 in the code above, you create a new object.<\/p>\n<p>Now imagine doing this in the Update function which is called every frame. You are creating a new object that is stacked up memory every single frame and this is something mobile devices can\u2019t handle.<\/p>\n<p>The solution is to use StringBuilders.<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-45293db1 elementor-widget elementor-widget-text-editor\" data-id=\"45293db1\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>Use string builders wherever you need to use strings often especially when it comes to timers and countdowns.<\/div>\n<div><\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-a132b80 elementor-widget elementor-widget-heading\" data-id=\"a132b80\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Avoid Using Instantiate Function During Gameplay<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-fc261fc elementor-widget elementor-widget-text-editor\" data-id=\"fc261fc\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>When it comes to Instantiate function, which creates a copy of the provided prefab, you will find different opinions online. The majority say don\u2019t use Instantiate during gameplay.<\/p>\n<p>This is somewhat true. I say somewhat because I\u2019ve used Instantiate during gameplay in one of my mobile games and when I profiled the game it was running smoothly never going below 60 FPS.<\/p>\n<p>This goes to show that you should always revert back to the Profiler and the stats you see there.<\/p>\n<p>That being said, it is always a better idea to use the pooling technique instead of relying on Instantiate, especially if you are spawning bullets, collectable items or any other game element that is often spawned in the game.<\/p>\n<div>If you don\u2019t know what is pooling, I am going to leave a basic generic pooling class below for you to inspect the code and learn:<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-5331c29a elementor-widget elementor-widget-text-editor\" data-id=\"5331c29a\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>But sometimes there will be situations where you simply need to use Instantiate as that is the shortest solution, and there is no harm in using it if you see that the Profiler is not showing any issues, so keep that in mind.<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-481e1d89 elementor-widget elementor-widget-heading\" data-id=\"481e1d89\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">Remove Empty Callback Functions<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-7822c0d9 elementor-widget elementor-widget-text-editor\" data-id=\"7822c0d9\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>As you already know, Awake, Start, and OnEnable initialization functions are called when the game object is spawned.<\/p>\n<p>Update and LateUpdate are called every frame and LateUpdate is called every fixed frame rate.<\/p>\n<p>The issue with these functions is that they will be called even if they are empty because Unity doesn\u2019t know that these functions are empty e.g. they don\u2019t have any code inside.<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-58e9fd05 elementor-widget elementor-widget-text-editor\" data-id=\"58e9fd05\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>even if they are empty like in the example above, Unity is going to call them.<\/div>\n<div><\/div>\n<div>Now you might say, okay but they don\u2019t have any code inside so what is the harm when nothing is going to be executed.<\/div>\n<div><\/div>\n<div>The harm is the fact that whenever a game object is instantiated in the game, Unity will add any defined callbacks, such as Awake or Update, to a list of functions that will be called at specific moments(Awake will be called when the object is spawned, Update will be called every frame and so on).<\/div>\n<div><\/div>\n<div>This will waste CPU power due to the cost of the engine invoking these functions. And this can be a problem especially if you leave empty callback functions in let\u2019s say a bullet prefab that you call every time you shoot, or a collectable item that is spawned when the player makes an achievement and so on.<\/div>\n<div><\/div>\n<div>Not to mention if you are creating a larger game and over time you populate your scenes with thousands of game objects with empty Awake, Start, Update, and so on, which can cause slow scene load time.<\/div>\n<div><\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-3eff67cd elementor-widget elementor-widget-text-editor\" data-id=\"3eff67cd\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>I am going to attach the two functions on two prefabs and I am going to spawn 1000 copies of each prefab using the following code:<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-568226a elementor-widget elementor-widget-text-editor\" data-id=\"568226a\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<div>Let\u2019s take a look at the Profiler and see what happens when we instantiate the object that has empty callback functions and what happens when we instantiate the object that doesn\u2019t have empty call back functions:<\/div>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-5a9a1739 elementor-widget elementor-widget-text-editor\" data-id=\"5a9a1739\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>As you saw from the example, just by having empty Start and Update functions in the class the spike on the Profiler skyrocketed when we created objects which had that class attached to them.<\/p>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-98f2ce6 elementor-widget elementor-widget-heading\" data-id=\"98f2ce6\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n<div class=\"elementor-widget-container\">\n<h3 class=\"elementor-heading-title elementor-size-default\">When Raycasting Use Zero Allocation Code<\/h3>\n<\/div>\n<\/div>\n<div class=\"elementor-element elementor-element-727cc702 elementor-widget elementor-widget-text-editor\" data-id=\"727cc702\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n<div class=\"elementor-widget-container\">\n<p>Avoid using raycast code that allocates memory. All raycast functions have their non memory allocation version:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>When developing your game, one of the hardest things to do is optimization, no matter if you are creating a mobile, desktop or a console game. And we all know that if your game is not well optimized, it will result in downloads lost, refunds requested, and ultimately labeling your game and your game development<\/p>\n","protected":false},"author":1,"featured_media":597,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-439","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=\/wp\/v2\/posts\/439"}],"collection":[{"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=439"}],"version-history":[{"count":2,"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=\/wp\/v2\/posts\/439\/revisions"}],"predecessor-version":[{"id":598,"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=\/wp\/v2\/posts\/439\/revisions\/598"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=\/wp\/v2\/media\/597"}],"wp:attachment":[{"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=439"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=439"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/globalgoodplay.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=439"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}