{"id":1616,"date":"2015-03-20T10:24:37","date_gmt":"2015-03-20T10:24:37","guid":{"rendered":"http:\/\/mertboru.com\/?p=1616"},"modified":"2018-07-25T08:57:07","modified_gmt":"2018-07-25T08:57:07","slug":"3-bit-node-graph-architecture-for-next-gen-video-game-development","status":"publish","type":"post","link":"http:\/\/mertboru.com\/?p=1616","title":{"rendered":"3-bit Node Graph Architecture for Next-Gen Game Development"},"content":{"rendered":"<p>Speaking of my latest video game development project, yet an another milestone achieved. &#8211; Quite a tough one, indeed!<\/p>\n<p>But first, please allow me to focus on some of the very basic <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mathematical_logic\" target=\"_blank\" rel=\"noopener\">mathematical logic<\/a> definitions heavily used in software engineering, so that we can clearly understand what&#8217;s going on under the hood of a <em>decent<\/em> game development process.<\/p>\n<p>Don&#8217;t worry, it&#8217;s not rocket science \ud83d\ude09<\/p>\n<p><strong>Some theory<\/strong><\/p>\n<p>All video games have gameplay mechanics based on logic. A game is <em>&#8220;a set of story driven goals to achieve&#8221;<\/em> from a programmer&#8217;s perspective.<\/p>\n<p>When you open a chest, solve a puzzle or kill an enemy, you are actually triggering a <strong>logic unit<\/strong> that is predefined within the game code. Depending on game&#8217;s technical requirements and gameplay complexity, there can be thousands of these units forming a <strong>web of logic units<\/strong>.<\/p>\n<p>Game programmers tend to use <a href=\"http:\/\/en.wikipedia.org\/wiki\/Graph_theory\" target=\"_blank\" rel=\"noopener\">graph\u00a0theory<\/a> for defining and coding logic units. Each unit\u00a0is symbolized with a simple geometric shape. A box, a circle, anything&#8230; And these units are connected to each other with links.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-1629 aligncenter\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_sample.png\" alt=\"\" width=\"408\" height=\"264\" srcset=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_sample.png 408w, http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_sample-300x194.png 300w\" sizes=\"auto, (max-width: 408px) 100vw, 408px\" \/><\/p>\n<p style=\"text-align: right; padding-left: 120px;\"><em><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0<strong>&#8220;Logic units&#8221;<\/strong><\/em> (nodes) represent tasks that the player will perform.<\/p>\n<p style=\"text-align: right; padding-left: 120px;\"><em><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0<strong>&#8220;Links&#8221;<\/strong><\/em> (lines) represent the relationship between the logic units.<\/p>\n<p><strong>Behaviour Analysis<\/strong><\/p>\n<p>A node graph architecture is <i>almost <\/i>identical to an <a href=\"http:\/\/en.wikipedia.org\/wiki\/Electronic_circuit\" target=\"_blank\" rel=\"noopener\">electronic circuit<\/a>. When you start executing a node graph code, you are actually branching from one component (node, in our case) to an another by the rules you&#8217;ve set for the logic units, just like <a href=\"http:\/\/en.wikipedia.org\/wiki\/Electric_current\" target=\"_blank\" rel=\"noopener\">electric current<\/a> flowing from a resistor to a capacitor. And, as you can guess, this type of signal flow is 100% linear.<\/p>\n<p>When the player accomplishes a task, the node related to that event will be <em>&#8220;expired&#8221;<\/em>. In other words, it will be dead. Expired nodes cannot be resurrected. Once they&#8217;re done, they will be ignored (skipped) during code execution, forever. &#8211; Which is unlikely in electronics! An electronic component, such as a resistor, a diode, etc. cannot be conditionally turned on\/off.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-1658 aligncenter\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_endof.png\" alt=\"\" width=\"27\" height=\"27\" \/><\/p>\n<p><strong>Back to 2002 for a &#8220;classic&#8221; implementation: Flagger<\/strong><\/p>\n<p>During the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Culpa_Innata\" target=\"_blank\" rel=\"noopener\"><em>&#8220;Culpa Innata&#8221;<\/em><\/a> development sessions, we precisely knew that we needed a node graph architecture for handling game&#8217;s complex execution flow. Many discussions were held on the method of implementation. All members of the <em>core<\/em> management &amp; development team were expert electric\/electronics engineers with no experience in video game\u00a0production <sup><a href=\"http:\/\/www.comicbookmom.com\/2012\/10\/culpa-innata-from-video-game-to-book.html\" target=\"_blank\" rel=\"noopener\">[Reference]<\/a><\/sup>, but me! As a video game programmer, my perspective towards node graph theory was <i>naturally <\/i>very different, contrary to their classical approaches. I wasn&#8217;t thinking in terms of voltage, current, etc., but focused\u00a0on just one thing: optimized code execution.<\/p>\n<p>Thanks to my <a href=\"http:\/\/en.wikipedia.org\/wiki\/Zilog_Z80\" target=\"_blank\" rel=\"noopener\">Zilog Z80<\/a> and <a href=\"http:\/\/en.wikipedia.org\/wiki\/Motorola_68000\" target=\"_blank\" rel=\"noopener\">Motorola 68000<\/a> assembly language programming background, I offered the term <em>&#8220;Flag&#8221;<\/em> for the base logic unit (node), and teamed up with Mr. Mete Balc\u0131 for 3 weeks. In December 2002, we developed a tool called <em>&#8220;Flagger&#8221;<\/em>.<\/p>\n<p><strong>Pros and Cons<\/strong><\/p>\n<p><em>Flagger<\/em>\u00a0was a C++ code generator with a very handy visual interface similar to UE4&#8217;s current Blueprint approach. Using <em>Flagger<\/em>, we were able to add nodes, connect them to each other, program the logic behind the nodes\/links, and even take printout of the whole node graph scenario. When the visual logic design process was over, it was just a matter of selecting <em>&#8220;Generate C++ code&#8221;<\/em> from the menu, and source code was generated within minutes.<\/p>\n<p>Over\u00a0the following years, <em>Flagger<\/em> evolved into a more sophisticated development tool capable of handling various scenarios.<span lang=\"\"> Although it was a very handy tool and saved many hours during <em>&#8220;Culpa Innata&#8221;<\/em> sessions, there were a few problems with the <i>classical<\/i> node graph theory that the implementation was based on;<\/span><\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0 Flags were<strong> single threaded.<\/strong> Only one node was allowed to execute at a time. No multi-threading.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0 Flags were<strong> expirable.<\/strong> When a task was done, related flag (node) was marked as &#8220;expired&#8221;, not deleted for the sake of logic <span lang=\"EN\">integrity<\/span><span lang=\"\">.<\/span><\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0 Flags were<strong> not reusable.<\/strong> Once they were expired, there was no way of resurrecting them. &#8211; Inefficient memory usage, thanks to hundreds of expired nodes.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0 Flags were<strong> heavily loaded with variables.<\/strong> Too many dialogue related &#8220;customized&#8221; variables were defined for special cases (exceptions). &#8211;\u00a0Inefficient memory usage, once again.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0 Flag execution flow<strong> wasn&#8217;t well optimized<\/strong> because of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Binary_search_tree\" target=\"_blank\" rel=\"noopener\">node-tree search<\/a> algorithm. The more nodes we had, the longer it took to accomplish the search.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0 Flag execution was<strong> linear.<\/strong> When a node was expired, the graph code was first searching for related nodes and then retriggering the whole diagram from the beginning, like an electronic circuit simulator. &#8211; Well, that was\u00a0ideal for modeling a circuit, not for developing a video game!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-1658 aligncenter\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_endof.png\" alt=\"\" width=\"27\" height=\"27\" \/><\/p>\n<p><strong>A Modern Approach: 3-bit Worker!<\/strong><\/p>\n<p>13 years later, I have once again found an opportunity to dive into node graph theory, and just completed implementing a new architecture for my latest video game development project. Unlike <em>Flagger<\/em>, it is something <em>extraordinary<\/em>! It is very&#8230; <em>atypical<\/em>, <em>unconventional<\/em>, <em>unorthodox<\/em>&#8230; Well, whatever&#8230; You got it \ud83d\ude09<\/p>\n<p>First of all, it has nothing to do with classical electric\/electronic circuit theory. This time, I&#8217;m on my own, and approaching the problem as a software engineer. Everything I designed\/coded is based on game requirement specifications. In other words, it is implemented with &#8220;practical usage&#8221; in mind.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0I have defined the <strong>basic logic unit<\/strong> (node), as a<strong> &#8220;worker&#8221;.<\/strong> &#8211; <em>(Due to functional similarities, I simply borrowed this term from <a href=\"http:\/\/en.wikipedia.org\/wiki\/Web_worker\" target=\"_blank\" rel=\"noopener\">Web Workers<\/a>.)<\/em><\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0A worker is a background task with <strong>adjustable priority<\/strong> settings. It\u00a0performs\/responds like a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Interrupt\" target=\"_blank\" rel=\"noopener\">hardware interrupt<\/a>.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0 Each worker is<strong> multi-threaded.<\/strong><\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Depending on conditional requirements,<strong> a worker can expire and\/or live forever.<\/strong> If expired, it can be resurrected and\/or reinitialized, while preserving its previous state. So, a worker is a 100% <span style=\"text-decoration: underline;\">reusable<\/span> node.<\/p>\n<p style=\"padding-left: 30px;\"><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-1680 aligncenter\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_3bit_xxl.png\" alt=\"\" width=\"311\" height=\"115\" srcset=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_3bit_xxl.png 311w, http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_3bit_xxl-300x111.png 300w\" sizes=\"auto, (max-width: 311px) 100vw, 311px\" \/><\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Each worker<strong> uses only 3-bits!<\/strong> No additional variables, no references, nothing else. &#8211; <em>(If necessary, a worker offers flexible architecture for additional variables. However, I find it totally unnecessary. 3-bits are more than enough!)<\/em><\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Workers are <a href=\"http:\/\/en.wikipedia.org\/wiki\/Object-oriented_programming\" target=\"_blank\" rel=\"noopener\">object oriented<\/a><strong>.<\/strong>\u00a0They can easily be <a href=\"http:\/\/en.wikipedia.org\/wiki\/Inheritance_(object-oriented_programming)\" target=\"_blank\" rel=\"noopener\">inherited<\/a>.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Inherited workers<strong> don&#8217;t need additional logic variables.<\/strong> All child workers share the same 3-bit information that they inherited from their parents!<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Each worker has a<strong> time dependent <span style=\"color: #ff0000;\">linear<\/span> workflow.<\/strong> Just like a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Tape_recorder\" target=\"_blank\" rel=\"noopener\">reel-to-reel tape recorder<\/a>, it can be played, paused, slowed down, accelerated, fast forwarded, rewinded, and stopped.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Workers can be<strong><span style=\"color: #ff0000;\"> non-linearly<\/span> linked<\/strong> to other Workers! Which means, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Binary_search_tree\" target=\"_blank\" rel=\"noopener\">node-tree search<\/a> algorithms are no more necessary. There is no &#8220;main loop&#8221; for executing nodes! Code execution is pre-cached for optimum performance.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Workers are<strong> optimized for event driven methodology.<\/strong> No matter how many concurrent active workers (threads) you have in the scene, there is practically no CPU overhead. Ideal for mobile scenarios.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Workers are managed by<strong> &#8220;Managers&#8221;.<\/strong> A Manager is inherited from base Worker node. So, any worker can be assigned as a Manager.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Workers can communicate with each other and access shared variables via Managers.<\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0Whole architecture is<strong> 100% platform independent.<\/strong> For\u00a0a showcase, I&#8217;ve implemented it for <a href=\"https:\/\/www.unrealengine.com\/\" target=\"_blank\" rel=\"noopener\">Unreal Engine 4<\/a>\u00a0using C++ and Blueprints. It can easily be ported to other game engines<span lang=\"EN\">;<\/span><span lang=\"\"> such as <a href=\"http:\/\/unity3d.com\/\" target=\"_blank\" rel=\"noopener\">Unity<\/a>, <a href=\"http:\/\/cryengine.com\/\" target=\"_blank\" rel=\"noopener\">CryEngine<\/a>, etc.<\/span><\/p>\n<p style=\"padding-left: 60px;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1650\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_dashed.png\" alt=\"\" width=\"11\" height=\"11\" \/>\u00a0\u00a0And, most important of all, everything is meticulously tested. &#8211;\u00a0It&#8217;s working as of today \ud83d\ude42<\/p>\n<p><a href=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_WorkerManager_UE4_implementation.png\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\" size-medium wp-image-1655 aligncenter\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_WorkerManager_UE4_implementation-300x146.png\" alt=\"\" width=\"300\" height=\"146\" srcset=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_WorkerManager_UE4_implementation-300x146.png 300w, http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_WorkerManager_UE4_implementation-1024x498.png 1024w, http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/nodegraph_WorkerManager_UE4_implementation.png 1535w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-1658 aligncenter\" src=\"http:\/\/mertboru.com\/wp-content\/uploads\/2015\/03\/z.webbullet_endof.png\" alt=\"\" width=\"27\" height=\"27\" \/><\/p>\n<p><strong>Any drawbacks?<\/strong><\/p>\n<p>Sure&#8230; Due to complexity of comprehending <em>&#8220;a set of <strong>non-linearly<\/strong> linked time dependent <strong>linear<\/strong> nodes&#8221;<\/em>, debugging can be a nightmare. As always, designing simplified and organized logic sets reduces potential problems. &#8211; I keep\u00a0my\u00a0logic\u00a0sets\u00a0neat and tidy \ud83d\ude09<\/p>\n<p><strong>So, what&#8217;s next?<\/strong><\/p>\n<p>Well, to be honest, since all theoretical stuff is done, I&#8217;ll switch to game content development. I am quite sure that I&#8217;ll keep on adding\/removing things to my 3-bit node graph architecture. I will keep on improving it while preserving its <strong>simplicity<\/strong>, for sure.<\/p>\n<p style=\"text-align: right; padding-left: 60px;\"><em>&#8220;It is vain to do with more what can be done with less.&#8221; &#8211; <a href=\"https:\/\/en.wikipedia.org\/wiki\/William_of_Ockham\" target=\"_blank\" rel=\"noopener\">(William of Ockham)<\/a><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Speaking of my latest video game development project, yet an another milestone achieved. &#8211; Quite a tough one, indeed! But first, please allow me to focus on some of the very basic mathematical logic definitions heavily used in software engineering, so that we can clearly understand what&#8217;s going on under the hood of a decent &hellip; <a href=\"http:\/\/mertboru.com\/?p=1616\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">3-bit Node Graph Architecture for Next-Gen Game Development<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1620,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,7],"tags":[83,81,86,88,23,38,84,89,82,44,87],"class_list":["post-1616","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-articles","category-gamedev","tag-3-bit","tag-culpa-innata","tag-flagger","tag-manager","tag-mert-boru","tag-mete-balci","tag-node-graph","tag-non-linear-coding","tag-ue4","tag-unreal-engine","tag-worker"],"_links":{"self":[{"href":"http:\/\/mertboru.com\/index.php?rest_route=\/wp\/v2\/posts\/1616","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/mertboru.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/mertboru.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/mertboru.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/mertboru.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1616"}],"version-history":[{"count":1,"href":"http:\/\/mertboru.com\/index.php?rest_route=\/wp\/v2\/posts\/1616\/revisions"}],"predecessor-version":[{"id":2760,"href":"http:\/\/mertboru.com\/index.php?rest_route=\/wp\/v2\/posts\/1616\/revisions\/2760"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/mertboru.com\/index.php?rest_route=\/wp\/v2\/media\/1620"}],"wp:attachment":[{"href":"http:\/\/mertboru.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1616"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/mertboru.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1616"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/mertboru.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1616"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}