<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lunaria</title>
    <description>The latest articles on DEV Community by Lunaria (@lunaria).</description>
    <link>https://dev.to/lunaria</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3061%2F36f67a9e-e1c3-40cc-b307-dfbc1604b1c4.png</url>
      <title>DEV Community: Lunaria</title>
      <link>https://dev.to/lunaria</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lunaria"/>
    <language>en</language>
    <item>
      <title>This Month in Lunaria – July 2021</title>
      <dc:creator>Jan David</dc:creator>
      <pubDate>Sat, 31 Jul 2021 18:39:49 +0000</pubDate>
      <link>https://dev.to/lunaria/this-month-in-lunaria-july-2021-3pcn</link>
      <guid>https://dev.to/lunaria/this-month-in-lunaria-july-2021-3pcn</guid>
      <description>&lt;p&gt;I'm back! Let's just say that living through a global pandemic takes its toll, and I wasn't able to focus on the project as much as I would have liked. I'm trying to learn from this and set smaller, more achievable goals for the future. But the big news for July is that there has been some progress again!&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch to Godot Engine
&lt;/h2&gt;

&lt;p&gt;The original plan was to use the new game engine &lt;a href="https://bevyengine.org/"&gt;Bevy&lt;/a&gt; to create &lt;a href="https://playlunaria.com"&gt;Lunaria&lt;/a&gt;. Bevy is written in Rust, which provides a good foundation for the low-level services that Lunaria's API needs to run. But Bevy is still very young and in active development, which makes it hard to find good beginner resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://godotengine.org/"&gt;Godot&lt;/a&gt; on the other hand is very mature, and its community has created an abundance of tutorials for all kinds of games. The engine is written in C++, which means tightly integrating the backend into the engine will be more difficult. But Godot supports plugins written in Rust, which should make it possible to stick with Rust for the backend and the core logic.&lt;/p&gt;

&lt;p&gt;I have decided to experiment with Godot, since Bevy overwhelms me as complete game development novices. As I gain experience and a better understanding of this domain, I might reconsider this decision. But for now, I want to prototype as quickly as possible to learn if Lunaria can even work as a game...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--22Q4fa0d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3az6ci0s23f7em52m0lb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--22Q4fa0d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3az6ci0s23f7em52m0lb.png" alt="Screenshot of Lunaria running in the Godot engine"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Streaming API for the Game State
&lt;/h2&gt;

&lt;p&gt;The most interesting development has been a streaming API for the game state, which uses server-side streaming in &lt;a href="https://grpc.io/"&gt;gRPC&lt;/a&gt; to push changes to the client. The idea is that a client can start the game by calling the &lt;code&gt;startGame&lt;/code&gt; method. The response to the method is a stream of game states, starting with &lt;code&gt;GAME_STATUS_RUNNING&lt;/code&gt;. When the game ends or is stopped by the user, the server streams a &lt;code&gt;GAME_STATUS_STOPPED&lt;/code&gt; update to the client, indicating that it can stop running itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EBg_iZXq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2otizqzmle442gvjnrb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EBg_iZXq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2otizqzmle442gvjnrb.gif" alt="Animation showing a stream of updates from the game"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After experimenting with this idea for a while, I don't think it is well suited for this particular use case. For one, it introduces a significant barrier to entry. Players would have to implement asynchronous methods just to start the game, which will be challenging for less experienced developers. And the value of server-side streaming for this use case is pretty low, as changes do not happen frequently and can easily be captured by an error response to API calls. For example, a call to &lt;code&gt;moveUnit&lt;/code&gt; can simply return an &lt;code&gt;ERROR: Game stopped&lt;/code&gt; response, which eliminates the need to stream the state change in real-time.&lt;/p&gt;

&lt;p&gt;A better use case for server-side streaming are updates to systems that are controlled by the server. Taking a weather system for example. Clients could poll the weather ever so often using synchronous method calls, or they could subscribe to a stream of real-time weather updates that get pushed from the server whenever the weather changes.&lt;/p&gt;

&lt;p&gt;I am very excited about this experiment, since it enables a few very interesting game mechanics later on...&lt;/p&gt;

&lt;h2&gt;
  
  
  Camera Controls
&lt;/h2&gt;

&lt;p&gt;Less exciting but very practical is the implementation of camera controls in Godot. The controls are inspired by modern strategy games, in which the camera can be moved with the keys &lt;code&gt;W&lt;/code&gt;, &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;S&lt;/code&gt;, and &lt;code&gt;D&lt;/code&gt;. Additionally, players can zoom in and out using the keys &lt;code&gt;Q&lt;/code&gt; and &lt;code&gt;E&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tSR10-Iv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8mda3xelslgw6pkvyv6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tSR10-Iv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8mda3xelslgw6pkvyv6.gif" alt="Animation showing how the camera can be controlled in Lunaria"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Future plans for the camera controls are to support moving the camera with the mouse, for example my moving the cursor to the border of the screen.&lt;/p&gt;

&lt;p&gt;The implementation is done in &lt;a href="https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/gdscript_basics.html"&gt;GDScript&lt;/a&gt;, which is the default scripting language in Godot. Once the missing features have been implemented and the controls have been tested sufficiently, the plan is to open source the implementations and publish it as a plugin for Godot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Month in Lunaria
&lt;/h2&gt;

&lt;p&gt;This month has laid quite a good foundation with the switch to Godot, a better understanding of gRPC and its capabilities, and the camera controls as a prerequisite for navigating the in-game world.&lt;/p&gt;

&lt;p&gt;The focus for August is stabilizing the features introduced in July, and working towards the first game mechanic. This means finishing the implementation of the camera controls, implementing an API to start and stop a game, and then figuring out what the first game mechanic should be.&lt;/p&gt;

</description>
      <category>gamedev</category>
    </item>
    <item>
      <title>gRPC</title>
      <dc:creator>Jan David</dc:creator>
      <pubDate>Mon, 19 Oct 2020 18:41:42 +0000</pubDate>
      <link>https://dev.to/lunaria/grpc-fpf</link>
      <guid>https://dev.to/lunaria/grpc-fpf</guid>
      <description>&lt;p&gt;&lt;a href="https://playlunaria.com"&gt;Lunaria&lt;/a&gt; is a video game for programmers. It is played by writing code that sends commands to the game, and watching the effects of those commands on the game world. In this post, I will introduce the API between the players' code and the game, and explain why I chose to use the &lt;a href="https://grpc.io"&gt;gRPC&lt;/a&gt; framework.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;On a high level, Lunaria consists of two components: a simulation running the game, and an API enabling players to interact with the simulation. Because players can only control the game through the API, it probably has the most significant impact on how much fun it is to play the game.&lt;/p&gt;

&lt;p&gt;Lunaria is also supposed to be a sandbox for beginner and expert programmers alike, and a place where they can practice their skills. To do this, the game must be compatible with as many programming languages and paradigms as reasonably possible, so that developers can freely choose what to learn. Since the API is again the most important factor determining compatibility with the game, its design matters even more.&lt;/p&gt;

&lt;h1&gt;
  
  
  gRPC
&lt;/h1&gt;

&lt;p&gt;After much research and consideration, I made the decision to adopt the &lt;a href="https://grpc.io"&gt;gRPC&lt;/a&gt; framework to build Lunaria's API. gRPC is described as &lt;em&gt;a high-performance, open source universal RPC framework&lt;/em&gt;, and it has some interesting features.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Specification
&lt;/h2&gt;

&lt;p&gt;As the primary touchpoint between players and the game, the API has to be well documented. With gRPC, the endpoints of the API and the messages it consumes and produces are defined as &lt;a href="https://developers.google.com/protocol-buffers/"&gt;Protocol Buffers&lt;/a&gt;, a language-neutral standard to serialize data. Protocol Buffers are strongly typed and fairly easy to read, making them ideal candidates for API documentation.&lt;/p&gt;

&lt;p&gt;The following example defines the API that returns the current version of the game. It defines a &lt;code&gt;Version&lt;/code&gt; type with three field, an RPC endpoint &lt;code&gt;GetVersion&lt;/code&gt;, and two types for the request and response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;lunaria&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="na"&gt;major&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="na"&gt;minor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="na"&gt;patch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;GetVersionRequest&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;GetVersionResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;Lunaria&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;GetVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetVersionRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetVersionResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Multi-platform
&lt;/h2&gt;

&lt;p&gt;gRPC supports many programming languages and ecosystems out-of-the-box. It has &lt;a href="https://grpc.io/docs/languages/"&gt;official support&lt;/a&gt; for Node, Python, Go, Ruby, Java and more, and other languages are supported by their communities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auto-generated libraries
&lt;/h2&gt;

&lt;p&gt;While gRPC is built on open standards and can theoretically be used with any programming language, official or community supported languages provide a lot of tooling that makes it very easy to use gRPC. Most notably, client libraries for many languages can be generated from an API's Protocol Buffer definition. For Lunaria, a Node and a Rust library are already being published as a proof of concept.&lt;/p&gt;

&lt;p&gt;Take the Node.js library for Lunaria (&lt;a href="https://www.npmjs.com/package/lunaria-api"&gt;&lt;code&gt;lunaria-api&lt;/code&gt;&lt;/a&gt;) as an example. The library can easily be installed from &lt;code&gt;npm&lt;/code&gt;, and requesting the version is as simple as calling a method on the client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Asynchronously send the request and process the response in a callback&lt;/span&gt;
&lt;span class="nx"&gt;lunaria&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetVersionResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getVersion&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;versionString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getMajor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getMinor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPatch&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Lunaria is running version &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;versionString&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Streaming and Authentication
&lt;/h2&gt;

&lt;p&gt;Two other builtin features of gRPC are &lt;em&gt;streaming&lt;/em&gt; and &lt;em&gt;authentication&lt;/em&gt;. Streaming might be interesting for certain game mechanics, and authentication will come in handy for multiplayer. Even though there are no concrete plans for these features yet, it is still nice to know that they are there when we need them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Alternatives
&lt;/h1&gt;

&lt;p&gt;Before deciding on gRPC, I did a lot of research and considered the following alternatives. Each has its pros and cons, but none checked as many boxes as gRPC.&lt;/p&gt;

&lt;h2&gt;
  
  
  REST
&lt;/h2&gt;

&lt;p&gt;Probably the most widely supported API would have been an REST API. Every language on the planet has a way to query an HTTP endpoint (don't @ me), and especially web developers are very familiar with it. There are also decent ways to document these APIs, and some tools to auto-generate client libraries.&lt;/p&gt;

&lt;p&gt;In my experience, though, it requires a lot of effort to keep the documentation up-to-date, and the generation of client libraries is often fragile. But maybe more importantly, it is not a very fun API to use. The industry is moving to other solutions such as RPC or GraphQL, which are either more performant or offer more flexibility to clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL
&lt;/h2&gt;

&lt;p&gt;Another option I considered was GraphQL. It is widely supported, easy to document through its schema, and has excellent tooling such as the &lt;a href="https://www.apollographql.com/docs/apollo-server/testing/graphql-playground/"&gt;Playground&lt;/a&gt; to explore the API.&lt;/p&gt;

&lt;p&gt;There are not many arguments against GraphQL, and most will probably resolve themselves in the future. Streaming and subscriptions are still fairly new, as is the Rust implementation of GraphQL.&lt;/p&gt;

&lt;p&gt;Maybe my biggest issue with GraphQL is that it feels very focused on web technologies, while Lunaria is more of a distributed system. This probably wouldn't be a problem, but gRPC felt like the better fit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Message queues
&lt;/h2&gt;

&lt;p&gt;A third solution I considered where message queues, because it is a very simple solution that other video games have already implemented. In &lt;a href="https://screeps.com"&gt;Screeps&lt;/a&gt;, for example, players queue up commands for their units that get executed in the next turn.&lt;/p&gt;

&lt;p&gt;But compared with the alternatives, message queues are very hard to use. It's difficult to document their message formats and ensure that the documentation stays up-to-date, and it is not possible to generate client libraries that would hide some of the complexity. And since GraphQL and gRPC support streaming, the same pattern can be implemented in a much nicer environment.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;gRPC feels like a great choice for Lunaria. It provides a good experience to players, is easy to document and use, and is blazingly fast. The &lt;a href="https://github.com/playlunaria/lunaria-api"&gt;&lt;code&gt;playlunaria/lunaria-api&lt;/code&gt;&lt;/a&gt; repository contains the specification for Lunaria's API, tooling that publishes client libraries to &lt;a href="https://www.npmjs.com/package/lunaria-api"&gt;npm&lt;/a&gt; and &lt;a href="https://crates.io/crates/lunaria-api"&gt;crates.io&lt;/a&gt;, and automated integration tests for each language.&lt;/p&gt;

&lt;p&gt;gRPC is of course no silver bullet, and I can already see a few challenges ahead. At least in its initial form, Lunaria will expose a single service, and I am not sure if that's how gRPC is intended to be used. And it might turn out that players would actually feel more comfortable with GraphQL than gRPC. But we'll learn this as we go.&lt;/p&gt;

&lt;p&gt;With the API design out of the way, it is now time to focus on the actual game...&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>grpc</category>
    </item>
    <item>
      <title>Announcing Lunaria</title>
      <dc:creator>Jan David</dc:creator>
      <pubDate>Mon, 05 Oct 2020 18:27:37 +0000</pubDate>
      <link>https://dev.to/lunaria/announcing-lunaria-4179</link>
      <guid>https://dev.to/lunaria/announcing-lunaria-4179</guid>
      <description>&lt;p&gt;A few weeks ago, I wrote a lengthy blog post about &lt;a href="https://dev.to/jdno/why-i-want-to-build-a-video-game-for-programmers-l26"&gt;why I want to build a video game for programmers&lt;/a&gt;. Today, I am happy to announce &lt;strong&gt;Lunaria&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Lunaria is a video game for programmers. It is played by writing code that sends commands to the game, and watching the effects of those commands on the game world. As players progress through the game, they unlock new capabilities and have to expand and adapt their programs to solve new and ever increasing challenges.&lt;/p&gt;

&lt;p&gt;This post is split into the following sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vision&lt;/li&gt;
&lt;li&gt;
Gameplay

&lt;ul&gt;
&lt;li&gt;Setting and Scenario&lt;/li&gt;
&lt;li&gt;Programming Mechanic&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Roadmap&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Vision
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;To create the most engaging platform to practice programming&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's start by taking a look the motivation to create Lunaria. This section repeats a lot of arguments from &lt;a href="https://dev.to/jdno/why-i-want-to-build-a-video-game-for-programmers-l26"&gt;the post linked above&lt;/a&gt;, and I invite you to check it out for a more in-depth discussion of the following points.&lt;/p&gt;

&lt;p&gt;Briefly summarized, I am unhappy with the tools that are available to freely practice programming. Yes, there are plenty of course and tutorials available on the internet. And yes, it has never been easier to start and launch a side project. But neither is what I am looking for. What I want is a sandbox in which I can play around with code. Experiment and learn, without a strict curriculum or the pressure to produce something that would look good on a portfolio.&lt;/p&gt;

&lt;p&gt;And I want to combine this sandbox with the mechanics of video games to make it engaging and fun. Give users goals that they can pursue if they want some structure and direction. Create feedback loops that can be used to measure the efficiency and effectiveness of experiments. And provide a bit of a story around the programming so that it is interesting to come back and continue practicing. Mechanics that video games have perfected over the last few decades.&lt;/p&gt;

&lt;p&gt;The very ambitious dreams for Lunaria is to become the most engaging platform to practice programming, for beginners and experts alike. Because my theory is that a vast sandbox video game, in which players can pick and choose their own adventures, is generally more interesting than most courses or side projects...&lt;/p&gt;

&lt;h1&gt;
  
  
  Gameplay
&lt;/h1&gt;

&lt;p&gt;This section is divided into two topics. First, the setting and scenario of Lunaria is introduced. Second, we take a look at the initial design of the programming mechanic inside the game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting and Scenario
&lt;/h2&gt;

&lt;p&gt;Lunaria is heavily inspired by existing video games. It combines mechanics and ideas from strategy, base building, and survival games, and remixes them to work well with its core mechanic: programming.&lt;/p&gt;

&lt;p&gt;When starting the game, players find themselves in charge of an expedition to a foreign planet. A rocket has dropped them off on the planets surface, and unloaded some supply and a few drones. The player's first tasks are to set up a rudimentary base that protects against the environment, and to generate some energy so that the base and its drones continue to function.&lt;/p&gt;

&lt;p&gt;What happens next still needs to be designed, but the story arc will most likely focus on the following progression:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up an automated base that produces resources&lt;/li&gt;
&lt;li&gt;Bring in humans to unlock new capabilities&lt;/li&gt;
&lt;li&gt;Launch rockets into space to explore the solar system&lt;/li&gt;
&lt;li&gt;Unlock long-range travel, and explore the galaxy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The long-term vision is that the game takes place in a persistent massive-multiplayer online world. As players progress through the game, they can meet other players and collaborate to tackle the hardest challenges. Building the infrastructure for this is a serious undertaking, so in the beginning development will focus on the singleplayer experience and stand-alone multiplayer servers for a handful of players. Large-scale multiplayer will follow later.&lt;/p&gt;

&lt;p&gt;Over the next few weeks, I will publish a series of blog posts about the video games (and books and movies) that inspire Lunaria, and the ideas and mechanics that this game might adopt from them. The sum of these influences will hopefully paint a compelling picture of the game that Lunaria might become...&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming Mechanic
&lt;/h2&gt;

&lt;p&gt;The most important game mechanic of Lunaria is without a doubt programming. Two technical components will dominate the look &amp;amp; feel of this mechanic:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The runtime that executes the player's code&lt;/li&gt;
&lt;li&gt;The API that players use to interact with the game&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Certain technical limitations are unavoidable, but I find it very important that the game does not constrain players too much. To this end, I want Lunaria to deliver the following functionality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support as many programming languages are reasonably possible. Do not require players to use a single language or tech stack.&lt;/li&gt;
&lt;li&gt;Give players freedom in their software design. Treat their code as a blackbox and interact through a well-defined API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Runtime
&lt;/h3&gt;

&lt;p&gt;In the beginning, especially as long as there is no multiplayer, the game will run locally on a player's machine. When running locally, no special runtime is required and players can simply run the code in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# A Rust player&lt;/span&gt;
cargo run

&lt;span class="c"&gt;# A Ruby player&lt;/span&gt;
ruby lunaria.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The long-term vision for the game is to become a massive-multiplayer game, which executes the player's code "in the cloud". For this environment, the idea is to utilize Docker to allow players to upload their own runtimes. Players will package their code in a Docker image and upload it to the server where it will get executed. This enables each player to choose their own runtime and execution environment, even when playing online.&lt;/p&gt;

&lt;h3&gt;
  
  
  API
&lt;/h3&gt;

&lt;p&gt;The code that players write to play Lunaria interacts with the game through an API. Because of this, the API has a huge influence on how Lunaria feels to play. It should provide a high-level interface that is easy to use, and provide good documentation about the parameters that are passed along requests and responses. It is also important that it is performant, especially in a future MMO scenario. And finally, to not limit the choice of programming language, the API implementation should be as widely supported as possible.&lt;/p&gt;

&lt;p&gt;The best fit for these requirements is gRPC. It is widely supported, has low-latency and small message sizes, and supports auto-generated client libraries. I am particular excited about the client libraries, because they provide a well-documented, strongly typed, and high-level interface to interact with the game. By using gRPC and its libraries, players do not need to deal with transport protocols, message formats and encoding, or other low-level details. Instead, they can call a method and focus on the impact they'd like to have.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c"&gt;// Send an asynchronous request to move a drone to a new location.&lt;/span&gt;
&lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="nf"&gt;.moveUnit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drone&lt;/span&gt;&lt;span class="py"&gt;.uuid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Coordinate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will write more about this decision in the future.&lt;/p&gt;

&lt;h1&gt;
  
  
  Roadmap
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Shoot for the moon. Even if you miss, you'll land among the stars.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lunaria as introduced here is an overly ambitious project. I think it is helpful to have the long-term vision as a north start to work towards, but its success is of course not guaranteed. For foreseeable future, I have much more modest plans for the project.&lt;/p&gt;

&lt;p&gt;The goal for the &lt;strong&gt;next 6 months&lt;/strong&gt; is to create a playable prototype of the game. The prototype will be limited to singleplayer, and it will only implement a narrow slice of the game mechanics I ultimately want to have in the game. Its purpose is to find a solid foundation for both the game design as well as we technical architecture.&lt;/p&gt;

&lt;p&gt;With a prototype in hand, I want to focus the &lt;strong&gt;following 6-12 months&lt;/strong&gt; on building out more game mechanics. The goal is to create something people actually like to play to make sure the concept works. This is also when I want to invest time and effort to foster the community. I expect that it will be much easier to participate in the project when there is something to see, try, and comment on.&lt;/p&gt;

&lt;p&gt;Everything beyond the next year is probably too early to pin down, and depends very much on the health of the project by then. If we get there, a focus for the second year could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bigger game world, e.g. going from planets to solar systems to galaxies&lt;/li&gt;
&lt;li&gt;Procedural world generation to add more variety and depth&lt;/li&gt;
&lt;li&gt;Multiplayer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest risk for the success of the project is me burning out or losing interest before a significant milestone is achieved. If I can get a prototype out, and we can gather as a community around the game, I will feel more optimistic about the long-term sustainability of the project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Stay in Touch
&lt;/h1&gt;

&lt;p&gt;This post was only able to scratch the surface of what Lunaria is and might become. Therefore, make sure to check in here regularly for updates on the project. I intend to write roughly two posts per months, covering the progress on the project, important design decisions, and games and other content that inspire Lunaria. The following posts are already in the pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A detailed look at gRPC and why it was chosen for Lunaria&lt;/li&gt;
&lt;li&gt;A discussion about the decision to build Lunaria as open source&lt;/li&gt;
&lt;li&gt;A bunch of posts of various video games and movies that inspire Lunaria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://playlunaria.com/blog"&gt;https://playlunaria.com/blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also join Lunaria's Discord server to chat with me and others. Right now, the server is pretty empty, but I hope that'll change as the project develops.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://discord.gg/WkgJcsq"&gt;https://discord.gg/WkgJcsq&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then there is GitHub of course, where you can find Lunaria's source code. This is also where I'll plan to have in-depth technical discussions on new features and game mechanics, probably through an RFC process once there are more contributors than just me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/playlunaria"&gt;https://github.com/playlunaria&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for your interest in the project! 👋&lt;/p&gt;

</description>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
