{"id":28,"date":"2024-10-18T14:00:29","date_gmt":"2024-10-18T14:00:29","guid":{"rendered":"https:\/\/sites.wsagames.com\/pe1n23\/?p=28"},"modified":"2025-02-20T11:01:34","modified_gmt":"2025-02-20T11:01:34","slug":"godot-experiments-and-initial-game-concepts","status":"publish","type":"post","link":"https:\/\/sites.wsagames.com\/pe1n23\/godot-experiments-and-initial-game-concepts\/","title":{"rendered":"Godot Experiments and Initial Game Concepts"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">As some development practice on the side I have also been working in Godot, and was inspired to make a roll-a-ball game similar to Hamsterball or Marble Blast. At first this was as simple as creating a Rigidbody3D node for the player, and attaching a sphere mesh and spherical collision shape to it. I also threw on a texture of a billiard ball, both for fun as well as to give me some visual context as to how fast the ball will be rolling.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"854\" src=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-1024x854.png\" alt=\"\" class=\"wp-image-29\" style=\"width:653px;height:auto\" srcset=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-1024x854.png 1024w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-300x250.png 300w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-768x641.png 768w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image.png 1308w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">I then had to create a camera that would orbit around the ball with what is known as a &#8220;gimbal&#8221; movement. Rather than manually setting the camera&#8217;s position, I instead created an empty node as a child of the player that would automatically follow above the player. I would then attach the camera as a child of that at a certain offset away from the ball. The rotation of the parent node according to the camera can then be done at the centre, and the offset of the camera (i.e how &#8220;zoomed out&#8221; it is) can be set to whatever I want on the fly.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img decoding=\"async\" width=\"1013\" height=\"638\" src=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-1.png\" alt=\"\" class=\"wp-image-30\" style=\"width:672px;height:auto\" srcset=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-1.png 1013w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-1-300x189.png 300w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-1-768x484.png 768w\" sizes=\"(max-width: 1013px) 100vw, 1013px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">I also attached a &#8220;spring arm&#8221; to the camera, meaning it will move closer to the player if colliding with a wall or floor, preventing the camera from clipping inside of them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now that the nodes were added I had to add some code to rotate the camera&#8217;s origin node according to movement of the mouse. I am using GDScript for this project, as I do not need the performance and data management-related benefits of C# for a simple game concept like this so far. I first added a script to the player with the following code to let the camera &#8220;orbit&#8221; around the player.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" width=\"739\" height=\"292\" src=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-4.png\" alt=\"\" class=\"wp-image-579\" srcset=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-4.png 739w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-4-300x119.png 300w\" sizes=\"(max-width: 739px) 100vw, 739px\" \/><figcaption class=\"wp-element-caption\">At first camera rotation was broken and leading to incorrect rotations, however rotating the pivot in local transform with the rotate_object_local() method seems to fix this.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Then came adding code to make the player move. In <a href=\"https:\/\/sites.wsagames.com\/pe1n23\/game-research-review-marble-blast-ultra\/\" data-type=\"post\" data-id=\"40\">Marble Blast Ultra<\/a> the player&#8217;s marble rolls to move in a snappy fashion, but also has some control in the air from a direct force pushing it. To recreate I find the intended direction the player wants to travel in by getting the rotation of the camera &amp; multiplying it by the input direction, so a &#8220;forwards&#8221; input will always be straight ahead for the ball from where the player is facing.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"924\" height=\"69\" src=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-8.png\" alt=\"\" class=\"wp-image-584\" srcset=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-8.png 924w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-8-300x22.png 300w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-8-768x57.png 768w\" sizes=\"(max-width: 924px) 100vw, 924px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Then I apply a force in that direction, and add angular velocity for the &#8220;rolling&#8221; effect.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"724\" height=\"65\" src=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-9.png\" alt=\"\" class=\"wp-image-585\" srcset=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-9.png 724w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-9-300x27.png 300w\" sizes=\"(max-width: 724px) 100vw, 724px\" \/><figcaption class=\"wp-element-caption\">The cross function gets the vector pointing out the left side of the ball from where the camera faces. This is required as that&#8217;s just how angular velocity works.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now I can roll the ball around just fine! However the ball does feel somewhat &#8220;slippy&#8221;, and simply increasing the friction could lead to unintended results like being able to roll up walls. I solved this problem by checking if the intended direction is opposite (or near enough to it) to the velocity the ball is going in, we slow the ball down quickly so it can switch directions in a much snappier fashion. It only does this when the ball is grounded to simulate &#8220;grip&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"553\" height=\"74\" src=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-11.png\" alt=\"\" class=\"wp-image-587\" srcset=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-11.png 553w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-11-300x40.png 300w\" sizes=\"(max-width: 553px) 100vw, 553px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This works! The movement feels really responsive now.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"586\" src=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-12-1024x586.png\" alt=\"\" class=\"wp-image-589\" srcset=\"https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-12-1024x586.png 1024w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-12-300x172.png 300w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-12-768x439.png 768w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-12-1536x879.png 1536w, https:\/\/sites.wsagames.com\/pe1n23\/wp-content\/uploads\/sites\/10\/2024\/10\/image-12.png 1699w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Also I made it look prettier. I&#8217;d be giving Godot a bad rep otherwise.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">After making this basic concept, I was inspired to expand on this concept and have my game for this assignment be a <strong>physics based game<\/strong>, with a <strong>rolling mechanic <\/strong>as the primary method of traversal. However, I may not have the player always control a perfectly spherical ball, and therefore I will continue to use the angular velocity method to allow objects of any shape to be able to roll.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As some development practice on the side I have also been working in Godot, and was inspired to make a roll-a-ball game similar to Hamsterball or Marble Blast. At first this was as simple as creating a Rigidbody3D node for the player, and attaching a sphere mesh and spherical collision shape to it. I also [&hellip;]<\/p>\n","protected":false},"author":11,"featured_media":589,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,17,28],"tags":[15,11],"class_list":["post-28","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development","category-research","category-semester-1","tag-gameplay","tag-gamedev"],"_links":{"self":[{"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/posts\/28","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/comments?post=28"}],"version-history":[{"count":8,"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/posts\/28\/revisions"}],"predecessor-version":[{"id":592,"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/posts\/28\/revisions\/592"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/media\/589"}],"wp:attachment":[{"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/media?parent=28"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/categories?post=28"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sites.wsagames.com\/pe1n23\/wp-json\/wp\/v2\/tags?post=28"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}