Jekyll2021-03-23T23:44:56+00:00https://mondradiko.github.io/feed.xmlMondradikoMondradiko is a future-proof VR engine for creating multiplayer virtual reality experiences.Marceline Cramercramermarceline@gmail.comWinter Devlog2021-03-23T00:00:00+00:002021-03-23T00:00:00+00:00https://mondradiko.github.io/winter-devlog<p>Hello everyone! We’ve been quite busy for the last couple of months, but we
have a lot to show off in this post, including:</p>
<ul>
<li>Scripting upgrades</li>
<li>Renderer improvements and eye candy</li>
<li>New asset bundler features</li>
<li>In-repository documentation</li>
</ul>
<p>Let’s get started.</p>
<h1 id="scripting">Scripting</h1>
<p>Thanks to a brand-new automatic code generation system, we’re able to easily
add more functionality to the scripting subsystem. Here, we’ve added bindings
to <code class="language-plaintext highlighter-rouge">TransformComponent</code>, and written a script to move around some point lights!</p>
<blockquote class="imgur-embed-pub" lang="en" data-id="a/YwgNhqB">
<a href="//imgur.com/a/YwgNhqB">Mondradiko moving point lights</a>
</blockquote>
<script async="" src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
<h2 id="assemblyscript">AssemblyScript</h2>
<p>We now support writing scripts in
<a href="https://www.assemblyscript.org/">AssemblyScript</a>! AssemblyScript is a language
based on TypeScript that targets WebAssembly, allowing for flexible and
user-friendly scripting that doesn’t compromise on performance.</p>
<p>Here’s the AssemblyScript code used to animate the moving lights above:</p>
<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="nx">Transform</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./components/Transform.d</span><span class="dl">"</span><span class="p">;</span>
<span class="k">export</span> <span class="kd">class</span> <span class="nx">SlidingLight</span> <span class="p">{</span>
<span class="nl">speed</span><span class="p">:</span> <span class="nx">f64</span> <span class="o">=</span> <span class="mf">3.0</span><span class="p">;</span>
<span class="nl">destination_a</span><span class="p">:</span> <span class="nx">f64</span> <span class="o">=</span> <span class="o">-</span><span class="mf">10.0</span><span class="p">;</span>
<span class="nl">destination_b</span><span class="p">:</span> <span class="nx">f64</span> <span class="o">=</span> <span class="mf">10.0</span><span class="p">;</span>
<span class="nl">velocity</span><span class="p">:</span> <span class="nx">f64</span><span class="p">;</span>
<span class="kd">constructor</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">velocity</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">speed</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// TODO(marceline-cramer) ComponentScript component fetching</span>
<span class="nx">update</span><span class="p">(</span><span class="nx">transform</span><span class="p">:</span> <span class="nx">Transform</span><span class="p">,</span> <span class="nx">dt</span><span class="p">:</span> <span class="nx">f64</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">x</span> <span class="o">=</span> <span class="nx">transform</span><span class="p">.</span><span class="nx">getX</span><span class="p">();</span>
<span class="kd">let</span> <span class="nx">y</span> <span class="o">=</span> <span class="nx">transform</span><span class="p">.</span><span class="nx">getY</span><span class="p">();</span>
<span class="kd">let</span> <span class="nx">z</span> <span class="o">=</span> <span class="nx">transform</span><span class="p">.</span><span class="nx">getZ</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">x</span> <span class="o"><</span> <span class="k">this</span><span class="p">.</span><span class="nx">destination_a</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">velocity</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">speed</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">x</span> <span class="o">></span> <span class="k">this</span><span class="p">.</span><span class="nx">destination_b</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">velocity</span> <span class="o">=</span> <span class="o">-</span><span class="k">this</span><span class="p">.</span><span class="nx">speed</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">x</span> <span class="o">+=</span> <span class="k">this</span><span class="p">.</span><span class="nx">velocity</span> <span class="o">*</span> <span class="nx">dt</span><span class="p">;</span>
<span class="nx">transform</span><span class="p">.</span><span class="nx">setPosition</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="nx">y</span><span class="p">,</span> <span class="nx">z</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The nitty-gritty details behind AssemblyScript are still being worked on, so
expect the specific API demonstrated here to change, but hopefully this gives
you a general idea as to how easy writing scripts for Mondradiko will be.</p>
<h1 id="windows-builds">Windows Builds</h1>
<p>Thanks to <a href="https://github.com/humbletim">humbletim on GitHub</a>, Mondradiko now
builds and runs on Windows! We now rely on vcpkg for downloading and compiling
dependencies, and building the entire project on any OS is now only a two-step
process, dependencies included:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>cmake <span class="nt">-GNinja</span> .. <span class="c"># Configure project and build dependencies</span>
<span class="nv">$ </span>ninja <span class="c"># Compile</span>
</code></pre></div></div>
<p>Although Mondradiko runs on Windows now, it’s not yet to the point where anyone
other than project developers will find much of a use for it. Mondradiko is
still very early in development, but at least we’ve ported it to Windows earlier
rather than later. If you’re on Windows and want to tinker around or contribute
to it though, now is the time!</p>
<h1 id="renderer-upgrades">Renderer Upgrades</h1>
<p>The renderer has been massively improved since January, and it now features:</p>
<ul>
<li>Physically-based rendering (PBR)</li>
<li>Normal mapping</li>
<li>Depth prepass</li>
<li>Masked texture</li>
</ul>
<h2 id="screenshots">Screenshots</h2>
<p><img src="/assets/images/winter-sponza-with-mask.png" alt="Sponza masking" /></p>
<p><img src="/assets/images/winter-pbr-hall.png" alt="Hall PBR" /></p>
<p><img src="/assets/images/winter-pbr-tapestry.png" alt="Tapestry PBR" /></p>
<p><img src="/assets/images/winter-pbr-lion.png" alt="Lion PBR" /></p>
<h2 id="to-do">To-Do</h2>
<p>The renderer doesn’t yet support materials that don’t supply a base color
texture, but after support for materials without those textures is implemented,
we’ll be able to load a much larger variety of scenes. Keep an eye out for
even more eye candy!</p>
<p>The renderer also doesn’t support proper blended transparency yet. More on that
in <a href="#gltf-support">the section on glTF support</a>.</p>
<p>There is also a distracting amount of aliasing in these screenshots. The
aliasing is made worse when moving the camera around the scene. This can be
resolved by adding trilinear filtering, anisotropic filtering, and multisampled
anti-aliasing.</p>
<h1 id="bundler-improvements">Bundler Improvements</h1>
<h2 id="aliases">Aliases</h2>
<p>Assets can now be given string aliases that other assets and manual prefabs can
reference:</p>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[[assets]]</span>
<span class="py">file</span> <span class="p">=</span> <span class="s">"scripts/SlidingLight.wat"</span>
<span class="py">alias</span> <span class="p">=</span> <span class="s">"SlidingLight"</span>
</code></pre></div></div>
<h2 id="manual-prefabs">Manual Prefabs</h2>
<p>Prefabs can also now be created in the bundler manifest manually, where before,
the bundler was limited to using prefabs created from glTF models and their node
hierarchies.</p>
<p>Here, for example, we’re creating a prefab that has a <code class="language-plaintext highlighter-rouge">PointLightComponent</code> to
emit light, a <code class="language-plaintext highlighter-rouge">TransformComponent</code> to position the light in the scene, and a
<code class="language-plaintext highlighter-rouge">ScriptComponent</code> bound to the script asset declared above to animate the
light’s transform.</p>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[[prefabs]]</span>
<span class="py">initial_prefab</span> <span class="p">=</span> <span class="kc">true</span> <span class="c"># Load this prefab when the world is created</span>
<span class="nn">[prefabs.point_light]</span>
<span class="py">position</span> <span class="p">=</span> <span class="p">[</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.5</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">]</span>
<span class="py">intensity</span> <span class="p">=</span> <span class="p">[</span><span class="mf">100.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">100.0</span><span class="p">]</span>
<span class="nn">[prefabs.script]</span>
<span class="py">script_asset</span> <span class="p">=</span> <span class="s">"SlidingLight"</span>
<span class="nn">[prefabs.transform]</span>
<span class="py">position</span> <span class="p">=</span> <span class="p">[</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">]</span>
</code></pre></div></div>
<h2 id="multithreaded-compression">Multithreaded Compression</h2>
<p>The bundler now begins compressing and saving lumps to disk as soon as their
size limit is reached. This is also done on an individual thread for every
lump. These two things together MASSIVELY reduce bundling time, allowing for
more rapid testing and content creation.</p>
<h2 id="to-do-1">To-Do</h2>
<ul>
<li>Dump command</li>
<li>Bundle caching and dependency graph construction</li>
<li>Manual prefab nesting</li>
<li>Prefab glTF model children</li>
<li>TOML-to-transform helpers</li>
<li>Cameras for automated tests</li>
</ul>
<h1 id="gltf-support">glTF Support</h1>
<p>The glTF converter has been patched since January, and now correctly loads
glTF and VRM models!</p>
<p><img src="/assets/images/winter-vrm-no-blending.png" alt="VRM avatar (no blending)" /></p>
<p>You’ll notice that there are what look like bright pink sunglasses on the VRM’s
face. This is not the fault of the glTF loader, but of the renderer. Masked
materials are drawing correctly, but alpha-blended materials are not, so the
renderer inserts magenta where alpha-blended meshes are supposed to go, until
proper transparency support can be implemented.</p>
<p>If the renderer is configured to skip drawing the pink stand-in meshes, you can
see that the eyes are drawing correctly now too. However, the eyelashes and
eyebrows are missing:</p>
<p><img src="/assets/images/winter-vrm-with-blending.png" alt="VRM avatar (with blending)" /></p>
<p>Little creepy.</p>
<p>There are still lots of things left to implement in the glTF specification, such
as bones, weights, blend shapes, multiple texture coordinates, animations, and
more primitive types, but the loader is coming along quite nicely so far.</p>
<h1 id="serverless-entrypoint">Serverless Entrypoint</h1>
<p>The Mondradiko client can now also run standalone (or serverless), meaning
that testing out changes and content is much more convenient, as the server
doesn’t have to be launched separately anymore:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># From:</span>
<span class="nv">$ </span>server/mondradiko-server
<span class="nv">$ </span>client/mondradiko-client <span class="c"># In another terminal</span>
<span class="c"># To:</span>
<span class="nv">$ </span>client/mondradiko-client <span class="nt">--serverless</span>
</code></pre></div></div>
<h1 id="project-maintenance">Project Maintenance</h1>
<p>As of the time of writing, there are around 17,000 lines of code in the
repository, 12,000 of which are not empty or commented out. Mondradiko is
beginning to become a pretty large project with several subsystems, including a
scripting environment, a codegen system, and an asset management tool. Because
of this, we’ve been putting a lot of effort this month into making the
repository easier to work with, especially for new code contributors.</p>
<h2 id="in-repo-documentation">In-Repo Documentation</h2>
<p>This month, I’ve been working on moving all of my thoughts and plans for the
engine into markdown files in the code repository itself. This includes
high-level overviews, diagrams, and explanations for each individual engine
subsystem. This will make it easy for anyone wishing to contribute (or is just
curious about the engine) to jump into the codebase and quickly learn how
everything works.</p>
<p>This is being done in
<a href="https://github.com/mondradiko/mondradiko/pull/18">PR #18</a>, which at the time of
writing may still take a couple more weeks to be completed and merged. However,
this is an essential step to making the engine easy to work with for
programmers, and to growing it into a strong open-source project.</p>
<h2 id="to-do-lists">To-Do Lists</h2>
<p>The in-repo documentation also includes comprehensive to-do lists for each
subsystem. This will document what exactly needs done in each part of the
engine and provide resources to help out completing those to-do items. Then,
people wishing to contribute can pick out a to-do item (or several), work on
them in a separate branch, then open a pull request. It will also be each
contributor’s responsibility to update these to-do items and other documentation
in their PRs.</p>
<h2 id="version-010-release">Version 0.1.0 Release</h2>
<p>Because of the ever-increasing size of the project, it’s been decided that we’ll
be creating a version 0.1.0 release of the engine very soon! This is purely
symbolic, but it represents how the majority of the foundation has been laid
down, and how the major design points of the engine have been implemented.</p>
<h2 id="roadmap">Roadmap</h2>
<p>Around the same time v0.1.0 is released, we’ll post another devlog post
detailing a roadmap for this project. This will include goals, an overview of
the engine’s design, plans for advertising and documenting development, and what
state the project is expected to be in a year from now.</p>
<h1 id="miscellaneous-to-do">Miscellaneous To-Do</h1>
<ul>
<li>Audio interface (AudioSourceComponent, OpenAL)</li>
<li>World queries (tags, entity bounding boxes, BVH acceleration)</li>
<li>ECS overhaul</li>
<li>Entity relationships and hierarchies</li>
<li>Resource caching (SDF atlases, GPU pipelines, JIT-compiled WebAssembly)</li>
<li>User interface (simple demo, scriptable draw functions, basic hooks)</li>
<li>More scripting (prefab instantiation, more component bindings, messages)</li>
<li>Avatars (posable VRMs, controller tracking, inverse kinematics)</li>
<li>Physics (Bullet integration, RigidBodyComponent, synchronization, bindings)</li>
</ul>
<h1 id="opportunities-for-contribution">Opportunities for Contribution</h1>
<h2 id="suggestions">Suggestions</h2>
<p>Any ideas or suggestions for Mondradiko are welcome! Please
join our <a href="https://discord.gg/CsDqbFw">Discord server</a>, where
I and the other developers are active, and drop any thoughts
you have. As a potential future user, your opinions are important.</p>
<h2 id="documentation">Documentation</h2>
<p>There’s a lot of <a href="#in-repo-documentation">documentation being currently written</a>,
and any feedback is appreciated, as the people reading this devlog post now are
likely the people who are going to be relying on this documentation in the
future.</p>
<h2 id="funding">Funding</h2>
<p>If you’d like to help support the development of
Mondradiko, please become our patron
on <a href="https://patreon.com/marcelinecramer">Patreon</a>!
A large part of Mondradiko’s development relies
on cloud services to function, such as automated
builds, testing, and packaging, along with hosting
the world servers themselves. The money also goes
towards buying a larger variety of VR hardware to
test on and develop for. Anything helps!</p>
<p><a href="https://www.patreon.com/bePatron?u=46447488" data-patreon-widget-type="become-patron-button">Become a Patron!</a><script async="" src="https://c6.patreon.com/becomePatronButton.bundle.js"></script></p>
<h2 id="programming">Programming</h2>
<p>If you have any coding experience, either from making
games in Unreal Engine or Unity, or low-level C++
programming, we need your help! Please join the
<a href="https://discord.gg/CsDqbFw">Discord server</a>
to get in touch with the project maintainers and
discuss the work needing to be done.</p>Marceline Cramercramermarceline@gmail.comHello everyone! We’ve been quite busy for the last couple of months, but we have a lot to show off in this post, including:January Devlog2021-02-03T00:00:00+00:002021-02-03T00:00:00+00:00https://mondradiko.github.io/january-devlog<h1 id="gltf-models">glTF Models</h1>
<p>The most significant feature added to Mondradiko this month has been glTF
loading. <a href="https://www.khronos.org/gltf/">glTF</a> is a model format developed by
the Khronos group, originally intended for ease of 3D asset delivery online, and
drawn using a graphics API like WebGL. However, because the model format is so
compact and easy to work with, it can also come in handy for a native
application like Mondradiko.</p>
<p>Here is a screenshot of a glTF model, <a href="https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Sponza">Crytek Sponza</a>,
that has been baked into an asset bundle and loaded into the engine:</p>
<p><img src="/assets/images/bundler-sponza-albedo.png" alt="Sponza albedo" /></p>
<p>As you can see, this is a reasonably complex model, which will make this example
world very useful for testing out different materials and rendering
optimizations in the future. However, Mondradiko’s glTF loading
capabilities are not entirely finished up, and there are lots of features
that the loader doesn’t support yet. This will have to change in the near
future, as having full glTF compliance gives us a lot of flexibility in
creating experimental content for the engine while it’s still in version 0.</p>
<h1 id="asset-bundler">Asset Bundler</h1>
<p>As mentioned above, 3D models, and all other runtime assets, like textures,
sounds, and scripts, are stored in “asset bundles.” Asset bundles contain
all of the assets that a server needs a client to have to connect and interact
with the world. The tool to create asset bundles and therefore in-engine content
is called <code class="language-plaintext highlighter-rouge">mondradiko-bundler</code>, or just the “bundler” for short. For now, it
will replace a traditional editor, until we can make a more sophisticated
graphical editor ourselves.</p>
<p>On the more technical side of things, the bundler, when ran, loads a
<code class="language-plaintext highlighter-rouge">bundler-manifest.toml</code> configuration file from a directory
passed as an argument, and converts all of the files specified in the manifest
from formats like glTF, PNG, WAV, etc. to Mondradiko’s internal asset format.
Then, it automatically packs the assets into “asset lumps,” which are
collections of assets, and stores them on disk as individual files to be loaded
into RAM as needed. Finally, the metadata about an asset bundle and its lumps
is stored in the “registry.”</p>
<p>For instance, the <code class="language-plaintext highlighter-rouge">v0/Sponza</code> example from the
<a href="https://github.com/mondradiko/mondradiko-examples">examples repository</a> can be
bundled like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mars@sol ~/Code/mondradiko/builddir $ bundler/mondradiko-bundler ~/Code/mondradiko-examples/v0/Sponza/
[DBG bundler/Bundler.cc:26] Bundler manifest: /home/mars/Code/mondradiko-examples/v0/Sponza/bundler-manifest.toml
[DBG bundler/Bundler.cc:27] Bundler source dir: /home/mars/Code/mondradiko-examples/v0/Sponza
[DBG bundler/Bundler.cc:28] Bundler bundle dir: ./
[DBG assets/saving/AssetBundleBuilder.cc:18] Building asset bundle at ./
[ ... bundler log ... ]
[DBG assets/saving/AssetBundleBuilder.cc:98] Writing lump 0
[DBG assets/saving/AssetBundleBuilder.cc:99] Lump size: 131546440
[DBG assets/saving/AssetBundleBuilder.cc:116] Lump has checksum 0x9cb538e2ef0fad90
[DBG assets/saving/AssetBundleBuilder.cc:98] Writing lump 1
[DBG assets/saving/AssetBundleBuilder.cc:99] Lump size: 134200584
[DBG assets/saving/AssetBundleBuilder.cc:116] Lump has checksum 0x19626caad0b327d0
[DBG assets/saving/AssetBundleBuilder.cc:98] Writing lump 2
[DBG assets/saving/AssetBundleBuilder.cc:99] Lump size: 7680288
[DBG assets/saving/AssetBundleBuilder.cc:116] Lump has checksum 0xc509d4f579abc26e
[DBG assets/saving/AssetBundleBuilder.cc:22] Cleaning up asset bundle ./
mars@sol ~/Code/mondradiko/builddir $ ls -l
...
-rw-r--r-- 1 mars mars 131546440 Jan 31 16:29 lump_0000.bin
-rw-r--r-- 1 mars mars 134200584 Jan 31 16:29 lump_0001.bin
-rw-r--r-- 1 mars mars 7680288 Jan 31 16:29 lump_0002.bin
-rw-r--r-- 1 mars mars 2968 Jan 31 16:29 registry.bin
...
mars@sol ~/Code/mondradiko/builddir $ server/mondradiko-server & client/mondradiko-client
</code></pre></div></div>
<p>After a world’s assets are bundled, they will be packaged into a
compressed format like LZMA, and made available for download to clients
who wish to connect to a server. More information on the content model, lump
compression, and the bundler system will be posted in a future devlog.</p>
<p>Here’s some improvements that we can still make to the bundler:</p>
<ul>
<li>Converted asset caching</li>
<li>Manual prefab building</li>
<li>Script instantiation</li>
</ul>
<h1 id="graphics">Graphics</h1>
<p>After loading the Crytek Sponza model into the engine, we can start
working on adding materials and proper shading. Here’s a screenshot
demonstrating simple diffuse lighting with some point lights:</p>
<p><img src="/assets/images/materials-diffuse-lighting.png" alt="Diffuse lighting" /></p>
<p>Now we’re getting somewhere! Just having these simple point lights placed
around the scene livens it up quite a bit. However, there is still a lot of
room for improvement. Here are some things that we’ll be working on this
February:</p>
<p><strong>Aliasing Reduction:</strong></p>
<ul>
<li>Texture mip-mapping</li>
<li>Multisampling</li>
<li>Anisotropic filtering</li>
</ul>
<p><strong>Features:</strong></p>
<ul>
<li>Alpha transparency</li>
<li>Normal mapping</li>
<li>Physically-correct PBR</li>
<li>Model skinning</li>
<li>Blend targets</li>
</ul>
<p><strong>Performance Improvements:</strong></p>
<ul>
<li>Depth prepass</li>
<li>Staging ring buffer for GPU transfers</li>
<li>Mesh data pool</li>
<li>Compute shader culling</li>
<li>Shader specialization constants</li>
</ul>
<h1 id="vrm-avatars">VRM Avatars</h1>
<p><a href="https://vrm.dev/en/vrm_about/">VRM</a> is a popular model format that
standardizes all of the components that you may expect in a 3D virtual
avatar. This includes bones, materials, and facial animation blend targets.
VRM avatar support is a big priority for us, and this is one reason why
we’re aiming for full glTF compliance so early.</p>
<p>Here is a VRM model created in <a href="https://vroid.com/en/studio/">VRoid Studio</a>
that we are using to test VRM importing:</p>
<p><img src="/assets/images/example-avatar-complete.png" alt="Complete avatar" /></p>
<p>Credits to Korakoe for making and sharing the model. Thank you Korakoe! :)</p>
<p>This is what the avatar currently looks like when imported into the engine:</p>
<p><img src="/assets/images/example-avatar-incomplete.png" alt="Incomplete avatar" /></p>
<p>There are obviously several problems with the current VRM loader.
The eyes, eyebrows, and eyelash primitives are missing their textures,
and the hair is missing altogether. However, the main body and its textures
are loading correctly, so this is a step in the right direction!</p>
<h1 id="scripting">Scripting</h1>
<p>Unfortunately, the scripting API did not get fleshed out as much as we’d like
in January, so next month we’ll be developing script bindings in conjunction
with the UI subsystem. Keep an eye out for future devlogs about them!</p>
<h1 id="console-variables-cvars">Console Variables (CVars)</h1>
<p>A “console variable,” or “CVar,” is a global variable that controls an aspect of
the engine at runtime, such as graphics settings, login information, or anything
else that a user would have to configure themselves. The CVars are currently
loaded from a <a href="https://toml.io/en/">TOML file</a> at runtime, but in the future,
they will also be modifiable from an actual console, and saved back to disk.</p>
<p>Here’s an example <code class="language-plaintext highlighter-rouge">config.toml</code>:</p>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[server]</span>
<span class="py">max_tps</span> <span class="p">=</span> <span class="mf">50.0</span>
<span class="py">update_rate</span> <span class="p">=</span> <span class="mf">20.0</span>
<span class="nn">[client]</span>
<span class="py">username</span> <span class="p">=</span> <span class="s">"ExampleUsername"</span>
<span class="py">metaverse_provider</span> <span class="p">=</span> <span class="s">""</span>
<span class="nn">[glyphs]</span>
<span class="py">font_path</span> <span class="p">=</span> <span class="s">"/usr/share/fonts/mononoki/mononoki-Regular.ttf"</span>
<span class="py">sdf_scale</span> <span class="p">=</span> <span class="mf">2.0</span>
<span class="py">sdf_border</span> <span class="p">=</span> <span class="mf">1.0</span>
<span class="py">sdf_range</span> <span class="p">=</span> <span class="mf">4.0</span>
<span class="nn">[renderer.debug]</span>
<span class="py">enabled</span> <span class="p">=</span> <span class="kc">true</span>
<span class="py">draw_lights</span> <span class="p">=</span> <span class="kc">true</span>
<span class="py">draw_transforms</span> <span class="p">=</span> <span class="kc">true</span>
</code></pre></div></div>
<h1 id="user-interface">User Interface</h1>
<p>This month, we’ve implemented basic TrueType font rendering, using
a graphics technique called a
<a href="https://en.wikipedia.org/wiki/Signed_distance_function">signed distance field</a>,
or SDF for short.</p>
<p><img src="/assets/images/sdf-demo.png" alt="SDF demo" /></p>
<p>(The font is <a href="https://madmalik.github.io/mononoki">Mononoki</a> by Matthias Tellen)</p>
<p>The SDF raster images are generated during client initialization using
<a href="https://github.com/Chlumsky/msdfgen">Chlumsky’s msdfgen library</a>, then
packed into a 4-channel texture atlas that looks like this:</p>
<p><img src="/assets/images/sdf-atlas.png" alt="SDF atlas" /></p>
<p>The texture contains RGB data representing the hard edges of the glyphs, as
well as an alpha channel encoding a basic SDF that can be used for soft
glyph effects. Finally, individual glyphs from the texture are mapped onto
quads, and rendered into the viewport with a special SDF glyph shader.</p>
<p>Here is a close-up of one of the font glyphs rendered using this method:</p>
<p><img src="/assets/images/sdf-close-up.png" alt="SDF close-up" /></p>
<p>Although there are a couple of artifacts in the glyph rendering, such as the
flat line segments on the end of the arm of the “e,” the glyph as a whole is
remarkably smooth, and should be more than sufficient in quality for typical text
rendering. If for some reason you need the quality to be higher, you can
increase the SDF atlas’s resolution by modifying the <code class="language-plaintext highlighter-rouge">glyphs.sdf_scale</code> CVar.</p>
<p>Text rendering is an essential component of any user interface, but we still
have a long ways to go before we have anything particularly useful or impressive.
Here’s some features that we can work on implementing in coming months:</p>
<ul>
<li>Proper font glyph alignment</li>
<li>A text console for changing CVars at runtime</li>
<li>Networked UI panel synchronization</li>
<li>UIML parsing and DOM</li>
<li>Support for drawing SDF glyphs from other sources, like SVGs</li>
<li>A variety of UI widget classes (buttons, labels, sliders, etc.)</li>
<li>User interaction with VR controllers</li>
</ul>
<h1 id="contributing">Contributing</h1>
<h2 id="suggestions">Suggestions</h2>
<p>Any ideas or suggestions for Mondradiko are welcome! Please
join our <a href="https://discord.gg/CsDqbFw">Discord server</a>, where
I and the other developers are active, and drop any thoughts
you have. As a potential future user, your opinions are important.</p>
<h2 id="funding">Funding</h2>
<p>If you’d like to help support the development of Mondradiko, please consider
<a href="https://patreon.com/marcelinecramer">becoming my patron on Patreon</a>!
A large part of Mondradiko’s development relies
on cloud services to function, such as automated
builds, testing, and packaging, along with hosting
the world servers themselves. I also save up the donations
to spend on VR and PC hardware, so that I can optimize
the engine for a variety of platforms. Anything helps!</p>
<h2 id="programming">Programming</h2>
<p>If you have any coding experience, either from making
games in Unreal Engine or Unity, or low-level C++
programming, we need your help!</p>
<p>Please join the <a href="https://discord.gg/CsDqbFw">Discord server</a>
to get in touch with the project maintainers and
discuss how you can help.</p>Marceline Cramercramermarceline@gmail.comglTF ModelsHello World!2021-01-01T00:00:00+00:002021-01-01T00:00:00+00:00https://mondradiko.github.io/hello-world<p>Happy New Year’s everyone!
This is the first development blog post for Mondradiko,
and I’d like to go over the current state of the project,
as well as where it’s expected to head in the near future.</p>
<h1 id="where-are-we-now">Where are we now?</h1>
<p>So far, we’ve accomplished a lot on the infrastructure of the
engine. We have an Entity-Component-System (ECS) world,
as well as basic network communication and sychronization,
and a rudimentary binary asset system. We’ve also successfully
ran Mondradiko on a VR headset (HTC Vive on Linux with Monado).</p>
<h1 id="next-steps">Next Steps</h1>
<p>Development on the engine has been picking up in speed
substantially, because of the time invested building the
framework for it. In the next several months, we can expect
a lot of features to come to fruition:</p>
<h2 id="windowsquest-builds">Windows/Quest Builds</h2>
<p>At the moment, Mondradiko only builds on Linux, meaning
that for most people, you won’t be able to run it yet.
Getting it to build on Windows, as well as on Oculus Quest,
is an essential goal, and we’re making it a priority.</p>
<h2 id="webassembly">WebAssembly</h2>
<p>We’ve picked out <a href="https://webassembly.org/">WebAssembly</a> (Wasm) to be
the main scripting environment for Mondradiko. This may seem like a
strange choice at first, but we have several reasons:</p>
<ul>
<li>Wasm is sandboxed, meaning guaranteed safety</li>
<li>Wasm is fast and JIT-compiled</li>
<li>Wasm is compact, for smaller script asset sizes</li>
<li>Wasm is popular and well-documented</li>
<li>Content creators have lots of language options</li>
</ul>
<p>Another very important feature of Wasm is that it’s very low-level,
and memory is linear. Local script data can be backed up and synchronized
over a network connection very easily, meaning that scripts are agnostic to
if they’re running on the client or server. For anyone that’s written
game netcode before, this is very convenient!</p>
<p>All of these features of Wasm make it a very appealing option for
a scripting environment, especially when considering that Mondradiko
has a lot in common with a typical web browser. Users download online
content that is ran locally on their computer, and they must be
safe from malicious code, while content creators should have
an enviroment that is easy to work with and portable.</p>
<p>We’re integrating <a href="https://github.com/bytecodealliance/wasmtime">Wasmtime</a>
as the WebAssembly runtime at the moment, as well as creating
a process for building C++ bindings to write scripts with.
In the future, we may also generate bindings for Rust, or any other
language that can target Wasm.</p>
<h2 id="customizable-user-interface">Customizable User Interface</h2>
<p>A major design goal for Mondradiko is that the user will
have complete control over the design of their user interface,
from everything from local settings menus, to
describing the client-side appearance of a server’s menu layouts.</p>
<p>To do this, we’ll be using <a href="https://en.wikipedia.org/wiki/UIML">UIML</a>
for high-level layout descriptions, and writing WebAssemebly
bindings (separate from script bindings!) to define how UI
elements are rendered and interacted with. This will give the
user a huge amount of control over what they can do with their
custom UI.</p>
<p>The Mondradiko client will come with a variety of UI presets
for the user to choose from, but they will also be able to download
premade UI configurations from online. Hopefully, a community of UI
designers will spring up!</p>
<h2 id="textglyph-rendering">Text/Glyph Rendering</h2>
<p>An important feature for Mondradiko to have this early on is a text
rendering system. This will be done by baking font files into
GlyphSetAssets, and rendering the text from those glyph sets using
signed-distance field (SDF) techniques, <a href="https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf">as popularized by Valve</a>.</p>
<p>This is very VR-friendly, as no low-resolution fuzziness is
visible as the user moves their view closer to the rendered text.
It is also very useful for rendering complex UI elements, without
having to process and store the polygonal geometry for those elements.</p>
<h2 id="avatar-rendering">Avatar Rendering</h2>
<p>Mondradiko uses <a href="https://vrm.dev/en/">VRM</a> for its avatar format.
It’s undetermined at this time how exactly VRM models will
be distributed to clients, but the current options are to
download them from a third-party source (such as <a href="https://hub.vroid.com/en/">VroidHub</a> or <a href="https://readyplayer.me/">ReadyPlayerMe</a>),
or to download and upload user avatars to the world server,
either directly or through a Matrix room’s file storage.
We’ll be discussing how this works, as well as Matrix integration, in
coming months.</p>
<h1 id="timeline">Timeline</h1>
<h2 id="january">January</h2>
<p>For January 2021, we’ll try to get these things done in this order:</p>
<ul>
<li>C++ scripting API</li>
<li>Asset system and mondradiko-bundler overhaul</li>
<li>Entity prefabs</li>
<li>Rudimentary UI</li>
<li>PBR shading</li>
</ul>
<p>Get ready for more blog updates on these features as we develop them!</p>
<h2 id="february-and-after">February and After</h2>
<ul>
<li>CVAR system</li>
<li>Launcher and release version control</li>
<li>Build for Windows/Quest</li>
<li>Avatar loading and rigging</li>
</ul>
<h1 id="community">Community</h1>
<p>We’ve set up a <a href="https://www.youtube.com/channel/UCFt7rHYh4ssg1vM1h-1K_RQ">YouTube channel</a>,
where we’ll post video devlogs in coming months.
Please subscribe!</p>
<p>We also have a <a href="https://discord.gg/CsDqbFw">Discord server</a>,
which is where all dev discussion takes place. Feel free
to join and say hi!</p>
<h1 id="opportunities-for-contribution">Opportunities for Contribution</h1>
<h1 id="design">Design</h1>
<h2 id="suggestions">Suggestions</h2>
<p>Any ideas or suggestions for Mondradiko are welcome! Please
join our <a href="https://discord.gg/CsDqbFw">Discord server</a>, where
I and the other developers are active, and drop any thoughts
you have. As a potential future user, your opinions are important.</p>
<h2 id="funding">Funding</h2>
<p>If you’d like to help support the development of
Mondradiko, please become our patron
on <a href="https://patreon.com/marcelinecramer">Patreon</a>!
A large part of Mondradiko’s development relies
on cloud services to function, such as automated
builds, testing, and packaging, along with hosting
the world servers themselves. Anything helps!</p>
<h2 id="programming">Programming</h2>
<p>If you have any coding experience, either from making
games in Unreal Engine or Unity, or low-level C++
programming, we need your help!</p>
<p>Please join the <a href="https://discord.gg/CsDqbFw">Discord server</a>
to get in touch with the project maintainers and
discuss the work needing to be done.</p>Marceline Cramercramermarceline@gmail.comHappy New Year’s everyone! This is the first development blog post for Mondradiko, and I’d like to go over the current state of the project, as well as where it’s expected to head in the near future.