{"id":390,"date":"2018-02-16T21:32:06","date_gmt":"2018-02-16T21:32:06","guid":{"rendered":"http:\/\/cppdepend.com\/blog\/?p=390"},"modified":"2023-05-31T16:43:19","modified_gmt":"2023-05-31T16:43:19","slug":"comparing-quake3-original-and-kenny-edition-codebases","status":"publish","type":"post","link":"https:\/\/cppdepend.com\/blog\/comparing-quake3-original-and-kenny-edition-codebases\/","title":{"rendered":"Comparing Quake3 Original and Kenny Edition Codebases"},"content":{"rendered":"<p>Quake III Arena is a multiplayer-focused first-person shooter video game released in December 1999. The game was developed by id Software. Quake III was a very popular game and even now it\u2019s still popular and many gamers enjoy with it.<\/p>\n<p>The original source code of Quake3 can be found\u00a0<a href=\"https:\/\/github.com\/id-Software\/Quake-III-Arena\">here<\/a>\u00a0.<span id=\"more-96\"><\/span><\/p>\n<p>Artem Kharytoniuk decide to create it\u2019s own\u00a0<a href=\"https:\/\/github.com\/kennyalive\/Quake-III-Arena-Kenny-Edition\">version<\/a>\u00a0 and his goal is described in it\u2019s repo:<\/p>\n<p><em>This repository contains updated version of the original Q3 codebase with reorganized code structure, compatibility fixes, build setup for the latest Visual Studio and modifications that update the core tech but preserve original gameplay, look and feel.<\/em><!--more--><\/p>\n<p>Let\u2019s compare the source code of the two projects\u00a0\u00a0and discover what improvements were\u00a0down in the Kenny edition version.<\/p>\n<p><strong>The whole picture<\/strong><\/p>\n<p>Here\u2019s a summary of some metrics of the original code<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-108\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake4.png\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake4.png 767w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake4-300x189.png 300w\" alt=\"quake4\" width=\"767\" height=\"483\" \/><\/p>\n<p>And here\u2019s the summary of\u00a0the modified version<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-101\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake1.png\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake1.png 769w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake1-300x188.png 300w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake1-768x481.png 768w\" alt=\"quake1\" width=\"769\" height=\"482\" \/><\/p>\n<p>Here are some remarks after comparing their summaries:<\/p>\n<ul>\n<li>Less code in the modified version.<\/li>\n<li>Less types, methods and variables.<\/li>\n<li>Rating and debt very similar for the whole solution.<\/li>\n<li>Similar method complexity.<\/li>\n<\/ul>\n<p>Let\u2019s discover these metrics for each project:<\/p>\n<p>The original code<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-106\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake2-2.png\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake2-2.png 613w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake2-2-300x183.png 300w\" alt=\"quake2\" width=\"613\" height=\"374\" \/><\/p>\n<p>And for the modified code<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-105\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake3.png\" sizes=\"auto, (max-width: 582px) 85vw, 582px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake3.png 582w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake3-300x203.png 300w\" alt=\"quake3\" width=\"582\" height=\"393\" \/><\/p>\n<p>Let\u2019s go further and compare deeply the differences between the two versions.<\/p>\n<p><strong>Modularity<\/strong><\/p>\n<p>Modularity is a software design technique that increases the extent to which software is composed from separate parts , you can manage and maintain modular code easily.<\/p>\n<p>For procedural language like C \u00a0where no logical artifacts like namespace, component or class does not exist, we can modularize by using directories and files.<\/p>\n<p>In the modified version, there are some refactoring concerning the folders structure. here\u2019s an example of the refactoring where the folders related to the engine are isolated in the engine directory.<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-109\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake5.png\" sizes=\"auto, (max-width: 400px) 85vw, 400px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake5.png 400w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake5-300x150.png 300w\" alt=\"quake5\" width=\"400\" height=\"200\" \/><\/p>\n<p><strong>Encapsulation<\/strong><\/p>\n<p>Encapsulation \u00a0is the hiding of functions and data which are internal to an implementation. \u00a0In C, encapsulation is performed by using the keyword static . These entities are called file-scope functions and variables.<\/p>\n<p>Let\u2019s search for all static functions for the original code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-110\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake6.png\" sizes=\"auto, (max-width: 500px) 85vw, 500px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake6.png 500w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake6-300x229.png 300w\" alt=\"quake6\" width=\"500\" height=\"382\" \/><\/p>\n<p>Many methods are declared as static to enforce the encapsulation. However there are many other ones not declared as static.<\/p>\n<p>We can use the Metric view to\u00a0have a good idea how many functions are static. In the Metric View, the code base is represented through a Treemap. Treemapping is a method for displaying tree-structured data by using nested rectangles. The tree structure used in a CppDepend treemap is the usual code hierarchy:<\/p>\n<ul>\n<li>Projects contains directories.<\/li>\n<li>Directories\u00a0contains files.<\/li>\n<li>Files\u00a0contains struects, functions\u00a0and variables.<\/li>\n<\/ul>\n<p>The treemap view provides a useful way to represent the result of a CQLinq request, so we can visually see the types concerned by the request.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"\" src=\"http:\/\/cppdepend.com\/img\/quake7.png\" alt=\"quake7\" width=\"729\" height=\"395\" \/><\/p>\n<p>As we can observe almost all the functions from renderer and cgame projects are declared as static, which is not the case for the other projects where only few functions are declared as static.<\/p>\n<p>Did the modified version enforce the encapsulation?<\/p>\n<p>Here\u2019s the CQLinq result of the static functions query:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-113\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake8.png\" sizes=\"auto, (max-width: 423px) 85vw, 423px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake8.png 423w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake8-300x276.png 300w\" alt=\"quake8\" width=\"423\" height=\"389\" \/><\/p>\n<p>There are less static functions than the original code, mainly because many functions were removed due to the refactoring, and this new version does not enforce more than the original one the encapsulation.<\/p>\n<p><strong>Usage of structs to store the data model<\/strong><\/p>\n<p>In C programing the functions uses variables to acheive their treatments, theses variables could be:<\/p>\n<ul>\n<li>Static variables.<\/li>\n<li>Global variables.<\/li>\n<li>Local variables<\/li>\n<li>Variables from structs.<\/li>\n<\/ul>\n<p>Each project has it\u2019s data model which could be used by many source files, using global variables is a solution but not the good one, using structs to group data is more recommended.<\/p>\n<p>Let\u2019s search for global variables with a primitive type:<a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/linux4.png\"><br \/>\n<\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-118\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake11.png\" sizes=\"auto, (max-width: 393px) 85vw, 393px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake11.png 393w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake11-222x300.png 222w\" alt=\"quake11\" width=\"393\" height=\"531\" \/><\/p>\n<p>Only 166 variables from 9084 fields could be refactored to make them const, static or embed them in a struct.<\/p>\n<p>And here\u2019s the same quey for the modified code<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-119\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake12.png\" sizes=\"auto, (max-width: 395px) 85vw, 395px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake12.png 395w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake12-191x300.png 191w\" alt=\"quake12\" width=\"395\" height=\"620\" \/><\/p>\n<p>few new global variables candidate to be refactored are added to the new code. For that we can search for the primitive global variables , not static , not const and not changed in the source code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-133\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake22.png\" sizes=\"auto, (max-width: 476px) 85vw, 476px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake22.png 476w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake22-239x300.png 239w\" alt=\"quake22\" width=\"476\" height=\"597\" \/><\/p>\n<p>some of them like \u00a0multi_texture_add_frag_spv_size or multi_texture_clipping_plane_vert_spv_size \u00a0added in the code could be declared as const.<\/p>\n<p><strong>Code Smells in two projects<\/strong><\/p>\n<p><em>Types with too many fields<\/em><\/p>\n<p>Let\u2019s search for structs with more than 30 fields:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-122\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake13.png\" sizes=\"auto, (max-width: 396px) 85vw, 396px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake13.png 396w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake13-206x300.png 206w\" alt=\"quake13\" width=\"396\" height=\"578\" \/><\/p>\n<p>And here\u2019s the result for the modified version<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-123\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake14.png\" sizes=\"auto, (max-width: 397px) 85vw, 397px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake14.png 397w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake14-197x300.png 197w\" alt=\"quake14\" width=\"397\" height=\"604\" \/><\/p>\n<p>Some big structs were refactored, for example the number of fields of cgMedia_t passed 258 from to 199 fields.<\/p>\n<p><em>Too big functions<\/em><\/p>\n<p>Here\u2019s from the\u00a0<a href=\"https:\/\/www.kernel.org\/doc\/Documentation\/CodingStyle\">linux coding style web page<\/a>, an\u00a0advice about the length of functions:<\/p>\n<pre>Functions should be short and sweet, and do just one thing.  They should\r\nfit on one or two screenfuls of text (the ISO\/ANSI screen size is 80x24,\r\nas we all know), and do one thing and do that well.\r\n\r\nThe maximum length of a function is inversely proportional to the\r\ncomplexity and indentation level of that function.  So, if you have a\r\nconceptually simple function that is just one long (but simple)\r\ncase-statement, where you have to do lots of small things for a lot of\r\ndifferent cases, it's OK to have a longer function.<\/pre>\n<p>Let\u2019s search for functions where the number of lines of code is more than 50 for the original code:<a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/linux14.png\"><br \/>\n<\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-135\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake23.png\" sizes=\"auto, (max-width: 392px) 85vw, 392px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake23.png 392w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake23-188x300.png 188w\" alt=\"quake23\" width=\"392\" height=\"624\" \/><\/p>\n<p>And here\u2019s the same result for the modified version:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-126\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake16.png\" sizes=\"auto, (max-width: 400px) 85vw, 400px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake16.png 400w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake16-199x300.png 199w\" alt=\"quake16\" width=\"400\" height=\"603\" \/><\/p>\n<p>Many big functions are gone, some of them are completly removed and the other ones are refactored.<\/p>\n<p><em>Functions with too many parameters<\/em><\/p>\n<p>Functions\u00a0where NbParameters &gt; 8\u00a0might be painful to call \u00a0and might degrade performance. Another alternative is to provide \u00a0a structure dedicated to handle arguments passing.<a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/linux7.png\"><br \/>\n<\/a><\/p>\n<p>Here are the functions concerned for the original code<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-128\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake18.png\" sizes=\"auto, (max-width: 390px) 85vw, 390px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake18.png 390w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake18-183x300.png 183w\" alt=\"quake18\" width=\"390\" height=\"641\" \/><\/p>\n<p>And here\u2019s the result for the modified version:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-127\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake17.png\" sizes=\"auto, (max-width: 398px) 85vw, 398px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake17.png 398w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake17-199x300.png 199w\" alt=\"quake17\" width=\"398\" height=\"601\" \/><\/p>\n<p>only very few functions has more than 8 parameters in both versions.<\/p>\n<p><em>Functions with too many \u00a0local variables<\/em><\/p>\n<p>Methods where NbVariables is higher than 8\u00a0are hard to understand and maintain. Methods where NbVariables is higher than 15 are extremely complex and should be split in smaller methods (except if they are automatically generated by a tool)<a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/linux9.png\"><br \/>\n<\/a><\/p>\n<p>Here\u2019s the result for the original code:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-129\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake20.png\" sizes=\"auto, (max-width: 398px) 85vw, 398px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake20.png 398w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake20-190x300.png 190w\" alt=\"quake20\" width=\"398\" height=\"627\" \/><\/p>\n<p>And the result for the modified one<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-130\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake21.png\" sizes=\"auto, (max-width: 398px) 85vw, 398px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake21.png 398w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake21-192x300.png 192w\" alt=\"quake21\" width=\"398\" height=\"622\" \/><\/p>\n<p>Some added functions in the new modified version have more thann 15 variables, vk_initialize() is an added function with 73 ariables.<\/p>\n<p><strong>Functions too complex<\/strong><\/p>\n<p>Many metrics exist to detect complex functions, NBLinesOfCode,Number of parameters and number of local variables are the basic ones.<\/p>\n<p>There are other interesting metrics to detect complex functions:<\/p>\n<ul>\n<li>Cyclomatic complexity is a popular procedural software metric equal to the number of decisions that can be taken in a procedure.<\/li>\n<li>Nesting Depth\u00a0is a metric defined on methods that is relative to the maximum depth\u00a0of the more nested scope in a method body.<\/li>\n<li>Max Nested loop is\u00a0equals the maximum level of loop nesting in a function.<\/li>\n<\/ul>\n<p>The max value tolerated for these metrics depends more on the team choices, there\u2019s no standard values.<\/p>\n<p>Let\u2019s search for functions candidate to be refactored for the original code:<a href=\"http:\/\/www.codergears.com\/Blog\/wp-content\/uploads\/linux8.png\"><br \/>\n<\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-137\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake24.png\" sizes=\"auto, (max-width: 464px) 85vw, 464px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake24.png 464w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake24-224x300.png 224w\" alt=\"quake24\" width=\"464\" height=\"622\" \/><\/p>\n<p>And the modified one:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138\" src=\"http:\/\/cppdepend.com\/wordpress\/wp-content\/uploads\/2017\/06\/quake25.png\" sizes=\"auto, (max-width: 475px) 85vw, 475px\" srcset=\"https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake25.png 475w, https:\/\/cppdepend.com\/blog\/wp-content\/uploads\/2017\/06\/quake25-229x300.png 229w\" alt=\"quake25\" width=\"475\" height=\"621\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>We can observe that many complex functions are removed or refactored.<\/p>\n<p><strong>\u00a0Conclusion<\/strong><\/p>\n<p>The original source code of Quake III is well implemented, few code smells are detected. However a big clean was introduced in the modified version where many functions and variables were removed, some structs are refactored and the physical structure a little changed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quake III Arena is a multiplayer-focused first-person shooter video game released in December 1999. The game was developed by id Software. Quake III was a very popular game and even now it\u2019s still popular and many gamers enjoy with it. The original source code of Quake3 can be found\u00a0here\u00a0. Artem Kharytoniuk decide to create it\u2019s &hellip; <a href=\"https:\/\/cppdepend.com\/blog\/comparing-quake3-original-and-kenny-edition-codebases\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Comparing Quake3 Original and Kenny Edition Codebases&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[7,212,24],"class_list":["post-390","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-c","tag-kenny-edition","tag-quake"],"_links":{"self":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/390","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/comments?post=390"}],"version-history":[{"count":5,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/390\/revisions"}],"predecessor-version":[{"id":1502,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/390\/revisions\/1502"}],"wp:attachment":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/media?parent=390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/categories?post=390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/tags?post=390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}