{"id":937,"date":"2024-10-14T00:37:37","date_gmt":"2024-10-14T00:37:37","guid":{"rendered":"https:\/\/abdoubouam.com\/?p=937"},"modified":"2024-10-14T00:37:37","modified_gmt":"2024-10-14T00:37:37","slug":"devlog-week-42-43","status":"publish","type":"post","link":"https:\/\/abdoubouam.com\/index.php\/2024\/10\/14\/devlog-week-42-43\/","title":{"rendered":"Devlog Week 42-43"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Bevel baker<\/h2>\n\n\n\n<p>I made a one-click bevel baking tool for Blender. It will be useful for models that don&#8217;t have a highpoly version. I made it by modifying one of my addons (Grungit).<br>I didn&#8217;t test it extensively yet, that will happen when I actually start using it<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/bevel_baker.mp4\"><\/video><figcaption class=\"wp-element-caption\">Bevel Baker<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Robot Head 2<\/h2>\n\n\n\n<p>I made another robot head for adverts and posters and other stuff in the game. I made it very futuristic and flashy compared to the normal model.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure data-wp-context=\"{&quot;uploadedSrc&quot;:&quot;https:\\\/\\\/abdoubouam.com\\\/wp-content\\\/uploads\\\/2024\\\/10\\\/architect.jpg&quot;,&quot;figureClassNames&quot;:&quot;aligncenter size-full&quot;,&quot;figureStyles&quot;:null,&quot;imgClassNames&quot;:&quot;wp-image-924&quot;,&quot;imgStyles&quot;:null,&quot;targetWidth&quot;:1172,&quot;targetHeight&quot;:1401,&quot;scaleAttr&quot;:false,&quot;ariaLabel&quot;:&quot;Enlarge image&quot;,&quot;alt&quot;:&quot;&quot;}\" data-wp-interactive=\"core\/image\" class=\"aligncenter size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1172\" height=\"1401\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/architect.jpg\" alt=\"\" class=\"wp-image-924\" srcset=\"https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/architect.jpg 1172w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/architect-251x300.jpg 251w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/architect-768x918.jpg 768w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/architect-1000x1195.jpg 1000w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/architect-230x275.jpg 230w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/architect-350x418.jpg 350w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/architect-480x574.jpg 480w\" sizes=\"(max-width: 1172px) 100vw, 1172px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge image\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"context.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"context.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Robot Head<\/figcaption><\/figure><\/div>\n\n\n<p>The design was accidental, because I was sculpting and I didn&#8217;t like the way it looked, but then I noticed the shape is diagonally symmetrical, so I thought about rotating it. I was very satisfied with the result.<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/head_sculpt.mp4\"><\/video><figcaption class=\"wp-element-caption\">Happy Little Accident<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Sound Visualization<\/h2>\n\n\n\n<p>I thought about making some pre-rendered videos of the robot above talking, so I needed a visual for the sound. <\/p>\n\n\n\n<p>I began by importing the sound into Audacity and changing the from the default waveform visualization into a spectrogram visualization. I made sure it&#8217;s the black and white color scheme.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure data-wp-context=\"{&quot;uploadedSrc&quot;:&quot;https:\\\/\\\/abdoubouam.com\\\/wp-content\\\/uploads\\\/2024\\\/10\\\/spectrogram.png&quot;,&quot;figureClassNames&quot;:&quot;aligncenter size-full&quot;,&quot;figureStyles&quot;:null,&quot;imgClassNames&quot;:&quot;wp-image-938&quot;,&quot;imgStyles&quot;:null,&quot;targetWidth&quot;:1600,&quot;targetHeight&quot;:531,&quot;scaleAttr&quot;:false,&quot;ariaLabel&quot;:&quot;Enlarge image&quot;,&quot;alt&quot;:&quot;&quot;}\" data-wp-interactive=\"core\/image\" class=\"aligncenter size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1600\" height=\"531\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram.png\" alt=\"\" class=\"wp-image-938\" srcset=\"https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram.png 1600w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram-300x100.png 300w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram-768x255.png 768w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram-1536x510.png 1536w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram-1000x332.png 1000w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram-230x76.png 230w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram-350x116.png 350w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/spectrogram-480x159.png 480w\" sizes=\"(max-width: 1600px) 100vw, 1600px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge image\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"context.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"context.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><figcaption class=\"wp-element-caption\">Spectrogram in Audacity<\/figcaption><\/figure><\/div>\n\n\n<p>The spectrogram shows the frequency on the Y axis, time on the X axis, and the brightness says how &#8220;loud&#8221; that frequency is.<br>That means we can import it as a texture and use the information as a displacement texture in Blender or any other 3D modelling software. The only requirement is to make the texture (or UVs) scroll from left to right, and align them properly. Here&#8217;s a timelapse of the process below.<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/process.mp4\"><\/video><figcaption class=\"wp-element-caption\">Sound Visualization in Blender<\/figcaption><\/figure>\n\n\n\n<p>At first it looked too fast and chaotic, so I applied some linear blur on the spectrogram to make the movement more smooth. If the blur is too strong, you lose a lot of detail, but if it&#8217;s too small the movement remains chaotic. I found a compromise by blending a non-blurred version with a slightly blurred version to get the best of both worlds (bottom-right).<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/viz.mp4\"><\/video><figcaption class=\"wp-element-caption\">Smoothed Motion. Music : Mortals by Warriyo<\/figcaption><\/figure>\n\n\n\n<p>Of course this is not the only way you could use the spectrogram, you can make the bars circular, only change materials, change size&#8230;etc.<br>In my case I used 5 circles, going from the lowest to highest frequency (bottom to top). Instead of using the spectrogram directly as displacement, I used it to control the strength of a moving noise texture, so if there&#8217;s no bass the circle that corresponds to bass stays perfectly circular. Likewise, if there&#8217;s bass, it gets distorted. I used Geometry Nodes for this, and also a material setup to change the color from blue to green when it&#8217;s loud. I rendered that to an MP4 and applied it as a texture on the robot screen, the result is in the video below (the audio is <em>slightly <\/em>misaligned)<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/sound_viz.mp4\"><\/video><figcaption class=\"wp-element-caption\">Sound Visualization<\/figcaption><\/figure>\n\n\n\n<p>As a bonus, I achieved the &#8220;radio&#8221; effect by adding some white noise, then applied Tremolo with 500hz and 20% and finally reduced the sample rate to 8000hz. I could also export the sound at a very low bitrate then reimport it before the tremolo and reducing sample rate for a more &#8220;crunched&#8221; sound.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Animations and movement<\/h2>\n\n\n\n<p>I made some rough animations for the robot model and completely deleted the Manny\/Quinn skeletons and models and animations, to start again from scratch, because I&#8217;m not going to understand something if I just use already-made systems. It honestly wasn&#8217;t as hard as I thought! I still didn&#8217;t get to state machines, but I figured out the animation and export workflow from Blender to UE, and how to blend animations and trigger them.<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/movement.mp4\"><\/video><figcaption class=\"wp-element-caption\">Character animations (draft)<\/figcaption><\/figure>\n\n\n\n<p>I tried to rig the character in Unreal, but I gave up for now. I&#8217;ll come back to it after I understand the animation system better.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Cutscenes<\/h2>\n\n\n\n<p>Another thing I figured out this week was the cutscene workflow, and how to integrate it with my interaction system (ie. trigger a cutscene when you interact with someone or something). I also found out you can trigger custom blueprint events from the timeline, which is certainly handy!<br>Below is a test scenario with a cutscene interaction.<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/cutscenes.mp4\"><\/video><figcaption class=\"wp-element-caption\">Cutscene interaction<\/figcaption><\/figure>\n\n\n\n<p>Here&#8217;s how wonky the animations are. I&#8217;m not an animator, and on top of that I spent less than 10 minutes on these two animations, so it&#8217;s extra bad. I was actually surprised I could salvage them at all with camera tricks. Notice how I&#8217;m just swapping the materials of the player and NPC, and not actually doing a real swap.<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/behind_cutscene.mp4\"><\/video><figcaption class=\"wp-element-caption\">Behind the scenes<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Save-load system<\/h2>\n\n\n\n<p>I finally got around making a save and load system. I was initially only going to make a simple proof-of-concept that saves the player&#8217;s position, but then I found it very easy to do and I extended it to also be part of the interaction component. By default, the interaction component doesn&#8217;t do saves, but if I set the save type to &#8220;basic&#8221; it will store its current position in the dialog, and if I set it to &#8220;full&#8221; it will also include the world transforms and current AI state (idle, patrol, random movement, inactive, talking&#8230;etc. Currently just a draft and not implemented). Each time an interaction ends, if the NPC or Object has the save flag, a save function will be called. In the future I will make a manager that takes care of it, especially to do asynchronous saving and loading safely without worrying about one save call overwriting another one that started at the same time.<\/p>\n\n\n\n<p>The system is seamless and autosaves whenever you interact with an NPC that has basic\/full saves turned on.<\/p>\n\n\n\n<p>Here is a full demo. It stores the NPC position, as well as some important objects, like open\/closed doors and gates. It&#8217;s a bit long and repetitive though, so you don&#8217;t have to watch everything. (The character didn&#8217;t have animations yet)<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save_full.mp4\"><\/video><figcaption class=\"wp-element-caption\">Save system demo<\/figcaption><\/figure>\n\n\n\n<p>I also took care of making the code readable. It does take a little bit more time, but it&#8217;s satisfying.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"713\" src=\"http:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-1920x713.jpg\" alt=\"\" class=\"wp-image-925\" srcset=\"https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-1920x713.jpg 1920w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-300x111.jpg 300w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-768x285.jpg 768w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-1536x570.jpg 1536w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-2048x761.jpg 2048w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-1000x371.jpg 1000w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-230x85.jpg 230w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-350x130.jpg 350w, https:\/\/abdoubouam.com\/wp-content\/uploads\/2024\/10\/save-480x178.jpg 480w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><figcaption class=\"wp-element-caption\">Clean code<\/figcaption><\/figure><\/div>\n\n\n<p>The performance is acceptable so far. It takes about 10ms on the steamdeck to save a file that has 1000 entries (the game will normally have 100 at most). This causes a stutter for a very short, almost unnoticeable time. It happens when the interaction ends and UI unloads and camera resets, so it&#8217;s almost unnoticeable.<\/p>\n\n\n\n<p>Additionally I read some documentation and watched videos about game design and related, and played Animal Well (very impressive btw, I highly recommend it!). I&#8217;m also busy with some paperwork on the side for a trip I&#8217;m preparing in the next few weeks. That&#8217;s about it for this devlog, thanks for reading!<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bevel baker I made a one-click bevel baking tool for Blender. It will be useful for models that don&#8217;t have a highpoly version. I made it by modifying one of my addons (Grungit).I didn&#8217;t test it extensively yet, that will happen when I actually start using it Robot Head 2 I made another robot head for adverts and posters and other stuff in the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":941,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/posts\/937"}],"collection":[{"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/comments?post=937"}],"version-history":[{"count":3,"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/posts\/937\/revisions"}],"predecessor-version":[{"id":942,"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/posts\/937\/revisions\/942"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/media\/941"}],"wp:attachment":[{"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/media?parent=937"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/categories?post=937"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/abdoubouam.com\/index.php\/wp-json\/wp\/v2\/tags?post=937"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}