<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Java on Smbat Voskanyan</title><link>https://senpie.net/tags/java/</link><description>Recent content in Java on Smbat Voskanyan</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Sun, 23 Jul 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://senpie.net/tags/java/index.xml" rel="self" type="application/rss+xml"/><item><title>Talos VFX</title><link>https://senpie.net/post/talos-vfx/</link><pubDate>Sun, 23 Jul 2023 00:00:00 +0000</pubDate><guid>https://senpie.net/post/talos-vfx/</guid><description>&lt;img src="https://senpie.net/post/talos-vfx/talos.png" alt="Featured image of post Talos VFX" />&lt;h1 id="introduction">Introduction
&lt;/h1>&lt;p>Talos VFX is a powerful open-source visual effects editor designed for Java and LibGDX projects. Create stunning particles, shaders, and custom scripts, while seamlessly managing game assets – all from a single workspace. Its intuitive, node-based VFX editor and support for visual programming routines (similar to Unreal Engine&amp;rsquo;s blueprints) empower you to craft dynamic effects. Build 2D levels and scenes with brushes, and bring your creations to life with Spine2d skeletal animations, easily attaching VFX directly to animation bones. While primarily focused on 2D, Talos VFX also offers limited 3D support.&lt;/p>
&lt;p>As a major contributor to Talos VFX, I&amp;rsquo;ve played a role in squashing critical bugs, implementing user-requested features, and refining the overall user experience. As of writing this post I authored around ~50% of Pull Requests on the project. Here&amp;rsquo;s the &lt;strong>&lt;a class="link" href="https://github.com/rockbite/talos/tree/talos-3d" target="_blank" rel="noopener"
>link to project&lt;/a>&lt;/strong>. Note, that active development is carried on &lt;code>talos-3d&lt;/code> branch and &lt;code>master&lt;/code> branch is greatly behind.&lt;/p>
&lt;p>&lt;img src="https://senpie.net/post/talos-vfx/talos.png"
width="2131"
height="1276"
srcset="https://senpie.net/post/talos-vfx/talos_hu9ab9ff59ef09db64b97121e1afd1e09a_1006924_480x0_resize_box_3.png 480w, https://senpie.net/post/talos-vfx/talos_hu9ab9ff59ef09db64b97121e1afd1e09a_1006924_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="On the top-left scene hierarchy, preview and scene editor. On the bottom-left routine graphical editor. On the right node-based particle system. "
class="gallery-image"
data-flex-grow="167"
data-flex-basis="400px"
>&lt;/p>
&lt;h1 id="feature-development">Feature Development
&lt;/h1>&lt;p>Since a lot of features were missing initally and we needed many tools for our prototypes, I had a chance to contribute a lot in this area.&lt;/p>
&lt;h2 id="fake-bvb-bone-attachment-support">Fake BVB&amp;quot; (Bone Attachment Support)
&lt;/h2>&lt;p>Problem: Users were limited in how they could interact with skeletal animations, hindering dynamic effects and customization.&lt;br>
Solution: Implemented &amp;ldquo;Fake BVB&amp;rdquo; functionality, exposing animation bones as restricted game objects within Talos, enabling the attachment of other objects.&lt;br>
Result: Users can now create more complex and visually engaging effects by directly linking particles, objects, and more to
skeletal animations. Examples include attaching characters to moving vehicles or syncing particle effects to bone movements.&lt;/p>
&lt;h2 id="nineslices-support-and-sprite-editor">NineSlices Support and Sprite Editor
&lt;/h2>&lt;p>Problem: Users lacked advanced scaling options for UI and graphic elements, limiting design flexibility. Limited or inefficient tools for sprite editing and managing NineSlice metadata within Talos VFX.&lt;br>
Solution: Implemented NineSlice rendering functionality, providing a system similar to Unity&amp;rsquo;s NineSlices. This allows specific sections of images to be repeated horizontally, vertically, or in both directions.&lt;br>
Result: Improved control over how UI elements and graphics scale, enhancing the ability to create visually polished and responsive interfaces within Talos VFX.&lt;br>&lt;/p>
&lt;h1 id="bug-fixes-and-refinements">Bug Fixes and Refinements
&lt;/h1>&lt;p>I have fixed more bugs than I could remember, however to recall some off the top of my head, then these would be the ones.&lt;/p>
&lt;h2 id="project-explorer-stability-and-user-experience">Project Explorer Stability and User Experience
&lt;/h2>&lt;p>Problem: File management was unreliable, with crashes and unexpected behaviors. Crashes when moving or renaming files. Bad user experience. Poor file search performance.&lt;br>
Solution: Revamped project explorer logic, preventing errors and ensuring a smoother file management experience. Refreshed the UI for more costumization and assets previews. Fast asset lookup.&lt;br>
Result: Increased stability and reliability within Talos VFX, protecting user work. Happy users.&lt;br>&lt;/p>
&lt;h2 id="routine-workflow">Routine Workflow
&lt;/h2>&lt;p>Problem: Editing curves within the Routine App was buggy, hindering intuitive workflow.&lt;br>
Solution: Fixed curve gizmo display and interaction points, including inserting new points and using the ESC key.&lt;br>
Result: Restored smooth and predictable curve editing, streamlining the creation of dynamic effects within routines.&lt;br>&lt;/p>
&lt;h1 id="concusion">Concusion
&lt;/h1>&lt;p>Through this project, I&amp;rsquo;ve learned many new topics and significantly improved my knowledge in Java, libGDX, and 2D engine development tools. It was both challenging and rewarding to work with a community of people directly affected by my contributions. Seeing others use Talos VFX to create amazing games is a deeply satisfying experience.&lt;/p></description></item><item><title>Tiny World</title><link>https://senpie.net/post/tiny-world/</link><pubDate>Thu, 05 Jan 2023 00:00:00 +0000</pubDate><guid>https://senpie.net/post/tiny-world/</guid><description>&lt;img src="https://senpie.net/post/tiny-world/capture.jpg" alt="Featured image of post Tiny World" />&lt;div class="video-wrapper">
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/hA-29bpJ4Bc"
allowfullscreen
title="YouTube Video"
>
&lt;/iframe>
&lt;/div>
&lt;p>I&amp;rsquo;ve created a game engine from scratch featuring a tiny
world. This project aimed to demonstrate my understanding of 3D graphics programming and the
principles of perspective, lighting, and texturing. I had a lot of fun implementing the water. It features Fresnel Effect, samples skybox and terrain for realistic reflections and uses depth buffer information to achieve soft edges.
I wrote the project purely in Java and OpenGL, and the source code is available on &lt;a class="link" href="https://github.com/TheSenPie/tiny-world-java" target="_blank" rel="noopener"
>git&lt;/a>.&lt;/p>
&lt;p>Furthermore, this is a personal live project meaning it will be constantly updated with new stuff as I keep
learning new techniques and would want to practically apply them somewhere. Specifics and more details
about the project, and how to run it on your local machine are uploaded to the webpage provided in the
link. Enjoy!&lt;/p>
&lt;p>&lt;strong>&lt;a class="link" href="https://github.com/TheSenPie/tiny-world-java" target="_blank" rel="noopener"
>Source code&lt;/a>&lt;/strong> for curious ones.&lt;/p></description></item><item><title>AI Algorithms Practice</title><link>https://senpie.net/post/ai/</link><pubDate>Thu, 22 Dec 2022 00:00:00 +0000</pubDate><guid>https://senpie.net/post/ai/</guid><description>&lt;img src="https://images.inc.com/uploaded_files/image/1920x1080/getty_484267200_109172.jpg" alt="Featured image of post AI Algorithms Practice" />&lt;p>I took a bonus assignment for my Artificial Intelligence course. The work demonstrates the implementation of various algorithms for solving the n-puzzle problem, along with useful statistics for analysis. Due to the professor’s request, I have made the repository private, so students of upcoming years will not copy it, but you can access the code with &lt;strong>&lt;a class="link" href="https://gitfront.io/r/SenPie/fhSwHm6Huxwx/ai-22/" target="_blank" rel="noopener"
>this link&lt;/a>&lt;/strong>.&lt;/p>
&lt;h2 id="statistics">Statistics
&lt;/h2>&lt;p>Part 1&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">Executed Breadth First Tree Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 2298274; Max Nodes in frontier 1473871
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed Breadth First Tree Search with Early Goal test
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 824404; Max Nodes in frontier 537119
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed Breadth First Graph Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 5019; Max Nodes in frontier 1926
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed Breadth First Graph Search with Early Goal test
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 4644; Max Nodes in frontier 1075
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Skipped the execution of Depth First Tree Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Algorithm gets into an infinite cycle of Right &amp;lt;-&amp;gt; Left actions
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed Depth First Graph Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 68217; Max Nodes in frontier 29633
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed Iterative Deepening Tree Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 34232; Max Nodes in frontier 43
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Both Breadth First Tree and Graph Searches found the optimal solution. Clearly huge improvements are observed with graph search version and the early goal test gives the extra bonus of cutting off extra nodes, that would be generated otherwise.&lt;br>
Although, Depth First Tree Search is known to consume very little memory space it is not effective in this case as it gets into an infinite loop.&lt;br>
Depth First Graph Search does a better job, than its Tree Search version xD. However, it generates many more nodes, than Breadth First Graph search and has a bigger frontier stretch.
Iterative Deepening Tree Search did a good job to find a solution, and it also spent very little memory. However, it is also worth to mention, that IDTS did not find the optimal solution. Also still, 4644 + 1075 &amp;lt; 34232 + 43 it still consumes more memory. You may argue, that compared to BFGS, IDTS does not use an extra set to keep track of &lt;em>reached&lt;/em> states, however reached states is not really making new states, but rather keeps references, which is still much less, than what we get with IDTS.&lt;br>
Overall, Breadth First Graph Search with the early goal test comes out as a winner in uninformed search category, reason being, that it just works better for this problem.&lt;br>
As it says in the book&lt;/p>
&lt;blockquote>
&lt;p>When all step costs are equal, breadth-first search is optimal because it always expands the shallowest unexpanded node.&lt;/p>
&lt;/blockquote>
&lt;p>Part 2&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">Executed Uniform Cost Tree Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 2587508; Max Nodes in frontier 1653452
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed Uniform Cost Graph Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 7549; Max Nodes in frontier 1656
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Skipped the execution of Greedy Tree Search with h1 number of misplaced tiles
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Algorithm gets into an infinite cycle.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Skipped the execution of Greedy Tree Search with h2 manhattan distance
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Algorithm gets into an infinite cycle.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed Greedy Graph Search with h1 number of misplaced tiles
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 233; Max Nodes in frontier 68
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed Greedy Graph Search with h2 manhattan distance
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 1051; Max Nodes in frontier 267
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed A* Tree Search with h1, number of misplaced tiles Tree Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 964; Max Nodes in frontier 613
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed A* Tree Search with h2 manhattan distance Tree Search
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 120; Max Nodes in frontier 74
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed A* Graph Search with h1 number of misplaced tiles
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 360; Max Nodes in frontier 91
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Executed A* Graph Search with h2 manhattan distance
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nodes Generated 106; Max Nodes in frontier 29
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Before we continue any further, I would like to right away give the trophy to A* Graph Search with Manhattan Distance heuristic.&lt;br>
Let&amp;rsquo;s jump into it! Right away we can see that Uniform Cost Tree Search gave similar results to Breadth First Tree Search. Reason is that action cost is 1, and path costs gets incrementally bigger with each level forcing UCS to iterate in Breadth first manner. Reason why numbers are not same is connected to the fact how JDK implemented the PriorityQueue, which means it is not guaranteed to return the leftmost node in the same level.&lt;br>
Same goes for Uniform Cost Graph Search and Breadth First Graph Search.&lt;br>
Neither Number of Misplaced Tiles heuristic, nor Manhattan Distance heuristic are good enough on their own to run Tree Search, therefore Greedy Tree search gets into a cycle.
Again quoting the book:&lt;/p>
&lt;blockquote>
&lt;p>Algorithms that don&amp;rsquo;t remember the past are doomed to repeat the history.&lt;/p>
&lt;/blockquote>
&lt;p>Regarding A* Search we see power of good heuristic, because A* Tree Search with Manhattan distance performs better than A* Graph Search with Number of Misplaced Tiles heuristic. It is proved in the book that &lt;strong>h2&lt;/strong> &lt;em>dominates&lt;/em> &lt;strong>h1&lt;/strong>.&lt;br>
It also has lower &lt;em>Effective Branching Factor&lt;/em>.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>d&lt;/th>
&lt;th>BFS&lt;/th>
&lt;th>A*(h1)&lt;/th>
&lt;th>A*(h2)&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>6&lt;/td>
&lt;td>2.01&lt;/td>
&lt;td>1.42&lt;/td>
&lt;td>1.34&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>8&lt;/td>
&lt;td>1.91&lt;/td>
&lt;td>1.40&lt;/td>
&lt;td>1.30&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>10&lt;/td>
&lt;td>1.85&lt;/td>
&lt;td>1.43&lt;/td>
&lt;td>1.27&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>12&lt;/td>
&lt;td>1.80&lt;/td>
&lt;td>1.45&lt;/td>
&lt;td>1.28&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>14&lt;/td>
&lt;td>1.77&lt;/td>
&lt;td>1.47&lt;/td>
&lt;td>1.31&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>16&lt;/td>
&lt;td>1.74&lt;/td>
&lt;td>1.48&lt;/td>
&lt;td>1.32&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>18&lt;/td>
&lt;td>1.72&lt;/td>
&lt;td>1.49&lt;/td>
&lt;td>1.34&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>20&lt;/td>
&lt;td>1.69&lt;/td>
&lt;td>1.50&lt;/td>
&lt;td>1.34&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>22&lt;/td>
&lt;td>1.66&lt;/td>
&lt;td>1.50&lt;/td>
&lt;td>1.34&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>24&lt;/td>
&lt;td>1.62&lt;/td>
&lt;td>1.50&lt;/td>
&lt;td>1.36&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Overall, obviously and for the reasons mentioned before, A* Graph Search with Manhattan Distance heuristic comes top as a winner.&lt;/p>
&lt;h2 id="solution">Solution
&lt;/h2>&lt;p>Following is a demonstration of A* Graph Search on 8-puzzle with Manhattan Distance heuristics.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt"> 10
&lt;/span>&lt;span class="lnt"> 11
&lt;/span>&lt;span class="lnt"> 12
&lt;/span>&lt;span class="lnt"> 13
&lt;/span>&lt;span class="lnt"> 14
&lt;/span>&lt;span class="lnt"> 15
&lt;/span>&lt;span class="lnt"> 16
&lt;/span>&lt;span class="lnt"> 17
&lt;/span>&lt;span class="lnt"> 18
&lt;/span>&lt;span class="lnt"> 19
&lt;/span>&lt;span class="lnt"> 20
&lt;/span>&lt;span class="lnt"> 21
&lt;/span>&lt;span class="lnt"> 22
&lt;/span>&lt;span class="lnt"> 23
&lt;/span>&lt;span class="lnt"> 24
&lt;/span>&lt;span class="lnt"> 25
&lt;/span>&lt;span class="lnt"> 26
&lt;/span>&lt;span class="lnt"> 27
&lt;/span>&lt;span class="lnt"> 28
&lt;/span>&lt;span class="lnt"> 29
&lt;/span>&lt;span class="lnt"> 30
&lt;/span>&lt;span class="lnt"> 31
&lt;/span>&lt;span class="lnt"> 32
&lt;/span>&lt;span class="lnt"> 33
&lt;/span>&lt;span class="lnt"> 34
&lt;/span>&lt;span class="lnt"> 35
&lt;/span>&lt;span class="lnt"> 36
&lt;/span>&lt;span class="lnt"> 37
&lt;/span>&lt;span class="lnt"> 38
&lt;/span>&lt;span class="lnt"> 39
&lt;/span>&lt;span class="lnt"> 40
&lt;/span>&lt;span class="lnt"> 41
&lt;/span>&lt;span class="lnt"> 42
&lt;/span>&lt;span class="lnt"> 43
&lt;/span>&lt;span class="lnt"> 44
&lt;/span>&lt;span class="lnt"> 45
&lt;/span>&lt;span class="lnt"> 46
&lt;/span>&lt;span class="lnt"> 47
&lt;/span>&lt;span class="lnt"> 48
&lt;/span>&lt;span class="lnt"> 49
&lt;/span>&lt;span class="lnt"> 50
&lt;/span>&lt;span class="lnt"> 51
&lt;/span>&lt;span class="lnt"> 52
&lt;/span>&lt;span class="lnt"> 53
&lt;/span>&lt;span class="lnt"> 54
&lt;/span>&lt;span class="lnt"> 55
&lt;/span>&lt;span class="lnt"> 56
&lt;/span>&lt;span class="lnt"> 57
&lt;/span>&lt;span class="lnt"> 58
&lt;/span>&lt;span class="lnt"> 59
&lt;/span>&lt;span class="lnt"> 60
&lt;/span>&lt;span class="lnt"> 61
&lt;/span>&lt;span class="lnt"> 62
&lt;/span>&lt;span class="lnt"> 63
&lt;/span>&lt;span class="lnt"> 64
&lt;/span>&lt;span class="lnt"> 65
&lt;/span>&lt;span class="lnt"> 66
&lt;/span>&lt;span class="lnt"> 67
&lt;/span>&lt;span class="lnt"> 68
&lt;/span>&lt;span class="lnt"> 69
&lt;/span>&lt;span class="lnt"> 70
&lt;/span>&lt;span class="lnt"> 71
&lt;/span>&lt;span class="lnt"> 72
&lt;/span>&lt;span class="lnt"> 73
&lt;/span>&lt;span class="lnt"> 74
&lt;/span>&lt;span class="lnt"> 75
&lt;/span>&lt;span class="lnt"> 76
&lt;/span>&lt;span class="lnt"> 77
&lt;/span>&lt;span class="lnt"> 78
&lt;/span>&lt;span class="lnt"> 79
&lt;/span>&lt;span class="lnt"> 80
&lt;/span>&lt;span class="lnt"> 81
&lt;/span>&lt;span class="lnt"> 82
&lt;/span>&lt;span class="lnt"> 83
&lt;/span>&lt;span class="lnt"> 84
&lt;/span>&lt;span class="lnt"> 85
&lt;/span>&lt;span class="lnt"> 86
&lt;/span>&lt;span class="lnt"> 87
&lt;/span>&lt;span class="lnt"> 88
&lt;/span>&lt;span class="lnt"> 89
&lt;/span>&lt;span class="lnt"> 90
&lt;/span>&lt;span class="lnt"> 91
&lt;/span>&lt;span class="lnt"> 92
&lt;/span>&lt;span class="lnt"> 93
&lt;/span>&lt;span class="lnt"> 94
&lt;/span>&lt;span class="lnt"> 95
&lt;/span>&lt;span class="lnt"> 96
&lt;/span>&lt;span class="lnt"> 97
&lt;/span>&lt;span class="lnt"> 98
&lt;/span>&lt;span class="lnt"> 99
&lt;/span>&lt;span class="lnt">100
&lt;/span>&lt;span class="lnt">101
&lt;/span>&lt;span class="lnt">102
&lt;/span>&lt;span class="lnt">103
&lt;/span>&lt;span class="lnt">104
&lt;/span>&lt;span class="lnt">105
&lt;/span>&lt;span class="lnt">106
&lt;/span>&lt;span class="lnt">107
&lt;/span>&lt;span class="lnt">108
&lt;/span>&lt;span class="lnt">109
&lt;/span>&lt;span class="lnt">110
&lt;/span>&lt;span class="lnt">111
&lt;/span>&lt;span class="lnt">112
&lt;/span>&lt;span class="lnt">113
&lt;/span>&lt;span class="lnt">114
&lt;/span>&lt;span class="lnt">115
&lt;/span>&lt;span class="lnt">116
&lt;/span>&lt;span class="lnt">117
&lt;/span>&lt;span class="lnt">118
&lt;/span>&lt;span class="lnt">119
&lt;/span>&lt;span class="lnt">120
&lt;/span>&lt;span class="lnt">121
&lt;/span>&lt;span class="lnt">122
&lt;/span>&lt;span class="lnt">123
&lt;/span>&lt;span class="lnt">124
&lt;/span>&lt;span class="lnt">125
&lt;/span>&lt;span class="lnt">126
&lt;/span>&lt;span class="lnt">127
&lt;/span>&lt;span class="lnt">128
&lt;/span>&lt;span class="lnt">129
&lt;/span>&lt;span class="lnt">130
&lt;/span>&lt;span class="lnt">131
&lt;/span>&lt;span class="lnt">132
&lt;/span>&lt;span class="lnt">133
&lt;/span>&lt;span class="lnt">134
&lt;/span>&lt;span class="lnt">135
&lt;/span>&lt;span class="lnt">136
&lt;/span>&lt;span class="lnt">137
&lt;/span>&lt;span class="lnt">138
&lt;/span>&lt;span class="lnt">139
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">0: start
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 4 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 8 | 1 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 5 | | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">1: move LEFT
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 4 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 8 | 1 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| | 5 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">2: move UP
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 4 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| | 1 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 8 | 5 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">3: move UP
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| | 4 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 1 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 8 | 5 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">4: move RIGHT
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 1 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 8 | 5 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">5: move DOWN
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 1 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 8 | 5 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">6: move DOWN
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 1 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 5 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 8 | | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">7: move LEFT
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 1 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 5 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| | 8 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">8: move UP
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 1 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| | 5 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 8 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">9: move UP
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| | 1 | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 5 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 8 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">10: move RIGHT
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 1 | | 2 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 5 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 8 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">11: move RIGHT
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 1 | 2 | |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 5 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 8 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">12: move DOWN
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 1 | 2 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 5 | |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 8 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">13: move DOWN
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 1 | 2 | 3 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 4 | 5 | 6 |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">| 7 | 8 | |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">-------------
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div></description></item><item><title>Battle Cards: Real-time PVP</title><link>https://senpie.net/post/battle-cards/</link><pubDate>Fri, 25 Feb 2022 00:00:00 +0000</pubDate><guid>https://senpie.net/post/battle-cards/</guid><description>&lt;img src="https://senpie.net/post/battle-cards/battlecards-bg.png" alt="Featured image of post Battle Cards: Real-time PVP" />&lt;p>Check out &lt;strong>&lt;a class="link" href="https://play.google.com/store/apps/details?id=com.rockbite.battlecards" target="_blank" rel="noopener"
>Battle Cards&lt;/a>&lt;/strong>! It was an incredible journey that began at the &lt;strong>&lt;a class="link" href="https://globalgamejam.org/2021/games/realtime-battlecards-9" target="_blank" rel="noopener"
>Playcrafting NYC Game Jam 2021&lt;/a>&lt;/strong>. Our team managed to create a compelling multiplayer prototype in just two days, earning recognition from the judges. Built with Java, LibGDX, and a Node.js backend, we had a solid foundation for a full release. Seeing the positive response, we decided to take &amp;ldquo;Battle Cards&amp;rdquo; to the next level. After a year of dedicated development, we launched a polished version that players genuinely enjoyed.&lt;/p>
&lt;p>&lt;img src="https://senpie.net/post/battle-cards/battle-cards-0.jpeg"
width="590"
height="1080"
srcset="https://senpie.net/post/battle-cards/battle-cards-0_hueb5e5c24123d5ee684c61a5d1c6a1652_397805_480x0_resize_q75_box.jpeg 480w, https://senpie.net/post/battle-cards/battle-cards-0_hueb5e5c24123d5ee684c61a5d1c6a1652_397805_1024x0_resize_q75_box.jpeg 1024w"
loading="lazy"
alt="Main page for searching a match"
class="gallery-image"
data-flex-grow="54"
data-flex-basis="131px"
>&lt;img src="https://senpie.net/post/battle-cards/battle-cards-1.jpeg"
width="592"
height="1080"
srcset="https://senpie.net/post/battle-cards/battle-cards-1_hu11c7ab14234c447f9c89cbc62e465f79_523041_480x0_resize_q75_box.jpeg 480w, https://senpie.net/post/battle-cards/battle-cards-1_hu11c7ab14234c447f9c89cbc62e465f79_523041_1024x0_resize_q75_box.jpeg 1024w"
loading="lazy"
alt="The battle arena"
class="gallery-image"
data-flex-grow="54"
data-flex-basis="131px"
>&lt;img src="https://senpie.net/post/battle-cards/battle-cards-2.jpeg"
width="592"
height="1080"
srcset="https://senpie.net/post/battle-cards/battle-cards-2_hu5fe3390afd1012ea7c16ac4c639de51e_645366_480x0_resize_q75_box.jpeg 480w, https://senpie.net/post/battle-cards/battle-cards-2_hu5fe3390afd1012ea7c16ac4c639de51e_645366_1024x0_resize_q75_box.jpeg 1024w"
loading="lazy"
alt="Card collection"
class="gallery-image"
data-flex-grow="54"
data-flex-basis="131px"
>&lt;/p>
&lt;p>My contributions centered on the UI, ensuring new features, code refactoring, and optimizations all worked toward a seamless player experience. However, being part of a small team meant I got to wear many hats! I contributed to gameplay programming, designed some eye-catching VFX, and tweaked the backend for better performance. For our marketing efforts, I created a compact 2MB playable ad to showcase the heart of the game.&lt;/p>
&lt;p>Additionally, I collaborated closely with our analytics team to improve dashboards, graphs, filters, and other tools. Our goal was to make analyzing user experience more accessible, enabling us to make informed game design changes. Ultimately, my focus was on making sure &amp;ldquo;Battle Cards&amp;rdquo; didn&amp;rsquo;t just look good – it had to play well too. It was a challenging, yet incredibly rewarding project.&lt;/p></description></item><item><title>Sandship: Crafting Factory</title><link>https://senpie.net/post/sandship/</link><pubDate>Mon, 15 Feb 2021 00:00:00 +0000</pubDate><guid>https://senpie.net/post/sandship/</guid><description>&lt;img src="https://senpie.net/post/sandship/sandship-bg.png" alt="Featured image of post Sandship: Crafting Factory" />&lt;p>Explore the world of &lt;strong>&lt;a class="link" href="https://play.google.com/store/apps/details?id=com.rockbite.sandship" target="_blank" rel="noopener"
>Sandship&lt;/a>&lt;/strong> blends the vastness of a Dune-like world with the addictive mechanics of Factorio. It was one of my first projects at Rockbite Games and offered an array of exciting technical challenges. I played a crucial role in crafting the game&amp;rsquo;s UI, implementing new elements, extensively refactoring for efficiency, and squashing bugs. Java and LibGDX were my tools of choice.&lt;/p>
&lt;div class="video-wrapper">
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/QR5Kn37fHyY"
allowfullscreen
title="YouTube Video"
>
&lt;/iframe>
&lt;/div>
&lt;p>My work wasn&amp;rsquo;t limited to just the UI. As part of a small team, I contributed in many areas from backend development to gameplay programming. One standout feature for me was the &amp;ldquo;News&amp;rdquo; system. To keep players connected, I built a Node.js microservice allowing our Community Management team to post website updates that seamlessly appeared in-game.&lt;/p>
&lt;p>Ultimately, I made sure &amp;ldquo;Sandship&amp;rdquo; delivered a visually engaging and smooth player experience. Tackling these challenges was as rewarding as seeing players immersed in the world we built.&lt;/p>
&lt;p>&lt;img src="https://senpie.net/post/sandship/sandship-1.jpeg"
width="1920"
height="1080"
srcset="https://senpie.net/post/sandship/sandship-1_hu1f2ced91771ffa736a99e93a73a6b369_270530_480x0_resize_q75_box.jpeg 480w, https://senpie.net/post/sandship/sandship-1_hu1f2ced91771ffa736a99e93a73a6b369_270530_1024x0_resize_q75_box.jpeg 1024w"
loading="lazy"
alt="Outside view. You can see the Sandship itself and crafting buildings on top of it."
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
>&lt;img src="https://senpie.net/post/sandship/sandship-2.jpeg"
width="1920"
height="1080"
srcset="https://senpie.net/post/sandship/sandship-2_hu1f2ced91771ffa736a99e93a73a6b369_514812_480x0_resize_q75_box.jpeg 480w, https://senpie.net/post/sandship/sandship-2_hu1f2ced91771ffa736a99e93a73a6b369_514812_1024x0_resize_q75_box.jpeg 1024w"
loading="lazy"
alt="Inside a Sadnship building."
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
>&lt;/p></description></item></channel></rss>