<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Dora SSR Blog</title>
        <link>https://ippclub.gitee.io/Dora-SSR/blog</link>
        <description>Dora SSR Blog</description>
        <lastBuildDate>Mon, 20 Jan 2025 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[A Happy New Year of the Snake for the Community!]]></title>
            <link>https://ippclub.gitee.io/Dora-SSR/blog/2025/1/20/year-of-snake</link>
            <guid>https://ippclub.gitee.io/Dora-SSR/blog/2025/1/20/year-of-snake</guid>
            <pubDate>Mon, 20 Jan 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[As the Chunjie (Spring Festival) approaches, to welcome the lively and wise Year of the Snake, we have created several illustrations filled with the festive atmosphere of the Spring Festival for the Dora SSR open-source game engine project. These artworks convey our sincere blessings and heartfelt gratitude to all community members.]]></description>
            <content:encoded><![CDATA[<p>As the Chunjie (Spring Festival) approaches, to welcome the lively and wise Year of the Snake, we have created several illustrations filled with the festive atmosphere of the Spring Festival for the Dora SSR open-source game engine project. These artworks convey our sincere blessings and heartfelt gratitude to all community members.</p>
<p>In this series of illustrations, a blonde little girl and a cute bear joyfully wander through the festive scenes of the Spring Festival:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="spring-festival-travel">Spring Festival Travel<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/20/year-of-snake#spring-festival-travel" class="hash-link" aria-label="Direct link to Spring Festival Travel" title="Direct link to Spring Festival Travel" translate="no">​</a></h3>
<p>They carry luggage and backpacks, boarding trains to return home or embark on new journeys;</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/2-792906bd551f142571b5b83c2ca9d545.png" alt="Spring Festival Travel" width="600px"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="red-envelopes">Red Envelopes<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/20/year-of-snake#red-envelopes" class="hash-link" aria-label="Direct link to Red Envelopes" title="Direct link to Red Envelopes" translate="no">​</a></h3>
<p>Holding bright red envelopes, they share the good fortune and joy of the New Year with everyone;</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/1-3a4beccc69067154aa492ea912442955.png" alt="Red Envelopes" width="600px"></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="fireworks">Fireworks<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/20/year-of-snake#fireworks" class="hash-link" aria-label="Direct link to Fireworks" title="Direct link to Fireworks" translate="no">​</a></h3>
<p>Fireworks light up the sky and firecrackers sound, symbolizing renewal and eager anticipation for the future. There are details representing programming languages like C++, Rust, and Lua, signifying our continued exploration of different technological fields in the new year, bringing more surprises and possibilities to Dora SSR.</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/3-1452190db6077ad44c40c24d74a3d515.png" alt="Fireworks" width="600px"></p>
<p>Reflecting on the past year, we have helped each other and progressed together in the community, allowing Dora SSR to grow from an inspiration into a vibrant and evolving open-source game engine. The participation of every enthusiastic contributor, developer, and player is our driving force. Just like the joyful and lively atmosphere in the illustrations, the new year will also be a brand new journey full of opportunities and challenges.</p>
<p>The <strong>snake</strong> in the Chinese zodiac symbolizes <strong>agility, intelligence, and insight</strong>. Like a nimble and adaptable snake, we will continue to lead the Dora SSR project forward through continuous learning, experimentation, and iteration in the new year.</p>
<p>Here, we sincerely wish everyone in the new year:</p>
<ol>
<li class=""><strong>Smooth Coding</strong>: May your work, studies, and development processes be more efficient and effective;</li>
<li class=""><strong>Unlimited Creativity</strong>: Whether in game creation or technical research, may you be inspired with endless ideas;</li>
<li class=""><strong>Good Health</strong>: While programming is important, don't forget to maintain a healthy lifestyle;</li>
<li class=""><strong>All the Best</strong>: Enjoy the Spring Festival with family and friends, and gather more beautiful moments.</li>
</ol>
<p>We sincerely thank every partner for their support and contributions, and we look forward to joining hands again in the new journey of the Year of the Snake in 2025, making Dora SSR even more exciting. Let's unleash our wisdom and passion together, bringing more surprises and emotions to the community.</p>
<p><strong>Wishing you a prosperous Year of the Snake, happiness for your family, and a joyful Spring Festival!</strong></p>]]></content:encoded>
            <category>Chunjie</category>
        </item>
        <item>
            <title><![CDATA[The Story of Writing Bindings for Wa Language]]></title>
            <link>https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa</link>
            <guid>https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa</guid>
            <pubDate>Wed, 15 Jan 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[1. The Beginning]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-the-beginning">1. The Beginning<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa#1-the-beginning" class="hash-link" aria-label="Direct link to 1. The Beginning" title="Direct link to 1. The Beginning" translate="no">​</a></h2>
<p>I've been following the Wa language team and "lurking" in their community for over a year. I was suddenly inspired by an article they published about the essence of open-source spirit. I've always been interested in the progress and survival of their open-source projects. As a core contributor to the Dora SSR project, I know that we are all the same, open-source authors from the working class, not looking down from above, but struggling like sardines in a can.</p>
<p>So, let me announce it here: we have prioritized the implementation of using <strong>Wa language combined with the Dora SSR game engine to develop cross-platform games</strong>!</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-learning-a-programming-language-is-like-weaving-a-cocoon-for-yourself">2. Learning a Programming Language is Like Weaving a Cocoon for Yourself<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa#2-learning-a-programming-language-is-like-weaving-a-cocoon-for-yourself" class="hash-link" aria-label="Direct link to 2. Learning a Programming Language is Like Weaving a Cocoon for Yourself" title="Direct link to 2. Learning a Programming Language is Like Weaving a Cocoon for Yourself" translate="no">​</a></h2>
<p>The goal of the Dora SSR game engine is to create an inclusive and diverse engine ecosystem. Many followers are puzzled as to why this engine supports so many programming languages. Currently, it officially supports Lua, Teal, YueScript, TypeScript, TSX, and Rust for hot update scripts, yet it's still not enough. As someone who has written code and various projects for many years, I understand that no programming language is perfect. If you find a language that seems to do everything, it only means you lack experience and understanding in cross-domain development or haven't been exposed to enough programming languages to develop an aesthetic sense for them.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-the-experience-of-using-wa-language">3. The Experience of Using Wa Language<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa#3-the-experience-of-using-wa-language" class="hash-link" aria-label="Direct link to 3. The Experience of Using Wa Language" title="Direct link to 3. The Experience of Using Wa Language" translate="no">​</a></h2>
<p>Integrating Wa language into the Dora SSR game engine (i.e., providing FFI support) is simple and involves three steps:</p>
<ul>
<li class="">
<ol>
<li class="">Reuse the C API interface exported by the engine for Rust.</li>
</ol>
</li>
<li class="">
<ol start="2">
<li class="">Import the C API interface in Wa language.</li>
</ol>
</li>
<li class="">
<ol start="3">
<li class="">Manually write and automatically generate wrapper interface code for the C API in Wa language to provide a development experience consistent with Wa language style.</li>
</ol>
</li>
</ul>
<p>Then you can develop games using Wa language!</p>
<p>However, saying it's simple is deceptive. The actual integration process is as follows:</p>
<p>Dora SSR is a game engine primarily developed in C++. It interprets and executes Wa language compiled into WASM binary code through an embedded WASM3 virtual machine and provides engine call functionality. The Dora C++ interface currently has over 1000 functions selected to perform necessary engine functions. Writing these interface wrapper codes takes a lot of time, and they need to be updated with the engine, so an automated tool is needed to generate these interface codes.</p>
<p>Our automation tool needs to accomplish the following, using a simple example:</p>
<ul>
<li class="">a. I have a C++ interface:</li>
</ul>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">public</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">int32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">getTargetFPS</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token macro property directive-hash" style="color:#9CDCFE">#</span><span class="token macro property directive keyword" style="color:#C586C0">define</span><span class="token macro property" style="color:#9CDCFE"> </span><span class="token macro property macro-name" style="color:#9CDCFE">SharedApplication</span><span class="token macro property" style="color:#9CDCFE"> </span><span class="token macro property punctuation" style="color:rgb(212, 212, 212)">\</span><span class="token macro property" style="color:#9CDCFE"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token macro property" style="color:#9CDCFE">    </span><span class="token macro property expression class-name" style="color:rgb(78, 201, 176)">Singleton</span><span class="token macro property expression operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token macro property expression" style="color:#9CDCFE">Application</span><span class="token macro property expression operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token macro property expression double-colon punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token macro property expression function" style="color:rgb(220, 220, 170)">shared</span><span class="token macro property expression punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token macro property expression punctuation" style="color:rgb(212, 212, 212)">)</span><br></span></code></pre></div></div>
<ul>
<li class="">b. Convert it to a C language export interface:</li>
</ul>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">extern</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"C"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token class-name" style="color:rgb(78, 201, 176)">int32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">application_get_target_fps</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> SharedApplication</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">getTargetFPS</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<ul>
<li class="">c. Then convert it to a Wa language import interface:</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token plain">#wa</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> dora application_get_target_fps</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">application_get_target_fps</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> i32</span><br></span></code></pre></div></div>
<ul>
<li class="">d. Finally, convert it to a mature Wa language call interface:</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> _App </span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token keyword" style="color:#C586C0">struct</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> _App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">GetTargetFPS</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> i32 </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">application_get_target_fps</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">global App </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> _App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<ul>
<li class="">e. Call it in a Wa language program:</li>
</ul>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"dora"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> init </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token function" style="color:rgb(220, 220, 170)">println</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">dora</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">GetTargetFPS</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<p>Steps b, c, and d are mainly the ones that need to be automated by tools.</p>
<p>But this example is the simplest case. Everyone knows that C++ has many complex mechanisms. Besides basic data types, we need to pass objects, inheritance relationships, type conversions in the inheritance chain, string objects, arrays containing various data types and objects, callback functions for mutual calls between C++ and Wa language, enum data types, static functions, member functions, class static member functions, etc. After handling object passing, a more challenging issue is managing object lifecycles. C++ manages C++, Wa language manages Wa language, and cross-language references need to manage each other.</p>
<p>There are many details that can't be covered here, so please check the source code (no responsibility).</p>
<p>Due to space constraints, I can't introduce everything here, but I'll share an interesting binding mechanism. It's about cross-language callback functions. In the world of C/C++ (and many other languages), the core of function call parameter passing is through a compiler-generated call stack to pass parameters into the function body and retrieve return values. When crossing languages, the call stacks of both languages usually can't directly access each other. So, can we write a call stack that both languages can access to simulate parameter passing and return value retrieval for cross-language function callbacks? This idea is certainly feasible.</p>
<p>For example, in a game loop, we often need to register an Update function called every game frame. There might be a C++ interface like this:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">GameScheduleUpdate</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token plain">function</span><span class="token operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token keyword" style="color:#C586C0">bool</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">double</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token operator" style="color:rgb(212, 212, 212)">&amp;</span><span class="token plain"> updateFunc</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<p>We first implement a function call stack:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">CallStack</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">public</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">push</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">double</span><span class="token plain"> v</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">push</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">bool</span><span class="token plain"> v</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">double</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">popDouble</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">popBool</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<p>Provide a C wrapper function:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">extern</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"C"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">int64_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">new_call_stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">/* Create CallStack object */</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">call_stack_push_bool</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">int64_t</span><span class="token plain"> stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">int32_t</span><span class="token plain"> v</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">/* Push bool */</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">int64_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">call_stack_pop_f64</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">int64_t</span><span class="token plain"> stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">/* Pop double */</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">game_schedule_update</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">int32_t</span><span class="token plain"> funcId</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">int64_t</span><span class="token plain"> stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        std</span><span class="token double-colon punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token plain">shared_ptr</span><span class="token operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token keyword" style="color:#C586C0">void</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">deref</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">nullptr</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">[</span><span class="token plain">funcId</span><span class="token punctuation" style="color:rgb(212, 212, 212)">]</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">auto</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            SharedWasmRuntime</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">deref</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">funcId</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">auto</span><span class="token plain"> args </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:rgb(220, 220, 170)">reinterpret_cast</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">CallStack</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">*</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token function" style="color:rgb(220, 220, 170)">GameScheduleUpdate</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">[</span><span class="token plain">funcId</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> deref</span><span class="token punctuation" style="color:rgb(212, 212, 212)">]</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">double</span><span class="token plain"> deltaTime</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            args</span><span class="token operator" style="color:rgb(212, 212, 212)">-&gt;</span><span class="token function" style="color:rgb(220, 220, 170)">push</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">deltaTime</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">// Pass parameter to Wa language</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            SharedWasmRuntime</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">invoke</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">funcId</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">// Execute callback</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> args</span><span class="token operator" style="color:rgb(212, 212, 212)">-&gt;</span><span class="token function" style="color:rgb(220, 220, 170)">popBool</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">// Retrieve return value from Wa language</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<p>Provide an interface in Wa language to register the Update callback function:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token plain">#wa</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> dora new_call_stack</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">new_call_stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> i64</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">#wa</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> dora call_stack_push_bool</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">call_stack_push_bool</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> i64</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> v</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> i32</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">#wa</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> dora call_stack_pop_f64</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">call_stack_pop_f64</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> i64</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> f64</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">#wa</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> dora game_schedule_update</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">game_schedule_update</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">funcId</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> i32</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> i64</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> _Game</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">ScheduleUpdate</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">update_func</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">func</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">delta_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> f64</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(86, 156, 214)">bool</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    stack </span><span class="token operator" style="color:rgb(212, 212, 212)">:=</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">new_call_stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    func_id </span><span class="token operator" style="color:rgb(212, 212, 212)">:=</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">PushFunction</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">func</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        delta_time </span><span class="token operator" style="color:rgb(212, 212, 212)">:=</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">call_stack_pop_f64</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">// Retrieve parameter from C++</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        result </span><span class="token operator" style="color:rgb(212, 212, 212)">:=</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">update_func</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">delta_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">// Execute actual callback</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            result </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token function" style="color:rgb(220, 220, 170)">call_stack_push_bool</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> result</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token comment" style="color:rgb(106, 153, 85)">// Pass return value to C++</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token function" style="color:rgb(220, 220, 170)">game_schedule_update</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">func_id</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> stack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<p>In a Wa program, you can use a clean program interface like this:</p>
<div class="language-go codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-go codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"dora"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">func</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">init</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    dora</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">Game</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">ScheduleUpdate</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">func</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">delta_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> f64</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(86, 156, 214)">bool</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token function" style="color:rgb(220, 220, 170)">println</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">delta_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token boolean" style="color:#569CD6">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<p>In actual operation, the process is more complex than it seems because Wa language runs on a WASM virtual machine, and interactions between the two languages must go through the WASM virtual machine as an intermediary. The actual callback execution process might look like this:</p>
<!-- -->
<p>This diagram simplifies some aspects, such as the call between the C++ program and the WASM virtual machine, which also goes through an additional process of simulating the call stack through the WASM virtual machine. So, you can see that the current solution for implementing cross-language function callbacks has some performance overhead. In the future, we might explore ways to directly access and reuse the WASM virtual machine's call stack to optimize performance.</p>
<p>Now, let's briefly discuss the issue of object lifecycle management. If we can't find a mechanism to automatically and correctly manage the lifecycle of C++ objects from the language level, we have to manually manage object releases in the new programming language environment. This means accurately arranging to call <code>obj.Destroy()</code> once to release objects, which can be exhausting for those eager to write game logic scripts.</p>
<p>Fortunately, Wa language has an advantage in that both it and the engine's C++ mechanism use reference counting. They even have very similar semantics for managing pointers to objects through reference counting. So, we just need to do this:</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-challenges-encountered-in-practice">4. Challenges Encountered in Practice<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa#4-challenges-encountered-in-practice" class="hash-link" aria-label="Direct link to 4. Challenges Encountered in Practice" title="Direct link to 4. Challenges Encountered in Practice" translate="no">​</a></h2>
<p>Let's talk about the challenges encountered in practice.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="challenge-1-wa-language-author-tells-me-not-to-use-this-language">Challenge 1: Wa Language Author Tells Me Not to Use This Language<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa#challenge-1-wa-language-author-tells-me-not-to-use-this-language" class="hash-link" aria-label="Direct link to Challenge 1: Wa Language Author Tells Me Not to Use This Language" title="Direct link to Challenge 1: Wa Language Author Tells Me Not to Use This Language" translate="no">​</a></h3>
<p>First, let's talk about why I'm so interested in Wa language. In fact, the Dora SSR engine has already implemented WASM bindings for Rust language. For a C++ veteran, Rust language is almost perfect. However, when it comes to quickly developing and iterating on game logic, I have some reservations. It's like trying to write an assignment with a teacher staring at every word you write, constantly criticizing you. Sometimes, due to not understanding the teacher's rules, you end up spending more time arguing and rewriting the assignment.</p>
<p>Wa language goes in the opposite direction of Rust. It has a Go-like design, emphasizing simplicity in language rules.</p>
<p>It doesn't have complex syntax challenges or mandatory elegant coding styles. You can quickly patch together your business logic with a minimal syntax set. I like this style so much that when I initially communicated with the core author of Wa language, I was warned that the project might not be mature, and I shouldn't have high expectations. I said, "If I can eat Rust crabs (Rust logo here), why not Wa?" If I encounter bugs in the language, I'll contribute to fixing them. Then came Challenge 2, where I did encounter bugs and contributed to fixing them.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="challenge-2-the-inevitable-path-of-software-engineering">Challenge 2: The Inevitable Path of Software Engineering<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa#challenge-2-the-inevitable-path-of-software-engineering" class="hash-link" aria-label="Direct link to Challenge 2: The Inevitable Path of Software Engineering" title="Direct link to Challenge 2: The Inevitable Path of Software Engineering" translate="no">​</a></h3>
<p>To be honest, the Dora SSR open-source game engine project has the same issue. Developing open-source software, since it's called software development, naturally faces the realities of software engineering. People used to joke that open-source projects are a novel form of unpaid crowd-sourced testing (labor exploitation). To develop a mature, stable, and powerful software, taking a steady path of requirement design, development, and testing, and investing sufficient manpower and time are essential. As an open-source developer working in my spare time, even a genius who can do the work of ten people can't match the resource costs needed to create the perfect software. So, using open-source co-creation, engaging in a long-term struggle and people's war, is the only way to achieve some wonders and create technical assets accessible to everyone.</p>
<p>During the process of creating Wa language bindings, I did encounter some compiler bugs. Within a few days of getting started, I submitted five issues to the author. One issue was critical because my code couldn't run without fixing it, so I had to read and study the Wa language compiler's source code to find a solution.</p>
<p>So, I submitted this issue: <a href="https://github.com/wa-lang/wa/issues/67" target="_blank" rel="noopener noreferrer" class="">https://github.com/wa-lang/wa/issues/67</a></p>
<p>And this corresponding fix PR: <a href="https://github.com/wa-lang/wa/pull/68" target="_blank" rel="noopener noreferrer" class="">https://github.com/wa-lang/wa/pull/68</a></p>
<p>I feel that open-source projects often have a strange pattern: the more issues you see submitted, the fewer problems you might encounter when using the project yourself. Users discovering and submitting issues is also a necessary labor investment in building a software project. The more issues you help an open-source project discover, the fewer long-term problems it will have. This interaction model is healthy and is the charm of open-source software projects. You are not just an irrelevant bystander; even participating in observation and trial use is a significant force in building it. Most importantly, the results of the construction are shared with you.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="challenge-3-where-is-the-path">Challenge 3: Where is the Path?<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa#challenge-3-where-is-the-path" class="hash-link" aria-label="Direct link to Challenge 3: Where is the Path?" title="Direct link to Challenge 3: Where is the Path?" translate="no">​</a></h3>
<p>Have you noticed that this article hasn't mentioned the popular large language models? Not jumping on the bandwagon?</p>
<p>Because developing a new language today is likely to be isolated from LLM assistance (not really). Fortunately, Wa language is still relatively similar to Go language, so code generated for Go can be adapted for Wa. Many people think that with AI large models, programming development has no value, but that's just a parallel universe that capitalists hope for. As developers who create the real world through practice, the world is what it is through our perception and direct creation with our hands. As an exploration of native languages on WASM, I realize the great value of Wa. For example, I can't delve into how Rust language's complex engineering implements compilation to WASM and interaction, but studying Wa has helped me quickly grasp many WASM knowledge details. With this practical experience, I can personally accept the actual value brought by authors initiating a new language.</p>
<p>So, I call on everyone to join in the wave of creating programming languages. Whether it's creating native, WASM, or Lua VM transpiled languages, use "one person, one language" to build a new world led by individuals rather than LLM automatically generated. If you dare to invent a new programming language, I dare to integrate a game runtime for your work through the Dora SSR open-source project, expanding the boundaries of your work.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-related-code-repository-links">5. Related Code Repository Links<a href="https://ippclub.gitee.io/Dora-SSR/blog/2025/1/15/dora-wa#5-related-code-repository-links" class="hash-link" aria-label="Direct link to 5. Related Code Repository Links" title="Direct link to 5. Related Code Repository Links" translate="no">​</a></h2>
<ul>
<li class="">Wa language development package for Dora SSR: <a href="https://github.com/IppClub/dora-wa" target="_blank" rel="noopener noreferrer" class="">https://github.com/IppClub/dora-wa</a></li>
<li class="">Wa language: <a href="https://github.com/wa-lang/wa" target="_blank" rel="noopener noreferrer" class="">https://github.com/wa-lang/wa</a></li>
<li class="">Dora SSR open-source game engine: <a href="https://github.com/IppClub/Dora-SSR" target="_blank" rel="noopener noreferrer" class="">https://github.com/IppClub/Dora-SSR</a></li>
</ul>]]></content:encoded>
            <category>Dora SSR</category>
            <category>Wa-lang</category>
        </item>
        <item>
            <title><![CDATA[Dora SSR: A New Experience in Game Development]]></title>
            <link>https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview</link>
            <guid>https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview</guid>
            <pubDate>Wed, 14 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Reflections on Game Engine Development]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="reflections-on-game-engine-development">Reflections on Game Engine Development<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#reflections-on-game-engine-development" class="hash-link" aria-label="Direct link to Reflections on Game Engine Development" title="Direct link to Reflections on Game Engine Development" translate="no">​</a></h2>
<p>There was a time when every major breakthrough in game engines led to significant technological advancements in the industry, such as the transition from 2D to 3D rendering or from basic lighting to real-time shadows and physics simulations. These innovations opened up endless possibilities for game development and propelled the industry forward. However, as technology has matured, such disruptive innovations have become less common.</p>
<!-- -->
<p>Today, the focus in game engine development has shifted toward <strong>optimizing and improving existing technologies</strong> to enhance user experience and development efficiency. Especially in open-source engine projects, the integration and refinement of existing open-source libraries have become increasingly important. Open-source developers often lack the resources and manpower to build everything from scratch, such as physics engines, font loaders, or animation runtime systems. In other words, much of the work in open-source game engine development involves <strong>integrating popular third-party libraries</strong>.</p>
<p>This approach not only boosts development efficiency but also makes the game engine more flexible, better catering to the diverse needs of game development. By reusing existing open-source libraries, developers can focus on creating innovative gameplay and content rather than reinventing the wheel. In this way, game engine development becomes more like <strong>building a service platform</strong>, providing developers with the necessary infrastructure to focus on their creative pursuits.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="positioning-of-the-dora-ssr-engine">Positioning of the Dora SSR Engine<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#positioning-of-the-dora-ssr-engine" class="hash-link" aria-label="Direct link to Positioning of the Dora SSR Engine" title="Direct link to Positioning of the Dora SSR Engine" translate="no">​</a></h2>
<p>Speaking of service platforms, the Dora SSR open-source game engine we are developing is positioned as <strong>a user-friendly, cross-device compatible game engine and development toolchain</strong>. Compared to the Godot engine, which includes a built-in development IDE, Dora SSR differs in that its <strong>integrated game editor</strong> is a <strong>Web application</strong> developed using ReactJS.</p>
<p>This means that Dora’s editor and runtime can run independently across different platforms and even on various hardware devices. As a result, the game under development and the IDE do not interfere with each other within the same process, nor do they compete for resources. Ultimately, it is still possible to package the runtime and development tools into an app or installation package, much like Godot, making it easy to distribute. Preparing a game development environment becomes as simple as installing a mobile app.</p>
<p>However, Dora SSR currently does not fully support 3D rendering. Although the game scene nodes have Z coordinates and rotation attributes for the XY axes, and a 3D camera is used by default, 3D animation models, material management, and a complete 3D rendering pipeline are yet to be implemented. Given the limited resources of the project maintainers, we also lack the capability to create advanced 3D art assets and games, which is a limitation faced by open-source developers without substantial financial backing.</p>
<p>But, does that mean we should abandon what we love just because we can't be the best?</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="open-source-open-source-and-open-source">Open Source, Open Source, and Open Source!<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#open-source-open-source-and-open-source" class="hash-link" aria-label="Direct link to Open Source, Open Source, and Open Source!" title="Direct link to Open Source, Open Source, and Open Source!" translate="no">​</a></h2>
<p>Of course not. We are developing an open-source game engine because of our deep passion for this endeavor. <strong>Open-source culture</strong> represents sharing, collaboration, and innovation, values that resonate strongly with us. Open-source is not just a development model; it's a belief—a belief that everyone can contribute to technological advancement and the growth of their field of interest, regardless of the scale.</p>
<p>In the gaming industry, the significance of open source is particularly profound. Through open source, more developers can participate, collectively refining and optimizing the engine, and driving continuous technological progress. Moreover, open source provides learning and growth opportunities for all, from beginners to seasoned developers. For me, witnessing open-source projects improve through collective effort and seeing more people finding their dreams through open source is incredibly exciting.</p>
<p>I envision a more <strong>open and collaborative</strong> world of <strong>game creation</strong>: a world where everyone with creativity can freely access and use various resources to bring their ideas to life without hindrance. Developers can freely distribute and share their work, receiving feedback and suggestions from around the globe. Such an open environment not only accelerates technological development but also nurtures more talented developers, advancing the entire industry. As a gaming enthusiast, the idea of having more unique and special game choices in the future, thanks to everyone's collaborative efforts, is thrilling.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="lets-talk-about-getting-hands-on">Let's Talk About Getting Hands-On!<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#lets-talk-about-getting-hands-on" class="hash-link" aria-label="Direct link to Let's Talk About Getting Hands-On!" title="Direct link to Let's Talk About Getting Hands-On!" translate="no">​</a></h2>
<p>The current version (v1.5.1) of the Dora SSR engine is structured as follows:</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/dora-ssr-architecture-9c099a74eb1b150796aea0c9b6aa6238.png" alt="Dora SSR Architecture"></p><p>Dora SSR Architecture</p><p></p>
<p>In summary, Dora SSR's software architecture is divided into three layers: <strong>Hardware Abstraction Layer, Core Engine Functionality Layer, and User Interface Layer</strong>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="hardware-abstraction-layer">Hardware Abstraction Layer<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#hardware-abstraction-layer" class="hash-link" aria-label="Direct link to Hardware Abstraction Layer" title="Direct link to Hardware Abstraction Layer" translate="no">​</a></h3>
<p>Firstly, the Hardware Abstraction Layer ensures that Dora SSR can run on various operating systems and hardware platforms. Whether it's Windows, Linux, macOS, or mobile devices like iOS and Android, Dora SSR achieves cross-platform compatibility through SDL2 and the Render Hardware Interface (RHI) technology framework, bgfx. bgfx serves as an abstraction layer, providing a unified interface for underlying rendering technologies such as OpenGL, Metal, DirectX, and Vulkan. These technologies address the adaptation to <strong>operating system interfaces</strong> and <strong>graphics rendering interfaces</strong>, ensuring efficient performance across different hardware environments.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="core-engine-functionality-layer">Core Engine Functionality Layer<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#core-engine-functionality-layer" class="hash-link" aria-label="Direct link to Core Engine Functionality Layer" title="Direct link to Core Engine Functionality Layer" translate="no">​</a></h3>
<p>Next is the Core Engine Functionality Layer, the "heart" of Dora SSR. It includes several sub-functional layers, each responsible for different engine functions:</p>
<ul>
<li class=""><strong>Rendering Layer</strong>: Comprising Line Renderer, Sprite Renderer, VG Renderer, and ImGui Renderer, these renderers handle various graphical rendering requests in batches.</li>
<li class=""><strong>Feature Layer</strong>: Encompassing basic modules like Physics, Assets (resource management), Graphics, Network, Audio, and ML (machine learning).</li>
<li class=""><strong>Game Framework Layer</strong>: Including modules like Platformer Game, AI (artificial intelligence), Unit (unit management), and Action (action management) to support game logic and gameplay.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="user-interface-layer">User Interface Layer<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#user-interface-layer" class="hash-link" aria-label="Direct link to User Interface Layer" title="Direct link to User Interface Layer" translate="no">​</a></h3>
<p>Finally, the User Interface Layer is where developers directly interact with the engine. Dora SSR offers a powerful Web IDE, integrating the work of other open-source projects like Monaco Editor (frontend of VSCode), Code Wire (visual script editor), Yarn Editor (game script editor), Spine Player (Spine2D animation preview), and TypeScript compiler. These tools are brought together to provide developers with a comprehensive, user-friendly development environment, allowing them to quickly get started and focus on realizing their creativity.</p>
<p>Additionally, the User Interface Layer includes the runtime and language compilers that load, compile, and execute the game scripts written by developers. It supports multiple scripting languages through Lua VM, WASM VM, YueScript compiler, Teal compiler, and various language bindings, offering developers flexibility in choosing languages for game development.</p>
<p>The architecture of Dora SSR is designed with cross-platform compatibility, modular functionality, and user experience in mind. Through its open-source nature, Dora SSR invites more developers to participate and contribute to creating a powerful and flexible game development platform. By organizing its architecture into distinct, scalable layers, Dora SSR simplifies the development process and provides rich feature support, making game development more accessible and enjoyable.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="dora-ssr-from-a-user-functionality-perspective">Dora SSR from a User Functionality Perspective<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#dora-ssr-from-a-user-functionality-perspective" class="hash-link" aria-label="Direct link to Dora SSR from a User Functionality Perspective" title="Direct link to Dora SSR from a User Functionality Perspective" translate="no">​</a></h3>
<p>From a user functionality perspective, the Dora SSR open-source engine is divided into two main parts: the engine runtime and the Web IDE. The engine runtime can operate independently of the Web IDE and external resources. By simply removing the scripts and resources required by the Web IDE from the published engine, you can obtain a pure Dora SSR runtime program, which can be used to load developed games and resources and package them for standalone release.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="dora-ssr-engine-execution-process">Dora SSR Engine Execution Process<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#dora-ssr-engine-execution-process" class="hash-link" aria-label="Direct link to Dora SSR Engine Execution Process" title="Direct link to Dora SSR Engine Execution Process" translate="no">​</a></h3>
<p>The execution process of the Dora SSR engine can be easily understood from the perspective of data flow. Essentially, the game scripts written by users are handling game logic data processing and submission operations. Once this data is submitted to the core engine modules, further data transformation, processing, and merging occur, ultimately generating the data needed by the GPU for rendering. This results in various forms of feedback and interaction, including but not limited to graphical updates and displays.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="showcase-of-some-web-ide-features">Showcase of Some Web IDE Features<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#showcase-of-some-web-ide-features" class="hash-link" aria-label="Direct link to Showcase of Some Web IDE Features" title="Direct link to Showcase of Some Web IDE Features" translate="no">​</a></h2>
<ul>
<li class=""><strong>Code Editor</strong></li>
</ul>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/1-1814ea2a8a51ee7069ed0f550e08f8d2.jpg" alt="Dora SSR Code Editor"></p><p>Dora SSR Code Editor</p><p></p>
<p>Dora SSR’s Web IDE offers a fully-featured code editor that supports multiple programming languages and file types. In this demo image, we can see users writing TypeScript code and using TSX to define and control the behavior of game objects. The file tree on the left displays the project’s resource structure, including scripts, assets, and configuration files. The code editor features syntax highlighting, auto-completion, and document navigation, enhancing development efficiency. Additionally, the small window at the bottom right shows the real-time preview of the engine runtime, allowing developers to <strong>immediately see</strong> the <strong>effects</strong> of their code changes.</p>
<ul>
<li class=""><strong>Yarn Spinner Script Editor</strong></li>
</ul>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/2-2990bda867454d1ce44807d0efdf3a0f.jpg" alt="Dora SSR Story Editor"></p><p>Dora SSR Story Editor</p><p></p>
<p>The Dora SSR Web IDE integrates the Yarn Spinner script editor, providing a visual and efficient storytelling tool for game developers. In this demo image, you can see the interface of the Yarn Spinner editor, where the user is writing an interactive script with decision points. The central editing window shows the script content being edited, supporting rich text formatting and simple tags like <code>&lt;&lt;jump&gt;&gt;</code> for story branching.</p>
<p>The visual node graph on the right illustrates the script’s flow, with each node representing a story segment, connected by lines to show the story’s progression and decision paths. This graphical script editing approach allows developers to intuitively design and adjust the narrative flow.</p>
<p>Yarn Spinner’s features not only improve the efficiency of game script writing and testing but also facilitate the design and management of complex narratives, making Dora SSR’s Web IDE a comprehensive game development platform.</p>
<ul>
<li class=""><strong>Visual Script Editor</strong></li>
</ul>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/3-1603fcfe5317a389453642c43047242c.jpg" alt="Dora SSR Visual Script Editor"></p><p>Dora SSR Visual Script Editor</p><p></p>
<p>The Dora SSR Web IDE includes a Visual Script Editor, primarily aimed at <strong>beginners in programming</strong>, especially teenagers, to help them transition smoothly into programming and enhance their experience. In this demo image, you can see the interface of the Visual Script Editor, which uses a graphical programming approach, allowing users to create program logic by dragging and connecting different nodes.</p>
<p>The left panel displays variable management features, enabling users to easily add and manage variables. The central workspace shows various nodes, including loops, conditional statements, and array operations. Users can connect these nodes in an intuitive way to build complex program logic. The right panel, which is collapsible, allows users to view the compiled Teal code, which is used by the engine to execute the visual script.</p>
<p>This graphical programming approach lowers the barrier to entry for programming, allowing beginners to grasp and implement basic programming concepts without needing to master complex syntax. For teenagers, this approach not only makes learning more enjoyable but also fosters logical thinking and problem-solving skills, helping more people easily enter the world of programming.</p>
<ul>
<li class=""><strong>Spine Animation Preview</strong></li>
</ul>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/4-3f8ab5a8efa6201c4a27bd1bd2f4fcf4.jpg" alt="Dora SSR Animation Preview"></p><p>Dora SSR Animation Preview</p><p></p>
<p>The Dora SSR Web IDE also integrates a Spine2D animation model preview feature. This feature allows developers to easily view and adjust Spine animation models, including switching the model’s skin and playing different animations, helping ensure that Spine animation models are loaded and played correctly in the program.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="user-experience-of-game-development-on-various-devices">User Experience of Game Development on Various Devices<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#user-experience-of-game-development-on-various-devices" class="hash-link" aria-label="Direct link to User Experience of Game Development on Various Devices" title="Direct link to User Experience of Game Development on Various Devices" translate="no">​</a></h2>
<p>Lastly, let’s talk about user experience. Earlier, I mentioned that Dora SSR aims to make setting up a game development environment as quick and simple as installing and using an app. Can Dora really achieve this?</p>
<p>We have already been experimenting with running Dora SSR on various mobile devices, handheld consoles, and embedded devices, utilizing remote access to the Web IDE for game development and testing. Whether on Raspberry Pi, domestic MCUs, or high-performance SoCs on mobile phones, Dora SSR offers a relatively smooth experience. Even on some niche mobile devices with built-in keyboards and trackballs, we can run the engine and access the development environment locally through a browser, turning game development into an activity accessible anytime, anywhere.</p>
<p>However, to ensure a good user experience, we recommend using at least a larger screen and a keyboard-equipped Android tablet or iPad to remotely access and use the Web IDE for game development on small-screen devices, providing a more comfortable game development experience. Whether at home, in a café, or outdoors, Dora SSR offers developers a game development environment that can be accessed anytime, anywhere, removing the constraints of device and location.</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/dev-everywhere-1580ed46ea92ee7ed14ac91a39afbb68.jpg" alt="Dora SSR Cross-Platform Development"></p><p>Dora SSR Cross-Platform Development</p><p></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="join-our-community">Join Our Community<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#join-our-community" class="hash-link" aria-label="Direct link to Join Our Community" title="Direct link to Join Our Community" translate="no">​</a></h2>
<p>If you’re interested in Dora SSR, we welcome you to join our community, where we can discuss, share ideas, and collaborate together. You can find us at the following locations:</p>
<ul>
<li class="">GitHub: <a href="https://github.com/IppClub/Dora-SSR" target="_blank" rel="noopener noreferrer" class="">https://github.com/IppClub/Dora-SSR</a></li>
<li class="">Gitee: <a href="https://gitee.com/pig/Dora-SSR" target="_blank" rel="noopener noreferrer" class="">https://gitee.com/pig/Dora-SSR</a></li>
<li class="">GitCode: <a href="https://gitcode.com/ippclub/Dora-SSR" target="_blank" rel="noopener noreferrer" class="">https://gitcode.com/ippclub/Dora-SSR</a></li>
</ul>
<p>We look forward to your participation in advancing open-source game engines!</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="coming-soon">Coming Soon<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/8/14/dora-ssr-overview#coming-soon" class="hash-link" aria-label="Direct link to Coming Soon" title="Direct link to Coming Soon" translate="no">​</a></h2>
<p>In the upcoming series of articles, we will delve into the various modules of Dora SSR, giving you a detailed understanding of the internal workings and implementation techniques of this ever-evolving game engine. Stay tuned for our updates!</p>]]></content:encoded>
            <category>Dora SSR</category>
        </item>
        <item>
            <title><![CDATA[An Introduction to Cross-Platform Game Development for Frontend Developers]]></title>
            <link>https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro</link>
            <guid>https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro</guid>
            <pubDate>Thu, 25 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Hello everyone! I’m a game engine enthusiast and a programmer with a solid background in frontend development. If you’ve ever wondered how to transition from crafting websites to developing games, you’re in the right place!]]></description>
            <content:encoded><![CDATA[<p>Hello everyone! I’m a game engine enthusiast and a programmer with a solid background in frontend development. If you’ve ever wondered how to transition from crafting websites to developing games, you’re in the right place!</p>
<p>Today, let’s talk about using Dora SSR—a game engine that supports TSX and runs cross-platform natively. It’s a seamless way to step into the world of game development. Don’t worry, game engines aren’t as inaccessible as they might seem; in fact, they have surprising similarities to the frontend tools we’re used to.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-game-client-development-as-frontend-development">1. Game Client Development as Frontend Development<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#1-game-client-development-as-frontend-development" class="hash-link" aria-label="Direct link to 1. Game Client Development as Frontend Development" title="Direct link to 1. Game Client Development as Frontend Development" translate="no">​</a></h2>
<p>First off, let’s define what a game engine is. Simply put, a game engine is a collection of tools and libraries that help developers build games, handling graphics, sound, physics calculations, or collision detection. For frontend developers, think of it as a specialized browser that runs games.</p>
<p>Dora SSR manages game scenes with a tree structure similar to the HTML DOM—quite familiar territory for us. Imagine swapping out HTML div elements with various game objects and replacing CSS animations with game animations. The concepts and even some of the coding practices are not that different. Exciting, isn’t it?</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-from-typescript-to-tsx-applying-frontend-tech-in-games">2. From TypeScript to TSX: Applying Frontend Tech in Games<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#2-from-typescript-to-tsx-applying-frontend-tech-in-games" class="hash-link" aria-label="Direct link to 2. From TypeScript to TSX: Applying Frontend Tech in Games" title="Direct link to 2. From TypeScript to TSX: Applying Frontend Tech in Games" translate="no">​</a></h2>
<p>Many frontend developers are familiar with TypeScript and React’s JSX syntax. In the open-source Dora SSR game engine, we embrace TSX, offering a game development interface similar to frontend programming patterns. Yes, you heard that right—TSX!</p>
<p>Developing games with TSX means you can leverage your existing frontend tech stack—components, modules, and other modern frontend technologies—directly in game development. Moreover, Dora SSR’s performance optimizations ensure smooth operations even in complex game scenarios.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-challenge-craft-an-angry-birds-like-game-in-under-100-lines-of-code">3. Challenge: Craft an "Angry Birds"-like Game in Under 100 Lines of Code<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#3-challenge-craft-an-angry-birds-like-game-in-under-100-lines-of-code" class="hash-link" aria-label="Direct link to 3. Challenge: Craft an &quot;Angry Birds&quot;-like Game in Under 100 Lines of Code" title="Direct link to 3. Challenge: Craft an &quot;Angry Birds&quot;-like Game in Under 100 Lines of Code" translate="no">​</a></h2>
<p>Enough with the theory; let’s dive into some practical work. Let’s see how to write a game similar to "Angry Birds" using less than 100 lines of TSX code in Dora SSR. Before starting, setting up the development environment with Dora SSR is straightforward: install the package, open the browser, and let’s start coding! For installation and getting started, see: <a href="https://dora-ssr.net/zh-Hans/docs/tutorial/quick-start" target="_blank" rel="noopener noreferrer" class="">Dora Startup!</a></p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/dora-on-android-61f4254f2bb8648cc2d994871d429301.jpg" alt="Accidentally installed as an APK on your phone? Access it over the same local network for on-device development and debugging"></p><p>Accidentally installed as an APK on your phone? Access it over the same local network for on-device development and debugging</p><p></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-crafting-the-simplest-game-scene">1. Crafting the Simplest Game Scene<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#1-crafting-the-simplest-game-scene" class="hash-link" aria-label="Direct link to 1. Crafting the Simplest Game Scene" title="Direct link to 1. Crafting the Simplest Game Scene" translate="no">​</a></h3>
<p>Before diving into the actual code, we can start with a special comment that tells Dora SSR’s Web IDE to automatically hot-reload the code upon saving with Ctrl + S, allowing real-time preview of the code execution results.</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token comment" style="color:rgb(106, 153, 85)">// @preview-file on</span><br></span></code></pre></div></div>
<p>We then import the necessary libraries and components. Our code editor also assists by automatically suggesting the required modules, which can be included later in the coding process:</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">React</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> toNode</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> useRef </span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'DoraX'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">Body</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">BodyMoveType</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">Ease</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">Label</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">Line</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">Scale</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">TypeName</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:#4EC9B0">Vec2</span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token imports"> tolua </span><span class="token imports punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">'Dora'</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<p>Displaying an image in Dora SSR is simple, just use the <code>&lt;sprite&gt;</code> tag, and then instantiate it into a game object with the <code>toNode()</code> function.</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token function" style="color:rgb(220, 220, 170)">toNode</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">sprite</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">file</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(212, 212, 212)">=</span><span class="token tag attr-value punctuation" style="color:rgb(212, 212, 212)">'</span><span class="token tag attr-value" style="color:rgb(206, 145, 120)">Image/logo.png</span><span class="token tag attr-value punctuation" style="color:rgb(212, 212, 212)">'</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">scaleX</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0.2</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">scaleY</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0.2</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<p>Now, you’ve pretty much got the hang of most of Dora SSR’s game development tricks. Start creating your own game (seriously).</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-crafting-the-game-box-component">2. Crafting the Game Box Component<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#2-crafting-the-game-box-component" class="hash-link" aria-label="Direct link to 2. Crafting the Game Box Component" title="Direct link to 2. Crafting the Game Box Component" translate="no">​</a></h3>
<p>Next, the colliding boxes in our game are defined by the <code>Box</code> component, which accepts properties such as <code>num</code>, <code>x</code>, <code>y</code>, and <code>children</code>:</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">interface</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">BoxProps</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	num</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(86, 156, 214)">number</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	x</span><span class="token operator" style="color:rgb(212, 212, 212)">?</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(86, 156, 214)">number</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	y</span><span class="token operator" style="color:rgb(212, 212, 212)">?</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(86, 156, 214)">number</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	children</span><span class="token operator" style="color:rgb(212, 212, 212)">?</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(86, 156, 214)">any</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">|</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(86, 156, 214)">any</span><span class="token punctuation" style="color:rgb(212, 212, 212)">[</span><span class="token punctuation" style="color:rgb(212, 212, 212)">]</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:rgb(220, 220, 170)">Box</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">props</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:#4EC9B0">BoxProps</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	</span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> numText </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> props</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token property-access">num</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token method function property-access" style="color:rgb(220, 220, 170)">toString</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	</span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">		</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">body</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">type</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript maybe-class-name" style="color:#4EC9B0">BodyMoveType</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access maybe-class-name" style="color:#4EC9B0">Dynamic</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">scaleX</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">scaleY</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">x</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">props</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">x</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">y</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">props</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">y</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">tag</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">numText</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">			</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">rect-fixture</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">width</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">100</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">height</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">100</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">			</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">draw-node</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">				</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">rect-shape</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">width</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">100</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">height</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">100</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">fillColor</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0x8800ffff</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">borderWidth</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">1</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">borderColor</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0xff00ffff</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">			</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">draw-node</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">			</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">label</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">fontName</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(212, 212, 212)">=</span><span class="token tag attr-value punctuation" style="color:rgb(212, 212, 212)">'</span><span class="token tag attr-value" style="color:rgb(206, 145, 120)">sarasa-mono-sc-regular</span><span class="token tag attr-value punctuation" style="color:rgb(212, 212, 212)">'</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">fontSize</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">40</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain">numText</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">label</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">			</span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain">props</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token property-access">children</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">		</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">body</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<p>We use a React-like functional component approach to define our box components, where:</p>
<ul>
<li class=""><code>body</code> component’s <code>tag</code> attribute: stores the score of the box.</li>
<li class=""><code>rect-fixture</code>: defines the collision shape of the box.</li>
<li class=""><code>draw-node</code>: used to render the appearance of the box.</li>
<li class=""><code>label</code>: displays the score on the box.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-creating-tsx-instantiated-object-references">3. Creating TSX-Instantiated Object References<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#3-creating-tsx-instantiated-object-references" class="hash-link" aria-label="Direct link to 3. Creating TSX-Instantiated Object References" title="Direct link to 3. Creating TSX-Instantiated Object References" translate="no">​</a></h3>
<p>Use <code>useRef</code> to create two reference variables for later use, one for the bird and one for the score label:</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> bird </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:rgb(220, 220, 170)">useRef</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">Body</span><span class="token generic-function generic class-name punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">Type</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> score </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:rgb(220, 220, 170)">useRef</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">Label</span><span class="token generic-function generic class-name punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">Type</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-creating-the-launch-line">4. Creating the Launch Line<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#4-creating-the-launch-line" class="hash-link" aria-label="Direct link to 4. Creating the Launch Line" title="Direct link to 4. Creating the Launch Line" translate="no">​</a></h3>
<p>The launch line is created by the <code>line</code> variable, and touch (or mouse click) event handling is added:</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> start </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:#4EC9B0">Vec2</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token property-access">zero</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> delta </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:#4EC9B0">Vec2</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token property-access">zero</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> line </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">Line</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token function" style="color:rgb(220, 220, 170)">toNode</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">physics-world</span><span class="token tag" style="color:#569CD6"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag" style="color:#569CD6">		</span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">onTapBegan</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">touch </span><span class="token tag script language-javascript arrow operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			start </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> touch</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">location</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			line</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">clear</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">		</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag" style="color:#569CD6">		</span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">onTapMoved</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">touch </span><span class="token tag script language-javascript arrow operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			delta </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> delta</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">add</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">touch</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">delta</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			line</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">set</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">[</span><span class="token tag script language-javascript" style="color:#D4D4D4">start</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token tag script language-javascript" style="color:#D4D4D4"> start</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">add</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">delta</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">]</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">		</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag" style="color:#569CD6">		</span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">onTapEnded</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript arrow operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			</span><span class="token tag script language-javascript keyword" style="color:#C586C0">if</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">!</span><span class="token tag script language-javascript" style="color:#D4D4D4">bird</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">current</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript keyword" style="color:#C586C0">return</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			bird</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">current</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">velocity</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> delta</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">mul</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript function" style="color:rgb(220, 220, 170)">Vec2</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript number" style="color:#B5CEA8">10</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript number" style="color:#B5CEA8">10</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			start </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript maybe-class-name" style="color:#4EC9B0">Vec2</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">zero</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			delta </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript maybe-class-name" style="color:#4EC9B0">Vec2</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">zero</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			line</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">clear</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">		</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag" style="color:#569CD6">		</span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">onMounted</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">world </span><span class="token tag script language-javascript arrow operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			world</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">addChild</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">line</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">		</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">		</span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token comment" style="color:rgb(106, 153, 85)">/* ...create other game elements under the physics world... */</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">physics-world</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<ul>
<li class="">In the <code>onTapBegan</code> event, record the starting touch location and clear the launch line.</li>
<li class="">In the <code>onTapMoved</code> event, calculate the distance moved by the touch and update the launch line.</li>
<li class="">In the <code>onTapEnded</code> event, set the launch velocity of the bird based on the touch movement and clear the launch line.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-creating-other-game-elements">5. Creating Other Game Elements<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#5-creating-other-game-elements" class="hash-link" aria-label="Direct link to 5. Creating Other Game Elements" title="Direct link to 5. Creating Other Game Elements" translate="no">​</a></h3>
<p>Next, we continue creating other elements in the game scene under the <code>&lt;physics-world&gt;</code> parent tag:</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="51-ground">5.1 Ground<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#51-ground" class="hash-link" aria-label="Direct link to 5.1 Ground" title="Direct link to 5.1 Ground" translate="no">​</a></h4>
<p>First, we use the <code>body</code> component to create the ground and set it as a static body:</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">body</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">type</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript maybe-class-name" style="color:#4EC9B0">BodyMoveType</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access maybe-class-name" style="color:#4EC9B0">Static</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">rect-fixture</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">centerY</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">-</span><span class="token tag script language-javascript number" style="color:#B5CEA8">200</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">width</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">2000</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">height</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">10</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">draw-node</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">		</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">rect-shape</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">centerY</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">-</span><span class="token tag script language-javascript number" style="color:#B5CEA8">200</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">width</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">2000</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">height</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">10</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">fillColor</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0xfffbc400</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">draw-node</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text"></span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">body</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><br></span></code></pre></div></div>
<ul>
<li class=""><code>type={BodyMoveType.Static}</code>: indicates this is a static body, unaffected by physics simulations.</li>
<li class=""><code>rect-fixture</code>: defines the ground’s collision shape as a rectangle.</li>
<li class=""><code>draw-node</code>: used to render the appearance of the ground.</li>
<li class=""><code>rect-shape</code>: draws a rectangle in yellow color.</li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="52-boxes">5.2 Boxes<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#52-boxes" class="hash-link" aria-label="Direct link to 5.2 Boxes" title="Direct link to 5.2 Boxes" translate="no">​</a></h4>
<p>Next, we use the previously defined <code>Box</code> component to create 5 boxes with different initial positions and scores, and play their entrance animations upon creation:</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(212, 212, 212)">[</span><span class="token number" style="color:#B5CEA8">10</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">20</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">30</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">40</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">50</span><span class="token punctuation" style="color:rgb(212, 212, 212)">]</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token method function property-access" style="color:rgb(220, 220, 170)">map</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">num</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> i</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">		</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag class-name" style="color:rgb(78, 201, 176)">Box</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">num</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">num</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">x</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">200</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">y</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">-</span><span class="token tag script language-javascript number" style="color:#B5CEA8">150</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">+</span><span class="token tag script language-javascript" style="color:#D4D4D4"> i </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">*</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript number" style="color:#B5CEA8">100</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">			</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">sequence</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">				</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">delay</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">time</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">i </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">*</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript number" style="color:#B5CEA8">0.2</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">				</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">scale</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">time</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0.3</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">start</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">stop</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">1</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">			</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">sequence</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">		</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag class-name" style="color:rgb(78, 201, 176)">Box</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<ul>
<li class=""><code>map</code> function: used to iterate through an array of scores from 10 to 50, creating a box for each score that needs to be hit by the bird.</li>
<li class=""><code>Box</code> component: used to create boxes, with the following properties passed:<!-- -->
<ul>
<li class=""><code>num={num}</code>: the score of the box, corresponding to the number in the array.</li>
<li class=""><code>x={200}</code>: the initial x-axis position of the box, set at 200.</li>
<li class=""><code>y={-150 + i * 100}</code>: the initial y-axis position of the box, incrementally adjusted based on the creation index.</li>
</ul>
</li>
<li class=""><code>sequence</code> component: used to create an animation sequence to be played on the parent node, including the following animations:<!-- -->
<ul>
<li class=""><code>delay time={i * 0.2}</code>: delays the animation playback, with the delay time incrementing based on the creation index.</li>
<li class=""><code>scale time={0.3} start={0} stop={1}</code>: scale animation, from not visible to fully visible, lasting 0.3 seconds.</li>
</ul>
</li>
</ul>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="53-bird">5.3 Bird<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#53-bird" class="hash-link" aria-label="Direct link to 5.3 Bird" title="Direct link to 5.3 Bird" translate="no">​</a></h4>
<p>Lastly, we use the <code>body</code> component to create the bird and set its collision shape, appearance, and score label:</p>
<div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">body</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">ref</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">bird</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">type</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript maybe-class-name" style="color:#4EC9B0">BodyMoveType</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access maybe-class-name" style="color:#4EC9B0">Dynamic</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">x</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">-</span><span class="token tag script language-javascript number" style="color:#B5CEA8">200</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">y</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">-</span><span class="token tag script language-javascript number" style="color:#B5CEA8">150</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">onContactStart</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">other</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript arrow operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">		</span><span class="token tag script language-javascript keyword" style="color:#C586C0">if</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">other</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">tag</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">!==</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript string" style="color:rgb(206, 145, 120)">''</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">&amp;&amp;</span><span class="token tag script language-javascript" style="color:#D4D4D4"> score</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">current</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			</span><span class="token tag script language-javascript comment" style="color:rgb(106, 153, 85)">// accumulate score</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			</span><span class="token tag script language-javascript keyword" style="color:#C586C0">const</span><span class="token tag script language-javascript" style="color:#D4D4D4"> sc </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript function" style="color:rgb(220, 220, 170)">parseFloat</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">score</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">current</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">text</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">+</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript function" style="color:rgb(220, 220, 170)">parseFloat</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">other</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">tag</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			score</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">current</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">text</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> sc</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">toString</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			</span><span class="token tag script language-javascript comment" style="color:rgb(106, 153, 85)">// clear the score on the collided box</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			</span><span class="token tag script language-javascript keyword" style="color:#C586C0">const</span><span class="token tag script language-javascript" style="color:#D4D4D4"> label </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> tolua</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">cast</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">other</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">children</span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">?.</span><span class="token tag script language-javascript" style="color:#D4D4D4">last</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript maybe-class-name" style="color:#4EC9B0">TypeName</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access maybe-class-name" style="color:#4EC9B0">Label</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			</span><span class="token tag script language-javascript keyword" style="color:#C586C0">if</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript" style="color:#D4D4D4">label</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript" style="color:#D4D4D4"> label</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">text</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript string" style="color:rgb(206, 145, 120)">''</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			other</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript property-access" style="color:#D4D4D4">tag</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript operator" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript string" style="color:rgb(206, 145, 120)">''</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			</span><span class="token tag script language-javascript comment" style="color:rgb(106, 153, 85)">// play the box collision animation</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">			other</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token tag script language-javascript method function property-access" style="color:rgb(220, 220, 170)">perform</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript function" style="color:rgb(220, 220, 170)">Scale</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0.2</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript number" style="color:#B5CEA8">0.7</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token tag script language-javascript" style="color:#D4D4D4"> </span><span class="token tag script language-javascript number" style="color:#B5CEA8">1.0</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">		</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag script language-javascript" style="color:#D4D4D4"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token tag script language-javascript" style="color:#D4D4D4">	</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">disk-fixture</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">radius</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">50</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">draw-node</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">		</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">dot-shape</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">radius</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">50</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">color</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">0xffff0088</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">draw-node</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;</span><span class="token tag" style="color:#569CD6">label</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">ref</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript" style="color:#D4D4D4">score</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">fontName</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(212, 212, 212)">=</span><span class="token tag attr-value punctuation" style="color:rgb(212, 212, 212)">'</span><span class="token tag attr-value" style="color:rgb(206, 145, 120)">sarasa-mono-sc-regular</span><span class="token tag attr-value punctuation" style="color:rgb(212, 212, 212)">'</span><span class="token tag" style="color:#569CD6"> </span><span class="token tag attr-name" style="color:rgb(156, 220, 254)">fontSize</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(212, 212, 212)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token tag script language-javascript number" style="color:#B5CEA8">40</span><span class="token tag script language-javascript punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text">0</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">label</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text">	&lt;scale time=</span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token number" style="color:#B5CEA8">0.4</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain-text"> start=</span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token number" style="color:#B5CEA8">0.3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain-text"> stop</span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token number" style="color:#B5CEA8">1.0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain-text"> easing=</span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token maybe-class-name" style="color:#4EC9B0">Ease</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token property-access maybe-class-name" style="color:#4EC9B0">OutBack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain-text">/&gt;</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain-text"></span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&lt;/</span><span class="token tag" style="color:#569CD6">body</span><span class="token tag punctuation" style="color:rgb(212, 212, 212)">&gt;</span><br></span></code></pre></div></div>
<ul>
<li class=""><code>ref={bird}</code>: uses <code>ref</code> to create a reference variable for later manipulation of the bird.</li>
<li class=""><code>type={BodyMoveType.Dynamic}</code>: indicates this is a dynamic body, affected by physics simulations.</li>
<li class=""><code>onContactStart={(other) =&gt; {}}</code>: callback function triggered when the bird’s physics body contacts another object.</li>
<li class=""><code>disk-fixture</code>: defines the bird’s shape as a disk.</li>
<li class=""><code>draw-node</code>: used to render the bird’s appearance.</li>
<li class=""><code>label</code>: displays the bird’s accumulated score.</li>
<li class=""><code>scale</code>: plays the bird’s entrance animation.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="6-completing-the-game-logic">6. Completing the Game Logic<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#6-completing-the-game-logic" class="hash-link" aria-label="Direct link to 6. Completing the Game Logic" title="Direct link to 6. Completing the Game Logic" translate="no">​</a></h3>
<p>With that, we have completed the core logic of our small game. You can further refine the game logic and add features based on your own ideas. The complete demo code can be seen at this link: <a href="https://github.com/IppClub/Dora-Example/blob/master/Example/Birdy.tsx" target="_blank" rel="noopener noreferrer" class="">Dora-Example/Example/Birdy.tsx</a>. Below are some screenshots of the game in action.</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/birdy1-4ae21702d205aae54fbb29507a4f3b4d.png" alt="Dragging the screen to launch the &quot;Angry Birds"></p><p>Dragging the screen to launch the "Angry Birds</p><p></p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/birdy2-607933996611fd031ef52003f9447ba0.png" alt="Skilled moves earned me all the scores in one shot"></p><p>Skilled moves earned me all the scores in one shot</p><p></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-a-little-reveal">4. A Little Reveal<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#4-a-little-reveal" class="hash-link" aria-label="Direct link to 4. A Little Reveal" title="Direct link to 4. A Little Reveal" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-deer-or-horse">1. Deer or Horse<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#1-deer-or-horse" class="hash-link" aria-label="Direct link to 1. Deer or Horse" title="Direct link to 1. Deer or Horse" translate="no">​</a></h3>
<p>In fact, the game code we wrote can ensure consistent performance across Linux, Android, iOS, macOS, and Windows thanks to the capabilities of the Dora SSR engine. However, to run this code, our Dora SSR engine doesn’t even support a JavaScript runtime environment... (What did you say?)</p>
<p>Yes, the underlying technology of Dora SSR is actually based on Lua and WASM virtual machines as the scripting language runtime. Support for TypeScript is provided through the integration of the TypeScriptToLua compiler <a href="https://github.com/TypeScriptToLua/TypeScriptToLua" target="_blank" rel="noopener noreferrer" class="">TypeScriptToLua</a>. TSTL has rewritten the backend of the TypeScript language compiler to compile TS and TSX code into equivalent Lua code, allowing TS code to run on Dora. The Dora Web IDE’s code editor helps with TS language checking, completion, and Dora built-in library API hints. In the end, whether it’s a deer or a horse, as long as the code passes the TS compilation check, it will run just the same.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-is-there-a-connection-with-react">2. Is There a Connection with React?<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/25/tsx-dev-intro#2-is-there-a-connection-with-react" class="hash-link" aria-label="Direct link to 2. Is There a Connection with React?" title="Direct link to 2. Is There a Connection with React?" translate="no">​</a></h3>
<p>The answer to this question is currently: it could be (thus far, it hasn’t been). React’s most important capability is synchronizing the rendering of components and business data states through the Virtual DOM and Tree Diff process, which has not yet been implemented in Dora SSR. Currently, the code written in TSX for game rendering objects is only built once at runtime, and then the underlying C++ engine functionality continues to handle processing. Maybe one day we will provide a React-like mechanism for game UI development, executing Tree Diff to synchronize state, or a mechanism based on TSX like SolidJS for other rendering component state synchronizations. So here, we sincerely invite all frontend developers to join us, play with the Dora SSR project, and explore how to apply frontend development ideas to game development, bringing more convenient tools into the mix.</p>]]></content:encoded>
            <category>TSX</category>
            <category>TypeScript</category>
        </item>
        <item>
            <title><![CDATA[The Tale of Rewriting the Moonscript Compiler]]></title>
            <link>https://ippclub.gitee.io/Dora-SSR/blog/2024/4/17/a-moon-script-tale</link>
            <guid>https://ippclub.gitee.io/Dora-SSR/blog/2024/4/17/a-moon-script-tale</guid>
            <pubDate>Wed, 17 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Moonscript: A Niche Language with a Twist]]></description>
            <content:encoded><![CDATA[<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/tokyo-moon-b7e7e52a4ef04622c08ee55c8e67d577.jpg" alt="tokyo moon" height="300px"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="moonscript-a-niche-language-with-a-twist">Moonscript: A Niche Language with a Twist<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/17/a-moon-script-tale#moonscript-a-niche-language-with-a-twist" class="hash-link" aria-label="Direct link to Moonscript: A Niche Language with a Twist" title="Direct link to Moonscript: A Niche Language with a Twist" translate="no">​</a></h2>
<p>Moonscript is a fascinating programming language that compiles into Lua and runs on the Lua virtual machine. Its syntax and features draw inspiration from Coffeescript, offering a sweet spot between expressiveness and readability—minimizing code while maximizing clarity. It's particularly adept at handling frequently changing business logic, allowing developers to slash code volumes significantly when compared to native Lua—sometimes down to a third! This not only saves time but also reduces bugs and troubleshooting headaches. But perhaps one of its quirkiest features, as revealed by a seasoned developer in a Discord chat, is its dedicated global but modest-sized user base and its delightful Sailor Moon-themed aesthetic.</p>
<!-- -->
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/moonscript-0f7963b0bd86484283e9e43ccd47841f.png" alt="emotions embedded" height="200px"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="open-source-and-free-a-challenging-sustainability">Open Source and Free: A Challenging Sustainability<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/17/a-moon-script-tale#open-source-and-free-a-challenging-sustainability" class="hash-link" aria-label="Direct link to Open Source and Free: A Challenging Sustainability" title="Direct link to Open Source and Free: A Challenging Sustainability" translate="no">​</a></h2>
<p>The creator of Moonscript has developed commercial sites like the indie game marketplace itch.io and the art-sharing platform streak.club using this language. To maintain stability, he paused the addition of new features and slowed down on fixing issues since 2017. Understandably, life's tough, and the creator has set up a GitHub sponsor page hoping for more support for his open-source efforts. It's unfair to expect continuous free contributions from anyone, after all.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="rewriting-on-my-own-terms">Rewriting on My Own Terms<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/17/a-moon-script-tale#rewriting-on-my-own-terms" class="hash-link" aria-label="Direct link to Rewriting on My Own Terms" title="Direct link to Rewriting on My Own Terms" translate="no">​</a></h2>
<p>As a die-hard fan of Moonscript, I couldn't just stand by. The original Moonscript compiler was written in Moonscript itself, with a core parser built in C using a PEG grammar library to generate ASTs, which were then processed back in Lua. This was a resource-intensive process, particularly for large projects where dynamic loading of Moonscript code could cause noticeable lag. Additionally, the dynamic nature of Lua made it ill-suited for handling strict data types in ASTs—a typical weak point in dynamic language development.</p>
<p>So, instead of building on the existing codebase, I opted for a fresh start in my second favorite programming language, C++ (with Moonscript being the first, of course). This rewrite not only solved several unresolved issues but also reintroduced some long-missed programming features from other languages. Check out the new project here: <a href="https://yuescript.org/zh" target="_blank" rel="noopener noreferrer" class="">YueScript</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="transpilers-for-lua-and-peg-grammar">Transpilers for Lua and PEG Grammar<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/17/a-moon-script-tale#transpilers-for-lua-and-peg-grammar" class="hash-link" aria-label="Direct link to Transpilers for Lua and PEG Grammar" title="Direct link to Transpilers for Lua and PEG Grammar" translate="no">​</a></h2>
<p>Nowadays, compilers that generate code in another programming language are more accurately called transpilers. Lua’s simple design allows for fast compilation with a one-pass recursive descent parser. With diverse programming preferences, many have ventured into developing transpilers from various languages like JavaScript, TypeScript, Lisp, C, Python, Go, and C# into Lua. This enhances Lua's capabilities, driven by aesthetic preferences, personalized needs, and advancing hardware that liberates computing power. Even Python’s creator once used a LL(1) grammar to ensure parser efficiency thirty years ago. With today's better hardware, more complex grammars like PEG that allow infinite backtracking for matches have become viable, improving parser flexibility and future language evolution.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-advantages-of-c-in-writing-a-transpiler">The Advantages of C++ in Writing a Transpiler<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/17/a-moon-script-tale#the-advantages-of-c-in-writing-a-transpiler" class="hash-link" aria-label="Direct link to The Advantages of C++ in Writing a Transpiler" title="Direct link to The Advantages of C++ in Writing a Transpiler" translate="no">​</a></h2>
<p>Describing Moonscript as a macro system on Lua isn’t far from the truth, as many of its features are essentially syntactic sugar over Lua. The process involves three steps: parsing the code into a Moon AST, converting this AST into a Lua equivalent, and finally translating that into code. C++ shines in handling ASTs with its compile-time and runtime type checking, which minimizes errors significantly. Since C++17, the language has become even more powerful and expressive. For instance, the use of template metaprogramming allows us to ensure safety and efficiency:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token comment" style="color:rgb(106, 153, 85)">// Checking if an AST node is either Exp or ExpList</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">item</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token generic-function function" style="color:rgb(220, 220, 170)">is</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">Exp_t</span><span class="token generic-function generic class-name punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)"> ExpList_t</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">// Fetching the last matching node for a given AST structure</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">auto</span><span class="token plain"> variable </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    node</span><span class="token operator" style="color:rgb(212, 212, 212)">-&gt;</span><span class="token generic-function function" style="color:rgb(220, 220, 170)">getByPath</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">ChainValue_t</span><span class="token generic-function generic class-name punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)"> Callable_t</span><span class="token generic-function generic class-name punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)"> Variable_t</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">auto</span><span class="token plain"> varName </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">toString</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">variable</span><span class="token operator" style="color:rgb(212, 212, 212)">-&gt;</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token comment" style="color:rgb(106, 153, 85)">// Handling different AST structures with a switch statement</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">node</span><span class="token operator" style="color:rgb(212, 212, 212)">-&gt;</span><span class="token function" style="color:rgb(220, 220, 170)">getId</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token generic-function function" style="color:rgb(220, 220, 170)">id</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">While_t</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">auto</span><span class="token plain"> while_ </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:rgb(220, 220, 170)">static_cast</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">While_t</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">*</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">node</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">break</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token generic-function function" style="color:rgb(220, 220, 170)">id</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">For_t</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">auto</span><span class="token plain"> for_ </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:rgb(220, 220, 170)">static_cast</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(78, 201, 176)">For_t</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">*</span><span class="token generic-function generic class-name operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">node</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">break</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="yuescript-in-action-more-than-just-a-language">YueScript in Action: More Than Just a Language<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/17/a-moon-script-tale#yuescript-in-action-more-than-just-a-language" class="hash-link" aria-label="Direct link to YueScript in Action: More Than Just a Language" title="Direct link to YueScript in Action: More Than Just a Language" translate="no">​</a></h2>
<p>Initially, YueScript was tied to an open-source game engine project, Dora SSR (<a href="https://dora-ssr.net/" target="_blank" rel="noopener noreferrer" class="">https://dora-ssr.net</a> ), aiming to elevate the capabilities of the Lua-supported engine with an advanced version of Moonscript. Along with the engine’s Web IDE, YueScript also adds modest code completion and type inference features to enhance coding efficiency.</p>
<p>I particularly enjoy using YueScript during Game Jams, brainstorming with teammates and then diving into coding without overthinking the design—a somewhat reckless yet fun approach to programming. Although we still integrate some programming design using Dora SSR’s messaging system combined with YueScript’s functional style. You can see some of our frenzied Game Jam projects in YueScript at <a href="https://github.com/IppClub/Dora-SSR/tree/main/Assets/Script/Game" target="_blank" rel="noopener noreferrer" class="">Dora SSR's repository</a>.</p>
<p>So, as a dialect of Lua's dialect Moonscript, YueScript not only holds its ground in theory but has also been battle-tested in real applications within the Dora SSR project.</p>]]></content:encoded>
            <category>YueScript</category>
            <category>Lua</category>
        </item>
        <item>
            <title><![CDATA[Cross-Platform Game Dev with Rust!]]></title>
            <link>https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev</link>
            <guid>https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev</guid>
            <pubDate>Mon, 15 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Introduction]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>Ever since I was captivated by the magic of Warcraft III MODs in my childhood, I've held a special fondness for game scripting languages. Reflecting back on those days, using Blizzard's JASS language to create levels in Warcraft III was quite basic by today's standards—being statically typed with no garbage collection—but it represented a bold experiment in the early days of game development standards.</p>
<!-- -->
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-use-scripting-languages-for-game-development">Why Use Scripting Languages for Game Development?<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#why-use-scripting-languages-for-game-development" class="hash-link" aria-label="Direct link to Why Use Scripting Languages for Game Development?" title="Direct link to Why Use Scripting Languages for Game Development?" translate="no">​</a></h3>
<p>The main purpose of incorporating scripting languages into game development is to enhance the convenience of development and testing. Using lower-level languages like C++ could mean waiting for lengthy recompilations with every single line of code changed. Scripting languages allow for hot-loading of gameplay code, significantly boosting development efficiency.</p>
<p>Over time, dynamic scripting languages like Lua and JavaScript have become regulars in game development. However, as programming languages have evolved, we have the opportunity to redefine the new standards for game scripting languages—a blend of retro and innovation, namely, the combination of Rust and WASM.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="rust--wasm--dora-ssr-redefining-game-script-development">Rust + WASM + Dora SSR: Redefining Game Script Development<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#rust--wasm--dora-ssr-redefining-game-script-development" class="hash-link" aria-label="Direct link to Rust + WASM + Dora SSR: Redefining Game Script Development" title="Direct link to Rust + WASM + Dora SSR: Redefining Game Script Development" translate="no">​</a></h2>
<p>Combining Rust with WASM enables us to conduct game updates and testing on devices like Android or iOS without sacrificing performance and without relying on traditional app development toolchains. Moreover, with the help of the Dora SSR open-source game engine's Web IDE interface, games written in Rust can be compiled once and then tested and run on various gaming devices.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-choose-rust">Why Choose Rust?<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#why-choose-rust" class="hash-link" aria-label="Direct link to Why Choose Rust?" title="Direct link to Why Choose Rust?" translate="no">​</a></h3>
<p>Rust offers unparalleled memory safety guarantees and operates without the need for a garbage collector, making it ideal for game development, especially in performance-sensitive scenarios. With WASM, Rust not only delivers high performance but also maintains consistency and security across platforms.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="quick-start-guide">Quick Start Guide<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#quick-start-guide" class="hash-link" aria-label="Direct link to Quick Start Guide" title="Direct link to Quick Start Guide" translate="no">​</a></h3>
<p>Before diving into development, we need to install the Dora SSR game engine. This engine supports multiple platforms including Windows, Linux, macOS, iOS, and Android. For specific installation steps and requirements, please refer to the official Quick Start Guide: <a href="https://dora-ssr.net/docs/tutorial/quick-start" target="_blank" rel="noopener noreferrer" class="">Dora SSR Quick Start</a>.</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/rusty-0-f020839e0d1b0cdf196560e49f596483.jpg" alt="Dora SSR v1.3.17 running on macOS"></p><p>Dora SSR v1.3.17 running on macOS</p><p></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-one-create-a-new-project">Step One: Create a New Project<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#step-one-create-a-new-project" class="hash-link" aria-label="Direct link to Step One: Create a New Project" title="Direct link to Step One: Create a New Project" translate="no">​</a></h4>
<p>Once the Dora SSR engine is running, open the Dora SSR Web IDE in your browser, right-click on the left-side game resource tree, and choose 'New' to create a new folder named 'Hello'.</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/rusty-1-8c830c9d5b104d16d4aca95346d82fbc.jpg" alt="Accessing Dora SSR's Web IDE and creating a new folder in the browser"></p><p>Accessing Dora SSR's Web IDE and creating a new folder in the browser</p><p></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-two-write-the-game-code">Step Two: Write the Game Code<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#step-two-write-the-game-code" class="hash-link" aria-label="Direct link to Step Two: Write the Game Code" title="Direct link to Step Two: Write the Game Code" translate="no">​</a></h4>
<p>Next, create a new Rust project from the command line:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token plain">rustup target </span><span class="token function" style="color:rgb(220, 220, 170)">add</span><span class="token plain"> wasm32-wasip1</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token function" style="color:rgb(220, 220, 170)">cargo</span><span class="token plain"> new hello-dora </span><span class="token parameter variable" style="color:rgb(156, 220, 254)">--name</span><span class="token plain"> init</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(78, 201, 176)">cd</span><span class="token plain"> hello-dora</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token function" style="color:rgb(220, 220, 170)">cargo</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">add</span><span class="token plain"> dora_ssr</span><br></span></code></pre></div></div>
<p>Write the code in <code>src/main.rs</code>:</p>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">use</span><span class="token plain"> </span><span class="token namespace">dora_ssr</span><span class="token namespace punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:rgb(220, 220, 170)">main</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">mut</span><span class="token plain"> sprite </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">match</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Sprite</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">with_file</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"Image/logo.png"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token class-name" style="color:rgb(78, 201, 176)">Some</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">sprite</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token plain"> sprite</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token class-name" style="color:rgb(78, 201, 176)">None</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">return</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">mut</span><span class="token plain"> sprite_clone </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> sprite</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">clone</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    sprite</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">schedule</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token function" style="color:rgb(220, 220, 170)">once</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token keyword" style="color:#C586C0">move</span><span class="token plain"> </span><span class="token closure-params closure-punctuation punctuation" style="color:rgb(212, 212, 212)">|</span><span class="token closure-params keyword" style="color:#C586C0">mut</span><span class="token closure-params"> co</span><span class="token closure-params closure-punctuation punctuation" style="color:rgb(212, 212, 212)">|</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">async</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">move</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">for</span><span class="token plain"> i </span><span class="token keyword" style="color:#C586C0">in</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:#B5CEA8">1</span><span class="token punctuation" style="color:rgb(212, 212, 212)">..=</span><span class="token number" style="color:#B5CEA8">3</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">rev</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            </span><span class="token macro property" style="color:#9CDCFE">p!</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"{}"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> i</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            </span><span class="token macro property" style="color:#9CDCFE">sleep!</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">co</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1.0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token macro property" style="color:#9CDCFE">p!</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"Hello World"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        sprite_clone</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">perform_def</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">ActionDef</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">sequence</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token operator" style="color:rgb(212, 212, 212)">&amp;</span><span class="token macro property" style="color:#9CDCFE">vec!</span><span class="token punctuation" style="color:rgb(212, 212, 212)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            </span><span class="token class-name" style="color:rgb(78, 201, 176)">ActionDef</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">scale</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:#B5CEA8">0.1</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1.0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">0.5</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">EaseType</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token class-name" style="color:rgb(78, 201, 176)">Linear</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">            </span><span class="token class-name" style="color:rgb(78, 201, 176)">ActionDef</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">scale</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:#B5CEA8">0.5</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">0.5</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1.0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">EaseType</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token class-name" style="color:rgb(78, 201, 176)">OutBack</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(212, 212, 212)">]</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><br></span></code></pre></div></div>
<p>Build the WASM file:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token function" style="color:rgb(220, 220, 170)">cargo</span><span class="token plain"> build </span><span class="token parameter variable" style="color:rgb(156, 220, 254)">--release</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(156, 220, 254)">--target</span><span class="token plain"> wasm32-wasip1</span><br></span></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-three-upload-and-run-the-game">Step Three: Upload and Run the Game<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#step-three-upload-and-run-the-game" class="hash-link" aria-label="Direct link to Step Three: Upload and Run the Game" title="Direct link to Step Three: Upload and Run the Game" translate="no">​</a></h4>
<p>In the Dora SSR Web IDE, right-click the newly created 'Hello' folder, select 'Upload', and upload the compiled WASM file <code>init.wasm</code>.</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/rusty-2-5ccbbce7ef9afb2f4328fc523b917556.jpg" alt="Uploading files through the Web IDE"></p><p>Uploading files through the Web IDE</p><p></p>
<p>Alternatively, use a helper script to upload the WASM file within the Rust project folder. Here’s the command, where the IP parameter should be the address shown in Dora SSR’s Web IDE after startup, and the last parameter is the relative path of the directory to upload:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token plain">python3 upload.py </span><span class="token string" style="color:rgb(206, 145, 120)">"192.168.3.1"</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"Hello"</span><br></span></code></pre></div></div>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/rusty-3-01c1dec3d43cda223fa6690f4a92bc64.jpg" alt="Using a script for one-click compile, upload, and run"></p><p>Using a script for one-click compile, upload, and run</p><p></p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-four-publish-the-game">Step Four: Publish the Game<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#step-four-publish-the-game" class="hash-link" aria-label="Direct link to Step Four: Publish the Game" title="Direct link to Step Four: Publish the Game" translate="no">​</a></h4>
<p>In the editor's left-side game resource tree, right-click the newly created project folder and choose 'Download'.</p>
<p>Wait for the browser to prompt with a download notification for the packaged project files.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-its-implemented">How It's Implemented<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#how-its-implemented" class="hash-link" aria-label="Direct link to How It's Implemented" title="Direct link to How It's Implemented" translate="no">​</a></h2>
<p>In Dora SSR, implementing support for Rust language development and embedding the WASM runtime was a new technical exploration and trial, involving three key steps:</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-design-of-the-interface-definition-language-idl">1. Design of the Interface Definition Language (IDL)<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#1-design-of-the-interface-definition-language-idl" class="hash-link" aria-label="Direct link to 1. Design of the Interface Definition Language (IDL)" title="Direct link to 1. Design of the Interface Definition Language (IDL)" translate="no">​</a></h3>
<p>To embed the WASM runtime in a C++-written game engine and support Rust, it was first necessary to design an Interface Definition Language (IDL) to facilitate communication and data exchange between different programming languages. Below is an example of a WASM IDL designed for Dora SSR, based on the native C++ programming interface with added annotations needed to transition to Rust interfaces, such as object, readonly, and optional. One of the challenges in cross-language interface mapping is the object-oriented interface design of C++, as Rust does not provide complete object-oriented capabilities, requiring additional code in Rust to simulate some object-oriented features. Fortunately, this language difference is not overly large or complex to manage.</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token plain">object </span><span class="token keyword" style="color:#C586C0">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">EntityGroup</span><span class="token plain"> @ Group</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    readonly common </span><span class="token keyword" style="color:#C586C0">int</span><span class="token plain"> count</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    optional readonly common Entity</span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    optional Entity</span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">find</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">function</span><span class="token operator" style="color:rgb(212, 212, 212)">&lt;</span><span class="token keyword" style="color:#C586C0">bool</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">Entity</span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> e</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">&gt;</span><span class="token plain"> func</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">const</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">static</span><span class="token plain"> EntityGroup</span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">create</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token plain">VecStr components</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<p>Considering the differences between C++'s object-oriented features and Rust's design philosophy, we partially simulated object-oriented behavior in Rust, necessitating additional mechanisms in Rust to correspond to C++ classes and methods. Although this approach increased the development workload, it maintained the cleanliness of the interface and the maintainability of the system.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-generating-glue-code">2. Generating Glue Code<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#2-generating-glue-code" class="hash-link" aria-label="Direct link to 2. Generating Glue Code" title="Direct link to 2. Generating Glue Code" translate="no">​</a></h3>
<p>The second step involved writing a program to generate the glue code that facilitates calls between C++, WASM, and Rust through the IDL. For this purpose, we chose to use YueScript, a dynamic programming language based on Lua, developed as part of the Dora SSR project. YueScript combines the flexibility and lightweight nature of Lua with the rich syntax and features necessary for complex code generation tasks, utilizing Lua's lpeg syntax parsing library to handle IDL parsing and glue code generation. Below is an excerpt from the IDL parser written using PEG grammar in YueScript.</p>
<div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token class-name" style="color:rgb(78, 201, 176)">Param</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token string" style="color:rgb(206, 145, 120)">"Param"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token class-name" style="color:rgb(78, 201, 176)">Param</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">V</span><span class="token string" style="color:rgb(206, 145, 120)">"Func"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Name</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">/</span><span class="token plain"> mark</span><span class="token string" style="color:rgb(206, 145, 120)">"callback"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">+</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Type</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Name</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">/</span><span class="token plain"> mark</span><span class="token string" style="color:rgb(206, 145, 120)">"variable"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">    </span><span class="token class-name" style="color:rgb(78, 201, 176)">Func</span><span class="token punctuation" style="color:rgb(212, 212, 212)">:</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Ct</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">"function&lt;"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Type</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Ct</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">"("</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">V</span><span class="token string" style="color:rgb(206, 145, 120)">"Param"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">","</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">V</span><span class="token string" style="color:rgb(206, 145, 120)">"Param"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">^</span><span class="token number" style="color:#B5CEA8">0</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">^</span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token number" style="color:#B5CEA8">1</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">")"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">"&gt;"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token class-name" style="color:rgb(78, 201, 176)">Method</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Docs</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Ct</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">MethodLabel</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Type</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">C</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">"operator=="</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">+</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Name</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">"@"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Name</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">+</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Cc</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">false</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Ct</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">"("</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">Param</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">","</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Param</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">^</span><span class="token number" style="color:#B5CEA8">0</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">^</span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token number" style="color:#B5CEA8">1</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">")"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">C</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">"const"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token operator" style="color:rgb(212, 212, 212)">^</span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token number" style="color:#B5CEA8">1</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">White</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">P</span><span class="token string" style="color:rgb(206, 145, 120)">";"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">/</span><span class="token plain"> mark</span><span class="token string" style="color:rgb(206, 145, 120)">"method"</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-embedding-wasm-runtime-and-code-integration">3. Embedding WASM Runtime and Code Integration<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#3-embedding-wasm-runtime-and-code-integration" class="hash-link" aria-label="Direct link to 3. Embedding WASM Runtime and Code Integration" title="Direct link to 3. Embedding WASM Runtime and Code Integration" translate="no">​</a></h3>
<p>The final step was to embed the WASM runtime and the generated C++ glue code into the game engine, completing the code integration. For the WASM runtime, we chose WASM3, a high-performance, lightweight WebAssembly interpreter that supports multiple CPU architectures. This choice simplifies the complexity of the compilation chain and enhances cross-platform compatibility. By doing so, Dora SSR can support games developed in Rust running on hardware devices with various architectures, greatly enhancing the accessibility and flexibility of game projects.</p>
<p>During the integration process, we released a crate package for Rust developers, which includes all necessary interfaces and tools, enabling developers to easily develop and republish other game modules written in Rust based on the Dora SSR game engine.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="performance-comparison">Performance Comparison<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#performance-comparison" class="hash-link" aria-label="Direct link to Performance Comparison" title="Direct link to Performance Comparison" translate="no">​</a></h2>
<p>Dora SSR supports Lua scripting as well, currently using the Lua 5.5 version virtual machine. Like WASM3, it does not perform JIT compilation of real-time machine code but interprets script codes within the virtual machine. This setting allows us to make some performance comparisons between these two scripting approaches.</p>
<p>Before delving into comparisons, it's evident that disregarding Lua's garbage collection time, the inherent dynamics of Lua mean that C++ mappings to Lua interfaces must perform runtime checks for input parameter types. Moreover, accessing Lua object properties requires runtime searches through a hash table structure—costs that Rust's static typing and WASM virtual machine either avoid or minimize. Here are some basic performance tests focusing on cross-language calling and parameter passing efficiency, specifically selecting interfaces that require minimal computational processing on the C++ side.</p>
<ul>
<li class="">Rust Test Code</li>
</ul>
<div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">mut</span><span class="token plain"> root </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Node</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">new</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> node </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Node</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">new</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> start </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">get_elapsed_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">for</span><span class="token plain"> _ </span><span class="token keyword" style="color:#C586C0">in</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">..</span><span class="token number" style="color:#B5CEA8">10000</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	root</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">set_transform_target</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token operator" style="color:rgb(212, 212, 212)">&amp;</span><span class="token plain">node</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token macro property" style="color:#9CDCFE">p!</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"object passing time: {} ms"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">get_elapsed_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> start</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1000.0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> start </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">get_elapsed_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">for</span><span class="token plain"> _ </span><span class="token keyword" style="color:#C586C0">in</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">..</span><span class="token number" style="color:#B5CEA8">10000</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	root</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">set_x</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token number" style="color:#B5CEA8">0.0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token macro property" style="color:#9CDCFE">p!</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"number passing time: {} ms"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">get_elapsed_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> start</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1000.0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> start </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">get_elapsed_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">for</span><span class="token plain"> _ </span><span class="token keyword" style="color:#C586C0">in</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">..</span><span class="token number" style="color:#B5CEA8">10000</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	root</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token function" style="color:rgb(220, 220, 170)">set_tag</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"Tag name"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token punctuation" style="color:rgb(212, 212, 212)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token macro property" style="color:#9CDCFE">p!</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"string passing time: {} ms"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">::</span><span class="token function" style="color:rgb(220, 220, 170)">get_elapsed_time</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> start</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1000.0</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token punctuation" style="color:rgb(212, 212, 212)">;</span><br></span></code></pre></div></div>
<ul>
<li class="">Lua Test Code</li>
</ul>
<div class="language-lua codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-lua codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token keyword" style="color:#C586C0">local</span><span class="token plain"> root </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Node</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">local</span><span class="token plain"> node </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">Node</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">local</span><span class="token plain"> start </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">elapsedTime</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">for</span><span class="token plain"> i </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">10000</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">do</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	root</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">transformTarget </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> node</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">end</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token function" style="color:rgb(220, 220, 170)">print</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"object passing time: "</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">..</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">tostring</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">elapsedTime </span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> start</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1000</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">..</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">" ms"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">start </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">elapsedTime</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">for</span><span class="token plain"> i </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">10000</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">do</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	root</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">x </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">end</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token function" style="color:rgb(220, 220, 170)">print</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"number passing time: "</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">..</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">tostring</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">elapsedTime </span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> start</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1000</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">..</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">" ms"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">start </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">elapsedTime</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">for</span><span class="token plain"> i </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1</span><span class="token punctuation" style="color:rgb(212, 212, 212)">,</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">10000</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">do</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">	root</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">tag </span><span class="token operator" style="color:rgb(212, 212, 212)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">"Tag name"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">end</span><span class="token plain"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain"></span><span class="token function" style="color:rgb(220, 220, 170)">print</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token string" style="color:rgb(206, 145, 120)">"string passing time: "</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">..</span><span class="token plain"> </span><span class="token function" style="color:rgb(220, 220, 170)">tostring</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token punctuation" style="color:rgb(212, 212, 212)">(</span><span class="token class-name" style="color:rgb(78, 201, 176)">App</span><span class="token punctuation" style="color:rgb(212, 212, 212)">.</span><span class="token plain">elapsedTime </span><span class="token operator" style="color:rgb(212, 212, 212)">-</span><span class="token plain"> start</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">*</span><span class="token plain"> </span><span class="token number" style="color:#B5CEA8">1000</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(212, 212, 212)">..</span><span class="token plain"> </span><span class="token string" style="color:rgb(206, 145, 120)">" ms"</span><span class="token punctuation" style="color:rgb(212, 212, 212)">)</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="performance-results">Performance Results<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#performance-results" class="hash-link" aria-label="Direct link to Performance Results" title="Direct link to Performance Results" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#D4D4D4;--prism-background-color:#212121"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#D4D4D4;background-color:#212121"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#D4D4D4"><span class="token plain">Rust + WASM:</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">object passing time: 0.63 ms</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">number passing time: 0.59 ms</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">string passing time: 3.54 ms</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">Lua:</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">object passing time: 6.73 ms</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">number passing time: 2.69 ms</span><br></span><span class="token-line" style="color:#D4D4D4"><span class="token plain">string passing time: 4.23 ms</span><br></span></code></pre></div></div>
<p>As observed, aside from string type interface calling, Lua's cross-language calling performance in Dora SSR is almost an order of magnitude slower than WASM's. The slight difference in string handling is likely due to the bulk of performance loss occurring during string object copying, a minor concern compared to cross-language calling overheads.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="user-experience-discussion">User Experience Discussion<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#user-experience-discussion" class="hash-link" aria-label="Direct link to User Experience Discussion" title="Direct link to User Experience Discussion" translate="no">​</a></h2>
<p>Introducing Rust into game development has offered a distinct boost in productivity compared to traditional approaches, especially when integrating with large language models like ChatGPT for code generation assistance. Unlike C or C++—or even many dynamic languages—where generated code might compile but often contains hidden runtime errors and defects such as memory leaks or misuse of pointers and references, Rust's strict compiler environment provides a more stable and secure coding environment for game development.</p>
<p>Rust's ownership and borrowing mechanisms, along with its design for type and memory safety, allow many potential issues to be caught and corrected during compilation. By supporting Rust in the Dora SSR game engine, I've found that scripting for games is not only safer but also more efficient, transforming game development from a process of debugging to one focused more on creation and realization.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/4/15/rusty-game-dev#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Opting for Dora SSR + Rust as a game development toolkit is not just about being on the cutting edge of technology—it's a new exploration of the game development process itself. I warmly invite every game development enthusiast to join our community and embark on this exciting technological journey. Visit our <a href="https://github.com/IppClub/Dora-SSR" target="_blank" rel="noopener noreferrer" class="">GitHub repository</a> for more information and to get involved. Let's start a new era of game development together!</p>]]></content:encoded>
            <category>Rust</category>
            <category>WASM</category>
        </item>
        <item>
            <title><![CDATA[From Compiler, Game Engine to Handheld Console: My Journey in Indie Game Development]]></title>
            <link>https://ippclub.gitee.io/Dora-SSR/blog/2024/3/25/indie-game-made-so-hard</link>
            <guid>https://ippclub.gitee.io/Dora-SSR/blog/2024/3/25/indie-game-made-so-hard</guid>
            <pubDate>Mon, 25 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Introduction]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="introduction">Introduction<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/3/25/indie-game-made-so-hard#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction" translate="no">​</a></h2>
<p>Developing my own games has been a dream since childhood, particularly fueled by my extensive use of the Warcraft 3 World Editor. This sparked a fascination with game engines and development tools. As a student, I delved into programming and soon felt the urge to expand beyond just using various programming languages for development. I started maintaining a programming language called YueScript, tailored for writing game logic. My learning journey in graphics led me to rewrite the Cocos2d-x as a learning project, which eventually evolved into the Dora SSR game engine. Later, as my love for handheld gaming consoles grew, I began collaborating on an open, programmable gaming device called the "Auspice Gear", aiming to achieve the ultimate digital freedom in gaming.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-fun-and-challenges-of-game-scripting-languages">The Fun and Challenges of Game Scripting Languages<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/3/25/indie-game-made-so-hard#the-fun-and-challenges-of-game-scripting-languages" class="hash-link" aria-label="Direct link to The Fun and Challenges of Game Scripting Languages" title="Direct link to The Fun and Challenges of Game Scripting Languages" translate="no">​</a></h2>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/3-a7fac222eef3422da6800af1f341c8e7.png" alt="Multilingual Playground!" width="600px"></p><p>Multilingual Playground!</p><p></p>
<p>Programming in various languages is exhilarating, as each language offers unique programming philosophies and design principles. For scripting complex and dynamic game mechanics, I prefer using languages that are succinct and expressive. YueScript, translatable to Lua, fulfills this need beautifully. Over time, as I developed more with my Dora SSR engine, I integrated languages like Teal (which adds static typing to Lua), TypeScript (for enhanced code hints and checks), JSX, and XML (for descriptive, componentized development). Each scripting language shines in specific game development contexts and seamlessly inter-operates through translation to Lua. Beyond Lua-based extensions, the Dora SSR engine also experiments with supporting diverse scripting languages via the WASM virtual machine, such as Rust and upcoming support for C++ and Go, balancing performance with runtime expansibility.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="innovating-with-game-engines">Innovating with Game Engines<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/3/25/indie-game-made-so-hard#innovating-with-game-engines" class="hash-link" aria-label="Direct link to Innovating with Game Engines" title="Direct link to Innovating with Game Engines" translate="no">​</a></h2>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/2-3c0f6aac2b13b494cc22c47876094d4a.png" alt="Game creation at your fingertips!" width="600px"></p><p>Game creation at your fingertips!</p><p></p>
<p>While high-performance graphic rendering and complex scene construction are typically associated with game engines, as an indie developer and enthusiast, I believe many 2D games or those blending 2D and 3D effects can also offer highly creative and unique experiences. Ideally, devices for developing and running games should be unrestricted. Thus, Dora SSR was envisioned to provide an accessible and user-friendly environment, or even a full-fledged game development IDE, on as many devices as possible. Game development has become a part of my daily routine, allowing me to enjoy coding and debugging game features leisurely and sporadically, using whatever devices are at hand.</p>
<p>Dora SSR features a built-in Web IDE server within the game engine runtime, enabling code writing, running, and debugging directly on any terminal device via a web browser. This integration provides visual hints and access to various game development and resource management tools. Presently, Dora SSR supports game development on platforms like Windows, macOS, iOS, Android, and several Linux distributions.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pursuing-the-dream-of-a-free-and-open-gaming-handheld">Pursuing the Dream of a Free and Open Gaming Handheld<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/3/25/indie-game-made-so-hard#pursuing-the-dream-of-a-free-and-open-gaming-handheld" class="hash-link" aria-label="Direct link to Pursuing the Dream of a Free and Open Gaming Handheld" title="Direct link to Pursuing the Dream of a Free and Open Gaming Handheld" translate="no">​</a></h2>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/1-2dfb3c8ea227c9d6b7a1c2aa81ce5632.png" alt="Open source everything?" width="600px"></p><p>Open source everything? Want it for both software and hardware!</p><p></p>
<p>Despite the progress, the pursuit of an unrestricted and open gaming development experience is far from over. As a veteran handheld gaming enthusiast dissatisfied with many commercial open-source handhelds, I envisioned a device not just for playing games but also for freely developing, running, and even distributing homemade games. Many manufacturers restrict programmability for profit, so with like-minded hardware enthusiasts, we developed the fully open "Auspice Gear", offering modular customization of its core components and design.</p>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/auspice-gear-57b55973e700488b6381e04d6a82f0b9.png" alt="Auspice Gear + Dora SSR"></p><p>Auspice Gear + Dora SSR</p><p></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="returning-to-the-essence-of-game-creation">Returning to the Essence of Game Creation<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/3/25/indie-game-made-so-hard#returning-to-the-essence-of-game-creation" class="hash-link" aria-label="Direct link to Returning to the Essence of Game Creation" title="Direct link to Returning to the Essence of Game Creation" translate="no">​</a></h2>
<p align="center"><img src="https://ippclub.gitee.io/Dora-SSR/assets/images/lsd-banner-ff13d49db769a7c066294fc221490e9b.jpg" alt="An open-source indie game project"></p><p>An open-source indie game project made by the community called 'Luv Sense Digital'</p><p></p>
<p>So, did I eventually make my game? Yes, though it's not entirely complete yet. Before the generative AI boom of 2020, we envisioned a future where AI played a central role in games—where humans, having their material needs fully met, engage in games to provide creative and intelligent data for AI training. This data, assessed by futuristic banks, determines an individual's monetary worth. The AI trained with this data helps with all aspects of material production, individual nurturing, and social management. This narrative reflects our ongoing quest to define ourselves through our creations rather than being defined by circumstances into which we were born.</p>
<p>If you're interested in our work on programming languages, game engines, gaming handhelds, or our game project, feel free to star our repositories or join our discussion groups. Although our projects are still in their early stages, they are continuously integrated and iterated upon, offering a glimpse into our progress and processes.</p>
<p>We warmly invite everyone passionate about game development to join us. Whether contributing code, providing feedback, or sharing our projects, your efforts help us collectively realize the dream of freely developing games.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="project-links">Project Links<a href="https://ippclub.gitee.io/Dora-SSR/blog/2024/3/25/indie-game-made-so-hard#project-links" class="hash-link" aria-label="Direct link to Project Links" title="Direct link to Project Links" translate="no">​</a></h2>
<ul>
<li class="">Game Engine: <a href="https://github.com/IppClub/Dora-SSR" target="_blank" rel="noopener noreferrer" class="">Dora-SSR on GitHub</a></li>
<li class="">YueScript Language: <a href="https://github.com/IppClub/YueScript" target="_blank" rel="noopener noreferrer" class="">YueScript on GitHub</a></li>
<li class="">"Luv Sense Digital" Open Source Game Project: <a href="https://luv-sense-digital.readthedocs.io/" target="_blank" rel="noopener noreferrer" class="">Documentation</a></li>
</ul>]]></content:encoded>
            <category>Dora SSR</category>
            <category>YueScript</category>
            <category>Auspice Gear</category>
            <category>Game LSD</category>
        </item>
        <item>
            <title><![CDATA[🌈 Dora SSR - A Magical Journey from "The Wizard of Oz" to the World of Gaming]]></title>
            <link>https://ippclub.gitee.io/Dora-SSR/blog/dora-ssr</link>
            <guid>https://ippclub.gitee.io/Dora-SSR/blog/dora-ssr</guid>
            <pubDate>Sat, 18 Nov 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[🌟]]></description>
            <content:encoded><![CDATA[<p style="text-align:center">🌟</p>
<hr>
<p>Behind every great creation lies a story filled with magic. The inspiration for Dora SSR stems from one of my favorite childhood tales—<em>The Wizard of Oz</em>. In this classic story, young Dorothy and her dog Toto embark on a wondrous and challenging adventure alongside their new friends—the Tin Man who lacks a heart, the Scarecrow who lacks intelligence, and the Cowardly Lion who lacks courage.</p>
<p style="text-align:center">✨</p>
<hr>
<p>The journey of the Dora SSR engine mirrors Dorothy’s experience in <em>The Wizard of Oz</em>—a voyage of exploration and discovery. It is not just a technological product but a platform that ignites creativity and brings dreams to life. In this open ecosystem, we yearn for a world of open-source ideals, where everyone can freely contribute and share knowledge within the community. We hope that every developer using Dora SSR will, like Dorothy and her companions, bravely chase their dreams in the realm of game development, overcome obstacles, and discover their true selves.</p>
<p style="text-align:center">🚀</p>
<hr>
<p>In the world of Dora SSR, we encourage developers to seek wisdom like the Scarecrow, explore the depths of love like the Tin Man, and find courage like the Lion. Each game represents a new adventure, and every creative idea is an exploration of the unknown. We firmly believe that through this platform, everyone can find their own “Emerald City”—a place where dreams are realized. More importantly, in this open community, every idea and effort is respected and shared, sparking endless possibilities.</p>
<p style="text-align:center">🌍</p>
<hr>
<p>The strength of Dora SSR, much like Dorothy and her friends, comes from its ever-growing community—a vibrant environment filled with creativity, support, and collaboration. Our community is our very own “Emerald City,” where everyone can find their voice and place. The open-source philosophy allows every developer to participate, collectively building a better world. We believe that true innovation leaps forward only through openness and cooperation.</p>
<p style="text-align:center">🔥</p>
<hr>
<p>Our journey has just begun. Dora SSR will continue to grow and evolve, much like the characters in <em>The Wizard of Oz</em>, constantly learning, advancing, and surpassing themselves. We look forward to witnessing more creativity and miracles emerge on this platform and hope to attract like-minded individuals through the power of open source, together writing the chapters of the future.</p>
<p style="text-align:center">🤝</p>
<hr>
<p>Therefore, let us join hands and strive together to continue our own “Wizard of Oz” story in the magical journey of Dora SSR! On this journey, everyone can become Dorothy, and every creative idea has the potential to become the next miracle. In an open world, we dream together and achieve together.</p>]]></content:encoded>
            <category>Dora SSR</category>
            <category>hello world</category>
        </item>
    </channel>
</rss>