<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Ivan Arellano Maurizi]]></title><description><![CDATA[Programming and Games]]></description><link>https://ivanarellano.com/</link><image><url>https://ivanarellano.com/favicon.png</url><title>Ivan Arellano Maurizi</title><link>https://ivanarellano.com/</link></image><generator>Ghost 6.72</generator><lastBuildDate>Sun, 25 Oct 2026 13:48:49 GMT</lastBuildDate><atom:link href="https://ivanarellano.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Bubble Battle]]></title><description><![CDATA[<p><a href="https://globalgamejam.org/games/2025/bubble-battle-0-0?ref=ivanarellano.com">Download the Mac game and source code here</a>!</p><p>My first Global Game Jam went without a hitch! Completing a game within 48 hours is a feat on its own. What if it&apos;s with people you just met in the room? Oh. Also, what if the game should fit</p>]]></description><link>https://ivanarellano.com/bubble-battle/</link><guid isPermaLink="false">67be220454b7b60001f617cb</guid><category><![CDATA[game-jam]]></category><dc:creator><![CDATA[Ivan Arellano Maurizi]]></dc:creator><pubDate>Tue, 25 Feb 2025 20:47:22 GMT</pubDate><media:content url="https://ivanarellano.com/content/images/2025/02/Screenshot-2025-01-27-230055-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://ivanarellano.com/content/images/2025/02/Screenshot-2025-01-27-230055-1.png" alt="Bubble Battle"><p><a href="https://globalgamejam.org/games/2025/bubble-battle-0-0?ref=ivanarellano.com">Download the Mac game and source code here</a>!</p><p>My first Global Game Jam went without a hitch! Completing a game within 48 hours is a feat on its own. What if it&apos;s with people you just met in the room? Oh. Also, what if the game should fit a theme that&apos;s revealed minutes before you find your team? We did all of that!</p><p>The internet, and <a href="https://globalgamejam.org/jammer-resources?ref=ivanarellano.com">even the official GGJ website</a>, has many articles about becoming a jammer, so I won&apos;t go into that. Instead, I&apos;m briefly offering my perspective as a seasoned engineer on my first time as a jammer.</p><h2 id="the-ggj"><strong>The GGJ</strong></h2><figure class="kg-card kg-image-card"><img src="https://ivanarellano.com/content/images/2025/02/bb-intro-day.jpg" class="kg-image" alt="Bubble Battle" loading="lazy" width="2000" height="1500" srcset="https://ivanarellano.com/content/images/size/w600/2025/02/bb-intro-day.jpg 600w, https://ivanarellano.com/content/images/size/w1000/2025/02/bb-intro-day.jpg 1000w, https://ivanarellano.com/content/images/size/w1600/2025/02/bb-intro-day.jpg 1600w, https://ivanarellano.com/content/images/2025/02/bb-intro-day.jpg 2000w" sizes="(min-width: 720px) 720px"></figure><p>George Mason University gave us a grand start to the festivities with this theme reveal video! At this point in the night, I was concerned about finding a team to help me make a &quot;Bubble&quot; themed game. Is it standard practice at game jams to put color-coded stickers, i.e. red for programmers, on your name tag? That helped me spot artists and programmers. A complete surprise to me was that the people who I sat next to all became my teammates after the theme reveal. We exchanged game ideas and it just worked out that way.</p><p>The first night went by faster than I imagined. Most of us simply got the tools needed for the rest of the game jam and went home. The next day was an exhilarating whirlwind of collaboration, progress, and coffee trips. The last day easily won as the most stressful day of the event, but it was worth it. We had a finished, polished game! The work that could be done after submission was correctly delegated into the &quot;Wish List&quot; column.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://ivanarellano.com/content/images/2025/02/bb-group-shot-1.jpg" class="kg-image" alt="Bubble Battle" loading="lazy" width="2000" height="1126" srcset="https://ivanarellano.com/content/images/size/w600/2025/02/bb-group-shot-1.jpg 600w, https://ivanarellano.com/content/images/size/w1000/2025/02/bb-group-shot-1.jpg 1000w, https://ivanarellano.com/content/images/size/w1600/2025/02/bb-group-shot-1.jpg 1600w, https://ivanarellano.com/content/images/2025/02/bb-group-shot-1.jpg 2048w" sizes="(min-width: 720px) 720px"><figcaption>Minus a sixth member.</figcaption></figure><h3 id="on-ai">On AI</h3><p>Something I quickly noticed during development was how much my teammates got done using AI-generated code. Now, I have been critical of AI in the past, mostly due to how AI &quot;creativity&quot; is trained on images it finds on the internet, but I&apos;ve been lax on generated code because it&apos;s easier for AI to show attribution for text. I have used AI for some professional work but it&apos;s safe to say that I&apos;m a late adopter.</p><p>That being said, AI and game jams go together like peanut butter and jelly. It&apos;s the right kind of code for a 2-day project with a presentation to make. We used AI to allow us to make a larger game than what we might have attempted without it. Yes, some game jams don&apos;t allow it, but the GGJ does. My takeaway is to learn to freely use AI to help scaffold ideas. For game jams the scaffolding is the final product, so let the AI rip.</p><h2 id="post-ggj-fixing-the-bomb"><strong>Post-GGJ: &quot;Fixing&quot; the bomb</strong></h2><p>In Bubble Battle&apos;s gameplay, a known issue with the bomb happens when you fire it while facing towards the right. The bomb should explode but it will look like it implodes. Huh? While this looks cool it wasn&apos;t what the team had expected.</p><figure class="kg-card kg-video-card kg-width-regular kg-card-hascaption" data-kg-thumbnail="https://ivanarellano.com/content/media/2025/02/bad_angle-bad_parent_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://ivanarellano.com/content/media/2025/02/bad_angle-bad_parent.mp4" poster="https://ivanarellano.com/content/media/2025/02/bad_angle-bad_parent_thumb.jpg" width="1920" height="1080" playsinline preload="metadata" controls></video>
                
                
            </div>
            <figcaption>Projectiles swirl differently based on the heading.</figcaption>
        </figure><p>I tackled this problem by simplifying it to gain clarity. I like to think of this as if I&apos;m running a binary search for the issue. I find code that, when removed, doesn&apos;t affect the problem I&apos;m seeing and by repeating that process eventually all that&apos;s left is problematic code.</p><p>In this issue, I noticed that the bomb&apos;s projectiles were inheriting unnecessary transform details from the parent like scale and rotation. There has to be a nice way to say this, but I split the parent-child relationship. After changing that the explosions stayed consistent no matter which way the player faces.</p><pre><code class="language-csharp">GameObject projectile = new GameObject(&quot;Projectile&quot;);

// From this
projectile.transform.SetParent(transform);
projectile.transform.localPosition = new Vector3(xAngle * _radius, yAngle * _radius, 0);

// To this
projectile.transform.position = new Vector3(
    xAngle * _radius + transform.position.x,
    yAngle * _radius + transform.position.y,
    0
);
</code></pre><figure class="kg-card kg-video-card kg-width-regular kg-card-hascaption" data-kg-thumbnail="https://ivanarellano.com/content/media/2025/02/bad_angle-no_parent_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://ivanarellano.com/content/media/2025/02/bad_angle-no_parent.mp4" poster="https://ivanarellano.com/content/media/2025/02/bad_angle-no_parent_thumb.jpg" width="1920" height="1080" playsinline preload="metadata" controls></video>
                
                
            </div>
            <figcaption>Projectiles without a parent.</figcaption>
        </figure><h3 id="the-ideal-version">The ideal version</h3><p>I could stop here but I wanted to know how the twisting effect worked. During the game jam I assumed it was something in Unity&apos;s physics engine affecting the velocity. Here&apos;s the effect:</p><figure class="kg-card kg-video-card kg-width-regular kg-card-hascaption" data-kg-thumbnail="https://ivanarellano.com/content/media/2025/02/0-pos_pi_div_4_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://ivanarellano.com/content/media/2025/02/0-pos_pi_div_4.mp4" poster="https://ivanarellano.com/content/media/2025/02/0-pos_pi_div_4_thumb.jpg" width="578" height="558" playsinline preload="metadata" controls></video>
                
                
            </div>
            <figcaption>Bad angle</figcaption>
        </figure><p>Aha, now I see that the projectiles start at an angle so that they move along the edges of the bomb. Slowing down the effect made that easy to spot. Here&apos;s the code that sets those angles:</p><pre><code class="language-csharp">/*   
 * Rotate the projectile using Atan2 to get the angle between the   
 * projectile and the center of the circle  
 */
float angleOffset = (float) Math.PI/4;
float angleInDegrees = (Mathf.Atan2(yAngle, xAngle) + angleOffset) * Mathf.Rad2Deg;
projectile.transform.rotation = Quaternion.Euler(0, 0, angleInDegrees);
</code></pre><p>This was so close! At the game jam I tried a few different <code>angleOffset</code> angles and stopped at <code>Math.PI/4</code> because it created that swirl effect. The angle that I intended to use was 90&#xb0;, or <code>Math.PI/2</code>. Except that didn&apos;t look correct either:</p><figure class="kg-card kg-video-card kg-width-regular kg-card-hascaption" data-kg-thumbnail="https://ivanarellano.com/content/media/2025/02/1_pi-div-2-incorrect_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://ivanarellano.com/content/media/2025/02/1_pi-div-2-incorrect.mp4" poster="https://ivanarellano.com/content/media/2025/02/1_pi-div-2-incorrect_thumb.jpg" width="1920" height="1080" playsinline preload="metadata" controls></video>
                
                
            </div>
            <figcaption>Not quite there yet</figcaption>
        </figure><p>If I flip this by 180&#xb0;, i.e. set <code>angleOffset</code> to -90&#xb0;, <code>-Math.PI/2</code>, things look better.</p><figure class="kg-card kg-video-card kg-width-regular kg-card-hascaption" data-kg-thumbnail="https://ivanarellano.com/content/media/2025/02/2_neg-pi-div-2-correct_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://ivanarellano.com/content/media/2025/02/2_neg-pi-div-2-correct.mp4" poster="https://ivanarellano.com/content/media/2025/02/2_neg-pi-div-2-correct_thumb.jpg" width="1920" height="1080" playsinline preload="metadata" controls></video>
                
                
            </div>
            <figcaption>That&apos;s it!</figcaption>
        </figure><p>Now let&apos;s see how it looks in the game with 10 projectiles.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://ivanarellano.com/content/media/2025/02/3-final-bomb_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://ivanarellano.com/content/media/2025/02/3-final-bomb.mp4" poster="https://ivanarellano.com/content/media/2025/02/3-final-bomb_thumb.jpg" width="1920" height="1080" playsinline preload="metadata" controls></video>
                
                
            </div>
            
        </figure><h2 id="future-game-jams">Future game jams</h2><p>I enjoyed the passion that everyone brought to this event. My first game jam couldn&apos;t have gone better. I went into this blind, I didn&apos;t prepare, so I know I&apos;ll have goals for the next time I attend a jam. For now, I&apos;m re-learning Unreal Engine and hope to try that out for a jam in the future. Until next time!</p><figure class="kg-card kg-image-card"><img src="https://ivanarellano.com/content/images/2025/02/ggj-group-shot.jpg" class="kg-image" alt="Bubble Battle" loading="lazy" width="2000" height="1126" srcset="https://ivanarellano.com/content/images/size/w600/2025/02/ggj-group-shot.jpg 600w, https://ivanarellano.com/content/images/size/w1000/2025/02/ggj-group-shot.jpg 1000w, https://ivanarellano.com/content/images/size/w1600/2025/02/ggj-group-shot.jpg 1600w, https://ivanarellano.com/content/images/2025/02/ggj-group-shot.jpg 2000w" sizes="(min-width: 720px) 720px"></figure>]]></content:encoded></item><item><title><![CDATA[Tree City, made with Unity]]></title><description><![CDATA[<p>Walk through Philadelphia and learn about Philadelphia&apos;s street trees.</p><p><a href="https://games.ivanarellano.com/treecity?ref=ivanarellano.com">Try the TreeCity demo</a> in your browser or <a href="https://github.com/ivanarellano/unity-tree-city?ref=ivanarellano.com">browse the source code</a> on GitHub.</p><h2 id="about">About</h2><p>This WebGL demo was made in Unity and uses Mapbox&apos;s Unity SDK. Before this demo, I had only read or heard about</p>]]></description><link>https://ivanarellano.com/tree-city/</link><guid isPermaLink="false">6764758654b7b60001f6167b</guid><category><![CDATA[portfolio]]></category><category><![CDATA[demo]]></category><dc:creator><![CDATA[Ivan Arellano Maurizi]]></dc:creator><pubDate>Fri, 22 Sep 2017 21:00:00 GMT</pubDate><media:content url="https://ivanarellano.com/content/images/2024/12/TreeCity_Shot1_lo.png" medium="image"/><content:encoded><![CDATA[<img src="https://ivanarellano.com/content/images/2024/12/TreeCity_Shot1_lo.png" alt="Tree City, made with Unity"><p>Walk through Philadelphia and learn about Philadelphia&apos;s street trees.</p><p><a href="https://games.ivanarellano.com/treecity?ref=ivanarellano.com">Try the TreeCity demo</a> in your browser or <a href="https://github.com/ivanarellano/unity-tree-city?ref=ivanarellano.com">browse the source code</a> on GitHub.</p><h2 id="about">About</h2><p>This WebGL demo was made in Unity and uses Mapbox&apos;s Unity SDK. Before this demo, I had only read or heard about GIS and didn&apos;t understand it at a deeper level other than &quot;it&apos;s about mapping.&quot; After Hurricane Harvey hit Texas, I started to learn more about how storm-based flooding becomes more prevalent with the mass removal of trees in urban areas. Out of curiosity I looked at street tree maps where I live, in Philadelphia, PA, to gauge how well gathered our data is.</p><h2 id="controls">Controls</h2><ul><li>Arrow keys or W,A,S,D keys: Walk</li><li>Left Mouse Button: View tree information on selection</li><li>Esc key: Quit demo</li><li>C key: Show controls</li></ul><h2 id="instructions">Instructions</h2><p>At the center of the screen is your aiming reticle. Walk around the city to see trees. Click on a tree to learn what kind of tree is planted there.</p>]]></content:encoded></item><item><title><![CDATA[Porsche Cayman, made with Maya]]></title><description><![CDATA[<p>This is a rendering of a 3D model I made. I gained deeper skills in Autodesk Maya while being challenged to model larger smooth surfaces. I was more experienced with starting a model using polygonal meshes, like a cube or a plane, but I didn&apos;t want to manage</p>]]></description><link>https://ivanarellano.com/porsche-cayman-3d-model/</link><guid isPermaLink="false">67646fbc54b7b60001f61618</guid><category><![CDATA[portfolio]]></category><category><![CDATA[3d]]></category><category><![CDATA[maya]]></category><dc:creator><![CDATA[Ivan Arellano Maurizi]]></dc:creator><pubDate>Sun, 16 Jul 2017 22:19:00 GMT</pubDate><media:content url="https://ivanarellano.com/content/images/2024/12/porsche_cayman_render_web.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://ivanarellano.com/content/images/2024/12/porsche_cayman_render_web.jpg" alt="Porsche Cayman, made with Maya"><p>This is a rendering of a 3D model I made. I gained deeper skills in Autodesk Maya while being challenged to model larger smooth surfaces. I was more experienced with starting a model using polygonal meshes, like a cube or a plane, but I didn&apos;t want to manage a dense mesh. I could have depended on subdivision previews to see smooth surfaces, but the result was always an approximation and sometimes looked lumpy. Instead, I started with NURBS because it lets you see a smooth surface immediately. Another benefit is using the NURBS to polygon command to create a polygonal mesh while still having NURBS curves for further tweaks.</p><h2 id="skills-used">Skills Used</h2><ul><li>Used picture references within Maya while modeling using NURBS</li><li>Converted NURBS surfaces into lower-res polygonal meshes</li><li>Rendered with Mental Ray rendering using final gathering and HDR lighting</li><li>Composited the wireframe with the beauty shot using Adobe Photoshop</li></ul>
<!--kg-card-begin: html-->
<iframe width="710" height="480" src="https://sketchfab.com/models/5fe40fef6cb34346acec031d4c325a2c/embed?autospin=0.2" frameborder="0" allowvr allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true" onmousewheel></iframe>
<!--kg-card-end: html-->
]]></content:encoded></item><item><title><![CDATA[Pong, made with SFML]]></title><description><![CDATA[<p><a href="https://github.com/ivanarellano/sfml-pong?ref=ivanarellano.com">See <code>sfml-pong</code> on Github</a>.</p><p>This project served as C++11 practice for game development using SFML. I also wanted to learn better task management for open source projects. I kept track of tasks using Trello, but only at the start of development. It was fine for Pong since there</p>]]></description><link>https://ivanarellano.com/pong/</link><guid isPermaLink="false">67646c5254b7b60001f615eb</guid><category><![CDATA[portfolio]]></category><category><![CDATA[game]]></category><category><![CDATA[pc]]></category><dc:creator><![CDATA[Ivan Arellano Maurizi]]></dc:creator><pubDate>Tue, 18 Apr 2017 13:05:00 GMT</pubDate><media:content url="https://ivanarellano.com/content/images/2024/12/Screenshot-2024-12-19-165915.png" medium="image"/><content:encoded><![CDATA[<img src="https://ivanarellano.com/content/images/2024/12/Screenshot-2024-12-19-165915.png" alt="Pong, made with SFML"><p><a href="https://github.com/ivanarellano/sfml-pong?ref=ivanarellano.com">See <code>sfml-pong</code> on Github</a>.</p><p>This project served as C++11 practice for game development using SFML. I also wanted to learn better task management for open source projects. I kept track of tasks using Trello, but only at the start of development. It was fine for Pong since there weren&apos;t many tasks. I did get tired of manually moving tasks along category lanes, so I started searching for a way to track tasks with actual pull requests. That&apos;s how I found Waffle. It&apos;s a task manager that always shows a current task board without having to manually move tasks and it does this by linking to Github. What&apos;s there left to do? This demo would be a lot more fun with networked multiplayer gameplay.</p><h2 id="game-features">Game Features</h2><ul><li>Two paddles</li><li>One ball</li><li>Two score keepers</li><li>Serving</li><li>A win screen</li><li>Restart the game</li></ul><h3 id="tools-used">Tools Used</h3><ul><li>Visual Studio 2015/2017</li><li>Xcode 8.3.1</li><li>Git + Github</li><li><a href="https://www.sfml-dev.org/?ref=ivanarellano.com">SFML 2.4.2</a></li><li><a href="http://trello.com/?ref=ivanarellano.com">Trello</a></li><li><a href="http://blog.bahraniapps.com/gifcam/?ref=ivanarellano.com">GifCam</a></li></ul><h3 id="resources-used">Resources Used</h3><ul><li><a href="http://www.stroustrup.com/Programming/?ref=ivanarellano.com">Programming: Principles and Practice Using C++ (2nd Edition)</a></li><li><a href="https://www.sfml-dev.org/tutorials/2.4/?ref=ivanarellano.com">SFML 2.4 tutorials</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Vivid Dreams, made with Unreal 3]]></title><description><![CDATA[<p>This project dates from college. I worked with five other student game artists and developed all programming solutions using Unreal Engine 3, UnrealScript, Kismet, and Maya Embedded Language (MEL) scripting. I was the primary software engineer on the project.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://ivanarellano.com/content/media/2024/12/VividDreams-VideoCap_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://ivanarellano.com/content/media/2024/12/VividDreams-VideoCap.mp4" poster="https://ivanarellano.com/content/media/2024/12/VividDreams-VideoCap_thumb.jpg" width="640" height="481" playsinline preload="metadata" controls></video>
                
                
            </div>
            
        </figure><h2 id="work-done">Work Done</h2><h3 id="technical-art">Technical Art</h3><ul><li>Created identical shaders for Autodesk Maya&apos;</li></ul>]]></description><link>https://ivanarellano.com/vivid-dreams/</link><guid isPermaLink="false">67644a5954b7b60001f6158f</guid><category><![CDATA[portfolio]]></category><category><![CDATA[game]]></category><category><![CDATA[pc]]></category><dc:creator><![CDATA[Ivan Arellano Maurizi]]></dc:creator><pubDate>Tue, 18 Apr 2017 13:00:00 GMT</pubDate><media:content url="https://ivanarellano.com/content/images/2024/12/Screenshot-2024-12-19-172510.png" medium="image"/><content:encoded><![CDATA[<img src="https://ivanarellano.com/content/images/2024/12/Screenshot-2024-12-19-172510.png" alt="Vivid Dreams, made with Unreal 3"><p>This project dates from college. I worked with five other student game artists and developed all programming solutions using Unreal Engine 3, UnrealScript, Kismet, and Maya Embedded Language (MEL) scripting. I was the primary software engineer on the project.</p><figure class="kg-card kg-video-card kg-width-regular" data-kg-thumbnail="https://ivanarellano.com/content/media/2024/12/VividDreams-VideoCap_thumb.jpg" data-kg-custom-thumbnail>
            <div class="kg-video-container">
                <video src="https://ivanarellano.com/content/media/2024/12/VividDreams-VideoCap.mp4" poster="https://ivanarellano.com/content/media/2024/12/VividDreams-VideoCap_thumb.jpg" width="640" height="481" playsinline preload="metadata" controls></video>
                
                
            </div>
            
        </figure><h2 id="work-done">Work Done</h2><h3 id="technical-art">Technical Art</h3><ul><li>Created identical shaders for Autodesk Maya&apos;s viewport and Unreal Engine 3</li><li>Automated 3-point light rigs in Maya using MEL script</li><li>Imported animation skeletons from Autodesk Maya into Unreal&apos;s editor</li></ul><h3 id="gameplay">Gameplay</h3><ul><li>Implemented hit detection using tracers for melee weapon fighting</li><li>Setup a top-down fixed camera with smooth zooming</li><li>Blended animations with Unreal&apos;s C++ API using available animation nodes</li><li>Teleported an out-of-bounds player to their nearest node path</li><li>Faded trees with occlusion using Kismet and Material Instance Constants</li><li>Implemented health pickups</li></ul>]]></content:encoded></item><item><title><![CDATA[Maya viewport shader, made with CgFX]]></title><description><![CDATA[<p><a href="https://github.com/ivanarellano/cgfx-bfs?ref=ivanarellano.com">View source code on Github</a></p><p>I started this project to learn more about video game graphics and how it fits within the art pipeline. I thought the best way to discover these technical art intricacies would be to start in a 3D modeling program in which artists spend a lot</p>]]></description><link>https://ivanarellano.com/bfs-2500/</link><guid isPermaLink="false">6763a47f54b7b60001f6154b</guid><category><![CDATA[portfolio]]></category><category><![CDATA[maya]]></category><category><![CDATA[graphics]]></category><dc:creator><![CDATA[Ivan Arellano Maurizi]]></dc:creator><pubDate>Tue, 17 Jan 2017 04:15:00 GMT</pubDate><media:content url="https://ivanarellano.com/content/images/2024/12/bfs_card.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://ivanarellano.com/content/images/2024/12/bfs_card.jpg" alt="Maya viewport shader, made with CgFX"><p><a href="https://github.com/ivanarellano/cgfx-bfs?ref=ivanarellano.com">View source code on Github</a></p><p>I started this project to learn more about video game graphics and how it fits within the art pipeline. I thought the best way to discover these technical art intricacies would be to start in a 3D modeling program in which artists spend a lot of time in. I wrote an Autodesk Maya viewport shader from scratch. This shader would have to be capable of providing a good variety of choices for the artist. It would also have to be of at least PS3/360 generation. Its user interface would be kept as simple as possible, but not watered down.</p><h2 id="a-big-fshader">A Big F- Shader</h2><p>This shader, lovingly named &quot;BFS 2500,&quot; clocks in with 68 distinct shading attributes. I wanted to retain current-gen standards and 68 of them is just the tip of the iceberg. Starting with foundational lighting, this shader provides two lighting models called <a href="https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model?ref=ivanarellano.com">Blinn</a> and <a href="https://en.wikipedia.org/wiki/Phong_reflection_model?ref=ivanarellano.com">Phong</a>. They&#x2019;re named after the people who created them, <a href="https://en.wikipedia.org/wiki/Jim_Blinn?ref=ivanarellano.com">Jim Blinn</a> and <a href="https://en.wikipedia.org/wiki/Bui_Tuong_Phong?ref=ivanarellano.com">Bui Tuong Phong</a>. These aren&#x2019;t the only models around. There&#x2019;s also Ward anisotropy, Cook-Torrance, and <a href="https://en.wikipedia.org/wiki/Oren%E2%80%93Nayar_reflectance_model?ref=ivanarellano.com">Oren-Nayar</a>&#xa0;to name a few. We don&#x2019;t see these often in PS3 or Xbox 360 games because of their high mathematical overhead. In this post&#x2019;s image, all of the materials use Phong lighting and are hooked up to one directional light and two point lights. They&#x2019;re all also in&#xa0;<a href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html?ref=ivanarellano.com">linear color space</a>, a gamma-correct format meant to portray real-life lighting more accurately. Lighting is less likely to look overblown within a linear color space, mid-tones are preserved, and color resolution appears more true to life.</p><h3 id="lets-add-more">Let&apos;s Add More</h3><p>BFS 2500 also includes two different types of <a href="https://en.wikipedia.org/wiki/Parallax_mapping?ref=ivanarellano.com">parallax mapping</a>. Parallax is an ever-evolving term with numerous amounts of techniques floating around. I included basic offset mapping, seen in Unreal Engine 3, and also parallax occlusion mapping [1] which is used in CryEngine 3. Their parallax is superior to Unreal&#x2019;s but it comes at a higher cost. This parallax technique uses iterative quality sampling which increases the offset quality at steeper angles. Offset mapping is faster but it can look the most distorted. The second sphere from the left uses a <a href="https://en.wikipedia.org/wiki/Cube_mapping?ref=ivanarellano.com">cube map</a>&#xa0;to reflect an environment. A cube map, which is an environment unwrapped into six images, can be used for reflection, refraction, or even ambient lighting. The sphere furthest away is using only a pre-blurred cube map for ambient lighting. It&#x2019;s the same cube map used on the second sphere. You can see that the top of the sphere is blue and as you go lower it turns brown. The method I used for blurring is called <a href="http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter10.html?ref=ivanarellano.com">diffuse convolution</a>. It&#x2019;s an algorithm that scatters light from the cube map and averages them. This gives finer color results than normal blurring. The third sphere uses ideas from Team Fortress 2&#x2019;s lighting scheme. They use a technique called diffuse warping [2], usually used with cel shading. However, Team Fortress&apos; cel-shading doesn&#x2019;t have hard edges because the texture they used was designed to keep a smooth edge. In the third sphere, the texture is comprised of five shades of color with no transitions.</p><h2 id="an-interface-for-all">An Interface For All</h2><figure class="kg-card kg-image-card"><img src="https://ivanarellano.com/content/images/2024/12/bfs-2500-mockup.jpg" class="kg-image" alt="Maya viewport shader, made with CgFX" loading="lazy" width="463" height="1000"></figure><p>This mockup GUI to control BFS 2500 focuses on being informative, useful, and unobtrusive. I started with Autodesk Maya&#x2019;s dark theme UI and kept its appeal because users are already used to it. The texture wells were created to make the UI feel more interactive. It partitions the shader&#x2019;s features and lets users remember what part of the interface they need to use based on the texture well locations.</p><h3 id="research-papers">Research Papers</h3><ul><li>[1] <a href="http://gamedevs.org/uploads/practical-dynamic-parallax-occlusion-mapping.pdf?ref=ivanarellano.com">Parallax Occlusion Mapping</a></li><li>[2] <a href="http://www.valvesoftware.com/publications/2007/NPAR07_IllustrativeRenderingInTeamFortress2.pdf?ref=ivanarellano.com">Illustrative Rendering in Team Fortress 2</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Sushi Loco, made with LibGDX]]></title><description><![CDATA[<p>In 2010, back in the early days of smartphones, a friend and I decided to create a different type of mobile game from what was currently available. Sushi Loco is a project we worked on from the ground up to make a side-scrolling platform game that uses the accelerometer.</p>]]></description><link>https://ivanarellano.com/sushi-loco/</link><guid isPermaLink="false">6764732b54b7b60001f61655</guid><category><![CDATA[portfolio]]></category><category><![CDATA[game]]></category><category><![CDATA[android]]></category><category><![CDATA[mobile]]></category><dc:creator><![CDATA[Ivan Arellano Maurizi]]></dc:creator><pubDate>Tue, 17 Jan 2017 03:10:00 GMT</pubDate><media:content url="https://ivanarellano.com/content/images/2024/12/Screenshot-2024-12-19-171714.png" medium="image"/><content:encoded><![CDATA[<img src="https://ivanarellano.com/content/images/2024/12/Screenshot-2024-12-19-171714.png" alt="Sushi Loco, made with LibGDX"><p>In 2010, back in the early days of smartphones, a friend and I decided to create a different type of mobile game from what was currently available. Sushi Loco is a project we worked on from the ground up to make a side-scrolling platform game that uses the accelerometer.</p>
<!--kg-card-begin: html-->
<figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/vTGNaYLkfRU?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Sushi Loco on Nexus 7 (2013) - libgdx/Android"></iframe></figure>
<!--kg-card-end: html-->
<h2 id="its-open-source">It&apos;s Open Source</h2><p>I&apos;m excited to have my largest personal project written released as open <a href="https://github.com/ivanarellano/SushiLoco?ref=ivanarellano.com">source code on Github</a>.</p><p>If you aren&apos;t inclined yet, are you here looking for a way to make a Katamari Damacy clone? Are you curious to see how linear impulses affect a circle shaped body in a Box2D physics world? Perhaps I&apos;ve written similar features to things you&apos;ve written and you&apos;d like to see what conclusions I&apos;ve made. Learn from this code base as I have from open source code.</p><h2 id="early-day-android-challenges">Early Day Android Challenges</h2><p>My friend and I didn&apos;t have many options to create a quick mobile game for Android. We both had Android phones with an accelerometer, something that was a desired feature then, and that made our hardware specific enough to begin with. We easily ruled out the Android NDK because we didn&apos;t have an existing C++ code base to port. More so, the debugging and build tools were absolutely minimal or non-existent. We couldn&apos;t work with blindfolds on! Eventually we well understood that Java was the only way forward. This is why Sushi Loco is written with <a href="https://libgdx.badlogicgames.com/?ref=ivanarellano.com">LibGDX</a>. There simply was no other framework at the time that was fast, worked with native platform tools, and had a strong community presence with active developers. Times have changed and so have the tools. If I were to make a new project today I&apos;d pick LibGDX, Unity, and Unreal as a starting point and then evaluate for my needs. Even the Android NDK is a solid option for an existing code base in C++.</p><h2 id="skills-learned">Skills Learned</h2><ul><li>LibGDX game framework architecture</li><li>Box2D physics for movement and hit detection</li><li>Java on Android (back when public field access was a CPU optimization)</li><li>Frustrum culling</li><li>Texture atlas packing and retrieval</li><li>Google Wave (RIP) to organize docs and collaborate with teammate</li></ul>]]></content:encoded></item><item><title><![CDATA[The little website that could]]></title><description><![CDATA[<p>There could not have been a better way to start 2017 than by fixing this website. What started as a small task of self-hosting actually spiraled into many smaller projects. The additional time demands, along with a full-time job, culminated to breaking ivanarellano.com for nearly a year.</p>]]></description><link>https://ivanarellano.com/the-little-website-that-could-2/</link><guid isPermaLink="false">67639a8c54b7b60001f614f9</guid><category><![CDATA[docker]]></category><dc:creator><![CDATA[Ivan Arellano Maurizi]]></dc:creator><pubDate>Tue, 03 Jan 2017 03:30:00 GMT</pubDate><media:content url="https://ivanarellano.com/content/images/2024/12/fireworks.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://ivanarellano.com/content/images/2024/12/fireworks.jpg" alt="The little website that could"><p>There could not have been a better way to start 2017 than by fixing this website. What started as a small task of self-hosting actually spiraled into many smaller projects. The additional time demands, along with a full-time job, culminated to breaking ivanarellano.com for nearly a year. And yet I&apos;ve been able to script a way, a convenient one, to spin-up this website and a photography site. Enter <a href="https://www.docker.com/products/docker-compose?ref=ivanarellano.com">Docker Compose</a>.</p><h2 id="background">Background</h2><p>First, I have to explain how Docker can be a downside. I quickly started writing scripts after going through an enormous amount of setup steps for each container. All setup scripts can then be fired in a correct sequence from another script to re-create this website, like a reset. &#xa0;For added convenience, I saved each script onto private Github gists, so that I could download and execute them in a terminal, with something like <code>wget -qO - https://gist.github.com/ivanarellano/[gist_hash]/raw/start_website.sh | sudo bash</code>. &#xa0;Initializing containers this way isn&apos;t so bad at first, but there are too many pieces to maintain. There are also unforeseen issues. Containers can fail to restart after a server restart. The scripts needed constant documentation for every new solution. The tech debt was real and I started regretting containers.</p><h2 id="how-it-went-uphill-with-docker-compose">How It Went Uphill With Docker Compose</h2><p>Docker Compose is able to run multiple containers with only one file to describe dependencies. After <a href="https://docs.docker.com/compose/install/?ref=ivanarellano.com">installing it</a>, you should be able to run <code>docker-compose</code> from your terminal. All of your container dependencies are then listed in a file named <code>docker-compose.yaml</code>. Here is a sample based on this website:</p><pre><code class="language-yaml"># Describes a Ghost blog with a host name, build variant, Mailgun info, and Let&apos;s Encrypt info 
my_blog:     
  image: ghost   
  volumes: - /my_path/blog:/var/lib/ghost
  environment:
    - VIRTUAL_HOST=example.com 
    - NODE_ENV=production
    - EMAIL_SERVICE=Mailgun
    - EMAIL_USER=postmaster@mg.example.com
    - EMAIL_PASSWORD=1234567890
    - LETSENCRYPT_HOST=example.com
    - LETSENCRYPT_EMAIL=user@example.com
  restart: always
  
# Describes a Koken photo gallery with a host name and Let&apos;s Encrypt info my_photo_gallery:
  image: koken/koken-lemp
  volumes:
    - /data/koken/www:/usr/share/nginx/www
    - /data/koken/mysql:/var/lib/mysql
  environment:
    - VIRTUAL_HOST=sub.example.com
    - LETSENCRYPT_HOST=sub.example.com
    - LETSENCRYPT_EMAIL=user@example.com

# Describes an Nginx web server that proxies to other container&apos;s nginx server nginx-proxy:
  image: jwilder/nginx-proxy
  ports:
    - \&quot;##:##\&quot;
    - \&quot;##:##\&quot;
  volumes:
    - /my_path/certs:/etc/nginx/certs:ro
    - /etc/nginx/vhost.d
    - /usr/share/nginx/html
    - /var/run/docker.sock:/tmp/docker.sock:ro
    - /my_path/vhost.d:/etc/nginx/vhost.d
  restart: always
  
# Describes a container that automatically creates Let&apos;s Encrypt certifications for each other container
letsencrypt:
  image: jrcs/letsencrypt-nginx-proxy-companion
  volumes:
    - /my_path/certs:/etc/nginx/certs:rw
    - /var/run/docker.sock:/var/run/docker.sock:ro
  volumes_from:
    - nginx-proxy
  restart: always
</code></pre><p>It&apos;s straightforward to run this script with <code>docker-compose up</code>. You can optionally add <code>-d</code> to run detached containers in the background. Containers can be stopped with <code>docker-compose stop</code> and upgraded with <code>docker-compose pull</code>.</p><h2 id="the-websites-future">The Website&apos;s Future</h2><p>This website is going to be my grounds for ideas, thoughts, and stories. Though, less of the stories at the start. It&apos;s going to be about discovering new hobbies, game programming, some math, and it&apos;s going to be messy while I try to explain it all. Here&apos;s to 2017!</p>]]></content:encoded></item></channel></rss>