<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:source="https://www.antoniocaggiano.eu" version="2.0">
    <channel>
      <title>multidimensional code - Blog</title>
      <link>https://www.antoniocaggiano.eu/posts/</link>
      <description>Notes and thoughts of an open-source graphics-software engineer</description>
      <generator>Zola</generator>
      <language>en</language>
      <image>
        <url>https://www.antoniocaggiano.eu/icons/favicon.png</url>
        <title>Multidimensional Code</title>
        <link>https://www.antoniocaggiano.eu</link>
        <description>Multidimensional Code logo</description>
      </image>
      <lastBuildDate>Sun, 21 Jun 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Lua bindings with Zig reflection</title>
          <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/lua-bindings-with-zig-reflection/</link>
          <guid>https://www.antoniocaggiano.eu/posts/lua-bindings-with-zig-reflection/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/lua-bindings-with-zig-reflection/">&lt;p&gt;I am building a small game engine in Zig, and at a certain point I had to ask myself a question: do I keep writing gameplay in the same language as the engine, recompiling everything to move a cube, or do I add a scripting layer? I went with the scripting layer, and I picked &lt;a rel=&quot;external&quot; href=&quot;https://www.lua.org/&quot;&gt;Lua&lt;/a&gt; for it. It is tiny, fast, easy to embed, and games have used it for decades.&lt;/p&gt;
&lt;p&gt;Adding Lua is the easy part. The work is in how the engine and Lua talk to each other. A script is useless unless it can reach into the engine: read the input, move a node, ask the scene for its camera. That bridge is called a binding, and writing bindings by hand is some of the most repetitive code you will ever produce.&lt;/p&gt;
&lt;p&gt;So this post is about generating that bridge instead of typing it out. I&#39;ll start from the bottom, with what a binding really is at the level of the Lua stack, then write a couple by hand to show why that does not scale, and finally let Zig&#39;s compile-time reflection do the rest. The part I like is that by the end one description of my API is enough to both bind the functions and generate the autocompletion stubs my editor reads.&lt;/p&gt;
&lt;p&gt;Let&#39;s start.&lt;/p&gt;
&lt;h2 id=&quot;two-worlds-that-do-not-share-a-language&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#two-worlds-that-do-not-share-a-language&quot; aria-label=&quot;Anchor link for: two-worlds-that-do-not-share-a-language&quot;&gt;Two worlds that do not share a language&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As I mentioned, the engine is written in Zig, which is statically typed and compiled, and a &lt;code&gt;Node&lt;/code&gt; is a struct with a fixed layout in memory. Lua is dynamically typed and interpreted, and it knows nothing about that struct. The two meet across the Lua C API, and the first thing to understand about that API is that everything goes through a stack.&lt;/p&gt;
&lt;p&gt;You do not call a C function from Lua by passing arguments the way you would in C. Lua gives you a small virtual stack. When Lua calls your function, the arguments are already sitting on it. You read them off, do your work, push your return values back, and return one integer: how many values you left up there. That is the whole protocol.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;zlua&lt;/code&gt;, the Zig binding library I use, I write that function in a Zig-friendly shape, &lt;code&gt;fn (lua: *Lua) i32&lt;/code&gt;, and &lt;code&gt;zlua.wrap&lt;/code&gt; turns it into the C-callable function pointer (&lt;code&gt;CFn&lt;/code&gt;) that Lua actually expects:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; myFunction&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; 1. read arguments off the stack (index 1, 2, 3, ...)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; 2. do the work&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; 3. push results onto the stack&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; n&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; I left n results on the stack&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Index &lt;code&gt;1&lt;/code&gt; is the first argument, &lt;code&gt;2&lt;/code&gt; the second, and so on. Negative indices count from the top, so &lt;code&gt;-1&lt;/code&gt; is whatever is on top right now. Say a script calls &lt;code&gt;node:translate(10, 20, 30)&lt;/code&gt;. Inside your function the stack looks like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;index    1       2     3     4      &amp;lt;- count from the bottom&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        node    10    20    30&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;index   -4      -3    -2    -1      &amp;lt;- count from the top&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So &lt;code&gt;node&lt;/code&gt; is at index &lt;code&gt;1&lt;/code&gt;, the first real argument &lt;code&gt;10&lt;/code&gt; is at index &lt;code&gt;2&lt;/code&gt;, and the same &lt;code&gt;10&lt;/code&gt; is at index &lt;code&gt;-3&lt;/code&gt;. Reading slot &lt;code&gt;2&lt;/code&gt; and reading slot &lt;code&gt;-3&lt;/code&gt; give you the same value. Once that clicks, the rest is detail.&lt;/p&gt;
&lt;p&gt;A binding is mechanical work on top of this. You pull the Zig-typed arguments out of the stack, call the real Zig function, then push the result back. Converting values between Lua&#39;s stack and Zig&#39;s types like this has a name: marshalling. A binding is mostly marshalling, and marshalling is the kind of mechanical work a computer should be doing instead of us.&lt;/p&gt;
&lt;h2 id=&quot;making-a-zig-pointer-look-like-an-object&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#making-a-zig-pointer-look-like-an-object&quot; aria-label=&quot;Anchor link for: making-a-zig-pointer-look-like-an-object&quot;&gt;Making a Zig pointer look like an object&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before a script can call methods, Lua needs something to call them on. When a script writes &lt;code&gt;scene:get_name()&lt;/code&gt;, what is &lt;code&gt;scene&lt;/code&gt;? It cannot be a plain Lua table, because the real scene lives in engine memory and Zig owns it. Lua has to hold a reference to it.&lt;/p&gt;
&lt;p&gt;Lua&#39;s tool for that is userdata: a block of memory that Lua owns and garbage-collects, but whose contents are opaque to Lua. I do not store the scene itself in there. The engine owns the scene, and its lifetime has nothing to do with Lua&#39;s garbage collector. Instead, I store a pointer to it. The userdata is an 8-byte box holding a borrowed &lt;code&gt;*Scene&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; pushScene&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; scene&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;model&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Scene&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; ud&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;newUserdata&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;model&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Scene&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Lua owns an 8-byte slot&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;    ud&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; scene&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;                                 //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; store the borrowed pointer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;    lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;setMetatableRegistry&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Scene&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; attach the &amp;quot;Scene&amp;quot; behaviour&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That last line does the interesting work. A userdata on its own is inert. You cannot index it or call methods on it. A metatable gives it behaviour. When Lua evaluates &lt;code&gt;scene:get_name()&lt;/code&gt;, it does not find &lt;code&gt;get_name&lt;/code&gt; on the userdata, because there is nothing there. So it looks at the userdata&#39;s metatable for a special key called &lt;code&gt;__index&lt;/code&gt;. If &lt;code&gt;__index&lt;/code&gt; is a table, Lua searches that table for &lt;code&gt;get_name&lt;/code&gt;. This is how objects work in Lua. The metatable plays the role a vtable plays in C++.&lt;/p&gt;
&lt;p&gt;So binding a class to Lua comes down to this: create a metatable, register some functions into it under their Lua names, and point &lt;code&gt;__index&lt;/code&gt; at the metatable itself so method lookup finds them. Here it is for a &lt;code&gt;Scene&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Create a fresh table, store it in Lua&amp;#39;s registry under the name &amp;quot;Scene&amp;quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; and leave it on the stack.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;newMetatable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Scene&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; stack: [ mt ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Copy the value at index -1 (the metatable we just made) onto the top.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;pushValue&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;             //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; stack: [ mt, mt ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Pop the top value and store it as mt[&amp;quot;__index&amp;quot;]; the table is at index -2.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;setField&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;__index&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; mt.__index = mt   -&amp;gt;  stack: [ mt ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ... register each method into mt, then pop mt off the stack ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Three stack operations happen here, and the same three turn up all over Lua binding code, so they are worth understanding.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;newMetatable(&quot;Scene&quot;)&lt;/code&gt; creates a fresh table, registers it under the name &lt;code&gt;&quot;Scene&quot;&lt;/code&gt; so I can find it again later, and leaves it on top of the stack. After this line the stack holds one value: the metatable, at index &lt;code&gt;-1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pushValue(-1)&lt;/code&gt; does not invent a value. It copies an existing stack slot to the top. To put a brand-new value on the stack you call a typed push like &lt;code&gt;pushString&lt;/code&gt; or &lt;code&gt;pushInteger&lt;/code&gt;; &lt;code&gt;pushValue&lt;/code&gt; is specifically &quot;duplicate whatever is at this index&quot;. I pass &lt;code&gt;-1&lt;/code&gt;, the top, so now two copies of the metatable sit on the stack.&lt;/p&gt;
&lt;p&gt;Why two? Because the next call eats one. &lt;code&gt;setField(index, key)&lt;/code&gt; does &lt;code&gt;t[key] = v&lt;/code&gt;, where &lt;code&gt;t&lt;/code&gt; is the value at &lt;code&gt;index&lt;/code&gt;, &lt;code&gt;v&lt;/code&gt; is the value on top, and &lt;code&gt;v&lt;/code&gt; is popped afterwards. I want &lt;code&gt;mt.__index = mt&lt;/code&gt;, so the metatable has to play both parts: the table &lt;code&gt;t&lt;/code&gt; and the value &lt;code&gt;v&lt;/code&gt;. After the duplicate, the table is the second slot from the top, which is index &lt;code&gt;-2&lt;/code&gt;, and the value to assign is on top. So &lt;code&gt;setField(-2, &quot;__index&quot;)&lt;/code&gt; pops the top copy and leaves the original metatable behind, now pointing its &lt;code&gt;__index&lt;/code&gt; back at itself.&lt;/p&gt;
&lt;p&gt;With that, the metatable is wired up.&lt;/p&gt;
&lt;h2 id=&quot;the-honest-painful-way&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-honest-painful-way&quot; aria-label=&quot;Anchor link for: the-honest-painful-way&quot;&gt;The honest, painful way&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I will write a binding by hand first, because you should feel the problem before automating it away. Here is &lt;code&gt;Scene:get_name()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; sceneGetName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; arg 1 must be a &amp;quot;Scene&amp;quot; userdata&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; scene_ud&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;checkUserdata&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;model&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Scene&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Scene&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; unwrap to the borrowed *Scene&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; scene&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;model&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Scene&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; scene_ud&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; push the name as the result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;    _&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;pushString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;scene&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;name&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; one value left on the stack&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Read it against the protocol from before. Argument 1 is the &lt;code&gt;self&lt;/code&gt; userdata. &lt;code&gt;checkUserdata&lt;/code&gt; pulls it off the stack and also checks that it really carries the &lt;code&gt;&quot;Scene&quot;&lt;/code&gt; metatable, so a script that passes the wrong object gets a clean error instead of corrupting memory. We dereference to the real &lt;code&gt;*Scene&lt;/code&gt;, push its name, and return &lt;code&gt;1&lt;/code&gt; because we left one value on the stack.&lt;/p&gt;
&lt;p&gt;The code is correct, and it is also ten lines that do almost nothing. I have to write a near-identical ten for &lt;code&gt;get_camera_node&lt;/code&gt;, and again for every field of every struct, and again for every method of every type I want to expose. Each one is a place to slip up: read argument &lt;code&gt;2&lt;/code&gt; instead of &lt;code&gt;1&lt;/code&gt;, forget the &lt;code&gt;return&lt;/code&gt;, push an integer where Lua wanted a number. This is plumbing the type system already knows how to write. So I will bring in reflection.&lt;/p&gt;
&lt;h2 id=&quot;what-reflection-means-in-zig&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-reflection-means-in-zig&quot; aria-label=&quot;Anchor link for: what-reflection-means-in-zig&quot;&gt;What reflection means in Zig&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you come from C++, the word &quot;reflection&quot; might suggest runtime cost, RTTI, and a bit of magic. In Zig it is none of that. Zig runs ordinary Zig code at compile time, and during that compile-time execution it can inspect types. There is no runtime cost, because by the time the program runs the inspection is long over and only the generated code is left.&lt;/p&gt;
&lt;p&gt;I lean on two tools. The first is &lt;code&gt;@typeInfo(T)&lt;/code&gt;, which returns a value that describes a type: for a struct it lists the fields, for a function it gives the parameter types and the return type, for an integer it gives the bit width. You &lt;code&gt;switch&lt;/code&gt; on it like any other tagged union. The second is &lt;code&gt;std.meta&lt;/code&gt;, which adds convenience helpers on top, such as &lt;code&gt;std.meta.fields(T)&lt;/code&gt; and &lt;code&gt;std.meta.ArgsTuple(F)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An example makes it concrete. Take a small struct and a small function:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; a plain struct with two scalar fields&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; Mouse&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; struct&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;x&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; f32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; y&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; f32&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; a plain function with two arguments&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; add&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;a&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; i64&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; i64&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;i64&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; a&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; b&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;@typeInfo(Mouse)&lt;/code&gt; comes back tagged &lt;code&gt;.@&quot;struct&quot;&lt;/code&gt; (the tag is quoted because &lt;code&gt;struct&lt;/code&gt; is a keyword), and inside it carries a &lt;code&gt;.fields&lt;/code&gt; array. Each field knows its &lt;code&gt;.name&lt;/code&gt; (&lt;code&gt;&quot;x&quot;&lt;/code&gt;, then &lt;code&gt;&quot;y&quot;&lt;/code&gt;) and its &lt;code&gt;.type&lt;/code&gt; (&lt;code&gt;f32&lt;/code&gt;). &lt;code&gt;std.meta.fields(Mouse)&lt;/code&gt; is just a shortcut to that &lt;code&gt;.fields&lt;/code&gt; array, which I can loop over:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;inline&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;meta&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fields&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Mouse&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; f.name is &amp;quot;x&amp;quot; then &amp;quot;y&amp;quot;;  f.type is f32&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A function reflects the same way. &lt;code&gt;@typeInfo(@TypeOf(add))&lt;/code&gt; is tagged &lt;code&gt;.@&quot;fn&quot;&lt;/code&gt;, and it gives me &lt;code&gt;.params&lt;/code&gt; (each with a &lt;code&gt;.type&lt;/code&gt;, here &lt;code&gt;i64&lt;/code&gt; and &lt;code&gt;i64&lt;/code&gt;) and &lt;code&gt;.return_type&lt;/code&gt; (&lt;code&gt;i64&lt;/code&gt;). On top of that, &lt;code&gt;std.meta.ArgsTuple(@TypeOf(add))&lt;/code&gt; turns the parameter list into a tuple type I can fill in and then call:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; a tuple shaped like .{ i64, i64 }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; args&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;meta&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;ArgsTuple&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@TypeOf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;add&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; undefined&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;args&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; first parameter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;args&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; second parameter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; calls add(2, 3); r == 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; r&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @call&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;auto&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; add&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That last move, building an argument tuple from a function&#39;s type and calling the function with it, is the trick behind binding functions automatically.&lt;/p&gt;
&lt;p&gt;The keyword that ties all this together is &lt;code&gt;inline for&lt;/code&gt;. A normal &lt;code&gt;for&lt;/code&gt; loops at runtime. An &lt;code&gt;inline for&lt;/code&gt; is unrolled at compile time, and its loop variable is a comptime value, so inside the loop you can use it where Zig needs a compile-time constant: a field name, or a type. That is what lets me walk a struct&#39;s fields and generate one branch per field.&lt;/p&gt;
&lt;p&gt;With that, the hand-written boilerplate can go.&lt;/p&gt;
&lt;h2 id=&quot;structs-for-free&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#structs-for-free&quot; aria-label=&quot;Anchor link for: structs-for-free&quot;&gt;Structs for free&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most of what a script wants from the engine is plain data. Read &lt;code&gt;input.mouse.x&lt;/code&gt;, set &lt;code&gt;input.key.w&lt;/code&gt;. There is no real method here, only field access. So instead of one getter per field, I write one generic &lt;code&gt;__index&lt;/code&gt; that works for any struct &lt;code&gt;T&lt;/code&gt; by reflecting over its fields:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; metaIndex&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; T&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;zlua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;CFn&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; wrap a plain Zig fn as a Lua-callable CFn&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; zlua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;wrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; index&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; arg 1: the object, resolved to *T&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;checkUserdata&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @typeName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;T&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; arg 2: the field name Lua asked for&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; key&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;checkString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            inline&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;meta&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fields&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;T&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;                //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; skip &amp;quot;private&amp;quot; fields&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;name&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;#39;_&amp;#39;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;continue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;mem&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;eql&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; key&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;name&lt;/span&gt;&lt;span&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;                    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; push that one field, by pointer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;                    pushFieldValue&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;name&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@field&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;self&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;name&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;                    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; one value returned to Lua&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                    return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;index&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are two phases here. The &lt;code&gt;inline for&lt;/code&gt; runs at compile time and unrolls into one &lt;code&gt;if&lt;/code&gt; per field, so a struct with &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, &lt;code&gt;z&lt;/code&gt; produces three comparisons in the generated code. The &lt;code&gt;std.mem.eql&lt;/code&gt; comparison runs at runtime, against the key the script actually asked for. The result is a dispatcher of the same quality I would have written by hand, except I did not write it.&lt;/p&gt;
&lt;p&gt;Two details I like. Fields whose name starts with &lt;code&gt;_&lt;/code&gt; are skipped, which is my convention for a private field that Lua should not see. And an unknown key returns &lt;code&gt;0&lt;/code&gt;, meaning &quot;I pushed nothing&quot;, which Lua reads as &lt;code&gt;nil&lt;/code&gt;. That is exactly the Lua behaviour you would want.&lt;/p&gt;
&lt;p&gt;Writing a field needs the mirror image, &lt;code&gt;__newindex&lt;/code&gt;, which Lua calls on assignment. It pulls the value off the stack and writes it back into the struct. It has one extra rule: only leaf fields, like a number or a bool, are writable. A whole nested struct is not a writable leaf, so &lt;code&gt;__newindex&lt;/code&gt; skips it and the assignment is quietly ignored, the same as writing to an unknown key.&lt;/p&gt;
&lt;p&gt;How do we push a field once we have found it? We reflect on the field&#39;s type and pick the matching Lua push function:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; pushFieldValue&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; field_name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; field_ptr&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; anytype&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; the field&amp;#39;s Zig type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; F&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @TypeOf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;field_ptr&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; choose a Lua push based on that type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    switch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@typeInfo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;F&lt;/span&gt;&lt;span&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;pushBoolean&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;field_ptr&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;pushInteger&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@intCast&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;field_ptr&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;pushNumber&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@floatCast&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;field_ptr&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;@&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; pushStruct&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; field_ptr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @compileError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;unsupported field type&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look at the &lt;code&gt;.@&quot;struct&quot;&lt;/code&gt; branch. A nested struct is not copied into Lua. It gets wrapped as its own userdata pointing at the sub-struct, with its own metatable. So &lt;code&gt;input.mouse&lt;/code&gt; returns a &lt;code&gt;Mouse&lt;/code&gt; userdata, and &lt;code&gt;input.mouse.x&lt;/code&gt; then indexes into that. The recursion in the data structure becomes recursion in the binding, for free.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;else&lt;/code&gt; branch matters too. If I ever add a field of a type the bridge cannot marshal, say an enum or a tagged union, the program does not compile, and the error names the exact field and type. A hand-written binding would have crashed at runtime months later. Here the failure shows up today, at the line. Reflection saves typing, but moving a class of bugs from runtime to compile time is the part I care about more.&lt;/p&gt;
&lt;h2 id=&quot;walking-the-whole-type-tree&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#walking-the-whole-type-tree&quot; aria-label=&quot;Anchor link for: walking-the-whole-type-tree&quot;&gt;Walking the whole type tree&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If &lt;code&gt;input.mouse&lt;/code&gt; is going to return a &lt;code&gt;Mouse&lt;/code&gt; userdata with a working metatable, then &lt;code&gt;Mouse&lt;/code&gt; needs a registered metatable too. And &lt;code&gt;Mouse&lt;/code&gt; might contain a &lt;code&gt;Position&lt;/code&gt;, which needs one as well. So registering a type means registering every struct it contains, all the way down. That is a recursive walk over the type tree, again with &lt;code&gt;inline for&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; registerStructTree&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; T&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; give T a metatable with the generic __index/__newindex&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    try&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; registerStruct&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; look at each field of T at compile time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    inline&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;meta&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fields&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;T&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; skip &amp;quot;private&amp;quot; fields&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;name&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;#39;_&amp;#39;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;continue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        switch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@typeInfo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;type&lt;/span&gt;&lt;span&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; a struct field: recurse into it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;@&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; try&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; registerStructTree&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;type&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; a scalar field: nothing to register&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; {}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One call, &lt;code&gt;registerStructTree(lua, Input)&lt;/code&gt;, makes my whole input struct readable and writable from Lua, however deeply it nests. When I add a field to &lt;code&gt;Input&lt;/code&gt; in the engine, the script sees it on the next run, and I touch no binding code. The binding follows the types instead of duplicating them, which is what I was after.&lt;/p&gt;
&lt;h2 id=&quot;functions-for-free&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#functions-for-free&quot; aria-label=&quot;Anchor link for: functions-for-free&quot;&gt;Functions for free&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At this point, the data side is done. Calling real Zig functions like &lt;code&gt;node:translate(dx, dy, dz)&lt;/code&gt; is the part that looks harder: each one has its own arguments and its own return type, so this looks like where I finally have to write the code by hand.&lt;/p&gt;
&lt;p&gt;It is not. A function&#39;s signature is type information too, and &lt;code&gt;@typeInfo&lt;/code&gt; of a function gives me its parameter types and return type. So I can generate the adapter automatically from the function value alone. I keep calling that adapter a marshalling shim. A &lt;em&gt;shim&lt;/em&gt; is a thin layer that sits between two sides so they fit together, and this one does the marshalling we named earlier: it reads Lua values off the stack, converts them to Zig types, calls the function, and converts the result back. One small shim per function, written by the compiler.&lt;/p&gt;
&lt;p&gt;We already met &lt;code&gt;std.meta.ArgsTuple&lt;/code&gt; in the reflection section: it turns a function type into a tuple holding exactly that function&#39;s arguments. Here it earns its keep. I declare one of those tuples, fill each slot by pulling the matching value off the Lua stack, then call the function with &lt;code&gt;@call&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; methodCFn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; anytype&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; pullSelf&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; anytype&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;zlua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;CFn&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; zlua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;wrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; call&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;i32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; A tuple shaped exactly like f&amp;#39;s argument list&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; e.g. .{ *Node, f32, f32, f32 }.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            var&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; args&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;meta&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;ArgsTuple&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@TypeOf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;f&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; undefined&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; A free function passes null here.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; A method passes a pullSelf, so it has one leading arg.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; self_count&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@TypeOf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;pullSelf&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @TypeOf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;null&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; fill slot 0 with the receiver&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;self_count&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;args&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; pullSelf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; reflect on f&amp;#39;s signature&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; fi&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @typeInfo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@TypeOf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;f&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;@&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            inline&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;fi&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;params&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;self_count&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; self_count&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;param&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;                //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; read Lua stack slot i+1 as param.type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;                args&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;i&lt;/span&gt;&lt;span&gt;] &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; pullArg&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; param&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;type&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;?&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;fi&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;return_type&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; void&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;                //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; call f(args...) and return nothing to Lua&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;                @call&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;auto&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            } &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;                //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; call f and push its result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;                pushReturnValue&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @call&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;auto&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; args&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;                return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;call&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the function the rest of the binding leans on. The &lt;code&gt;inline for&lt;/code&gt; walks the function&#39;s parameter list at compile time. For each parameter it emits a &lt;code&gt;pullArg&lt;/code&gt; call that reads stack slot &lt;code&gt;i + 1&lt;/code&gt; and converts it to that parameter&#39;s exact Zig type. Then &lt;code&gt;@call&lt;/code&gt; invokes the real function with the assembled tuple. The &lt;code&gt;void&lt;/code&gt; versus non-&lt;code&gt;void&lt;/code&gt; check decides whether we return &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt; values to Lua. That is the protocol from the first section, derived from the return type instead of typed out.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pullArg&lt;/code&gt; is the inverse of &lt;code&gt;pushFieldValue&lt;/code&gt;. It reflects on the wanted type and reads it from the stack:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; pullArg&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; A&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; idx&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; i32&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;A&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; dispatch on the wanted Zig type&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; switch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;@typeInfo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;A&lt;/span&gt;&lt;span&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @floatCast&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;checkNumber&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;idx&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @intCast&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;checkInteger&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;idx&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;toBoolean&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;idx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; []const u8 &amp;lt;- Lua string&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;pointer&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; and&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; u8&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;checkString&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;idx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @compileError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Lua arg unsupported: `&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; @typeName&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;A&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To expose &lt;code&gt;Node.translate&lt;/code&gt;, a normal Zig method I wrote for the engine that knows nothing about Lua, I write zero lines of marshalling. I point the generator at it and I am done.&lt;/p&gt;
&lt;h2 id=&quot;the-self-problem&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-self-problem&quot; aria-label=&quot;Anchor link for: the-self-problem&quot;&gt;The self problem&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is one wrinkle you may already have spotted. A method is called &lt;em&gt;on&lt;/em&gt; an object, and that object is called the receiver: in &lt;code&gt;node:translate(...)&lt;/code&gt;, &lt;code&gt;node&lt;/code&gt; is the receiver, the thing the method acts on. A free function like &lt;code&gt;add(x, y)&lt;/code&gt; has no receiver; it is just called with its arguments. In Lua the colon is what makes the difference. Writing &lt;code&gt;node:translate(...)&lt;/code&gt; passes &lt;code&gt;node&lt;/code&gt; as a hidden first argument, so on the stack argument 1 is the receiver and the real arguments start at slot 2. The dot form, &lt;code&gt;node.translate(node, ...)&lt;/code&gt;, is the same call with the receiver written out by hand.&lt;/p&gt;
&lt;p&gt;That is what the &lt;code&gt;pullSelf&lt;/code&gt; parameter handles. For a free function I pass &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;self_count&lt;/code&gt; is 0, and every parameter is pulled as a normal argument. For a method I pass a small function that unwraps the receiver from slot 1 into the right pointer type. For a simple Zig-owned struct that is a one-liner:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; pullPtrSelf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; T&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; u8&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;T&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; an anonymous struct, used only as a namespace&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; pull&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Lua&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;T&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;            //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; arg 1 must be a `name` userdata -&amp;gt; *T&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; lua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;checkUserdata&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;T&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; name&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;pull&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; hand back the function itself&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;code&gt;struct { fn pull ... }.pull&lt;/code&gt; shape deserves a full walk-through, because it looks odd the first time and it shows up all over this code. &lt;code&gt;metaIndex&lt;/code&gt; and &lt;code&gt;methodCFn&lt;/code&gt; use it too.&lt;/p&gt;
&lt;p&gt;Here is the problem it solves. I want &lt;code&gt;pullPtrSelf&lt;/code&gt; to return a function, and that returned function needs to know &lt;code&gt;T&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt;. But Zig functions are not closures: a plain nested function cannot capture the &lt;code&gt;T&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; from around it. What Zig does give me is comptime parameters and the fact that a &lt;code&gt;struct&lt;/code&gt; is a value I can define on the spot.&lt;/p&gt;
&lt;p&gt;So I define an anonymous struct type inside &lt;code&gt;pullPtrSelf&lt;/code&gt;, put a function called &lt;code&gt;pull&lt;/code&gt; inside it, and return &lt;code&gt;.pull&lt;/code&gt;, a reference to that function. The struct holds no data here. It is only a namespace for the function. The point is that &lt;code&gt;T&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; are comptime parameters of &lt;code&gt;pullPtrSelf&lt;/code&gt;, so when the compiler builds the struct it bakes their concrete values straight into &lt;code&gt;pull&lt;/code&gt;. Calling &lt;code&gt;pullPtrSelf(Gui, &quot;Gui&quot;)&lt;/code&gt; and &lt;code&gt;pullPtrSelf(Probe, &quot;Probe&quot;)&lt;/code&gt; produces two different struct types, and therefore two different &lt;code&gt;pull&lt;/code&gt; functions, each with its own &lt;code&gt;T&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; already filled in. Returning &lt;code&gt;.pull&lt;/code&gt; hands back one of those concrete functions, ready to be used as an ingredient of a &lt;code&gt;CFn&lt;/code&gt;. It is Zig&#39;s idiom for a function generated from comptime arguments, the same &lt;a rel=&quot;external&quot; href=&quot;https://ziglang.org/documentation/master/#comptime&quot;&gt;comptime&lt;/a&gt; machinery that powers generic types, and once you recognise it you will spot the same move in &lt;code&gt;metaIndex&lt;/code&gt; and &lt;code&gt;methodCFn&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Why make &lt;code&gt;pullSelf&lt;/code&gt; a pluggable function instead of hard-coding &quot;grab the pointer from slot 1&quot;? Because not every receiver is a raw pointer.&lt;/p&gt;
&lt;h2 id=&quot;store-handles-not-pointers&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#store-handles-not-pointers&quot; aria-label=&quot;Anchor link for: store-handles-not-pointers&quot;&gt;Store handles, not pointers&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For &lt;code&gt;Scene&lt;/code&gt; and &lt;code&gt;Input&lt;/code&gt; I stored a borrowed &lt;code&gt;*Scene&lt;/code&gt; inside the userdata. That is fine for them, because they live as long as the game does. A &lt;code&gt;Node&lt;/code&gt; is different. Nodes live in a pool inside the scene, they are created and destroyed during play, and I reload the scene while developing. The moment I reload, every pointer a script is holding dangles. Lua has no idea. It will happily call &lt;code&gt;translate&lt;/code&gt; on freed memory, and I get the worst kind of bug, the one that corrupts silently and crashes somewhere unrelated.&lt;/p&gt;
&lt;p&gt;A raw pointer is the wrong thing to hand across the scripting boundary. The script outlives the things it points at, and it has no way to know when one has gone away.&lt;/p&gt;
&lt;p&gt;The fix is to not store a pointer at all. I store a handle that can tell when it has gone stale. I follow the same approach as &lt;a rel=&quot;external&quot; href=&quot;https://floooh.github.io/2018/06/17/handles-vs-pointers.html&quot;&gt;Handles are the better pointers&lt;/a&gt; by Andre Weissflog: hand out an integer that packs an array index plus a generation tag, keep the real objects in arrays the system owns, and resolve a handle to a pointer only at the moment of use, checking the tag as you go.&lt;/p&gt;
&lt;p&gt;My node pool is built on &lt;a rel=&quot;external&quot; href=&quot;https://github.com/zig-gamedev/zpool&quot;&gt;zig-gamedev&#39;s zpool&lt;/a&gt;, which does exactly that. Every &lt;code&gt;Handle(Node)&lt;/code&gt; is an array index plus a cycle counter, and when a slot is freed and reused the cycle bumps, so a handle to the old occupant no longer resolves. The scene then carries one more counter of its own, an epoch that bumps every time the whole scene reloads. The userdata I give Lua bundles all three together:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RichHandle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; T&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; type&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;type&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; zpool handle: array index + cycle counter&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;        handle&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; model&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Handle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;T&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; the scene this handle belongs to&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;        scene&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; *&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;model&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Scene&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; the scene&amp;#39;s reload counter when we handed this out&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;        epoch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; u32&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Why both a cycle counter and an epoch? They catch different mistakes. zpool&#39;s cycle counter catches a single node being destroyed and its slot reused mid-game. The epoch catches a coarser case: when I reload a scene I throw the whole pool away and build a new one, and the fresh pool could hand out the same index and cycle the old one used. Bumping the epoch once per reload makes a handle from the previous scene fail to match.&lt;/p&gt;
&lt;p&gt;Every access from Lua goes through one resolver, and that resolver is where the safety lives:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; resolveNode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;node_handle&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RichHandle&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Node&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Node&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;node_handle&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;epoch&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; node_handle&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;scene&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;epoch&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; the scene was reloaded since we handed this out&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; error&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;StaleHandle&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; zpool resolves index+cycle to a live pointer, or errors if the slot was reused.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; try&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; node_handle&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;scene&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;nodes&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;getColumnPtr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;node_handle&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;handle&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;node&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The two checks stack. First the epoch comparison rejects handles from a reloaded scene. Then the &lt;code&gt;try&lt;/code&gt; lets zpool run its own cycle check inside &lt;code&gt;getColumnPtr&lt;/code&gt; and return an error if the slot was reused. Either way the script gets a clean error instead of a dangling dereference. This is why &lt;code&gt;pullSelf&lt;/code&gt; is pluggable: a &lt;code&gt;Node&lt;/code&gt;&#39;s receiver is not &lt;code&gt;userdata.*&lt;/code&gt;, it is &quot;validate the handle, then resolve it to a live pointer, or raise a Lua error&quot;. And because &lt;code&gt;pullSelf&lt;/code&gt; is just a parameter, the same &lt;code&gt;methodCFn&lt;/code&gt; machinery binds both kinds of type without a separate code path: the permanent ones like &lt;code&gt;Scene&lt;/code&gt;, where it takes the pointer directly, and the validated ones like &lt;code&gt;Node&lt;/code&gt;, where it checks the handle first.&lt;/p&gt;
&lt;p&gt;The rule I took away, after it cost me real debugging: a scripting layer must never hold a raw pointer to something whose lifetime it does not control. Hand it a handle it can validate, and validate on every access. The cost is one integer comparison. The other option is a crash you cannot reproduce.&lt;/p&gt;
&lt;h2 id=&quot;one-manifest-one-source-of-truth&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#one-manifest-one-source-of-truth&quot; aria-label=&quot;Anchor link for: one-manifest-one-source-of-truth&quot;&gt;One manifest, one source of truth&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All the pieces are here. The last step is to describe the API in one place. I use a small data structure, a list of classes, each with a list of methods, plus a couple of helpers to build each entry. This list is the single description everything else comes from:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; MANIFEST&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;_&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Class&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    .&lt;/span&gt;&lt;span&gt;{ &lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;methods&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; rawMethod: I supply both the CFn and the signature string by hand.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        rawMethod&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;is_valid&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; zlua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;wrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;nodeIsValid&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;fun(self: Node): boolean&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        rawMethod&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;get_name&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; zlua&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;wrap&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;nodeGetName&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;fun(self: Node): string&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; autoMethod: the CFn and the signature are both derived from the Zig function.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        autoMethod&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;translate&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; model&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Node&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;translate&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; pullNodeSelf&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        autoMethod&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;get_child_count&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; model&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;Node&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;getChildCount&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; pullNodeSelf&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ... Game, Scene, Gui ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Look at the two kinds of entry next to each other, because the contrast is the design. &lt;code&gt;autoMethod&lt;/code&gt; takes a real Zig function and derives two things from it by reflection: the marshalling shim, through &lt;code&gt;methodCFn&lt;/code&gt; as we built above, and a human-readable signature string, through a small helper called &lt;code&gt;luaSig&lt;/code&gt;. We have not used that second thing yet. It describes the function in the notation an editor understands, and it is the subject of the next section. &lt;code&gt;rawMethod&lt;/code&gt; is the escape hatch. When a binding needs something reflection cannot express, like the handle validation in &lt;code&gt;nodeIsValid&lt;/code&gt; or returning &lt;code&gt;nil&lt;/code&gt; for an optional, I hand-write the &lt;code&gt;CFn&lt;/code&gt; and supply its signature string myself. Most of the API is &lt;code&gt;autoMethod&lt;/code&gt;. The few genuinely special cases are &lt;code&gt;rawMethod&lt;/code&gt;. If the generator only automated and gave me no way out, the first irregular function would be a wall; keeping &lt;code&gt;rawMethod&lt;/code&gt; a first-class peer of &lt;code&gt;autoMethod&lt;/code&gt; means I never hit it.&lt;/p&gt;
&lt;p&gt;Binding the whole thing at startup is then a single loop over the manifest that builds each metatable and registers its methods. Add a class, add a line. Add a method, add a line.&lt;/p&gt;
&lt;h2 id=&quot;the-payoff-the-editor-learns-my-api&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-payoff-the-editor-learns-my-api&quot; aria-label=&quot;Anchor link for: the-payoff-the-editor-learns-my-api&quot;&gt;The payoff: the editor learns my API&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is the reason the manifest is shaped the way it is.&lt;/p&gt;
&lt;p&gt;When you write Lua against an engine, the editor has no idea what &lt;code&gt;node:&lt;/code&gt; can do. No autocompletion, no type checking, nothing, because Lua is dynamically typed and your API is invisible to the tooling. The Lua ecosystem&#39;s answer is &lt;a rel=&quot;external&quot; href=&quot;https://luals.github.io/wiki/annotations/&quot;&gt;LuaCATS&lt;/a&gt;: annotation comments that describe your classes and signatures, which the language server reads to give you completion and diagnostics. They look like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;lua&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;@class&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; Node&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; translate&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fun&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;arg1&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;arg2&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;, &lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;arg3&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;@field&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_child_count&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; fun&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;number&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Normally you write these by hand, and then you have two descriptions of your API, the bindings and the annotations, drifting apart the moment you forget to update one. I am not going to maintain the same thing twice.&lt;/p&gt;
&lt;p&gt;So I generate the annotations from the same manifest. Each &lt;code&gt;autoMethod&lt;/code&gt; already carries the signature string that &lt;code&gt;luaSig&lt;/code&gt; produced. &lt;code&gt;luaSig&lt;/code&gt; walks the function&#39;s parameter and return types and emits LuaCATS type names: &lt;code&gt;bool&lt;/code&gt; becomes &lt;code&gt;boolean&lt;/code&gt;, &lt;code&gt;[]const u8&lt;/code&gt; becomes &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;?*Node&lt;/code&gt; becomes &lt;code&gt;Node?&lt;/code&gt;. The same &lt;code&gt;@typeInfo&lt;/code&gt; walk that builds the runtime shim builds the documentation. Then a comptime string-concatenation pass turns the whole manifest into one &lt;code&gt;.lua&lt;/code&gt; stub file:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;zig&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; classesDefs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;comptime&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; classes&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; Class&lt;/span&gt;&lt;span&gt;) []&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; u8&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; the whole stub, built at compile time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    comptime&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; var&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; s&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; u8&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    inline&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;classes&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; one class header per manifest entry&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;        s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;---@class &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; c&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; one ---@field line per method: its Lua name and its luaSig signature&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        inline&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;c&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;methods&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;|&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;            s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;---@field &lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; m&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;lua_name&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; m&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;        s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; s&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; s&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The engine writes this file out, the language server picks it up, and my game scripts get autocompletion and type checking for an API that exists only inside my Zig source. Change a Zig function&#39;s signature and the stub changes with it on the next build. There is one source of truth, and it is the Zig code.&lt;/p&gt;
&lt;p&gt;That is the real reward of doing bindings through reflection. I wrote less plumbing, yes. But the better part is that the binding, the safety checks, and the editor tooling are all projections of the same types. They cannot drift apart, because there is nothing to keep in sync.&lt;/p&gt;
&lt;h2 id=&quot;what-i-would-tell-myself-before-starting&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-i-would-tell-myself-before-starting&quot; aria-label=&quot;Anchor link for: what-i-would-tell-myself-before-starting&quot;&gt;What I would tell myself before starting&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Three things, if you are about to do this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learn the stack protocol first. Every binding, by hand or generated, is &quot;pull arguments off the stack, call the function, push results back&quot;. Once that is second nature, the generator is just code that writes the pattern for you. The &lt;a rel=&quot;external&quot; href=&quot;https://www.lua.org/manual/5.4/manual.html#4&quot;&gt;Lua C API reference&lt;/a&gt; documents what every call pushes and pops.&lt;/li&gt;
&lt;li&gt;Reflect over types, do not duplicate them. &lt;a rel=&quot;external&quot; href=&quot;https://ziglang.org/documentation/master/#typeInfo&quot;&gt;&lt;code&gt;@typeInfo&lt;/code&gt;&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://ziglang.org/documentation/master/std/#std.meta&quot;&gt;&lt;code&gt;std.meta&lt;/code&gt;&lt;/a&gt;, and &lt;code&gt;inline for&lt;/code&gt; let the compiler write the marshalling, and they turn an unsupported type into a compile error instead of a runtime surprise.&lt;/li&gt;
&lt;li&gt;Never let a script hold a raw pointer to engine-owned, short-lived data. Hand it a handle it can validate, and check on every access. &lt;a rel=&quot;external&quot; href=&quot;https://floooh.github.io/2018/06/17/handles-vs-pointers.html&quot;&gt;Handles are the better pointers&lt;/a&gt; makes the full case, and &lt;a rel=&quot;external&quot; href=&quot;https://github.com/zig-gamedev/zpool&quot;&gt;zpool&lt;/a&gt; is a ready-made implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The engine is still small and the API keeps growing, but the binding layer has stopped being a chore. I add a Zig function, drop one line in the manifest, and it is callable from Lua and autocompleted in the editor.&lt;/p&gt;
&lt;p&gt;You tell me what to bind next.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Integrating Vulkan Ray Tracing in Godot</title>
          <pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/integrating-vulkan-ray-tracing-in-godot/</link>
          <guid>https://www.antoniocaggiano.eu/posts/integrating-vulkan-ray-tracing-in-godot/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/integrating-vulkan-ray-tracing-in-godot/">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This blog post is a transcript of my talk at &lt;a rel=&quot;external&quot; href=&quot;https://godotengine.org/godotcon/&quot;&gt;GodotCon&lt;/a&gt;. The conversational tone reflects the original presentation, aimed at walking through the work of bringing hardware ray tracing into the Godot engine.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/RM4xglHHYtY&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;During the pandemic I went deep into ray tracing. I wrote a software renderer from scratch, implemented a path tracer, and learned about techniques like &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Importance_sampling&quot;&gt;importance sampling&lt;/a&gt; and multiple importance sampling. With these I was able to render really cool images, like the Stanford dragon below.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/stanford-dragon.png&quot; alt=&quot;Stanford dragon&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;h2 id=&quot;why-ray-tracing&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-ray-tracing&quot; aria-label=&quot;Anchor link for: why-ray-tracing&quot;&gt;Why ray tracing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With ray tracing you can render beautiful pictures. The technique simulates the physics of light accurately, so you get effects that are difficult to fake: soft shadows, global illumination, reflections, and refractions.&lt;/p&gt;
&lt;p&gt;At a certain point I wanted to share this with more people, but my code was just a prototype, and nobody would care about my prototype. This is where Godot comes in.&lt;/p&gt;
&lt;h2 id=&quot;why-godot&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#why-godot&quot; aria-label=&quot;Anchor link for: why-godot&quot;&gt;Why Godot&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://godotengine.org/&quot;&gt;Godot&lt;/a&gt; is a game engine, and a lot of friends and colleagues use it. It ticks many boxes for me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is popular.&lt;/li&gt;
&lt;li&gt;It is open source under the MIT license.&lt;/li&gt;
&lt;li&gt;It is multiplatform.&lt;/li&gt;
&lt;li&gt;It does not require royalties for publishing your game.&lt;/li&gt;
&lt;li&gt;It is just a single file that you put on your desktop. You double-click, and it works.&lt;/li&gt;
&lt;li&gt;And most importantly, it compiles in a few minutes on my machine. If you have ever compiled other game engines, you know what that means for productivity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A couple of years ago, however, Godot had no support for hardware ray tracing. I thought I could help with that. How cool would it be to have something like this in Godot?&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/sponza-godot-rtao.png&quot; alt=&quot;Ray traced ambient occlusion in Sponza&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;The picture shows a technique called &lt;strong&gt;ray traced ambient occlusion&lt;/strong&gt;, which tries to estimate where light struggles to reach. You get nice soft shadows below a cube, or behind curtains, where the light cannot easily get in.&lt;/p&gt;
&lt;h2 id=&quot;adding-vulkan-ray-tracing-to-godot-how-hard-could-it-be&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#adding-vulkan-ray-tracing-to-godot-how-hard-could-it-be&quot; aria-label=&quot;Anchor link for: adding-vulkan-ray-tracing-to-godot-how-hard-could-it-be&quot;&gt;Adding Vulkan ray tracing to Godot. How hard could it be?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;That was the challenge. I had a bunch of Vulkan code in my prototype, which was the result of following the &lt;a rel=&quot;external&quot; href=&quot;https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/&quot;&gt;NVIDIA ray tracing tutorial&lt;/a&gt;. You cannot just take that code and drop it into Godot, it does not work like that.&lt;/p&gt;
&lt;p&gt;At a high level, to do ray tracing you need to do four things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a &lt;a rel=&quot;external&quot; href=&quot;https://jacco.ompf2.com/2022/04/13/how-to-build-a-bvh-part-1-basics/&quot;&gt;bounding volume hierarchy&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Create a ray tracing pipeline.&lt;/li&gt;
&lt;li&gt;Create the shader binding table.&lt;/li&gt;
&lt;li&gt;Trace rays.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let me go into a bit more detail on each.&lt;/p&gt;
&lt;h3 id=&quot;bounding-volume-hierarchies&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#bounding-volume-hierarchies&quot; aria-label=&quot;Anchor link for: bounding-volume-hierarchies&quot;&gt;Bounding volume hierarchies&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A bounding volume hierarchy is boxes containing boxes containing geometries. What problem does it solve?&lt;/p&gt;
&lt;p&gt;When you want to ray trace something, you shoot a ray and look for an intersection. Your scene may contain many geometries, and naively you would iterate through all of them looking for an intersection with the ray. That is a linear algorithm, and it does not scale.&lt;/p&gt;
&lt;p&gt;Instead, you can subdivide the space. You check for intersection on each cell of your space, and if you hit a cell, you go down and look for the geometries inside it. The algorithm becomes logarithmic.&lt;/p&gt;
&lt;p&gt;You can also subdivide the space within the space. You create a &lt;strong&gt;top level acceleration structure&lt;/strong&gt; (TLAS) at the top, and &lt;strong&gt;bottom level acceleration structures&lt;/strong&gt; (BLAS) underneath. Geometries live inside the BLAS, and instances of those BLAS are referenced from the TLAS.&lt;/p&gt;
&lt;p&gt;In pseudocode, you iterate through all the pixels in your framebuffer. You generate a ray and look for an intersection by traversing the bounding volume hierarchy. You either get an index of the geometry you hit, or you do not hit anything, which is a miss. If you hit a geometry, you can shade it: pick the material and, according to the lighting model, get a pixel colour on the screen.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;for&lt;/span&gt;&lt;span&gt; pixel&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; in&lt;/span&gt;&lt;span&gt; framebuffer&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ray&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; generate_ray&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pixel&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; intersects&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ray&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; bvh&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pixel&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;color&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; shade&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ray&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; geometries&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;ray-tracing-pipeline&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ray-tracing-pipeline&quot; aria-label=&quot;Anchor link for: ray-tracing-pipeline&quot;&gt;Ray tracing pipeline&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The ray tracing pipeline is tied to the GPU, and there are hardware modules for it.&lt;/p&gt;
&lt;p&gt;You generate a ray and trace it by looking for intersections in the bounding volume hierarchy. Inside the GPU this is a data structure, and the traversal is accelerated by the hardware. That is why we call it an &lt;em&gt;acceleration structure&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;If we have an intersection, we ask: is this the closest geometry to the origin of the ray? If so, we have a &lt;em&gt;closest hit&lt;/em&gt;, and we run a shader to compute the colour. If there is no hit, we have a &lt;em&gt;miss&lt;/em&gt;, and we still want to do something, for example return the colour of the sky. For that we use a &lt;em&gt;miss shader&lt;/em&gt;.&lt;/p&gt;
&lt;script src=https://www.antoniocaggiano.eu/js/mermaid.js&gt;&lt;/script&gt;
&lt;pre class=&quot;mermaid&quot;&gt;

flowchart TD
    RG[Ray Generation]
    AST[Acceleration Structure Traversal]
    RG --&gt;|Trace Ray| AST

    INT[Intersection]
    AH[Any Hit]
    AST --&gt; INT
    INT --&gt; AH
    AH --&gt; AST

    MISS[Miss]
    CH[Closest Hit]
    AST --&gt;|Hit? No| MISS
    AST --&gt;|Hit? Yes| CH

&lt;/pre&gt;
&lt;h2 id=&quot;fitting-ray-tracing-into-godot&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#fitting-ray-tracing-into-godot&quot; aria-label=&quot;Anchor link for: fitting-ray-tracing-into-godot&quot;&gt;Fitting ray tracing into Godot&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have this Vulkan code, I want to put it in Godot, but I cannot just drop it in. There are constraints:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I should not break the engine.&lt;/li&gt;
&lt;li&gt;It should fit Godot&#39;s rendering abstractions.&lt;/li&gt;
&lt;li&gt;It should perform automatic synchronisation via the render graph.&lt;/li&gt;
&lt;li&gt;I need to expose this new ray tracing API to the user via scripting.&lt;/li&gt;
&lt;li&gt;It should be multi-backend friendly. Godot does not only have Vulkan, it also supports Direct3D 12 and Metal. The interface should be unified.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-end-goal&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-end-goal&quot; aria-label=&quot;Anchor link for: the-end-goal&quot;&gt;The end goal&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Brace yourself, I am going to show you some code. This is what I would like the final API to look like. If you are familiar with GDScript and the &lt;code&gt;RenderingDevice&lt;/code&gt; object, you probably already use the parts at the top. The functions highlighted below are new and exposed to you.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;gdscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RenderingServer&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;create_local_rendering_device&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; New: create a bottom level acceleration structure for the scene geometries.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; blas&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;acceleration_structure_create_bottom_level&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;geometries&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; New: create a top level acceleration structure with one or more instances.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; tlas&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;acceleration_structure_create_top_level&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;instances&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Record commands.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; rtl&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_begin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_bind_pipeline&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rtl&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pipeline&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_bind_uniform_set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rtl&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; uniform_set&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_trace_rays&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rtl&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; width&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; height&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_end&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;where-gpu-rendering-lives-in-the-engine&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#where-gpu-rendering-lives-in-the-engine&quot; aria-label=&quot;Anchor link for: where-gpu-rendering-lives-in-the-engine&quot;&gt;Where GPU rendering lives in the engine&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;So, what code do I touch? I came up with the following picture. There are a few classes in the Godot source that matter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RenderingDevice&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RenderingDeviceGraph&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RenderingDeviceDriver&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script src=https://www.antoniocaggiano.eu/js/mermaid.js&gt;&lt;/script&gt;
&lt;pre class=&quot;mermaid&quot;&gt;

---
config:
  class:
    hideEmptyMembersBox: true
  layout: elk
  elk:
    nodePlacementStrategy: SIMPLE
---
classDiagram
    class RenderingDevice[&quot;RenderingDevice (RD)&quot;]
    class RenderingDeviceGraph[&quot;RenderingDeviceGraph (RDG)&quot;]
    class RenderingDeviceDriver[&quot;RenderingDeviceDriver (RDD)&quot;]
    class RDDVulkan
    class RDDD3D12
    class RDDMetal

    RenderingDevice *-- RenderingDeviceGraph
    RenderingDevice *-- RenderingDeviceDriver
    RenderingDeviceGraph *-- RenderingDeviceDriver
    RenderingDeviceDriver &lt;|-- RDDVulkan
    RenderingDeviceDriver &lt;|-- RDDD3D12
    RenderingDeviceDriver &lt;|-- RDDMetal

&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;RenderingDeviceDriver&lt;/code&gt; is a polymorphic type. It is a unified interface over the graphics APIs available to us, with concrete implementations for Vulkan, Direct3D 12, and Metal.&lt;/p&gt;
&lt;p&gt;In the middle is the &lt;code&gt;RenderingDeviceGraph&lt;/code&gt;. I really like this class. It is the authority on synchronisation. It is responsible for recording commands and tracking resource usages, and it generates barriers automatically based on those usages, which is incredibly useful.&lt;/p&gt;
&lt;h4 id=&quot;what-are-barriers&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-are-barriers&quot; aria-label=&quot;Anchor link for: what-are-barriers&quot;&gt;What are barriers?&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The GPU is highly parallel hardware. It tries to do everything at once if it can. Sometimes, though, you do not want that: you want to do something first, then something after that finishes. A &lt;strong&gt;GPU barrier&lt;/strong&gt; is the way to tell the GPU &quot;please wait for this operation to finish before starting the next one&quot;.&lt;/p&gt;
&lt;p&gt;I do not need to issue these barriers myself. The render graph generates them for me. That is why I like this class.&lt;/p&gt;
&lt;h4 id=&quot;how-the-graph-works&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-the-graph-works&quot; aria-label=&quot;Anchor link for: how-the-graph-works&quot;&gt;How the graph works&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The graph is a directed acyclic graph. Nodes represent GPU operations such as uploading data to a buffer, running a render pass, or running a compute pass. Edges between nodes are resource usages: do I read from the resource, do I write to it, do I use it for a specific reason?&lt;/p&gt;
&lt;p&gt;With this information, the &lt;code&gt;RenderingDeviceGraph&lt;/code&gt; detects dependencies between operations and resources, and generates barriers for me. There is a nice blog post on the Godot Engine website by DarioSamo, &lt;a rel=&quot;external&quot; href=&quot;https://godotengine.org/article/rendering-acyclic-graph/&quot;&gt;GPU synchronisation in Godot 4.3 is getting a major upgrade&lt;/a&gt;, that I recommend if you want a better understanding of the topic.&lt;/p&gt;
&lt;script src=https://www.antoniocaggiano.eu/js/mermaid.js&gt;&lt;/script&gt;
&lt;pre class=&quot;mermaid&quot;&gt;

flowchart TD
    a((a))
    b((b))
    c((c))
    d((d))
    e((e))

    a --&gt; b
    a --&gt; c
    a --&gt; d
    a --&gt; e
    b --&gt; d
    c --&gt; d
    c --&gt; e
    d --&gt; e

&lt;/pre&gt;
&lt;h4 id=&quot;the-rendering-device&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-rendering-device&quot; aria-label=&quot;Anchor link for: the-rendering-device&quot;&gt;The Rendering Device&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;At the very top is the &lt;code&gt;RenderingDevice&lt;/code&gt;. This is the GPU API exposed to Godot developers. It is responsible for creating GPU resources and recording commands, which it does by delegating to the classes on the right. Anything that involves command recording and synchronisation goes through the &lt;code&gt;RenderingDeviceGraph&lt;/code&gt;. Anything related to resource management goes through the &lt;code&gt;RenderingDeviceDriver&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;ray-tracing-hello-world&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ray-tracing-hello-world&quot; aria-label=&quot;Anchor link for: ray-tracing-hello-world&quot;&gt;Ray tracing hello world&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The idea is to do the ray tracing hello world: one triangle, one ray per pixel. What is the minimum set of changes needed to get a ray-traced triangle on the screen?&lt;/p&gt;
&lt;p&gt;Here is the road map I ended up with:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Extensions and properties.&lt;/li&gt;
&lt;li&gt;New types and APIs available to the user.&lt;/li&gt;
&lt;li&gt;Acceleration structures.&lt;/li&gt;
&lt;li&gt;Ray tracing shaders.&lt;/li&gt;
&lt;li&gt;Recording commands.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;vulkan-requirements&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#vulkan-requirements&quot; aria-label=&quot;Anchor link for: vulkan-requirements&quot;&gt;Vulkan requirements&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Not every GPU supports ray tracing. These features are quite new in the industry, and in Vulkan the ray tracing API is an extension, which means it is not enabled by default. I need to query the GPU: do you support acceleration structures? Do you support the ray tracing pipeline? Do you have all the requirements I need?&lt;/p&gt;
&lt;p&gt;If yes, the new Godot APIs become available. Otherwise, they do not. There are also a few properties I need to query for the size of objects, alignments in memory, and similar details, which the user will not have to care about. I take care of those.&lt;/p&gt;
&lt;h3 id=&quot;a-new-pipeline-type&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-new-pipeline-type&quot; aria-label=&quot;Anchor link for: a-new-pipeline-type&quot;&gt;A new pipeline type&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;So far Godot had two pipelines: rasterisation for drawing things on the screen, and compute for generic computation. Now we have a new one for ray tracing.&lt;/p&gt;
&lt;p&gt;Together with the pipeline come new shader stages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;raygen shader&lt;/strong&gt;: how we generate rays. Typically you generate rays at the camera position, shooting in the camera&#39;s view direction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;miss shader&lt;/strong&gt;: what happens when the ray does not hit any geometry. Maybe you want the colour of the sky.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;closest hit shader&lt;/strong&gt;: what happens when the ray hits the closest geometry.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;any hit shader&lt;/strong&gt;: invoked every time the ray hits something, not necessarily the closest. Useful for things like transparency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;intersection shader&lt;/strong&gt;: by default the GPU has a hardware module to accelerate ray-triangle intersection, which is super fast. If you want a different geometry, for example a &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Signed_distance_function&quot;&gt;signed distance function&lt;/a&gt;, you can provide your own intersection shader. I think that would be very cool.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I create the shader stages, group the closest hit and any hit shaders, and together they form a ray tracing pipeline.&lt;/p&gt;
&lt;h3 id=&quot;where-to-store-the-objects&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#where-to-store-the-objects&quot; aria-label=&quot;Anchor link for: where-to-store-the-objects&quot;&gt;Where to store the objects&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;At this point I have a question: where do I put my objects? I have all these Vulkan objects I created, and I need to specify their lifetime. Who creates them, who destroys them?&lt;/p&gt;
&lt;p&gt;There is a nice pattern in the Godot source code: the concept of an &lt;strong&gt;owner&lt;/strong&gt;. The owner is an object that holds GPU resources. You put your object into the owner and you get back a lightweight ID, an &lt;code&gt;RID&lt;/code&gt;, which is just an access key you can use later to retrieve the object.&lt;/p&gt;
&lt;p&gt;I ended up creating an owner for acceleration structures and an owner for ray tracing pipelines.&lt;/p&gt;
&lt;h3 id=&quot;new-engine-apis&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#new-engine-apis&quot; aria-label=&quot;Anchor link for: new-engine-apis&quot;&gt;New engine APIs&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;These are the new functions available via the &lt;code&gt;RenderingDevice&lt;/code&gt;. This is the part that you care about. The API is still experimental: the function names may change, the parameters may change. But so far we have functions for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating BLAS and building them.&lt;/li&gt;
&lt;li&gt;Creating TLAS and building them.&lt;/li&gt;
&lt;li&gt;Creating the ray tracing pipeline.&lt;/li&gt;
&lt;li&gt;Recording commands, which I will show in a moment.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-instances-buffer&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-instances-buffer&quot; aria-label=&quot;Anchor link for: the-instances-buffer&quot;&gt;The instances buffer&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The instances buffer is an interesting object. It is the way we build the TLAS.&lt;/p&gt;
&lt;p&gt;To build a BLAS we just need a collection of geometries, and we put those into the BLAS. The TLAS is different: we cannot just put a BLAS into a TLAS directly. We may want to use the same BLAS several times, instanced at different positions in space.&lt;/p&gt;
&lt;p&gt;This is done via the instances buffer: a reference to a BLAS plus a &lt;code&gt;Transform3D&lt;/code&gt; so we can place it in the world.&lt;/p&gt;
&lt;script src=https://www.antoniocaggiano.eu/js/mermaid.js&gt;&lt;/script&gt;
&lt;pre class=&quot;mermaid&quot;&gt;

flowchart TD
    BLAS[BLAS]
    T3D[Transform3D]
    IB[InstancesBuffer]
    TLAS[TLAS]

    BLAS --&gt;|*| IB
    T3D --&gt;|*| IB
    IB --&gt; TLAS

&lt;/pre&gt;
&lt;h3 id=&quot;the-scratch-buffer&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-scratch-buffer&quot; aria-label=&quot;Anchor link for: the-scratch-buffer&quot;&gt;The scratch buffer&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The scratch buffer is needed when we build acceleration structures. The GPU tells us: &quot;I need some memory where I can do my computation while building the acceleration structure, please give it to me.&quot; You ask, &quot;Can you not figure that out yourself?&quot; and the answer is no. You specify it, and the GPU can build the acceleration structure.&lt;/p&gt;
&lt;p&gt;You, the user, never have to care about this. I take care of it for you.&lt;/p&gt;
&lt;h3 id=&quot;resource-usages&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#resource-usages&quot; aria-label=&quot;Anchor link for: resource-usages&quot;&gt;Resource usages&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Earlier I mentioned that the render graph tracks operations and resource usages. For ray tracing the operations are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Building acceleration structures.&lt;/li&gt;
&lt;li&gt;Tracing rays.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The resource usages are things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When building a TLAS, the BLAS is used as a &lt;em&gt;build input&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;When tracing rays, we read from the memory representing the TLAS.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From these, the render graph generates the appropriate Vulkan barriers for me. Very cool.&lt;/p&gt;
&lt;h3 id=&quot;ray-tracing-shaders&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ray-tracing-shaders&quot; aria-label=&quot;Anchor link for: ray-tracing-shaders&quot;&gt;Ray tracing shaders&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is the part where I introduced new markers in source files: markers for raygen, miss, closest hit, any hit, and intersection. Below is an example of a single source file containing three shaders: a raygen shader, a miss shader, and a closest hit shader.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;glsl&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;raygen&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#version &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;460&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#extension GL_EXT_ray_tracing : require&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;layout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;set &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; binding &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; uniform&lt;/span&gt;&lt;span&gt; accelerationStructureEXT tlas&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;layout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;set &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; binding &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; rgba8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; uniform&lt;/span&gt;&lt;span&gt; image2D output_image&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;layout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;location &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; rayPayloadEXT &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;vec3&lt;/span&gt;&lt;span&gt; payload&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vec3 origin &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; vec3&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    vec3 direction &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; vec3&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    traceRayEXT&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;tlas&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; gl_RayFlagsOpaqueEXT&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; 0x&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;FF&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;                0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; origin&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;001&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; direction&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 10000&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    imageStore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;output_image&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; ivec2&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;gl_LaunchIDEXT&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;xy&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; vec4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;payload&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;miss&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#version &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;460&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#extension GL_EXT_ray_tracing : require&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;layout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;location &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; rayPayloadInEXT &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;vec3&lt;/span&gt;&lt;span&gt; payload&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    payload &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; vec3&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; red on miss&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;closest_hit&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#version &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;460&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#extension GL_EXT_ray_tracing : require&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;layout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;location &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; rayPayloadInEXT &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;vec3&lt;/span&gt;&lt;span&gt; payload&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    payload &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; vec3&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; green on hit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The raygen shader generates a ray at the origin pointing along the z-axis. There is probably a bug somewhere in there. The miss shader returns red when the ray hits nothing. The closest hit shader returns green when the ray hits something.&lt;/p&gt;
&lt;h3 id=&quot;the-shader-binding-table&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-shader-binding-table&quot; aria-label=&quot;Anchor link for: the-shader-binding-table&quot;&gt;The shader binding table&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The shader binding table was a headache for me. It is an object the GPU wants when you build your ray tracing pipeline. It does not contain shaders directly, it contains shader &lt;em&gt;group handles&lt;/em&gt;. When you build it, you also have to handle the size of the handles, their alignment in memory, and the strides of each region. It is complicated stuff that you, the user, should never have to care about.&lt;/p&gt;
&lt;h3 id=&quot;command-list&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#command-list&quot; aria-label=&quot;Anchor link for: command-list&quot;&gt;Command list&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is how Godot records commands: they are pushed into a list. There is a draw list for the rasterisation pipeline, a compute list for the compute pipeline, and now a ray tracing list for the ray tracing pipeline.&lt;/p&gt;
&lt;p&gt;In practice that is just a bunch of new functions on the &lt;code&gt;RenderingDevice&lt;/code&gt;, all available from GDScript. We have &lt;code&gt;raytracing_list_begin&lt;/code&gt; and &lt;code&gt;raytracing_list_end&lt;/code&gt;. Between those two, you bind objects, push data, and trace rays.&lt;/p&gt;
&lt;h2 id=&quot;the-minimal-sample-in-full&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-minimal-sample-in-full&quot; aria-label=&quot;Anchor link for: the-minimal-sample-in-full&quot;&gt;The minimal sample, in full&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Going back to our minimal sample, this time with the full picture:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;gdscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RenderingDevice&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;assert&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;has_feature&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;RenderingDevice&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;SUPPORTS_RAYTRACING_PIPELINE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Create BLAS and TLAS for a mesh.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; blas&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;blas_create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;/span&gt;&lt;span&gt;geometry&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    RenderingDevice&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;ACCELERATION_STRUCTURE_GEOMETRY_OPAQUE_BIT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; tlas&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;tlas_create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Build acceleration structures.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;blas_build&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;blas&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; instance&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RDAccelerationStructureInstance&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;instance&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;blas&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; blas&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;tlas_build&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;tlas&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;instance&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; raylist&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_begin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Bind pipeline and uniforms.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_bind_raytracing_pipeline&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;raylist&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; raytracing_pipeline&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_bind_uniform_set&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;raylist&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; uniform_set&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Trace rays.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; width&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_viewport&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; height&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; get_viewport&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;var&lt;/span&gt;&lt;span&gt; depth&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_trace_rays&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;raylist&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; sbt&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; width&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; depth&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_list_end&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;creating-the-ray-tracing-pipeline&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#creating-the-ray-tracing-pipeline&quot; aria-label=&quot;Anchor link for: creating-the-ray-tracing-pipeline&quot;&gt;Creating the ray tracing pipeline&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;How do you create the pipeline object? You take a GLSL shader, compile it to SPIR-V, create a shader object from the SPIR-V, group the resulting stages into hit groups, and call the pipeline create function. It looks convoluted, but you will figure it out.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;gdscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; _initialize_raytracing_pipeline&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Load shaders and create raytracing pipeline&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    var&lt;/span&gt;&lt;span&gt; shader_file&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; load&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;res://ray.glsl&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    var&lt;/span&gt;&lt;span&gt; shader_spirv&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; shader_file&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_spirv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    var&lt;/span&gt;&lt;span&gt; shader&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;shader_create_from_spirv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;shader_spirv&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    var&lt;/span&gt;&lt;span&gt; pipeline_shader&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RDPipelineShader&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pipeline_shader&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;shader&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; shader&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    var&lt;/span&gt;&lt;span&gt; hit_group&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RDHitGroup&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    hit_group&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;closest_hit_shader&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; pipeline_shader&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    var&lt;/span&gt;&lt;span&gt; raytracing_pipeline&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;raytracing_pipeline_create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        [&lt;/span&gt;&lt;span&gt;pipeline_shader&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        [&lt;/span&gt;&lt;span&gt;pipeline_shader&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        [&lt;/span&gt;&lt;span&gt;hit_group&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;        1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;creating-uniforms&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#creating-uniforms&quot; aria-label=&quot;Anchor link for: creating-uniforms&quot;&gt;Creating uniforms&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Uniforms are how we push data to the GPU. In my sample I have two: one for the output image, and one for the TLAS, which is the object I use to traverse the hierarchy and look for intersections.&lt;/p&gt;
&lt;p&gt;And here we have our nice triangle. The triangle is green, meaning the ray hit the geometry. Red means the ray missed.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;gdscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; _initialize_uniforms&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Storage image uniform&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    var&lt;/span&gt;&lt;span&gt; image_uniform&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RDUniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    image_uniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;uniform_type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RenderingDevice&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;UNIFORM_TYPE_IMAGE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    image_uniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;binding&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    image_uniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;add_id&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;output_image&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    #&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Acceleration structure uniform&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    var&lt;/span&gt;&lt;span&gt; as_uniform&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RDUniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    as_uniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;uniform_type&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; RenderingDevice&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;UNIFORM_TYPE_ACCELERATION_STRUCTURE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    as_uniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;binding&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    as_uniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;add_id&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;tlas&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    uniform_set&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;uniform_set_create&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;image_uniform&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;as_uniform&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; shader&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;the-pull-request&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-pull-request&quot; aria-label=&quot;Anchor link for: the-pull-request&quot;&gt;The pull request&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At this point I felt the implementation had enough code to call it done. I did not want to keep adding more. I wanted to open a pull request that was the minimum set of changes needed to implement this feature, because otherwise it would have been difficult for Godot maintainers to review and difficult for me to iterate on.&lt;/p&gt;
&lt;p&gt;Even so, the PR is around 3000 lines of code and accumulated 174 comments, mostly asking for changes. I opened it on November 12, 2024, and it was merged on January 27, 2025. I want to thank the reviewers: Calinou, Mickeon, AThousandShips, DarioSamo, clayjohn, and reduz. Thank you very much for reviewing my code.&lt;/p&gt;
&lt;h2 id=&quot;going-beyond-the-minimum-sponza&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#going-beyond-the-minimum-sponza&quot; aria-label=&quot;Anchor link for: going-beyond-the-minimum-sponza&quot;&gt;Going beyond the minimum: Sponza&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On a separate branch, which is not a pull request, I went further. I wanted to take the geometry from a real scene and forward it to the ray tracing pipeline.&lt;/p&gt;
&lt;p&gt;I rendered &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Sponza_Palace&quot;&gt;Sponza&lt;/a&gt;, but only half of it. Some geometries were missing. I started asking myself: where have those geometries gone? Why are some present and others not? I needed to debug it.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/sponza-godot-half.png&quot; alt=&quot;Half of Sponza rendered with ray tracing&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;I noticed a weird cube in the middle of the scene. It was not really a cube, there were things inside it.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/sponza-cube-bug.png&quot; alt=&quot;The cube in the middle of Sponza&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;I opened it in a profiler and saw that there were indeed many geometries inside, but the vertex positions were all between zero and one. I scratched my head. Maybe there is some compression going on here?&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/sponza-bug-profiler.png&quot; alt=&quot;Vertex positions between zero and one&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;Indeed, Godot compresses vertex attributes when you import a model. I disabled that behaviour, and boom: Sponza was rendered nicely through the ray tracing pipeline.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/sponza-godot-raytraced.png&quot; alt=&quot;Full Sponza rendered with ray tracing&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;h2 id=&quot;ray-traced-ambient-occlusion&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ray-traced-ambient-occlusion&quot; aria-label=&quot;Anchor link for: ray-traced-ambient-occlusion&quot;&gt;Ray traced ambient occlusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In that screenshot you can also see ray traced ambient occlusion in action. I noticed that Godot has a nice node called &lt;code&gt;WorldEnvironment&lt;/code&gt;, and I realised I could use it to add a post-processing step that does ray traced occlusion and composites the result with the default forward-plus pipeline.&lt;/p&gt;
&lt;p&gt;So this is forward-plus without ray traced ambient occlusion.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/sponza-godot-forward-plus.png&quot; alt=&quot;Forward-plus without ray traced ambient occlusion&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;This is forward-plus with it. Look at the difference, especially below the cube, where you can see a nice soft shadow, and behind the curtains, where you now see dark areas where the light struggles to reach. I think it is so nice.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/sponza-godot-forward-plus-rtao.png&quot; alt=&quot;Forward-plus with ray traced ambient occlusion&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;h2 id=&quot;what-is-next&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-is-next&quot; aria-label=&quot;Anchor link for: what-is-next&quot;&gt;What is next&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With this in place, we can do other interesting things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ray traced reflections.&lt;/li&gt;
&lt;li&gt;Custom visibility queries accelerated by the GPU&#39;s ray tracing hardware module.&lt;/li&gt;
&lt;li&gt;A hybrid renderer.&lt;/li&gt;
&lt;li&gt;Cinematic rendering.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You tell me.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Computer Graphics: Follow The Light</title>
          <pubDate>Tue, 03 Sep 2024 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/computer-graphics-follow-the-light/</link>
          <guid>https://www.antoniocaggiano.eu/posts/computer-graphics-follow-the-light/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/computer-graphics-follow-the-light/">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This blog post is a transcript of my talk at the &lt;a rel=&quot;external&quot; href=&quot;https://museopaestum.cultura.gov.it/il-parco-archeologico/?lang=en&quot;&gt;Archaeological Park of Paestum&lt;/a&gt; for &lt;a rel=&quot;external&quot; href=&quot;https://www.paestumtechdays.it/&quot;&gt;Paestum Tech Days&lt;/a&gt;. The conversational tone and simplified explanations reflect the original presentation style, aimed at making computer graphics concepts accessible to everyone, regardless of their technical background.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/2r3eyy8Y3Bw&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Okay, let&#39;s start with a nice question: How do we see? With the eyes. The eyes are a marvel of nature. They are light sensors. They capture light and send a signal to the brain, which we interpret as our internal representation of the reality around us. Wonderful.&lt;/p&gt;
&lt;p&gt;What is light? This second question is a bit more difficult. A didactic definition would be: a collection of &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Photon&quot;&gt;photons&lt;/a&gt;. It is &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Electromagnetic_radiation&quot;&gt;electromagnetic radiation&lt;/a&gt; — a variation of the electric and magnetic fields in space and time. It is a flow of particles and waves. The particles are photons. It has a &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Wave%E2%80%93particle_duality&quot;&gt;dual nature&lt;/a&gt;: it has both a particle nature and a wave nature. Let&#39;s say it bounces like a ball, but it waves like the sea. It is energy that travels, so much so that we can capture it with solar panels to power our homes.&lt;/p&gt;
&lt;p&gt;Yes, it&#39;s difficult. In fact, you need to be &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Albert_Einstein&quot;&gt;Einstein&lt;/a&gt; to have the genius idea to define light as a flow of photons, which are packets of energy. For example, a 60-watt light bulb emits 800 billion photons per second. And that&#39;s a lot. But what is the main source of photons that reaches planet Earth? The sun. How many photons does the sun emit per second? Many. It&#39;s such a large number that it&#39;s unimaginable.&lt;/p&gt;
&lt;h2 id=&quot;how-does-light-work&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-does-light-work&quot; aria-label=&quot;Anchor link for: how-does-light-work&quot;&gt;How Does Light Work?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Okay, but if we want to simulate light with a computer, we need to understand it a bit more. It behaves like particles, so we can use the concepts of particle and wave physics, but we should also observe some phenomena that are typical of light.&lt;/p&gt;
&lt;p&gt;For example, the phenomenon of transmission. Light passes from one medium to another, for instance, from space into the Earth&#39;s atmosphere. It arrives with a certain direction, intensity, and frequency, and continues in the same direction, with the same intensity and frequency.&lt;/p&gt;
&lt;p&gt;There&#39;s the phenomenon of &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Reflection_(physics)&quot;&gt;reflection&lt;/a&gt;, which happens with a mirror; a ray is reflected by the mirror and changes direction.&lt;/p&gt;
&lt;p&gt;The phenomenon of &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Refraction&quot;&gt;refraction&lt;/a&gt; is typical of water when a ray changes direction making it seem like a straw is broken, but it is not. It&#39;s just the optical effect of light refraction changing direction.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/the-dark-side-of-the-moon.png&quot; alt=&quot;The Dark Side Of The Moon&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;The phenomenon of &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Diffraction&quot;&gt;diffraction&lt;/a&gt;. Here we have a ray that splits into many other rays of different intensities or frequencies. A clear example is a prism, which is also &lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=k9ynZnEBtvw&quot;&gt;a beautiful album by a musical group&lt;/a&gt;. The ray enters the left side of the prism and is split into other rays of different intensities. It exits on the right side but at different frequencies, and different frequencies correspond to different colors. We perceive a different color if the frequency changes, and our eye can capture certain frequencies of electromagnetic radiation. There is a range that we see, but outside this range, there are frequencies we cannot see, such as &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Infrared&quot;&gt;infrared&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Ultraviolet&quot;&gt;ultraviolet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The phenomenon of absorption. Light is completely captured by an object and disappears, but it cannot disappear. No, because we know from the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Conservation_of_energy&quot;&gt;principle of conservation of energy&lt;/a&gt; that &quot;Nothing is created, nothing is destroyed, but everything is transformed&quot;, so this ray becomes something else, presumably it could become heat.&lt;/p&gt;
&lt;p&gt;The phenomenon of &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Scattering&quot;&gt;scattering&lt;/a&gt; happens in clouds. The ray splits into many other rays and goes everywhere. It also happens in fog. I don&#39;t know if you&#39;ve ever seen streetlights in the fog; you see this halo.&lt;/p&gt;
&lt;p&gt;In reality, all these light phenomena do not occur distinctly and separately but all happen together, everywhere, simultaneously. For example, there are materials that can reflect more, absorb more, or transmit/refract light more. But the other phenomena still occur, even if only to a small extent.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/materials.png&quot; alt=&quot;Materials&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;h2 id=&quot;light-simulation&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#light-simulation&quot; aria-label=&quot;Anchor link for: light-simulation&quot;&gt;Light Simulation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Finally, we get hands-on. Let&#39;s delve into the technical issue of real-time light simulation.&lt;/p&gt;
&lt;p&gt;What does real-time mean? I looked it up in the dictionary because I didn&#39;t know either. So, it means a duration corresponding to the real one, thus very quickly, almost immediately. Well, at least to give us the optical illusion of continuity. Our eye can perceive something as continuous if I update it every 16 milliseconds. Every 16 milliseconds a new image, so we perceive it as continuous. 16 milliseconds allow us to make 60 images per second.&lt;/p&gt;
&lt;p&gt;Okay, so 16 milliseconds, but we have to do a lot of calculations here. I talked about billions and billions of photons. I can&#39;t simulate all these photons because I only have 16 milliseconds. So, are we interested in all the photons? No, maybe I can focus on a reduced number of photons. Okay, and which ones interest me? Those that hit the eye. These are the ones that contribute to the image. These are the ones that actually interest me.&lt;/p&gt;
&lt;p&gt;In computer graphics, we use the term viewpoint or the term camera, from camera or video camera. So I will use camera and eye interchangeably. How can photons reach the eye? They can arrive directly. They start from a point source and reach our eye. Or they can also be emitted by objects that have a certain volume, like LED panels. They can bounce and reach our eye. In this case, it is called indirect light. And they can bounce more and more times, an indefinite number of times.&lt;/p&gt;
&lt;p&gt;So how do I know which photons reach my eye? This is an important question because there are photons that do not reach the eye that I want to ignore. So, it&#39;s time to talk about practical methodologies. In computer science, we call these algorithms, which in the world of cooking are called recipes.&lt;/p&gt;
&lt;h2 id=&quot;whitted-style-raytracing&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#whitted-style-raytracing&quot; aria-label=&quot;Anchor link for: whitted-style-raytracing&quot;&gt;Whitted-style Raytracing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Step number one: what do I see? I know where I am, I want to understand what is in front of me. I trace a ray, what do I hit? Maybe I hit something. Yes, I found something. Okay, let&#39;s trace more rays. Maybe I continue along this path. I trace a ray in the reflected direction and then trace other rays to reach the lights in my scene. How many lights are there? I trace as many rays as there are lights.&lt;/p&gt;
&lt;p&gt;Okay, so I trace a reverse path. This way, I make sure to trace paths that reach the camera, so I focus only on those photons, right? Clearly, it doesn&#39;t end here, because light bounces, so the reflected ray bounces on a new object. For the new object, I can trace other rays: a reflected ray and other rays to find the light recursively, repetitively.&lt;/p&gt;
&lt;p&gt;Great, this algorithm was created in 1980 by &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Turner_Whitted&quot;&gt;Turner Whitted&lt;/a&gt;. It&#39;s called &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Whitted-style_ray_tracing&quot;&gt;Whitted-Style Ray Tracing&lt;/a&gt;. Turner Whitted was a scientist at &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Bell_Labs&quot;&gt;Bell Labs&lt;/a&gt;. According to Americans, Bell is the inventor of the telephone, but according to us, it&#39;s &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Antonio_Meucci&quot;&gt;Meucci&lt;/a&gt;. At that time, Bell Labs was part of the American Telephone and Telegraph Company.&lt;/p&gt;
&lt;p&gt;I hope that&#39;s clear. For each bounce of light, a reflected ray and other rays towards the lights in the scene. But there&#39;s a small flaw in this algorithm. What happens if my scene has thousands and thousands of lights? My electrician went crazy and created a lot of LEDs in my room. Can I simulate them all? I could spend a lot of time tracing rays for all these lights, so I need to find a better solution. I need an algorithm that scales better with the complexity of the scene.&lt;/p&gt;
&lt;p&gt;So, let&#39;s try a new algorithm.&lt;/p&gt;
&lt;h2 id=&quot;path-tracing&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#path-tracing&quot; aria-label=&quot;Anchor link for: path-tracing&quot;&gt;Path Tracing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let&#39;s start from scratch. What do I see? I trace a ray. This remains common, alright? I found something, but at this point, I don&#39;t trace a ray following the previous steps; instead, I trace only one, but randomly. I find something. Okay, I continue. I trace another ray in a random direction. Oh, I was lucky. I found a light along the way. But I was very lucky. This is a path, let&#39;s remember that.&lt;/p&gt;
&lt;p&gt;However, there are rays that I choose randomly that might not hit anything in my scene; they might get lost in the void, they might miss the light. The ray is sad.&lt;/p&gt;
&lt;p&gt;I mentioned Path, in fact, this algorithm is called &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Path_tracing&quot;&gt;Path Tracing&lt;/a&gt;. It was created in 1986 by &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/James_Kajiya&quot;&gt;Jim Kajiya&lt;/a&gt;. At that time, he was a professor at the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/California_Institute_of_Technology&quot;&gt;California Institute of Technology&lt;/a&gt;, and since 1994, he is a researcher at &lt;a rel=&quot;external&quot; href=&quot;https://www.microsoft.com&quot;&gt;Microsoft&lt;/a&gt;.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/cornell-box.png&quot; alt=&quot;Cornell Box&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;How beautiful. This is an image created with the Path Tracing algorithm. It is a scene called &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Cornell_box&quot;&gt;Cornell Box&lt;/a&gt;. Cornell Boxes are a family of 3D scenes that can vary in wall color or objects in the scene. I can vary them a bit as I like, but fundamentally they are 3D scenes created by academics at &lt;a rel=&quot;external&quot; href=&quot;https://www.cornell.edu&quot;&gt;Cornell University&lt;/a&gt;. Cornell University is located in Ithaca, which is a college town in the state of New York.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/cornell-box-paths.png&quot; alt=&quot;Paths&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;These are examples of paths that light can take. Let&#39;s look at path number one. A bounce on the metal sphere and then it reaches the camera. Path number three bounces on the wall, the ceiling, and then reaches the camera. But path number two is more interesting because of the glass sphere, so we have the phenomenon of refraction. The ray is bent, passes through the sphere, and then reaches the camera.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/samples-per-pixel.png&quot; alt=&quot;Samples per Pixel&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;In this image, we can see how the final result improves as the number of paths I consider increases. Let&#39;s focus on image number one. You see, it&#39;s very noisy. There are many black pixels. Here, for each pixel, I made only one path, but some pixels are black. Why are they black?&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/cornell-box-low-samples.png&quot; alt=&quot;Cornell Box Low Samples&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;I&#39;ll tell you: because, as I mentioned before, there are random paths that do not find any light along the way, so it&#39;s as if it&#39;s dark. That&#39;s why. But I can do something: maybe, for each pixel, I don&#39;t make just one path but try to make another one, and I might be luckier. This way, I increase the chances of finding the light.&lt;/p&gt;
&lt;p&gt;In mathematics, we call these &quot;samples&quot;, using the technical term &quot;samples per pixel&quot;. I increase the number of samples per pixel to 2, 4, 8, 16, 32, 64, 128, and I get a more beautiful, more defined, clearer image. I found the light with a higher probability.&lt;/p&gt;
&lt;p&gt;However, I have to consider more paths, so I have to do more calculations, which means I might exceed the budget of 16 milliseconds. I always have to be careful not to overdo it. Maybe I can focus only on some paths; I can use some techniques. Indeed, Turner Whitted had somewhat guessed right in trying to find the light as soon as possible in order to reduce the number of samples to obtain a well-defined image.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/cornell-box-high-samples.png&quot; alt=&quot;Cornell Box High Samples&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;From 1986 onwards, however, algorithms have been improved, and I can achieve better results with fewer samples compared to naive ray tracing.&lt;/p&gt;
&lt;h2 id=&quot;maths&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#maths&quot; aria-label=&quot;Anchor link for: maths&quot;&gt;Maths&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In short, I talked about Whitted-Style Ray Tracing, I talked about Path Tracing, which are algorithms in the Ray Tracing family. What I really mean is: Maths.&lt;/p&gt;
&lt;p&gt;Maths. In fact, I can represent a ray with a point and a vector. The point is the origin, the vector is the direction of my ray. I represent geometries with points and indices to connect these points, like that puzzle game. For transformations, I can use matrix multiplications to enlarge, resize, rotate, and translate objects. I solve intersections between rays and geometries with systems of equations, the ray equation and the triangle equation, in this case.&lt;/p&gt;
&lt;p&gt;Light is simulated and calculated with integrals, and here it gets a bit more complicated. But speaking of integrals, let me show you my favorite formula: the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Rendering_equation&quot;&gt;rendering equation&lt;/a&gt;.&lt;/p&gt;
&lt;center&gt;&lt;big&gt;
$L_o(x, \omega_o) = L_e(x, \omega_o) + \int_{\Omega} f_r(x, \omega_i, \omega_o) L_i(x, \omega_i) (\omega_i \cdot n) d\omega_i$
&lt;/big&gt;&lt;/center&gt;
&lt;p&gt;How beautiful, look how beautiful it is. Okay, I&#39;ll read it to you, I&#39;ll read it simply. The light that arrives in my direction is equal to the light emitted by a certain surface, maybe a LED, and all the light that arrives on this surface and is reflected in my direction. They should teach mathematics like this in school.&lt;/p&gt;
&lt;h2 id=&quot;raytracing-algorithm&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#raytracing-algorithm&quot; aria-label=&quot;Anchor link for: raytracing-algorithm&quot;&gt;Raytracing Algorithm&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is roughly how a ray tracing algorithm works. Don&#39;t worry because I&#39;ll read it to you, line by line.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;for&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;screen&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;height&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;   for&lt;/span&gt;&lt;span&gt; x&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; in&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;screen&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;width&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       ray&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; Ray&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;origin&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; y&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; direction&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;       for&lt;/span&gt;&lt;span&gt; geometry&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; in&lt;/span&gt;&lt;span&gt; scene&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           intersection&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;color&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; intersect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ray&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; geometry&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;           if&lt;/span&gt;&lt;span&gt; intersection&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; is&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; not&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; None&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;               screen&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;pixels&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; intersection&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;color&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For y that goes from zero to the height of the screen, so I can do one row at a time, okay? 0, 1, 2, 3, 4, 5, 6, 7, up to the height of the screen. Simple.&lt;/p&gt;
&lt;p&gt;The second line, another loop, for x that goes from 0 to the width of the screen, and I do this for each row. So for the first row, all the pixels of the row. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15.&lt;/p&gt;
&lt;p&gt;Okay, I&#39;ll explain the rest in words. In simple terms, for each pixel, I do this: I trace a ray, see what is in front of me, if I hit something it&#39;s an intersection and I have to calculate the color. The color varies based on the material I hit and all the lights in the scene.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/cornell-box-low-res.png&quot; alt=&quot;Cornell Box: Low Resolution&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;This is an example of the result. Up close, you can&#39;t understand anything, but from a distance you can see that it&#39;s a Cornell box. There&#39;s a red wall on the left, a green wall on the right, and there are two objects in the scene.&lt;/p&gt;
&lt;p&gt;This algorithm is computationally expensive because you have to check for each ray if it intersects an object in the scene, and I have to check all the objects to see which one is closest, so if the complexity of the scene increases, the time I spend doing all these checks also increases. It requires a lot of memory because the entire scene has to be available in memory, because for each bounce I have to check again if I hit all the objects in my scene, and let&#39;s say a scene can weigh several MBs if not GBs, and here we are in 1986 and memory isn&#39;t like it is today.&lt;/p&gt;
&lt;p&gt;Do I have a reasonable alternative? Maybe an algorithm that allows me to focus on one geometry at a time? Yes, I do! It&#39;s called &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Rasterisation&quot;&gt;rasterization&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, what it actually does is focus on one geometry at a time. It loads the geometry into the graphics card, performs the necessary calculations, checks if each pixel is within the geometry, and calculates the color.&lt;/p&gt;
&lt;h2 id=&quot;rasterization-algorithm&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#rasterization-algorithm&quot; aria-label=&quot;Anchor link for: rasterization-algorithm&quot;&gt;Rasterization Algorithm&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Then, it unloads the geometry and loads another one, so I can focus on just one small triangle at a time, which is only a few bytes. Computationally, okay. I&#39;ve already mentioned this part: it checks if a point is within a geometry and has low memory usage because it focuses on one geometry at a time.&lt;/p&gt;
&lt;p&gt;However, the rasterization technique loses some of the phenomena that light gives us, and the trade-offs are these: I lose reflections, I lose refraction, I lose indirect light because I don&#39;t do the bounces, I lose shadows, and I also lose this beautiful phenomenon called &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Caustic_(optics)&quot;&gt;caustics&lt;/a&gt;.&lt;/p&gt;
&lt;center&gt;
&lt;p&gt;&lt;img src=&quot;../../images/caustics.jpg&quot; alt=&quot;Caustics&quot; /&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;Caustics are those light phenomena concentrated in certain points due to the curvature of geometries, in this case, the glass.&lt;/p&gt;
&lt;p&gt;I can achieve all these techniques with rasterization, but I have to use tricks, I have to approximate them, and they are not as faithful as ray tracing because ray tracing actually simulates the behavior of light and is very precise, giving us all these things for free.&lt;/p&gt;
&lt;p&gt;We are approaching the conclusion because a few decades later, after the 80s, the 90s, the 2000s, the 2010s, we reach 2020 and, along with the pandemic, the first hardware products that accelerate ray tracing come to market. What these beautiful, powerful graphics cards do is calculate the intersections between rays and geometries for us.&lt;/p&gt;
&lt;h2 id=&quot;hardware-accelerated-raytracing&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#hardware-accelerated-raytracing&quot; aria-label=&quot;Anchor link for: hardware-accelerated-raytracing&quot;&gt;Hardware Accelerated Raytracing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;They are incredibly fast, orders of magnitude faster than the normal processor we have in our computers. So, with the latest generation smartphones, we can do amazing things.&lt;/p&gt;
&lt;p&gt;Let me make this cameo: &#39;What a Time To Be Alive&#39;!&lt;/p&gt;
</description>
      </item>
      <item>
          <title>NcJump devlogs</title>
          <pubDate>Thu, 31 Dec 2020 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/ncjump-devlog/</link>
          <guid>https://www.antoniocaggiano.eu/posts/ncjump-devlog/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/ncjump-devlog/">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/Fahien/ncJump&quot;&gt;NcJump&lt;/a&gt; is a platform game project developed with a relatively new engine: &lt;a rel=&quot;external&quot; href=&quot;https://github.com/nCine/nCine&quot;&gt;nCine&lt;/a&gt;, an open-source C++ framework for 2D games developed by &lt;a rel=&quot;external&quot; href=&quot;https://encelo.itch.io/&quot;&gt;@encelo&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/IEs5XL2izVo&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Some time ago, a bunch of members of the &lt;a rel=&quot;external&quot; href=&quot;https://gameloop.it&quot;&gt;GameLoop&lt;/a&gt; community followed &lt;a rel=&quot;external&quot; href=&quot;https://cs50.harvard.edu/games/2018/&quot;&gt;CS50&#39;s introduction to game development&lt;/a&gt;, and I thought the sequence of games presented in this course could give me a good insight into what kind of game to create.&lt;/p&gt;
&lt;p&gt;A couple of developers have already made or started to make the first few games listed by that course. There is &lt;a rel=&quot;external&quot; href=&quot;https://github.com/nCine/ncPong&quot;&gt;a Pong clone&lt;/a&gt; made by @encelo, a Flappy Bird clone made by @Vasile-Peste, and a Breakout clone under development by &lt;a href=&quot;#&quot;&gt;@mat3&lt;/a&gt;. I opted for a Super Mario Bros clone.&lt;/p&gt;
&lt;p&gt;The idea was to follow the steps of &lt;a rel=&quot;external&quot; href=&quot;https://cs50.harvard.edu/games/2018/weeks/4/&quot;&gt;CS50&#39;s lecture 4&lt;/a&gt; by using nCine instead of &lt;a rel=&quot;external&quot; href=&quot;https://love2d.org/&quot;&gt;Love2D&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Some steps are required in order to start developing a game, but luckily everything you need to know is documented on the &lt;a rel=&quot;external&quot; href=&quot;https://ncine.github.io/download/&quot;&gt;nCine download web-page&lt;/a&gt;. I installed nCine, cloned &lt;a rel=&quot;external&quot; href=&quot;https://github.com/nCine/ncTemplate&quot;&gt;ncTemplate&lt;/a&gt;, and started working on top of it.&lt;/p&gt;
&lt;h1 id=&quot;writing-down-some-code&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#writing-down-some-code&quot; aria-label=&quot;Anchor link for: writing-down-some-code&quot;&gt;Writing down some code&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The main thing to consider from a software design perspective is that I renamed the main class of the template, &lt;code&gt;MyEventHandler&lt;/code&gt;, to &lt;code&gt;JumpHandler&lt;/code&gt; and introduced a &lt;code&gt;Game&lt;/code&gt; class. While &lt;code&gt;JumpHandler&lt;/code&gt; acts as a bridge between the game and the engine, &lt;code&gt;Game&lt;/code&gt; is the nucleus of the project and is responsible for the lifetimes of its objects and the logic of the application.&lt;/p&gt;
&lt;p&gt;Then I proceeded to implement an &lt;code&gt;Entity&lt;/code&gt; class, following the idea of an &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Entity_component_system&quot;&gt;Entity component system&lt;/a&gt;. The entity can have components like a graphics sprite, a finite state machine, or a body for physics and collisions.&lt;/p&gt;
&lt;p&gt;A GUI is mandatory to quickly iterate on new elements as they are added to the game, both to have visual feedback when debugging is needed and to tweak all sorts of values and configurations at run time. For this, I introduced an &lt;code&gt;Editor&lt;/code&gt; class, which makes heavy use of @ocornut&#39;s &lt;a rel=&quot;external&quot; href=&quot;https://github.com/ocornut/imgui&quot;&gt;Dear ImGui&lt;/a&gt;, also provided directly by nCine.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://box2d.org/&quot;&gt;Box2D&lt;/a&gt; is my choice for 2D physics and collisions. It is made by @erincatto and it is very easy to use.&lt;/p&gt;
&lt;h1 id=&quot;everything-is-entity&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#everything-is-entity&quot; aria-label=&quot;Anchor link for: everything-is-entity&quot;&gt;Everything is entity&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I implemented some key Entity states: idle, move, jump, and fall. In my opinion they are the foundations of the whole gameplay and I believe the result is good enough to move on to the next steps. Then I spent some time refactoring the Entity source code that was becoming too monolithic, and improving the tileset and tilemap by using entities instead of raw sprites for both tile prototypes and concrete tiles.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/KSodWW62p_c&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;An important consideration is that everything is an &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Entity_component_system&quot;&gt;entity&lt;/a&gt;. Characters are entities, tiles are entities, triggers are entities, and so on. So how do you distinguish between them? Every entity can have multiple components, whether it is an image or a &lt;a rel=&quot;external&quot; href=&quot;https://gameprogrammingpatterns.com/state.html&quot;&gt;state machine&lt;/a&gt; or a physics body, therefore different set of components will determine all the different kinds of entities which will populate a game scene.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;component&lt;/th&gt;&lt;th&gt;optional&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Transform&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Graphics&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Physics&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;State&lt;/td&gt;&lt;td&gt;yes&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;transform&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#transform&quot; aria-label=&quot;Anchor link for: transform&quot;&gt;Transform&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://www.gdcvault.com/play/1017652/Math-for-Game-Programmers-Matrix&quot;&gt;transform&lt;/a&gt; component is simply a wrapper around a &lt;code&gt;ncine::SceneNode&lt;/code&gt;. Everything else is supposed to be related to this node, so if we want to move the overall entity, we can just update the node of the transform component. It is worth mentioning that we use a unique pointer to store the node on the heap to make sure its memory would not move. This is needed as the nCine scene graph works with pointers.&lt;/p&gt;
&lt;h2 id=&quot;physics&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#physics&quot; aria-label=&quot;Anchor link for: physics&quot;&gt;Physics&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The physics component as well acts as an abstraction layer between the game and &lt;a rel=&quot;external&quot; href=&quot;https://box2d.org/&quot;&gt;Box2D&lt;/a&gt;; it holds values like the maximum velocity, jumping strength, and so on. Most importantly, it keeps track of a handle to a &lt;a rel=&quot;external&quot; href=&quot;https://box2d.org/documentation/classb2_body.html&quot;&gt;b2Body&lt;/a&gt;, which is the means to query the current physical state of the entity.&lt;/p&gt;
&lt;h2 id=&quot;graphics-and-state&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#graphics-and-state&quot; aria-label=&quot;Anchor link for: graphics-and-state&quot;&gt;Graphics and State&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At the base level, we have a graphics component with a single image or animation, and a state component with a single state which never changes. These are possibly the most common among the entities of a game.&lt;/p&gt;
&lt;p&gt;Now we need to consider the concept of a moving character with states like idle, move, jump, and fall. This set of states is also very common, so we implement it directly in C++. The result is the following class hierarchy.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Subclass&lt;/th&gt;&lt;th&gt;states&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;SingleState&lt;/td&gt;&lt;td&gt;IDLE&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CharacterState&lt;/td&gt;&lt;td&gt;IDLE, MOVE, JUMP, FALL&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;It follows that a &lt;code&gt;CharacterState&lt;/code&gt; class is closely coupled to its related graphics component, which we define as &lt;code&gt;CharacterGraphics&lt;/code&gt;, so the graphics components class hierarchy is quite similar to the previous one.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Subclass&lt;/th&gt;&lt;th&gt;graphics&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;SingleGraphics&lt;/td&gt;&lt;td&gt;IDLE&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CharacterGraphics&lt;/td&gt;&lt;td&gt;IDLE, MOVE, JUMP, FALL&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;As a final consideration, while a state component should be unique for each entity, a graphics component could be shared between multiple entities to avoid duplicating these kinds of heavy objects.&lt;/p&gt;
&lt;h1 id=&quot;the-smooth&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-smooth&quot; aria-label=&quot;Anchor link for: the-smooth&quot;&gt;The smooth&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I introduced a &lt;strong&gt;camera component&lt;/strong&gt; and &lt;strong&gt;serialization&lt;/strong&gt; to load and save to file the state of the game. While the former was pretty easy and straightforward to implement, the latter required introducing a new dependency and various scattered refactorings to pay some &lt;em&gt;technical debt&lt;/em&gt; accumulated from previous development iterations.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/5g_FacpB-J8&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;That was easy. The camera component has two main attributes: the scene root node and the target node. The scene root node is needed because we need to simulate the camera, which means that what we actually transform is the scene root node. In other words, to move the camera in one direction, we translate the scene root node to the opposite of such a direction. The target node is the one the camera should follow. As the target node moves around the scene, the camera is updated to match its coordinates.&lt;/p&gt;
&lt;p&gt;The quickest way to implement a following camera is to just write down something like &lt;code&gt;camera.position = target.position&lt;/code&gt;, and while it works, it is not the best we could do. A better and nicer approach, which might also prevent motion sickness, is to implement a camera with smooth movement. This can be done by linearly interpolating the camera and the target position by a small factor at every update of the game.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Camera&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;update&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;  float&lt;/span&gt;&lt;span&gt; smooth_factor&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;125&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;f&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;  Vec2f&lt;/span&gt;&lt;span&gt; smoothed_position&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; lerp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;position&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; target&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;position&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; smooth_factor&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;  this&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;position&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; smoothed_position&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;the-file&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-file&quot; aria-label=&quot;Anchor link for: the-file&quot;&gt;The file&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Conversely, this feature required a bit more work. I started by adding &lt;a rel=&quot;external&quot; href=&quot;https://github.com/nlohmann&quot;&gt;@nlohmann&lt;/a&gt;&#39;s &lt;a rel=&quot;external&quot; href=&quot;https://github.com/nlohmann/json&quot;&gt;json&lt;/a&gt; as a new dependency of the project for reading and writing to json files. I find it very easy to use in addition to the fact that I already used it for previous projects, like &lt;a rel=&quot;external&quot; href=&quot;https://github.com/GameLoop-it/jamspot/commit/931bba660fc9f855cbdb48b76dac825c57cf12c6&quot;&gt;Jamspot: Sokoban&lt;/a&gt;. The second step was implementing functions to save certain objects to and load them from file.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; to_json&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; j&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; const&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; t&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; from_json&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; json&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; j&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; T&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; t&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The trickiest part was to make sure that all the &lt;em&gt;serializable&lt;/em&gt; classes of objects could be &lt;em&gt;default constructed&lt;/em&gt;. That means avoiding references as class members and preferring pointers, hence allowing semi-initialized objects while making sure they stay in this state for the shortest period possible to avoid logic errors or even crashes.&lt;/p&gt;
&lt;p&gt;Once all this has been taken care of, I was able to edit the game configuration, the tileset, and the tilemap at runtime, close the game, and re-open it to find everything as I set it before. That is key to work on the levels of the game.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/6058008/104129583-c1ec6300-536c-11eb-890f-5fe3b3cfecc9.png&quot; alt=&quot;persistence&quot; /&gt;&lt;/p&gt;
&lt;h1 id=&quot;jump-higher&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jump-higher&quot; aria-label=&quot;Anchor link for: jump-higher&quot;&gt;Jump higher&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;From a gameplay perspective, the player gains confidence with the elements of interactivity of the game. First it moves, then jumps, then jumps higher. The implementation is straightforward thanks to &lt;a rel=&quot;external&quot; href=&quot;https://box2d.org/&quot;&gt;Box2D&lt;/a&gt;. If the &lt;em&gt;jump button&lt;/em&gt; is still down, keep applying a small force upwards. Keep in mind that the force should be weaker than gravity, otherwise the character would take off into space.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; can_jump_higher&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; input&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Entity&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; entity&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;jump&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;down&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    auto&lt;/span&gt;&lt;span&gt; force&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; b2Vec2&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; small_amount&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    entity&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;physics&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;ApplyForceToCenter&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;force&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; true&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/0ih-sGFFaLM&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;h1 id=&quot;resizing-the-tilemap&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#resizing-the-tilemap&quot; aria-label=&quot;Anchor link for: resizing-the-tilemap&quot;&gt;Resizing the tilemap&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This was less straightforward. I am starting to believe the more something is boring, the more difficult it is to implement. Resizing is not trivial; many things should be considered. For simplicity, here I will focus on the concrete tiles grid only. At the beginning, I used a simple vector to store all concrete tiles of the map and with a simple formula (&lt;code&gt;y + x * height&lt;/code&gt;) I was able to index a cell of the grid. Then I realized that resizing this vector was not convenient as the order of the tiles in the cells would not be preserved.&lt;/p&gt;
&lt;p&gt;As a solution, I changed the structure from a simple vector to a vector of vectors, so we could say a list of columns. That simplified indexing as you could just use the &lt;a rel=&quot;external&quot; href=&quot;https://docs.microsoft.com/en-us/cpp/cpp/subscript-operator&quot;&gt;subscript operator&lt;/a&gt; to access the right tile (&lt;code&gt;tiles[x][y]&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;It also simplified resizing. If you want to change the width of the tilemap, you just modify the number of columns by calling &lt;code&gt;tiles.resize(new_width)&lt;/code&gt;. As you can imagine, if the width shrinks, you lose those columns, while if the width grows, you get new columns with a &lt;em&gt;default&lt;/em&gt; concrete tile. I can not overstate the &lt;a rel=&quot;external&quot; href=&quot;https://www.codemotion.com/magazine/dev-hub/gamedev/john-romero-25-years-of-doom/&quot;&gt;importance of default values&lt;/a&gt;. Changing the height is slightly different, as you need to resize all the columns.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;uint32_t&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span&gt; width&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ++&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  tiles&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;resize&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new_height&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;the-easy-stuff&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-easy-stuff&quot; aria-label=&quot;Anchor link for: the-easy-stuff&quot;&gt;The easy stuff&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;While a static entity is not affected by physical forces and thus does not move, a dynamic entity is affected by forces, so it can fall and can be pushed and pulled around. Thanks again to &lt;a rel=&quot;external&quot; href=&quot;https://box2d.org/&quot;&gt;Box2D&lt;/a&gt;, implementing this was just a matter of setting the type of physics bodies to either &lt;code&gt;b2_dynamicBody&lt;/code&gt; or &lt;code&gt;b2_staticBody&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/0DUoYdU0fec&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;Another easy but important thing to add was a proper background to give to players&#39; eyes something more interesting to see than a boring solid color. I just added a static sprite, but I guess it would be nice to implement a fancy &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Parallax_scrolling&quot;&gt;parallax scrolling effect&lt;/a&gt; in the future.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/6058008/106210940-17779b00-61c8-11eb-8adb-76ff0b62a29b.png&quot; alt=&quot;github&quot; /&gt;&lt;/p&gt;
&lt;p&gt;At this point, I realized that something was missing. Tiles and entities could be added and positioned freely in the scene and, as all normal people who like symmetry, I started wanting to destroy them, not by interacting through the editor, but as Mario does by punching (or hitting with his head?)!&lt;/p&gt;
&lt;h1 id=&quot;appetite-for-destruction&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#appetite-for-destruction&quot; aria-label=&quot;Anchor link for: appetite-for-destruction&quot;&gt;Appetite for Destruction&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Well, not every tile should be destructible, but some of them certainly could, and I supposed it could be a good idea to give this ability to the player.&lt;/p&gt;
&lt;p&gt;I started by introducing a flag to determine whether a tile is destructible or not. Then I implemented a &lt;em&gt;destruction&lt;/em&gt; listener, which is a &lt;a rel=&quot;external&quot; href=&quot;https://box2d.org/documentation/classb2_contact_listener.html&quot;&gt;Box2D contact listener&lt;/a&gt;, responsible for checking impulses generated from collisions between entities. When this impulse is big enough, both flags of the entities involved in a collision are checked and, if destructible, added to a list. This list is processed later when the actual destruction happens. It is important to note that this should not be done in the previous step if you want to avoid errors while Box2D is still processing its update.&lt;/p&gt;
&lt;p&gt;After tweaking the threshold for the impulse triggering destructions, last thing to do was to increase manually impulses when the collision involved a character punching. In technical words, when one of the entities is a &lt;em&gt;character&lt;/em&gt; and the normal of the collision is close to &lt;code&gt;(0, -1)&lt;/code&gt; destruction is triggered for the other entity.&lt;/p&gt;
&lt;p&gt;The result is really cool because not only do entities get destroyed after a collision with the main character, but they also get destroyed when heavy collisions happen between each other.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/pVhfXCFCyt4&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;h1 id=&quot;push-and-pull&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#push-and-pull&quot; aria-label=&quot;Anchor link for: push-and-pull&quot;&gt;Push and pull&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Dynamic entities have been added to the game, and they can be pushed and pulled around the scene. This meant that new states should be added to characters, &lt;em&gt;push&lt;/em&gt; and &lt;em&gt;pull&lt;/em&gt; indeed.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;push&lt;/em&gt; state is enabled when a character is trying to move and finds an obstacle either on its left or its right, quite easy to implement. Obstacles in the four directions (up, right, down, left) are collected after the physics system update by checking for physics body collisions and the normal of contact points. In addition, some &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Bit_field&quot;&gt;bitflags&lt;/a&gt; are set which tell whether there are obstacles in any of the four directions.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/anDQ2s4gjwM&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;em&gt;pull&lt;/em&gt; state is enabled when the player presses the &lt;code&gt;x&lt;/code&gt; button and there is a dynamic obstacle, which is checked by querying the type of the obstacle&#39;s physics body. When the conditions are met, a &lt;a rel=&quot;external&quot; href=&quot;https://box2d.org/documentation/md__d_1__git_hub_box2d_docs_dynamics.html#autotoc_md85&quot;&gt;distance joint&lt;/a&gt; is created between the character and the dynamic entity to make sure that, when the character moves, the distance between the two bodies remains the same, effectively giving the character the ability to carry around the entity. Of course, the joint is destroyed when exiting from the pull state.&lt;/p&gt;
&lt;h1 id=&quot;data-submodule&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#data-submodule&quot; aria-label=&quot;Anchor link for: data-submodule&quot;&gt;Data submodule&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https://git-scm.com/book/en/v2/Git-Tools-Submodules&quot;&gt;git submodule&lt;/a&gt; has been added to the repository under the &lt;code&gt;data/&lt;/code&gt; directory, pointing to &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Fahien/ncJump-data&quot;&gt;Fahien/ncJump-data&lt;/a&gt;. There you could find the latest assets of the game: configurations, game maps, tile sets, and animations.&lt;/p&gt;
&lt;h1 id=&quot;a-better-editor&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#a-better-editor&quot; aria-label=&quot;Anchor link for: a-better-editor&quot;&gt;A better editor&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Many improvements have been added to the in-game editor: a main menu bar at the top for choosing a placing mode between &lt;em&gt;tile&lt;/em&gt; and &lt;em&gt;entity&lt;/em&gt;, changing the opacity of certain elements of the scene according to the current mode for immediate visual feedback; a config window to tweak all sorts of values not directly related to the gameplay, like the size of the window, the scale of the scene or the UI, the offset of the camera to move around the scene without necessarily moving the character.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/99qsQWYCDQE&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;h1 id=&quot;factories&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#factories&quot; aria-label=&quot;Anchor link for: factories&quot;&gt;Factories&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The time to add enemies to &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Fahien/ncJump&quot;&gt;the game&lt;/a&gt; has finally come, and that translates to &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Factory_method_pattern&quot;&gt;factories&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;An enemy is just another kind of entity, which is the reason that pushed me towards implementing a class which sole responsibility is to create entities: the &lt;code&gt;EntityFactory&lt;/code&gt;. This factory contains a list of entity &lt;em&gt;prototypes&lt;/em&gt; which can be selected from the editor and placed into the scene. Under the hood, the prototype is cloned, the clone is moved at mouse position, and it is added to the list of entities of the scene.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/uSHrcRkCzrM&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;At this point I realized that every clone was duplicating textures, which is something that could and should be avoided, so I introduced another factory: the &lt;code&gt;GraphicsFactory&lt;/code&gt;. The responsibility of this class is to maintain a list of textures which can be referenced by multiple &lt;em&gt;graphics components&lt;/em&gt;, as well as to create any kind of sprite that makes use of one of those textures.&lt;/p&gt;
&lt;h1 id=&quot;commands&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#commands&quot; aria-label=&quot;Anchor link for: commands&quot;&gt;Commands&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Once I had enemies in the scene, I began wondering how to make them move. Reusing the state component of the main character sounded OK to me, but there was a problem. The movement logic within the state component was directly checking the gamepad and the keyboard, which meant that player&#39;s input would move both the main character and all the enemies. &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Coupling_(computer_programming)&quot;&gt;Decoupling&lt;/a&gt; to the rescue.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Input → MoveCommand → StateComponent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I removed the dependency to the input from the state component, and I introduced the concept of commands. For simplicity, I will just focus on the &lt;code&gt;MoveCommand&lt;/code&gt;. The state component now is just listening for move commands and, when they are issued, the component inspects the values in a move command and updates its state accordingly. Move commands, and possibly other kinds of commands, can be issued by any source: player input, in-game console, scripts, and so on.&lt;/p&gt;
&lt;h1 id=&quot;scripts&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#scripts&quot; aria-label=&quot;Anchor link for: scripts&quot;&gt;Scripts&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Other engines may use terms like &lt;em&gt;behaviors&lt;/em&gt;, but I prefer to stick with the technical term: &lt;em&gt;script&lt;/em&gt;. With this you can indeed model behaviors of entities, like a wandering behavior that I had in mind for my first class of enemies. Ideally it might also be written with a scripting language, like &lt;a rel=&quot;external&quot; href=&quot;https://www.lua.org/&quot;&gt;LUA&lt;/a&gt; which is supported by nCine, but that is something I may explore in the future.&lt;/p&gt;
&lt;p&gt;I wrote down a couple of line for the wandering behavior which should just move the entity to the right or to the left until an obstacle is encountered, and then it should turn back and continue in a loop. The result is quite interesting, but I believe it can be further improved.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/GW3ofBKEidE&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;h1 id=&quot;dying-state&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dying-state&quot; aria-label=&quot;Anchor link for: dying-state&quot;&gt;Dying state&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Definitely one of the fundamental states. Any &lt;em&gt;living&lt;/em&gt; entity should die at some point, and this state represents that period of time where an animation should play, telling the player an enemy is defeated or that the game is over. The &lt;a rel=&quot;external&quot; href=&quot;https://gameprogrammingpatterns.com/update-method.html&quot;&gt;update method&lt;/a&gt; of this state is super easy and it looks like this.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; DyingState&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;update&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Entity&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; entity&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;entity&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;animation&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;has_finished&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        entity&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;set_enabled&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;false&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; just reuse this entity for something else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/WC6RI8gjJ30&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
&lt;h1 id=&quot;enabled-flag&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#enabled-flag&quot; aria-label=&quot;Anchor link for: enabled-flag&quot;&gt;Enabled flag&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Of course this explains the &lt;code&gt;Entity::set_enabled()&lt;/code&gt; method just introduced in the previous section. By calling it, we can effectively disable an entity and all its components without destroying it or freeing its memory, so that it can be recycled to be reused later when we, for example, need to spawn another entity.&lt;/p&gt;
&lt;h1 id=&quot;array-of-states&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#array-of-states&quot; aria-label=&quot;Anchor link for: array-of-states&quot;&gt;Array of states&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This was an important optimization. Before this, every state transition triggered the destruction of the old state and creation of an instance of the new state, which is not really needed and does not scale nicely as a scene grows. Now, a state component keeps track of an array of all the possible state objects, together with a pointer telling us which one is the current state.&lt;/p&gt;
&lt;h1 id=&quot;initial-position&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#initial-position&quot; aria-label=&quot;Anchor link for: initial-position&quot;&gt;Initial position&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Another requirement for the scene is to define where the player should start. This &lt;em&gt;initial position&lt;/em&gt; is a pair of coordinates which tells us just this. When a scene &lt;em&gt;starts&lt;/em&gt;, we put the player there.&lt;/p&gt;
&lt;h1 id=&quot;definitions-and-factories&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#definitions-and-factories&quot; aria-label=&quot;Anchor link for: definitions-and-factories&quot;&gt;Definitions and factories&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I love this pattern and I think I will use it from now on for all of my game projects. Basically, we have to deal with big and heavy objects which are not easily serializable. Think of wrappers around third party components like Box2D bodies or nCine sprites. I tried to find a way to serialize those objects and I believe I found a very nice solution which is anyway something widely used, so I possibly just reinvented the wheel here, but that is ok.&lt;/p&gt;
&lt;p&gt;I do not serialize those objects. I do serialize their definitions. A definition is a collection of all the parameters needed to construct an object. Let us take a &lt;em&gt;ncJump&lt;/em&gt; graphics component as an example.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Very simplified&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;auto&lt;/span&gt;&lt;span&gt; def&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; GraphicsDef&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;GraphicsType&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;TILE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; String&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;image.png&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;layer&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;auto&lt;/span&gt;&lt;span&gt; gfx&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; GraphicsComponent&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, the graphics component constructor takes a graphics definition as a parameter. A graphics definition, like all other definitions, is a &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Passive_data_structure&quot;&gt;Plain Old Data&lt;/a&gt; (POD) structure, which enables us to use &lt;a rel=&quot;external&quot; href=&quot;https://github.com/nlohmann/json#simplify-your-life-with-macros&quot;&gt;nlohmann macros&lt;/a&gt; to quickly define all the functions needed to serialize it. Done. Awesome.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; That&amp;#39;s it&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;GraphicsDef&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; type&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; path&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; layer&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;ci-and-automatic-deploy&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ci-and-automatic-deploy&quot; aria-label=&quot;Anchor link for: ci-and-automatic-deploy&quot;&gt;CI and automatic deploy&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The project builds automatically through GitHub actions, for &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Fahien/ncJump-artifacts&quot;&gt;Linux, Window, MacOS, Android&lt;/a&gt;, and believe it or not for the web. Indeed, &lt;a rel=&quot;external&quot; href=&quot;https://www.antoniocaggiano.eu/ncJump-artifacts/&quot;&gt;click here&lt;/a&gt; and be prepared to say &lt;strong&gt;wow&lt;/strong&gt;. All the credits for this go to the brilliant nCine author: &lt;a rel=&quot;external&quot; href=&quot;https://encelo.itch.io/&quot;&gt;@encelo&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;All the updates can be found on the &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Fahien/ncJump&quot;&gt;NcJump GitHub repository&lt;/a&gt;.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Rust+Wasm+WebGL: Create interesting interactive 3D content for the web</title>
          <pubDate>Thu, 17 Dec 2020 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/rust-wasm-webgl/</link>
          <guid>https://www.antoniocaggiano.eu/posts/rust-wasm-webgl/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/rust-wasm-webgl/">&lt;p&gt;&lt;a href=&quot;https://www.antoniocaggiano.eu/rust-webgl-demo/&quot; target=&quot;_blank&quot; class=&quot;btn btn--primary&quot;&gt;Direct Link&lt;/a&gt;&lt;/p&gt;
</description>
      </item>
      <item>
          <title>An exercise with boost::asio</title>
          <pubDate>Fri, 03 Apr 2020 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/exercize-with-boost-asio/</link>
          <guid>https://www.antoniocaggiano.eu/posts/exercize-with-boost-asio/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/exercize-with-boost-asio/">&lt;p&gt;If you are new to &lt;code&gt;boost::asio&lt;/code&gt;, you can find a good introduction on &lt;a rel=&quot;external&quot; href=&quot;https://www.boost.org/doc/libs/1_72_0/doc/html/boost_asio/tutorial.html&quot;&gt;boost.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This post describes an exercise built upon the asynchronous daytime server presented in the boost tutorial.&lt;/p&gt;
&lt;h2 id=&quot;list-of-clients&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#list-of-clients&quot; aria-label=&quot;Anchor link for: list-of-clients&quot;&gt;List of clients&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first thing we are going to implement is a way to ask the server for the list of clients currently connected. We need to keep track of incoming connections, therefore we add the following field to the server:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;vector&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Connection&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Server&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;connections&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Since we use references to connection objects in other parts of the program, connections should not move from their position in memory. New connections may come in while other connections are still being handled. If the vector resizes, its objects might move. This is why we allocate connections on the heap and use smart pointers as elements of the vector.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once we have a field to store incoming connections, &lt;code&gt;Server::accept()&lt;/code&gt; can be improved. We do not need to create new connections all the time, as we can recycle old connections that were closed.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;unique_ptr&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Connection&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt; new_con&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; nullptr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt; old_con&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt; connections&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;!&lt;/span&gt;&lt;span&gt;old_con&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;get_socket&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;is_open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Recycle old connection&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    new_con&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;old_con&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;!&lt;/span&gt;&lt;span&gt;new_con&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; No old connections found, so we create a new one&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  new_con&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;connections&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;emplace_back&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;make_unique&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Connection&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ctx&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;What happens if a large number of clients try to connect to the server at the same time?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;communication-protocol&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#communication-protocol&quot; aria-label=&quot;Anchor link for: communication-protocol&quot;&gt;Communication protocol&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When either the server or the client wants to wait for incoming packets, it uses the following asynchronous function:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;asio&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;async_read&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    socket&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    asio&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;buffer&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;Connection&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;handle_read&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; this&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;placeholders&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;_1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This function will call &lt;code&gt;handle_read&lt;/code&gt; only when exactly &lt;code&gt;sizeof(message)&lt;/code&gt; bytes have been received.
Data received will be stored in &lt;code&gt;message&lt;/code&gt;, an instance of &lt;code&gt;Message&lt;/code&gt;, which is defined like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;enum&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; class&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Command&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; uint16_t&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;  NOP&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; HI&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; LIST&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; STR&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; and more...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Message&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;  Command&lt;/span&gt;&lt;span&gt; command&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;  uint16_t&lt;/span&gt;&lt;span&gt; version&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;  std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;array&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 28&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; data&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are a few examples of messages that can be created using this design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This is a command message. It is used by a client to ask the server for the list of all connected clients.&lt;/p&gt;
&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;LIST (2 bytes)
      &lt;/td&gt;
      &lt;td&gt;VERSION (2 bytes)
      &lt;/td&gt;
      &lt;td&gt;- (28 bytes)
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This command sends a human-readable message.&lt;/p&gt;
&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;STR (2 bytes)
      &lt;/td&gt;
      &lt;td&gt;VERSION (2 bytes)
      &lt;/td&gt;
      &lt;td&gt;STR (28 bytes)
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;server&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#server&quot; aria-label=&quot;Anchor link for: server&quot;&gt;Server&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a new connection comes in, the server introduces itself with a &lt;code&gt;HI&lt;/code&gt; message. This message contains the name and version of the server:&lt;/p&gt;
&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;HI (2 bytes)
      &lt;/td&gt;
      &lt;td&gt;VERSION (2 bytes)
      &lt;/td&gt;
      &lt;td&gt;NAME (28 bytes)
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Then it waits for incoming packets via &lt;code&gt;async_read&lt;/code&gt;, as previously mentioned. By reading data directly into &lt;code&gt;message&lt;/code&gt;, the &lt;code&gt;handle_read&lt;/code&gt; callback becomes straightforward:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; handle_read&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; boost&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;system&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;error_code&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Error handling [...]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;  switch&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;command&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    case&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Command&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;NOP&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; nothing to do&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    case&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Command&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span&gt;LIST&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;      //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; @todo Send a message with the list of all clients&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;      break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; switch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; [...]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;client&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#client&quot; aria-label=&quot;Anchor link for: client&quot;&gt;Client&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The client should run two different threads:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A network thread to handle incoming messages from the server.&lt;/li&gt;
&lt;li&gt;A main thread to read user input, update its logic, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For this purpose, before the main loop, we spawn a thread to run the IO context:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;auto&lt;/span&gt;&lt;span&gt; con&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; Connection&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; endpoints&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;auto&lt;/span&gt;&lt;span&gt; thread&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; std&lt;/span&gt;&lt;span&gt;::&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;thread&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;io&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;span&gt; io&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;run&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;true&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;  //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; main loop&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</description>
      </item>
      <item>
          <title>Computer network notes</title>
          <pubDate>Mon, 21 Dec 2015 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/computer-network-notes/</link>
          <guid>https://www.antoniocaggiano.eu/posts/computer-network-notes/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/computer-network-notes/">&lt;h2 id=&quot;line-coding&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#line-coding&quot; aria-label=&quot;Anchor link for: line-coding&quot;&gt;Line coding&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Line_code&quot;&gt;line coding&lt;/a&gt;, it is possible to represent sequences of &lt;strong&gt;bits&lt;/strong&gt; using digital signals. Among the line codings we have: &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Unipolar_encoding&quot;&gt;unipolar&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Non-return-to-zero&quot;&gt;polar&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Bipolar_encoding&quot;&gt;bipolar&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/2B1Q&quot;&gt;multilevel&lt;/a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/MLT-3_encoding&quot;&gt;multiline&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nyquist theorem&lt;/strong&gt;&lt;br/&gt;
In a channel without noise, this theorem gives us the maximum velocity at which we can send bits:
N&lt;sub&gt;max&lt;/sub&gt; = 2 × B × log&lt;sub&gt;2&lt;/sub&gt; L&lt;br/&gt;
where &lt;em&gt;B&lt;/em&gt; is the bandwidth and &lt;em&gt;L&lt;/em&gt; is the number of signal levels used to represent the data.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;unipolar-code-nrz&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#unipolar-code-nrz&quot; aria-label=&quot;Anchor link for: unipolar-code-nrz&quot;&gt;Unipolar code NRZ&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;NRZ&lt;/strong&gt; (Non-Return-to-Zero) code represents &lt;code&gt;1&lt;/code&gt; as a positive voltage and &lt;code&gt;0&lt;/code&gt; as a null voltage. It is called NRZ because the signal does not return to zero while coding each bit.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../images/nrzunipolar.png&quot; alt=&quot;Unipolar code NRZ&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;polar-code-nrz&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#polar-code-nrz&quot; aria-label=&quot;Anchor link for: polar-code-nrz&quot;&gt;Polar code NRZ&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In a polar code, two levels of voltage are used: positive and negative. In &lt;strong&gt;NRZ-L&lt;/strong&gt; (Level) a positive voltage represents &lt;code&gt;0&lt;/code&gt; and a negative voltage represents &lt;code&gt;1&lt;/code&gt;. In &lt;strong&gt;NRZ-I&lt;/strong&gt; (Invert) the bit is determined by a change in the voltage level: absence of change means &lt;code&gt;0&lt;/code&gt;, change means &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../images/nrzpolar.png&quot; alt=&quot;Polar codes NRZ-L and NRZ-I&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;bipolar-code-ami&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#bipolar-code-ami&quot; aria-label=&quot;Anchor link for: bipolar-code-ami&quot;&gt;Bipolar code AMI&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;AMI&lt;/strong&gt; (Alternate Mark Inversion) code represents &lt;code&gt;0&lt;/code&gt; as a null voltage and &lt;code&gt;1&lt;/code&gt; as switches between positive and negative voltages.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../images/ami.png&quot; alt=&quot;Bipolar code AMI&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;switching&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#switching&quot; aria-label=&quot;Anchor link for: switching&quot;&gt;Switching&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Switching&lt;/strong&gt; is a convenient method to connect nodes in a very large network where special nodes, called &lt;em&gt;switches&lt;/em&gt;, are connected together and can create connections between two or more stations connected to the switches. There are three categories of switching networks: &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Circuit_switching&quot;&gt;circuit switching&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Packet_switching&quot;&gt;packet switching&lt;/a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Message_switching&quot;&gt;message switching&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;circuit-switching-networks&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#circuit-switching-networks&quot; aria-label=&quot;Anchor link for: circuit-switching-networks&quot;&gt;Circuit switching networks&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A circuit switching network has a collection of switches connected together with links divided into multiple channels thanks to &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Multiplexing&quot;&gt;multiplexing&lt;/a&gt;. The communication between two stations requires three steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Connection setup&lt;/strong&gt;, where a path is found on the links between the switches and a channel is reserved for each link.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data transfer&lt;/strong&gt;, where all the channels dedicated to the connection remain unavailable to other connections.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Connection teardown&lt;/strong&gt;, where a station sends a signal to every switch to free their resources.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using a circuit switching network is not the best for &lt;strong&gt;efficiency&lt;/strong&gt;: we could have long periods of inactivity with no data transfers, which means wasting those resources dedicated to the connection. On the other hand, the &lt;strong&gt;delay&lt;/strong&gt; is minimal: since a path is dedicated when establishing a connection, data flow without stopping at each switch.&lt;/p&gt;
&lt;h3 id=&quot;packet-switching-networks&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#packet-switching-networks&quot; aria-label=&quot;Anchor link for: packet-switching-networks&quot;&gt;Packet switching networks&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In this network, data need to be split into packets independent from each other, namely &lt;strong&gt;datagrams&lt;/strong&gt;, with variable or fixed length depending on the protocol. Switches here are also called &lt;strong&gt;routers&lt;/strong&gt;. A message can be subdivided into more datagrams which can travel on different paths and reach their destination in a different order, or they can get lost, or get eliminated due to a shortage of resources on the network.&lt;/p&gt;
&lt;p&gt;Datagram networks have &lt;strong&gt;no connection&lt;/strong&gt;, meaning that switches do not keep track of connection states. There is no connection setup nor teardown. In order to know how to send a datagram, switches maintain dynamic &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Routing_table&quot;&gt;routing tables&lt;/a&gt; periodically updated. From an &lt;strong&gt;efficiency&lt;/strong&gt; perspective, packet switching networks are better than circuit switching networks: resources are allocated only when there are packets to transfer. The &lt;strong&gt;delay&lt;/strong&gt; however can be higher: each packet could follow longer paths or need to wait in switches before being forwarded.&lt;/p&gt;
&lt;h2 id=&quot;multiple-access-protocols&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#multiple-access-protocols&quot; aria-label=&quot;Anchor link for: multiple-access-protocols&quot;&gt;Multiple access protocols&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With random access protocols, stations do not have control over the medium and its usage is competed for. Stations can check the state of the medium at any time and there is no access order. There could be cases where two or more stations try sending simultaneously, causing a &lt;strong&gt;collision&lt;/strong&gt; which destroys or modifies the frames. Among random access protocols we have: &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/ALOHAnet#ALOHA_protocol&quot;&gt;ALOHA&lt;/a&gt;; &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Carrier_sense_multiple_access&quot;&gt;CSMA&lt;/a&gt;; &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Carrier_sense_multiple_access_with_collision_avoidance&quot;&gt;CSMA/CA&lt;/a&gt;; &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Carrier_sense_multiple_access_with_collision_detection&quot;&gt;CSMA/CD&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;aloha&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#aloha&quot; aria-label=&quot;Anchor link for: aloha&quot;&gt;Aloha&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the original ALOHA protocol, each station sends a frame whenever it wants, therefore there are chances of collisions. We rely on feedback from the recipient and, if it does not come, the recipient will send the frame again. Before resending a frame destroyed by a collision, stations need to wait a random amount of time, namely &lt;strong&gt;backoff time&lt;/strong&gt; or T&lt;sub&gt;b&lt;/sub&gt;. After a maximum number of transmission attempts, K&lt;sub&gt;max&lt;/sub&gt;, stations must desist and retry later.&lt;/p&gt;
&lt;h3 id=&quot;csma&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#csma&quot; aria-label=&quot;Anchor link for: csma&quot;&gt;CSMA&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;Carrier Sense Multiple Access&lt;/strong&gt; method tries to improve network performance by minimizing collision probabilities by making stations check the state of the medium before sending data. If two stations check the medium and find it free at the same time, a collision can still happen if both stations choose to transmit. There are three methods which can determine the behavior of the stations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1-persistent&lt;/strong&gt;: if the medium is busy, the station continues to check the state until it becomes free to send data.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;non-persistent&lt;/strong&gt;: if the medium is free, the station sends data, otherwise it waits a random time before repeating the same operation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;p-persistent&lt;/strong&gt;: if the medium is busy, the station continuously checks the state until it becomes free, then:
&lt;ol&gt;
&lt;li&gt;it sends the frame with probability &lt;code&gt;p&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;it waits, with probability &lt;code&gt;1-p&lt;/code&gt;, for at least the maximum propagation time before checking the medium again. At this point, if the medium is free it restarts from 1, otherwise it performs a &lt;em&gt;backoff&lt;/em&gt; operation.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;csma-cd&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#csma-cd&quot; aria-label=&quot;Anchor link for: csma-cd&quot;&gt;CSMA/CD&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The CSMA/CD (collision detection) method adds an algorithm to detect and handle &lt;strong&gt;collisions&lt;/strong&gt;. A station, while sending a frame, continuously checks the medium and if it detects a collision, stops transmitting immediately. In order to be effective, it is important that the minimum transmission time of any frame is at least twice the maximum propagation time. Otherwise, stations could not detect all collisions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;T&lt;sub&gt;fr&lt;/sub&gt; ≥ 2·T&lt;sub&gt;p&lt;/sub&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;csma-ca&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#csma-ca&quot; aria-label=&quot;Anchor link for: csma-ca&quot;&gt;CSMA/CA&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The CSMA/CD method is not effective in a &lt;strong&gt;wireless network&lt;/strong&gt;, where signal energy loss during transmission could negatively affect collision detection. The CSMA/CA (collision avoidance) protocol avoids collisions with three strategies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;spacing between frames&lt;/strong&gt;: when a station finds the medium available, before transmitting, it waits for a period of time, namely &lt;em&gt;interframe spacing&lt;/em&gt; (IFS).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;collision window&lt;/strong&gt;: a station that has just finished waiting for IFS waits again for a random number of intervals. After each interval, it checks the state of the medium and if it is busy, pauses this process and restarts it later when the medium is free again.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;controls&lt;/strong&gt;: guarantee that the receiver has received the frame and no collisions have happened.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;controlled-access&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#controlled-access&quot; aria-label=&quot;Anchor link for: controlled-access&quot;&gt;Controlled access&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With controlled access protocols, stations agree on the usage of the medium. There are three methods:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reservation&lt;/strong&gt;: stations need to reserve a time interval during which they can transmit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Polling&lt;/strong&gt;: one of the stations controls the medium and the other stations follow its instructions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token passing&lt;/strong&gt;: stations are organized as a &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Token_ring&quot;&gt;logic ring&lt;/a&gt; and access to the medium is allowed only when a station has the token, a special frame, which circulates among the stations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;channelization&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#channelization&quot; aria-label=&quot;Anchor link for: channelization&quot;&gt;Channelization&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In channelization the &lt;strong&gt;bandwidth&lt;/strong&gt; is shared between the stations. Among channelization protocols we have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Frequency-division_multiple_access&quot;&gt;FDMA&lt;/a&gt;, where the bandwidth is subdivided into non-contiguous sections assigned to the stations.&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Time_division_multiple_access&quot;&gt;TDMA&lt;/a&gt;, where the channel is used by one station at a time.&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Code-division_multiple_access&quot;&gt;CDMA&lt;/a&gt;, where the medium carries all transmissions simultaneously, isolated thanks to an encoding system.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;spread-spectrum&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#spread-spectrum&quot; aria-label=&quot;Anchor link for: spread-spectrum&quot;&gt;Spread Spectrum&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Spread_spectrum&quot;&gt;Spread Spectrum&lt;/a&gt; techniques, signals of various sources are combined to prevent detection and interference. Those techniques are based on &lt;strong&gt;redundancy&lt;/strong&gt;, increasing the width of the original bandwidth.&lt;/p&gt;
&lt;h3 id=&quot;frequency-hopping-spread-spectrum&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#frequency-hopping-spread-spectrum&quot; aria-label=&quot;Anchor link for: frequency-hopping-spread-spectrum&quot;&gt;Frequency Hopping Spread Spectrum&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Frequency-hopping_spread_spectrum&quot;&gt;Frequency Hopping Spread Spectrum&lt;/a&gt; (FHSS) selects &lt;strong&gt;carrier frequencies&lt;/strong&gt; pseudo-randomly, modulated by the original signal. A third-party does not know on which frequencies data are transmitted and impeding the transmission is difficult since it would require generating interference on multiple frequencies.&lt;/p&gt;
&lt;h3 id=&quot;direct-sequence-spread-spectrum&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#direct-sequence-spread-spectrum&quot; aria-label=&quot;Anchor link for: direct-sequence-spread-spectrum&quot;&gt;Direct Sequence Spread Spectrum&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Direct-sequence_spread_spectrum&quot;&gt;Direct Sequence Spread Spectrum&lt;/a&gt; (DSSS) maps every bit of the original signal to a &lt;strong&gt;wordcode&lt;/strong&gt; of &lt;em&gt;n&lt;/em&gt; bits through a hopping code. Wireless LANs use &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Barker_code&quot;&gt;Barker code&lt;/a&gt;, where &lt;em&gt;n&lt;/em&gt; is 11, which means that the required bandwidth is 11 times larger.&lt;/p&gt;
&lt;h2 id=&quot;error-control-in-data-link-layer&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#error-control-in-data-link-layer&quot; aria-label=&quot;Anchor link for: error-control-in-data-link-layer&quot;&gt;Error Control in Data Link Layer&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;stop-and-wait-arq&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#stop-and-wait-arq&quot; aria-label=&quot;Anchor link for: stop-and-wait-arq&quot;&gt;Stop-and-wait ARQ&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Stop-and-wait_ARQ&quot;&gt;Stop-and-wait ARQ&lt;/a&gt; protocol is an improvement to the &lt;strong&gt;stop-and-wait&lt;/strong&gt;. After transmitting a frame, the sender waits for an acknowledgement (ACK) from the recipient. At this point, the &lt;a rel=&quot;external&quot; href=&quot;https://it.wikipedia.org/wiki/Automatic_repeat_request&quot;&gt;Automatic Repeat reQuest&lt;/a&gt; (ARQ) mechanism checks for errors. The data frame and ACK frame have a 1-bit field for a &lt;strong&gt;sequence number&lt;/strong&gt;, so it can be either &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;. The recipient does not send any feedback for damaged or out-of-order frames. After waiting for the ACK for a certain amount of time, the sender re-transmits the frame. This protocol is quite &lt;strong&gt;inefficient&lt;/strong&gt; as the communication channel will handle at any time at most one frame, therefore we would not use its full transmissive capacity.&lt;/p&gt;
&lt;h3 id=&quot;go-back-n-arq&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#go-back-n-arq&quot; aria-label=&quot;Anchor link for: go-back-n-arq&quot;&gt;Go-back-N ARQ&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Go-Back-N_ARQ&quot;&gt;Go-back-N ARQ&lt;/a&gt; protocol manages to send more than one frame, keeping a copy for each one if re-transmission is needed, discarding them when their relative ACK frame is received. It uses &lt;em&gt;m&lt;/em&gt; bits for the sequence number field, so its values are within [0, 2ᵐ - 1]. The sender maintains a &lt;strong&gt;sliding window&lt;/strong&gt; for these values, with size &lt;code&gt;Sₗₑₙ = 2ᵐ - 1&lt;/code&gt;, and two indices: &lt;code&gt;Sₚ&lt;/code&gt; pointing to the first frame still waiting for the ACK and &lt;code&gt;Sₙ&lt;/code&gt; pointing to the next frame to send. The recipient, on the other hand, has a window of size &lt;code&gt;1&lt;/code&gt; as it is only interested in one ordered frame, while discarding any other.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../images/go-back-n-arq.png&quot; alt=&quot;Go-back-N ARQ sender sliding-window with m = 3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Go-back-N ARQ sender sliding-window with m = 3&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When the time for the ACK of a frame is over, the &lt;code&gt;Sₙ&lt;/code&gt; index goes back (go-back) to the first frame without an ACK. In a channel with a high frequency of errors, this protocol would be inefficient: a damaged frame could mean re-sending many frames, resulting in a slowdown of the transmission.&lt;/p&gt;
&lt;h3 id=&quot;selective-repeat-arq&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#selective-repeat-arq&quot; aria-label=&quot;Anchor link for: selective-repeat-arq&quot;&gt;Selective Repeat ARQ&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Selective_Repeat_ARQ&quot;&gt;Selective Repeat ARQ&lt;/a&gt; protocol solves the Go-back-N ARQ problems by avoiding re-sending the frames which arrive out of order, focusing only on the damaged ones. Both sender window and recipient window have size &lt;code&gt;2ᵐ⁻¹&lt;/code&gt;. This means that frames can arrive out of order without being discarded by the recipient.&lt;/p&gt;
&lt;h2 id=&quot;network-switches&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#network-switches&quot; aria-label=&quot;Anchor link for: network-switches&quot;&gt;Network switches&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Network_switch&quot;&gt;Network switches&lt;/a&gt; are used to connect together multiple networks. They can operate at various layers of &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Internet_layer&quot;&gt;Internet&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;below the physics layer&lt;/strong&gt;: passive hubs;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;at the physics layer&lt;/strong&gt;: repeaters and active hubs;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;at the physics and link layer&lt;/strong&gt;: bridges;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;at the physics, link and network layer&lt;/strong&gt;: router;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;at all layers&lt;/strong&gt;: gateway.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;passice-hubs&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#passice-hubs&quot; aria-label=&quot;Anchor link for: passice-hubs&quot;&gt;Passice Hubs&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Passive hubs are simple &lt;strong&gt;connectors&lt;/strong&gt; between wires. They do not amplify the signal and do not need power supply.&lt;/p&gt;
&lt;h3 id=&quot;repeaters-and-active-hubs&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#repeaters-and-active-hubs&quot; aria-label=&quot;Anchor link for: repeaters-and-active-hubs&quot;&gt;Repeaters and Active Hubs&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A signal traveling within a wire is subject to attenuation which can affect the integrity of data. Repeaters receive a signal before it degrades, they &lt;strong&gt;regenerate&lt;/strong&gt; and forward it again. Active hubs are simply repeaters with multiple ports and are useful for &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Star_network&quot;&gt;star networks&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;bridge&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#bridge&quot; aria-label=&quot;Anchor link for: bridge&quot;&gt;Bridge&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A bridge, as well as having the same capabilities as a repeater, can check source and destination addresses in a frame and figure out which port to forward it to, through a &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Forwarding_information_base&quot;&gt;forwarding table&lt;/a&gt;. In a &lt;a rel=&quot;external&quot; href=&quot;https://docwiki.cisco.com/wiki/Transparent_Bridging&quot;&gt;transparent bridge&lt;/a&gt;, the forwarding table is built automatically based on the traffic on the network.&lt;/p&gt;
&lt;h3 id=&quot;router&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#router&quot; aria-label=&quot;Anchor link for: router&quot;&gt;Router&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Router_%28computing%29&quot;&gt;router&lt;/a&gt; operates on the network layer sending packets based on logic addresses. They are commonly used to connect LANs or WANs to the Internet.&lt;/p&gt;
&lt;h3 id=&quot;gateway&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#gateway&quot; aria-label=&quot;Anchor link for: gateway&quot;&gt;Gateway&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Gateway_%28telecommunications%29&quot;&gt;gateway&lt;/a&gt; is able to read and interpret messages from applications, therefore it could be used to connect two networks based on different models.&lt;/p&gt;
&lt;h2 id=&quot;address-resolution&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#address-resolution&quot; aria-label=&quot;Anchor link for: address-resolution&quot;&gt;Address resolution&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With address resolution protocols it is possible to obtain the logical address corresponding to a physical address and vice versa.&lt;/p&gt;
&lt;h3 id=&quot;address-resolution-protocol&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#address-resolution-protocol&quot; aria-label=&quot;Anchor link for: address-resolution-protocol&quot;&gt;Address Resolution Protocol&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Address_Resolution_Protocol&quot;&gt;Address Resolution Protocol&lt;/a&gt; (ARP) allows a node to discover the physical address associated with a particular logical address. Those requests are sent in &lt;strong&gt;broadcast&lt;/strong&gt; while the response is sent in &lt;strong&gt;unicast&lt;/strong&gt; from the unique node which corresponds to that logical address.&lt;/p&gt;
&lt;h3 id=&quot;reverse-address-resolution-protocol&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#reverse-address-resolution-protocol&quot; aria-label=&quot;Anchor link for: reverse-address-resolution-protocol&quot;&gt;Reverse Address Resolution Protocol&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Reverse_Address_Resolution_Protocol&quot;&gt;Reverse Address Resolution Protocol&lt;/a&gt; (RARP) enables a node to find its logical address from its own physical address. This protocol is &lt;strong&gt;obsolete&lt;/strong&gt; and it has been replaced by BOOTP and DHCP.&lt;/p&gt;
&lt;h3 id=&quot;bootstrap-protocol&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#bootstrap-protocol&quot; aria-label=&quot;Anchor link for: bootstrap-protocol&quot;&gt;Bootstrap Protocol&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Bootstrap_Protocol&quot;&gt;Bootstrap Protocol&lt;/a&gt; (BOOTP) works in the application layer and is based on a node of the network called a &lt;strong&gt;relay agent&lt;/strong&gt; which knows the IP address of the BOOTP server. It is not dynamic because the associations between addresses are based on static tables manually managed by the administrator.&lt;/p&gt;
&lt;h3 id=&quot;dynamic-host-configuration-protocol&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dynamic-host-configuration-protocol&quot; aria-label=&quot;Anchor link for: dynamic-host-configuration-protocol&quot;&gt;Dynamic Host Configuration Protocol&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol&quot;&gt;Dynamic Host Configuration Protocol&lt;/a&gt; (DHCP) allows both &lt;strong&gt;static and dynamic&lt;/strong&gt; allocation of IP addresses and it is compatible with BOOTP. A server using this protocol has a database to store static addresses and a database to store dynamic addresses.&lt;/p&gt;
&lt;h2 id=&quot;routing-protocols&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#routing-protocols&quot; aria-label=&quot;Anchor link for: routing-protocols&quot;&gt;Routing protocols&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Routing protocols allow routers to communicate between each other for updating routing tables. There are protocols for &lt;strong&gt;intra-domain&lt;/strong&gt; (Routing Information Protocol, Open Shortest Path First) and &lt;strong&gt;inter-domain&lt;/strong&gt; (Border Gateway Protocol) routing.&lt;/p&gt;
&lt;h3 id=&quot;distance-vector-routing-protocol&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#distance-vector-routing-protocol&quot; aria-label=&quot;Anchor link for: distance-vector-routing-protocol&quot;&gt;Distance-vector routing protocol&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Distance-vector_routing_protocol&quot;&gt;Distance-vector routing protocol&lt;/a&gt; every node maintains a vector with the minimum distance between other nodes. At the beginning, nodes know only the distance from the nodes they are directly connected to, but by sharing their routing tables with nearby nodes they can discover the topology of the entire network. &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Routing_Information_Protocol&quot;&gt;Routing Information Protocol&lt;/a&gt; (RIP) is based on a distance-vector and it is &lt;em&gt;trivial&lt;/em&gt; as it assumes that the cost of hopping from one node to another would always be one.&lt;/p&gt;
&lt;h3 id=&quot;link-state-routing-protocol&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#link-state-routing-protocol&quot; aria-label=&quot;Anchor link for: link-state-routing-protocol&quot;&gt;Link-state routing protocol&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Link-state_routing_protocol&quot;&gt;Link-state routing protocol&lt;/a&gt; every node builds its own routing table interpreting the entire network as a graph with &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Dijkstra&amp;#x27;s_algorithm&quot;&gt;Dijkstra&#39;s algorithm&lt;/a&gt;. At the beginning, every node has a partial knowledge of the network, with nearby nodes, and shares that information with other nodes by sending packets called Link State Packets (LSP). The &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Open_Shortest_Path_First&quot;&gt;Open Shortest Path First&lt;/a&gt; protocol is based on the link layer.&lt;/p&gt;
&lt;h3 id=&quot;path-vector-routing-protocol&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#path-vector-routing-protocol&quot; aria-label=&quot;Anchor link for: path-vector-routing-protocol&quot;&gt;Path-vector routing protocol&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Inter-domain routing is based on the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Path_vector_protocol&quot;&gt;Path-vector protocol&lt;/a&gt;, where the various autonomous systems have a special node which shares its own routing table with nearby autonomous systems. The routing table will contain all possible destinations and the paths to reach them. The &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Border_Gateway_Protocol&quot;&gt;Border Gateway Protocol&lt;/a&gt; is based on a path-vector.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Devember: Socket API</title>
          <pubDate>Tue, 15 Dec 2015 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/devember-socket-api/</link>
          <guid>https://www.antoniocaggiano.eu/posts/devember-socket-api/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/devember-socket-api/">&lt;p&gt;This devlog introduces the fundamental functions of the &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Berkeley_sockets&quot;&gt;Berkeley socket API&lt;/a&gt; by developing a simple client and server in the C language. The complete source code is available in this &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Fahien/exsocket&quot;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;client&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#client&quot; aria-label=&quot;Anchor link for: client&quot;&gt;Client&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first thing to do is to create a connection-oriented (&lt;code&gt;SOCK_STREAM&lt;/code&gt;) socket of the IPv6 Internet protocol family (&lt;code&gt;AF_INET6&lt;/code&gt;). This will use &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Transmission_Control_Protocol&quot;&gt;TCP&lt;/a&gt;, a reliable transport protocol.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; sockfd&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; socket&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;AF_INET6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; SOCK_STREAM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The socket can be used to establish a connection with a server, and we can specify the address to connect to using a &lt;code&gt;sockaddr_in6&lt;/code&gt; structure.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr_in6 servaddr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;bzero&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;servaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;servaddr.sin6_family &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span&gt; AF_INET6&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both the port and the address data follow the host byte-ordering, which is not guaranteed to be the same as the ordering used by the network protocol. Accordingly, we need to convert them to a network representation, which can be done by using &lt;code&gt;htons()&lt;/code&gt; for the integer port and &lt;code&gt;inet_pton()&lt;/code&gt; for the IPv6 address string.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;servaddr.sin6_port &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; htons&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;atoi&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;argv&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;2&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;inet_pton&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;AF_INET6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; argv&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;servaddr.sin6_addr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;inet_pton&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can then pass the socket and the sockaddr structure to &lt;code&gt;connect()&lt;/code&gt;, which will reach out to the server.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;connect&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;servaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once the connection is established, we can receive data from the server by reading from the socket. The bytes read will be stored in the &lt;code&gt;recvline&lt;/code&gt; buffer, then a &lt;code&gt;0&lt;/code&gt; is added at the end to finalize it as a string, and &lt;code&gt;fputs()&lt;/code&gt; is used to print it to &lt;code&gt;stdout&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; recvline&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; read&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; recvline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;    recvline&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    fputs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;recvline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; stdout&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the communication has finished, we need to close the socket, as with every file descriptor.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;close&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;server&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#server&quot; aria-label=&quot;Anchor link for: server&quot;&gt;Server&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As with the client, the first thing the server does is create an IPv6 socket.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; listenfd&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;listenfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; socket&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;AF_INET6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; SOCK_STREAM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then a &lt;code&gt;sockaddr&lt;/code&gt; structure is initialized using &lt;code&gt;in6addr_any&lt;/code&gt;, which is a wildcard IPv6 address, letting the system select the address for you.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr_in6 servaddr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;bzero&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;servaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;servaddr.sin6_family &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span&gt; AF_INET6&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;servaddr.sin6_addr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span&gt; in6addr_any&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;servaddr.sin6_port &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; htons&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;atoi&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;argv&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before continuing, we call &lt;code&gt;bind()&lt;/code&gt; to assign this address to the socket.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;listenfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;servaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we convert the socket to a listening one, so that it can be used to accept incoming connections.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;listen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;listenfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; BACKLOG&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we can finally make the server wait for client requests. The &lt;code&gt;accept()&lt;/code&gt; function is blocking and returns when a new incoming connection has been established. To generate a response from the server, we get the date and time with the &lt;code&gt;time()&lt;/code&gt; function, then build the string to send to the client, and finally write it to the socket and close the connection once finished.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; connfd&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;time_t&lt;/span&gt;&lt;span&gt; ticks&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; buff&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;true&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;connfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; accept&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;listenfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Send the time to the client&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ticks &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; time&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    snprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%.24s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; ctime&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;ticks&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;connfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; strlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Close the connection&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    close&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;connfd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;get-client-information&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#get-client-information&quot; aria-label=&quot;Anchor link for: get-client-information&quot;&gt;Get client information&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first thing we can do to improve the server is to make better use of the &lt;code&gt;accept()&lt;/code&gt; function. By passing a &lt;code&gt;sockaddr&lt;/code&gt; structure address as an argument, we can retrieve some information about the client.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr_in6 cliaddr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;socklen_t&lt;/span&gt;&lt;span&gt; clilen &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cliaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;bzero&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;cliaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; clilen&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;accept&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;listenfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;cliaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;clilen&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please note that the data memory layout is still following the network order, and if we want to have meaningful address and port values on our system, we need to convert them into the appropriate &lt;em&gt;host representation&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;inet_ntop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;AF_INET6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;cliaddr.sin6_addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; INET6_ADDRSTRLEN&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Serving new client from &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; ntohs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cliaddr.sin6_port&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;get-local-address&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#get-local-address&quot; aria-label=&quot;Anchor link for: get-local-address&quot;&gt;Get local address&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We have seen how the server can retrieve the address of a client. Let us see, on the other hand, how the host can query its own local address using &lt;code&gt;getsockname()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr_in6 cliaddr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;socklen_t&lt;/span&gt;&lt;span&gt; clilen &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cliaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;bzero&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;cliaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; clilen&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;getsockname&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;cliaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;clilen&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;getsockname&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have the information we need in &lt;code&gt;cliaddr&lt;/code&gt;, then we convert the IPv6 address and port into the appropriate &lt;em&gt;host representation&lt;/em&gt; and finally print it out.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; clistr&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;INET6_ADDRSTRLEN&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;inet_ntop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;AF_INET6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;cliaddr.sin6_addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; clistr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; INET6_ADDRSTRLEN&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;The current address is &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; clistr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; ntohs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cliaddr.sin6_port&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;sending-an-acknowledgement&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#sending-an-acknowledgement&quot; aria-label=&quot;Anchor link for: sending-an-acknowledgement&quot;&gt;Sending an acknowledgement&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We would like the client to respond to the server with an acknowledgement message, and this can be done after the reading step by calling &lt;code&gt;write()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt; ack &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Message received&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ack&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; strlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ack&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the other side of the connection, the server should invoke &lt;code&gt;read()&lt;/code&gt; to receive the data sent by the client.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; recvline&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; read&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;connfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; recvline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;    recvline&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    fputs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;recvline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; stdout&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you may notice, both &lt;code&gt;read()&lt;/code&gt; and &lt;code&gt;write()&lt;/code&gt; return the number of characters written into the socket buffer. In case of an error, the return value is negative (&lt;code&gt;-1&lt;/code&gt;) and the &lt;code&gt;errno&lt;/code&gt; global variable is set appropriately. This means we can retrieve an informative message corresponding to the current value of &lt;code&gt;errno&lt;/code&gt; through the &lt;code&gt;perror()&lt;/code&gt; function.&lt;/p&gt;
&lt;h2 id=&quot;recursive-echo-server&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#recursive-echo-server&quot; aria-label=&quot;Anchor link for: recursive-echo-server&quot;&gt;Recursive echo server&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let us now see two new functions useful for our network programs, &lt;code&gt;exso_readln()&lt;/code&gt; and &lt;code&gt;exso_writen()&lt;/code&gt;, based on some utility functions presented in the &lt;a rel=&quot;external&quot; href=&quot;https://www.informit.com/articles/article.aspx?p=169505&amp;amp;seqNum=9&quot;&gt;Unix Network Programming&lt;/a&gt; book and used in a &lt;a rel=&quot;external&quot; href=&quot;https://sites.google.com/a/unisa.it/forciuoli-insegnamenti/home/reti-di-calcolatori&quot;&gt;networking course&lt;/a&gt; I attended at university.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;exso_readln()&lt;/code&gt; function reads a line (a string ending with the newline character &lt;code&gt;&#39;\n&#39;&lt;/code&gt;) from a socket buffer and automatically appends &lt;code&gt;&#39;\0&#39;&lt;/code&gt; to mark the end of that string.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;exso_writen()&lt;/code&gt; function writes &lt;code&gt;n&lt;/code&gt; bytes into a socket buffer.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;More details can be found here: &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Fahien/exsocket/blob/master/libexso.c&quot;&gt;libexso.c&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The daytime server discussed so far features an &lt;em&gt;iterative&lt;/em&gt; behaviour, which means it can serve only one client at a time. In order to serve more clients concurrently, we could make it &lt;em&gt;recursive&lt;/em&gt; by spawning &lt;em&gt;child&lt;/em&gt; processes to manage new incoming connections. That is how it can be done with &lt;code&gt;fork()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;pit_t&lt;/span&gt;&lt;span&gt; childpid&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;childpid &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; fork&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    close&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;listenfd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    server_echo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;connfd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The child process must close the listening socket before executing its tasks. At the same time, the &lt;em&gt;parent&lt;/em&gt; closes the connected socket and returns to waiting for new requests. Here follows the &lt;code&gt;server_echo()&lt;/code&gt; function, which executes all the tasks of a server child process, also using the new read and write functions mentioned above.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; server_echo&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; sockfd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    ssize_t&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; line&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;true&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; exso_readln&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; line&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; connection closed by the other end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        exso_writen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; line&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;kill-the-zombies&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#kill-the-zombies&quot; aria-label=&quot;Anchor link for: kill-the-zombies&quot;&gt;Kill the zombies&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Good, now the server can handle multiple concurrent connections by spawning child processes. However, we should not forget to handle these processes when they finish serving clients, otherwise they will remain in memory as &lt;em&gt;zombies&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When a child process terminates, the operating system sends a &lt;code&gt;SIGCHLD&lt;/code&gt; signal to the parent, which by default does not do anything. If we want to remove zombies (dead child processes), the parent can do that by registering a callback function for the &lt;code&gt;SIGCHLD&lt;/code&gt; signal.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;signal&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;SIGCHLD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; handle_zombies&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;signal&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is how the callback function works. By calling the &lt;code&gt;waitpid()&lt;/code&gt; function with &lt;code&gt;-1&lt;/code&gt; as the first argument, the parent process waits for the termination of any of its children. The &lt;code&gt;stat&lt;/code&gt; output variable will contain information about a child&#39;s exit status.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; handle_zombies&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; signo&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    pid_t&lt;/span&gt;&lt;span&gt; pid&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    int&lt;/span&gt;&lt;span&gt; stat&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pid &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; waitpid&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;stat&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; WNOHANG&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Child &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; terminated with exit status &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; pid&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; stat&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;udp-echo-client&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#udp-echo-client&quot; aria-label=&quot;Anchor link for: udp-echo-client&quot;&gt;UDP echo client&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So far, we have been using TCP as the transport protocol. If we want to use &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/User_Datagram_Protocol&quot;&gt;UDP&lt;/a&gt;, we need to make some minor changes.&lt;/p&gt;
&lt;p&gt;Change the socket type to &lt;code&gt;SOCK_DGRAM&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; sockfd&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; socket&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;AF_INET6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; SOCK_DGRAM&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Data transmissions should be done using the &lt;code&gt;sendto()&lt;/code&gt; function.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; sendline&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fgets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sendline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; fp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sendto&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; sendline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; strlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sendline&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; servaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;sendto&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Incoming data is collected with the &lt;code&gt;recvfrom()&lt;/code&gt; function. Notice how, when working with a connectionless protocol, the address of the sender is collected; otherwise, we would not know who sent these packets.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;replyaddr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;replyaddr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; malloc&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;len &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; recvline&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; recvfrom&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; recvline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; replyaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;len&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;recvfrom&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;recvline&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Consequently, we should verify the identity of the peer. Here, we just make sure all the bytes of the &lt;code&gt;sockaddr&lt;/code&gt; structures are equal.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; buff&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;INET6_ADDRSTRLEN&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr_in6 &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;sa&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;len &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; sizeof&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servaddr&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ||&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; memcmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;servaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; replyaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   sa &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr_in6 &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; replyaddr&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;   inet_ntop&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;AF_INET6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;sa&lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;span&gt;sin6_addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; INET6_ADDRSTRLEN&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;   printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Ignoring reply from &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;   continue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;distributed-calculator&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#distributed-calculator&quot; aria-label=&quot;Anchor link for: distributed-calculator&quot;&gt;Distributed calculator&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let us try something a bit more complex: a &lt;strong&gt;distributed calculator&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The communication takes place via UDP, so we use &lt;code&gt;sendto()&lt;/code&gt; and &lt;code&gt;recvfrom()&lt;/code&gt; as introduced in the previous section.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; buff&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; b &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; op&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;OP_LEN&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fgets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; stdin&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; !=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sscanf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; %s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; %d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; op&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ... do networking&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the other end, the server receives the data, interprets it, computes the result, and sends it back to the client.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; buff&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;socklen_t&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; op&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;OP_LEN&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;true&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Receive datagram&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    len &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span&gt; clilen&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;recvfrom&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cliaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;len&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;recvfrom&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Interpret data and compute the result&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sscanf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; %s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; %d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; op&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;op&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;op&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;-&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;op&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;op&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;b &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;!=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;                sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;/&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;                sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Undefined&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;op&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;%&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Invalid operator&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Invalid message&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Send result to the client&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sendto&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; strlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cliaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;sendto&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;i-o-multiplexing-using-select&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#i-o-multiplexing-using-select&quot; aria-label=&quot;Anchor link for: i-o-multiplexing-using-select&quot;&gt;I/O multiplexing using select&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The simple &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Fahien/exsocket/blob/6c2f438cabaa80fbb6f4617ba9986f0bffafd732/echo/echocli.c&quot;&gt;echo client&lt;/a&gt; described previously suffers from some robustness problems. For example, if the server closes the connection while the client is blocked waiting for user input, the client would not be aware of anything until it tries to send data again after the user input has been read. I/O multiplexing can help us solve this problem.&lt;/p&gt;
&lt;p&gt;By means of the &lt;code&gt;select()&lt;/code&gt; function, we can work with more than one descriptor, and that requires preparing an &lt;code&gt;fd_set&lt;/code&gt; object. In the example below, we reset &lt;code&gt;readset&lt;/code&gt; with &lt;code&gt;FD_ZERO()&lt;/code&gt; and then add our file descriptors through &lt;code&gt;FD_SET()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FILE &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;fp&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; sockfd&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fd_set readset&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;FD_ZERO&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;readset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;FD_SET&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fileno&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;readset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;FD_SET&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;readset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;int&lt;/span&gt;&lt;span&gt; maxfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; MAX&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fileno&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; sockfd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; +&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;select&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;maxfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;readset&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When &lt;code&gt;select()&lt;/code&gt; returns, we can check whether the descriptors are ready by making use of &lt;code&gt;FD_ISSET()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Check if socket is ready to receive data from the server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;FD_ISSET&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;readset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; exso_readln&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; recvline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;exso_readln&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Server terminated prematurely&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    fputs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;recvline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; stdout&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Check if file is ready to send its content to the server&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;FD_ISSET&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fileno&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;readset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fgets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sendline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; fp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;exso_writen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; sendline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; strlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sendline&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;exso_writen&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;half-closing-the-socket&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#half-closing-the-socket&quot; aria-label=&quot;Anchor link for: half-closing-the-socket&quot;&gt;Half closing the socket&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Another way to improve the robustness of the client code is by shutting down the &lt;em&gt;write half&lt;/em&gt; of the connection once all reading operations from &lt;em&gt;standard input&lt;/em&gt; have finished. This can be done by calling the &lt;code&gt;shutdown()&lt;/code&gt; function.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span&gt; stdin_eof &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;FD_ISSET&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fileno&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;readset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fgets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sendline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; fp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        stdin_eof &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        shutdown&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; SHUT_WR&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        FD_CLR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;fileno&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;readset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        continue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;exso_writen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; sendline&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; strlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sendline&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;exso_writen&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;improved-echo-server&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#improved-echo-server&quot; aria-label=&quot;Anchor link for: improved-echo-server&quot;&gt;Improved echo server&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A recursive server is not the best choice if we want to avoid a proliferation of child processes, given that we fork every time a new client is connected. The server, as well as the client, could benefit from I/O multiplexing via &lt;code&gt;select()&lt;/code&gt; to handle both the listening socket and the other connection sockets.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ready &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; select&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;maxfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;rset&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Check for incoming connections&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;FD_ISSET&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;listenfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;rset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;connfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; accept&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;listenfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;struct&lt;/span&gt;&lt;span&gt; sockaddr &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;cliaddr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;clilen&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        return&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Save connected socket descriptor into an array&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;i &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; FD_SETSIZE&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;clients&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;            clients&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; connfd&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;            break&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;    //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Serve clients&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;i &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; FD_SETSIZE&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; clients&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        continue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;FD_ISSET&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;rset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; exso_readln&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXLINE&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;exso_readln&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            printf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;A client is gone&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            close&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            FD_CLR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;allset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;            clients&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;exso_writen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;            perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;exso_writen&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;        //&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;broadcast&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#broadcast&quot; aria-label=&quot;Anchor link for: broadcast&quot;&gt;Broadcast&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;What we have now is an array of all the connected clients, and that enables us to turn the server into a &lt;em&gt;chat room&lt;/em&gt;! Here, the server broadcasts every message sent by a client to all the other connected clients:&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;i &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; FD_SETSIZE&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;sockfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; client&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ||&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; client&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        continue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;exso_writen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;client&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;exso_writen&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;nickname-command&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#nickname-command&quot; aria-label=&quot;Anchor link for: nickname-command&quot;&gt;Nickname command&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After transforming the server into a chat room, it would definitely be a good idea to allow clients to set their nickname with a command. So, when a client is connected, the server expects to receive a message starting with &lt;code&gt;/nickname&lt;/code&gt; followed by the actual nickname.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; MAXNICK&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 32&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; nicknames&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;FD_SETSIZE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXNICK&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; Processing the i-th client&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;nicknames&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;/nickname&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 9&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        sscanf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;/nickname &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; nicknames&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; has joined the chat&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; nicknames&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;Error, expecting /nickname&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        exso_writen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;client&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; strlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        continue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once the nickname is set, we can use it as a prefix for the message and broadcast it to everyone.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; temp&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;MAXLINE&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;temp&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; nicknames&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; temp&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;i &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; FD_SETSIZE&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; i&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;++&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;sockfd &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; client&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ||&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt; client&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;        continue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;exso_writen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;client&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; buff&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; strlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;buff&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;        perror&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;exso_writen&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To conclude, when a client logs out, we can reset their nickname.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;z-l-5 z-d-3&quot;&gt; If there are no more characters to read&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;n &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    close&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    FD_CLR&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sockfd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;allset&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;    client&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; -&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;    bzero&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-12&quot;&gt;nicknames&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; MAXNICK&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</description>
      </item>
      <item>
          <title>Android notes</title>
          <pubDate>Tue, 27 Oct 2015 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/android-notes/</link>
          <guid>https://www.antoniocaggiano.eu/posts/android-notes/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/android-notes/">&lt;p&gt;This is a collection of notes I took during the &lt;strong&gt;Mobile Programming&lt;/strong&gt; course at my university.&lt;/p&gt;
&lt;h2 id=&quot;project&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#project&quot; aria-label=&quot;Anchor link for: project&quot;&gt;Project&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The project needs to follow a specific structure to be compiled and packaged correctly by the &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/sdk/index.html&quot;&gt;Android Software Development Kit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At a higher level, we subdivide it into modules, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Android application modules&lt;/strong&gt;: with code, resources, and configurations. These will be transformed into an &lt;em&gt;apk&lt;/em&gt; file that will be installed on devices.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;test modules&lt;/strong&gt;: containing &lt;a rel=&quot;external&quot; href=&quot;https://junit.org&quot;&gt;JUnit&lt;/a&gt; tests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;library modules&lt;/strong&gt;: which are code shared with other projects. These will be included in the &lt;em&gt;apk&lt;/em&gt; as well.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;files&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#files&quot; aria-label=&quot;Anchor link for: files&quot;&gt;Files&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;build/&lt;/code&gt;: application build artifacts.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;libs/&lt;/code&gt;: private libraries.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;src/&lt;/code&gt;: the source code.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;androidTest/&lt;/code&gt;: Java tests.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main/java/com.project.app&lt;/code&gt;: Java code such as &lt;em&gt;activities&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main/assets/&lt;/code&gt;: store for &lt;em&gt;game assets&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main/res/&lt;/code&gt;: various resources.
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;anim/&lt;/code&gt;: XML files compiled into &lt;em&gt;animation objects&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;color/&lt;/code&gt;: XML files with colors.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;drawable/&lt;/code&gt;: bitmap files (PNG, JPEG, GIF), 9-Patch, and XML describing &lt;em&gt;drawables&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mipmap/&lt;/code&gt;: Application icons.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;layout/&lt;/code&gt;: XML files compiled into &lt;em&gt;layouts&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;menu/&lt;/code&gt;: XML files defining &lt;em&gt;menus&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;raw/&lt;/code&gt;: for various assets, like &lt;em&gt;mp3&lt;/em&gt; or &lt;em&gt;ogg&lt;/em&gt; files.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;values/&lt;/code&gt;: XML files defining generic values.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xml/&lt;/code&gt;: other XML files.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AndroidManifest.xml&lt;/code&gt;: main file describing the application and all of its components.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.gitignore/&lt;/code&gt;: files to be ignored from &lt;a rel=&quot;external&quot; href=&quot;https://git-scm.com&quot;&gt;git&lt;/a&gt; versioning.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;app.iml/&lt;/code&gt;: &lt;em&gt;IntelliJ IDEA&lt;/em&gt; config file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;build.gradle&lt;/code&gt;: &lt;em&gt;build&lt;/em&gt; config file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;proguard-rules.pro&lt;/code&gt;: &lt;a rel=&quot;external&quot; href=&quot;https://proguard.sourceforge.net&quot;&gt;ProGuard&lt;/a&gt; config file.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;localization&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#localization&quot; aria-label=&quot;Anchor link for: localization&quot;&gt;Localization&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When the user launches an app, Android automatically selects and loads the right resources according to the device configuration.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;res/values/strings.xml&lt;/code&gt; file, strings are stored that are used by default, though it is possible to specify alternative resources using &lt;em&gt;qualifiers&lt;/em&gt; for different languages.&lt;/p&gt;
&lt;p&gt;For instance, to &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Language_localisation&quot;&gt;localize&lt;/a&gt; text content in Italian, we need to create an alternative &lt;code&gt;strings.xml&lt;/code&gt; file under the &lt;code&gt;res/values-it/&lt;/code&gt; folder.&lt;/p&gt;
&lt;h2 id=&quot;testing&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#testing&quot; aria-label=&quot;Anchor link for: testing&quot;&gt;Testing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It is possible to test our apps on an &lt;strong&gt;emulator&lt;/strong&gt; or a real Android &lt;strong&gt;device&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The number of &lt;em&gt;smartphones&lt;/em&gt; on the market is huge and continuously growing. Nevertheless, every device is different and deciding which ones to test can be challenging.&lt;/p&gt;
&lt;p&gt;It would be ideal to support as many devices as possible. We could buy a certain number of devices and test our app under real conditions, but it would definitely be more expensive than using the emulator.&lt;/p&gt;
&lt;p&gt;The emulator might not allow us to see how apps work on real devices, but it does not hurt from a financial perspective.&lt;/p&gt;
&lt;p&gt;When developing on a device, it is still good practice to use the emulator to test our apps on configurations that are different from those of real devices available to us. Even though the emulator cannot test all settings, it can verify that the apps work correctly on different Android versions, or screen sizes and orientations.&lt;/p&gt;
&lt;p&gt;A mix of real device testing and emulator testing could guarantee good &lt;strong&gt;test coverage&lt;/strong&gt; at a reasonable price.&lt;/p&gt;
&lt;h2 id=&quot;layout&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#layout&quot; aria-label=&quot;Anchor link for: layout&quot;&gt;Layout&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;em&gt;layout&lt;/em&gt; is the visual structure of a &lt;strong&gt;user interface&lt;/strong&gt; and it can be defined in two ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;XML&lt;/strong&gt;: Android provides XML tags corresponding to classes of the &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/view/package-summary.html&quot;&gt;View&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Runtime&lt;/strong&gt;: you can create &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/view/View.html&quot;&gt;View&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/view/ViewGroup.html&quot;&gt;ViewGroup&lt;/a&gt; objects programmatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can use one or both methods to declare and manage the graphical interface of our application. For example, we could declare some layout in XML, and later add code to modify at &lt;em&gt;runtime&lt;/em&gt; the state of the elements on the screen.&lt;/p&gt;
&lt;p&gt;The benefit of using XML files is the &lt;strong&gt;separation&lt;/strong&gt; between presentation and the code controlling the behaviour of the application. The description of the user interface is external to the logic code, enabling us to modify it without needing to recompile. Moreover, declaring the layout in XML makes it easier to visualize the structure of the user interface and simplifies &lt;em&gt;debugging&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;view&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#view&quot; aria-label=&quot;Anchor link for: view&quot;&gt;View&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A View is basically a rectangle with &lt;strong&gt;width&lt;/strong&gt; and &lt;strong&gt;height&lt;/strong&gt;, and a position expressed as &lt;strong&gt;left&lt;/strong&gt; and &lt;strong&gt;top&lt;/strong&gt;. The unit is the pixel. We can also distinguish two pairs of width and height: &lt;em&gt;measured&lt;/em&gt; width and height relative to its parent, and &lt;em&gt;drawing&lt;/em&gt; width and height, which define the size when drawing on screen.&lt;/p&gt;
&lt;p&gt;Drawing a layout involves two steps: &lt;strong&gt;measure&lt;/strong&gt; and &lt;strong&gt;layout&lt;/strong&gt;. The measure step is implemented in &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/view/View.html#measure%28int,%20int%29&quot;&gt;&lt;code&gt;measure(int, int)&lt;/code&gt;&lt;/a&gt;, which is a &lt;em&gt;top-down traversal&lt;/em&gt; of the view-tree where their dimensions are calculated. The second step is implemented in &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/view/View.html#layout%28int,%20int,%20int,%20int%29&quot;&gt;&lt;code&gt;layout(int, int, int, int)&lt;/code&gt;&lt;/a&gt;, also top-down, where every parent is responsible for moving their children using values calculated during the measure step.&lt;/p&gt;
&lt;h2 id=&quot;viewgroup&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#viewgroup&quot; aria-label=&quot;Anchor link for: viewgroup&quot;&gt;ViewGroup&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;linear-layout&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#linear-layout&quot; aria-label=&quot;Anchor link for: linear-layout&quot;&gt;Linear Layout&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A linear layout is a ViewGroup which aligns its children &lt;strong&gt;horizontally&lt;/strong&gt; or &lt;strong&gt;vertically&lt;/strong&gt; (&lt;code&gt;android:orientation&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id=&quot;relative-layout&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#relative-layout&quot; aria-label=&quot;Anchor link for: relative-layout&quot;&gt;Relative Layout&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A relative layout is a ViewGroup which shows children with &lt;strong&gt;relative&lt;/strong&gt; positions to their siblings (&lt;em&gt;left-of&lt;/em&gt;, &lt;em&gt;below&lt;/em&gt;, …) or parent (&lt;em&gt;bottom&lt;/em&gt;, &lt;em&gt;left&lt;/em&gt;, &lt;em&gt;center&lt;/em&gt;, …).&lt;/p&gt;
&lt;h2 id=&quot;list-view&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#list-view&quot; aria-label=&quot;Anchor link for: list-view&quot;&gt;List View&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A list view is a ViewGroup showing a &lt;strong&gt;list of elements&lt;/strong&gt;. The elements are added automatically using an &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/widget/Adapter.html&quot;&gt;Adapter&lt;/a&gt;, which takes the content of a source, like an &lt;em&gt;array&lt;/em&gt; or a &lt;em&gt;database&lt;/em&gt;, and converts each element into a View to be inserted into the list.&lt;/p&gt;
&lt;h3 id=&quot;grid-view&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#grid-view&quot; aria-label=&quot;Anchor link for: grid-view&quot;&gt;Grid View&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A grid view is a ViewGroup which shows a &lt;strong&gt;grid of elements&lt;/strong&gt; which, like the list view, is populated through an Adapter.&lt;/p&gt;
&lt;h3 id=&quot;adapter-view&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#adapter-view&quot; aria-label=&quot;Anchor link for: adapter-view&quot;&gt;Adapter View&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When the content is &lt;strong&gt;dynamic&lt;/strong&gt;, we can use an &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/widget/AdapterView.html&quot;&gt;AdapterView&lt;/a&gt; subclass to populate it at &lt;em&gt;runtime&lt;/em&gt;.
An AdapterView subclass uses an Adapter, which behaves like a mediator between the data source and the layout. The Adapter receives data and converts each entry into a View that can be added to the layout.&lt;/p&gt;
&lt;p&gt;Android provides some Adapter subclasses for certain cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ArrayAdapter&lt;/strong&gt;: useful when the data source is an &lt;em&gt;array&lt;/em&gt;. By default, it creates a View for every element of the array by calling &lt;code&gt;toString()&lt;/code&gt; and putting it into a &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/widget/TextView.html&quot;&gt;TextView&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ArrayAdapter&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;String&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; adapter&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; new&lt;/span&gt;&lt;span&gt; ArrayAdapter&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt;    this&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; android&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;layout&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;simple_list_item1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; myStringArray&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ListView&lt;/span&gt;&lt;span&gt; listView&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;ListView&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt; findViewById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;R&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;listview&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;listView&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;setAdapter&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;adapter&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SimpleCursorAdapter&lt;/strong&gt;: useful when data come from a &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/database/Cursor.html&quot;&gt;Cursor&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;toast&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#toast&quot; aria-label=&quot;Anchor link for: toast&quot;&gt;Toast&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A Toast provides simple &lt;strong&gt;feedback&lt;/strong&gt; for an operation in a small &lt;em&gt;popup&lt;/em&gt;. It occupies only the space required by the message and the current Activity remains visible and interactive. Toasts vanish automatically after a &lt;em&gt;timeout&lt;/em&gt;. We can create them with the static method &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/widget/Toast.html#makeText%28android.content.Context,%20int,%20int%29&quot;&gt;&lt;code&gt;Toast.makeText()&lt;/code&gt;&lt;/a&gt;, which takes three arguments (&lt;em&gt;context&lt;/em&gt;, &lt;em&gt;message&lt;/em&gt;, and &lt;em&gt;duration&lt;/em&gt;), and can be shown with the &lt;code&gt;show()&lt;/code&gt; method.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Toast&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;makeText&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;z-l-2 z-d-6&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; Toast&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;LENGTH_SHORT&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can position it with the &lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/reference/android/widget/Toast.html#setGravity%28int,%20int,%20int%29&quot;&gt;&lt;code&gt;setGravity()&lt;/code&gt;&lt;/a&gt; method, which accepts three arguments (&lt;em&gt;gravity constant&lt;/em&gt;, &lt;em&gt;x offset&lt;/em&gt;, and &lt;em&gt;y offset&lt;/em&gt;).&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;toast&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-l-6 z-d-7&quot;&gt;setGravity&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Gravity&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;TOP&lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt; |&lt;/span&gt;&lt;span&gt; Gravity&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;LEFT&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-l-1 z-d-4&quot;&gt; 0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is also possible to create a custom layout for toasts in XML and use it by passing it to the toast through the &lt;code&gt;setView(View)&lt;/code&gt; method.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Western Lion: Post mortem</title>
          <pubDate>Thu, 22 Oct 2015 00:00:00 +0000</pubDate>
          <author>Antonio Caggiano</author>
          <link>https://www.antoniocaggiano.eu/posts/western-lion-post-mortem/</link>
          <guid>https://www.antoniocaggiano.eu/posts/western-lion-post-mortem/</guid>
          <description xml:base="https://www.antoniocaggiano.eu/posts/western-lion-post-mortem/">&lt;p&gt;Western Lion is a collection of two minigames based on the &lt;strong&gt;spaghetti western&lt;/strong&gt; theme, developed during the one-month &lt;a rel=&quot;external&quot; href=&quot;https://itch.io/jam/spaghetti-western-jam&quot;&gt;Spaghetti Western Jam&lt;/a&gt; organized by &lt;a rel=&quot;external&quot; href=&quot;https://www.gameloop.it/&quot;&gt;IndieVault.it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In one of the games, you impersonate &lt;em&gt;Nobody&lt;/em&gt;, trying to shoot mugs before they shatter on the pavement, while in the other game you are &lt;em&gt;Jack&lt;/em&gt;, annoyed by a fly while waiting at the train station.&lt;/p&gt;
&lt;h2 id=&quot;preparation&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#preparation&quot; aria-label=&quot;Anchor link for: preparation&quot;&gt;Preparation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The idea of &lt;strong&gt;minigames&lt;/strong&gt; originated from the fragmentary way scenes from spaghetti western movies I have seen over the years came back to my mind. Figuring out how to realize that idea was the next step.&lt;/p&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;https://libgdx.badlogicgames.com/&quot;&gt;libGDX&lt;/a&gt; framework was definitely a good choice from both a prototyping speed and portability perspective.&lt;/p&gt;
&lt;p&gt;Talking about graphics, I reduced it to the lowest terms, as it was easier working with an 8-bit palette borrowed from the wonderful &lt;a rel=&quot;external&quot; href=&quot;https://www.lexaloffle.com/pico-8.php&quot;&gt;PICO-8&lt;/a&gt; fantasy console, and a resolution of 160x90 pixels.&lt;/p&gt;
&lt;p&gt;Audio resources were simply collected by searching on &lt;a rel=&quot;external&quot; href=&quot;https://freesound.org/&quot;&gt;Freesound.org&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;jack-and-the-fly&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#jack-and-the-fly&quot; aria-label=&quot;Anchor link for: jack-and-the-fly&quot;&gt;Jack and the Fly&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first mini-game is &lt;strong&gt;Jack and the fly&lt;/strong&gt;. It is inspired by the concept of waiting, which has a prominent role in the beginning of Sergio Leone&#39;s &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Once_Upon_a_Time_in_the_West&quot;&gt;Once Upon a Time in the West&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Waiting makes us think; it gives us time to breathe, to meditate, to observe. This emphasis projects us onto those boundless spaces and, at the same time, allows us to get lost in the tiny details.&lt;/p&gt;
&lt;h2 id=&quot;nobody-is-drinking&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#nobody-is-drinking&quot; aria-label=&quot;Anchor link for: nobody-is-drinking&quot;&gt;Nobody is drinking&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The second mini-game is &lt;strong&gt;Nobody is drinking&lt;/strong&gt;. It is based on a scene from Tonino Valerii&#39;s &lt;a rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/My_Name_Is_Nobody&quot;&gt;My Name Is Nobody&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Nobody, the main character of the movie, bets on a particular game where you drink whiskey from a mug, then throw the mug into the air, and try to shoot it before it shatters into pieces on the ground.&lt;/p&gt;
&lt;p&gt;With both games, the key to winning is &lt;strong&gt;being alert and quick&lt;/strong&gt;. Indeed, when you finish a game, your time is recorded onto a leaderboard.&lt;/p&gt;
&lt;h2 id=&quot;development&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#development&quot; aria-label=&quot;Anchor link for: development&quot;&gt;Development&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is the list of tools I used to develop Western Lion:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://developer.android.com/tools/studio/index.html&quot;&gt;Android Studio&lt;/a&gt;, for coding;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.gimp.org/&quot;&gt;The GNU Image Manipulation Program&lt;/a&gt; to create graphic content;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://audacityteam.org/&quot;&gt;Audacity&lt;/a&gt; to edit audio resources.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although the right tools greatly simplify the development of projects like this, a good understanding of &lt;strong&gt;mathematics&lt;/strong&gt; and &lt;strong&gt;physics&lt;/strong&gt; is fundamental to realizing the ideas that come to your mind.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A two-dimensional &lt;strong&gt;Cartesian coordinate system&lt;/strong&gt; helps position pictures in the right place on the screen;&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;laws of motion&lt;/strong&gt; allow you to simulate the movement of objects, like the fly and the mugs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trigonometric functions&lt;/strong&gt; can be used to make cool, smooth animations like the &lt;em&gt;sliding&lt;/em&gt; in the achievements screen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are only some examples of the countless applications that mathematics has in the world of game development.&lt;/p&gt;
&lt;div class=&quot;videowrapper&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/cRp78grR5lQ&quot;
            title=&quot;YouTube video&quot;
            loading=&quot;lazy&quot;
            referrerpolicy=&quot;strict-origin-when-cross-origin&quot;
            allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot;
            allowfullscreen&gt;
    &lt;/iframe&gt;
&lt;/div&gt;
</description>
      </item>
    </channel>
</rss>
