<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="pretty-atom-feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Notes by Austin Pocus</title>
  <subtitle>The personal blog of Austin Pocus.</subtitle>
  <link href="https://blog.austinpocus.com/feed/feed.xml" rel="self" />
  <link href="https://blog.austinpocus.com/" />
  <updated>2022-07-18T18:05:55Z</updated>
  <id>https://blog.austinpocus.com/</id>
  <author>
    <name>Austin Pocus</name>
  </author>
  <entry>
    <title>Patterns</title>
    <link href="https://blog.austinpocus.com/blog/patterns/" />
    <updated>2022-07-18T18:05:55Z</updated>
    <id>https://blog.austinpocus.com/blog/patterns/</id>
    <content type="html">&lt;p&gt;Man, it has been a &lt;em&gt;while&lt;/em&gt; since I&#39;ve written one of these. So I&#39;ll dive right in: lately, I&#39;m thinking about how to branch out from the Javascript-centric ecosystem I&#39;ve been working in over the past few years.&lt;/p&gt;
&lt;p&gt;I&#39;m feeling boxed in by my sole use of Javascript as my language of choice. I started to explore languages within the realm of, or adjacent to, the web. Specifically, I&#39;ve become interested in PHP and Python.&lt;/p&gt;
&lt;p&gt;This has led me to start comparing programming languages. As I&#39;ve thought about &lt;a href=&quot;https://blog.austinpocus.com/blog/the-foxie-language-and-the-hounddog-engine/&quot;&gt;designing my own programming language&lt;/a&gt; &lt;a href=&quot;https://blog.austinpocus.com/blog/zig-as-implementation-language/&quot;&gt;on this blog&lt;/a&gt; &lt;a href=&quot;https://blog.austinpocus.com/tags/adventure-kit/&quot;&gt;a few times before&lt;/a&gt;, I&#39;m naturally thinking about features and language characteristics that are shared, and those that set a language apart.&lt;/p&gt;
&lt;p&gt;What really inspired me to write this post was noticing the features that Python has picked up since I last used it. &lt;a href=&quot;https://peps.python.org/pep-0636/&quot;&gt;Structural pattern matching&lt;/a&gt; is a fantastic example, borrowing an extremely useful language feature from Rust. How did I miss this?&lt;/p&gt;
&lt;p&gt;But what am I getting at here? What&#39;s the purpose of this post?&lt;/p&gt;
&lt;p&gt;For one, I&#39;ve missed out on some key developments in programming languages I used to know well, or at least, I thought I knew them. PHP is another great example here -- while I always thought of PHP as a slightly more well-behaved Perl, more geared towards CGI and old-school web dev, that couldn&#39;t be further from the truth. Modern PHP, so far, has been surprisingly robust and effective. It draws more comparisons to Ruby + Rails than Perl, especially with frameworks like Laravel.&lt;/p&gt;
&lt;p&gt;It&#39;s led me to question where I want to spend my time writing code. Is it React frontends? I think I&#39;ve gotten into a rut there. Maybe Python audio analysis? Or PHP web dev? Maybe a return to Rails?&lt;/p&gt;
&lt;p&gt;In any case, I think I need a plan.&lt;/p&gt;
&lt;p&gt;The most interesting thing to me, right now, the thing I&#39;m most likely to sink my teeth into and finish, is audio analysis using Python. Specifically, I want to hum or whistle a tune, and translate that into MIDI or sheet music.&lt;/p&gt;
&lt;p&gt;Let&#39;s narrow that down. I want to whistle and get MIDI. I&#39;ve &lt;a href=&quot;https://github.com/ajpocus/bloopy&quot;&gt;done something like this before&lt;/a&gt;, but it was honestly half-baked. It was very raw, having a few flaws:&lt;/p&gt;
&lt;p&gt;For one, it could only work on pre-recorded WAV files. You had to record a short clip and run the program on the command line. There, it would output raw MIDI. For those unfamiliar with the world of audio files, this is really low-level stuff, something you would feed into an existing synthesizer or digital audio workstation.&lt;/p&gt;
&lt;p&gt;There, we would finally be able to hear the product, which was...not the &lt;em&gt;most&lt;/em&gt; accurate rendition of whatever was whistled. Sure, the notes would be mostly right, as long as you were within a half-tone or so of the &amp;quot;perfect&amp;quot; frequency. But it had a lot of holes.&lt;/p&gt;
&lt;p&gt;So what&#39;s the difference this time around?&lt;/p&gt;
&lt;p&gt;First, I would love to make this more of a real-time user-friendly application. The app should open a window where you can record, see a visual representation of the notes recorded, and play back any part of the result whenever you like.&lt;/p&gt;
&lt;p&gt;Second, I&#39;d like to use some sort of machine learning technology like &lt;a href=&quot;https://pytorch.org/&quot;&gt;PyTorch&lt;/a&gt; to fine-tune the resulting notes. This could be as simple as fixing individual notes that are sharp or flat, or it could be smart enough to learn how sharp or flat you are over time, or it could learn the difference between an error and an intentional pitch bend (like when a guitarist bends a string).&lt;/p&gt;
&lt;p&gt;Eventually, I&#39;d love to see auto-transcription of musical instruments being played, as the notes are being played, a sort of &amp;quot;smart musical assistant AI&amp;quot;. But that&#39;s a long way off.&lt;/p&gt;
&lt;p&gt;Right now, I&#39;d just like to get a solid MIDI signal out of my random whistling. I come up with some neat little melodies every now and then, and it would be great to capture that and maybe turn it into something musical.&lt;/p&gt;
&lt;p&gt;Related side idea: a beatboxing translator, an app that takes beatboxing and turns it into a MIDI drum loop. But that&#39;s another project for another day! I&#39;ve got enough to do for now.&lt;/p&gt;
&lt;p&gt;Tune in next time -- I should be writing something new within the next few days.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>A NES-like Virtual Machine</title>
    <link href="https://blog.austinpocus.com/blog/a-nes-like-virtual-machine/" />
    <updated>2022-03-22T20:05:09Z</updated>
    <id>https://blog.austinpocus.com/blog/a-nes-like-virtual-machine/</id>
    <content type="html">&lt;p&gt;Yesterday, I was thinking about &lt;a href=&quot;https://blog.austinpocus.com/blog/zig-as-implementation-langauge&quot;&gt;a layer of Zig between me and the NES&lt;/a&gt;. Naturally, this led me to wonder: what if I made a virtual machine that is NES-like, but easier to program?&lt;/p&gt;
&lt;p&gt;But first, a soundtrack, because I have this song stuck in my head and you should too:&lt;/p&gt;
&lt;div id=&quot;n1TNLU-ydLA&quot; class=&quot;eleventy-plugin-youtube-embed&quot; style=&quot;position:relative;width:100%;padding-top: 56.25%;&quot;&gt;&lt;iframe style=&quot;position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;&quot; width=&quot;100%&quot; height=&quot;100%&quot; frameborder=&quot;0&quot; title=&quot;Embedded YouTube video&quot; src=&quot;https://www.youtube-nocookie.com/embed/n1TNLU-ydLA&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;I&#39;ve thought about a custom virtual machine &lt;a href=&quot;https://blog.austinpocus.com/blog/the-foxie-language-and-the-hounddog-engine&quot;&gt;a few&lt;/a&gt; &lt;a href=&quot;https://blog.austinpocus.com/blog/the-parts-that-make-up-a-game-dev-kit/&quot;&gt;times before&lt;/a&gt;, but not so much in those terms. I think of this apart from those early efforts -- this is more of a fun thought experiment, not necessarily something I&#39;ll dive into further.&lt;/p&gt;
&lt;p&gt;So what would this virtual machine look like?&lt;/p&gt;
&lt;p&gt;The first thing I&#39;m thinking of is the behavior the VM exhibits, followed by the interface it defines to allow us to change that behavior (this might seem obvious, but bear with me -- I&#39;m thinking out loud here).&lt;/p&gt;
&lt;p&gt;The VM should let us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Define shapes, individual pixels, and tiles on the screen.&lt;/li&gt;
&lt;li&gt;Animate those graphics, using tiles or pixel transformations.&lt;/li&gt;
&lt;li&gt;Detect collisions between objects on the screen and react to them.&lt;/li&gt;
&lt;li&gt;Move pixels, groups of pixels, shapes, or tiles in any direction.&lt;/li&gt;
&lt;li&gt;React to user input, from the keyboard, mouse, or a controller.&lt;/li&gt;
&lt;li&gt;Define &amp;quot;action buttons&amp;quot; that trigger interactions with onscreen objects.&lt;/li&gt;
&lt;li&gt;Simulate user input like movement or interaction, to create NPCs and enemies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That seems like a solid base. The first thing to build would be the graphics -- that&#39;s the core, naturally. So how we define the shapes, pixels, and tiles will influence how the whole system works (a perfect opportunity to &lt;a href=&quot;https://blog.austinpocus.com/blog/deferring-decisions&quot;&gt;defer decisions&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;From here, how do we interact with this behavior? Do we use a language like Javascript, or Zig, or Lisp, or do we define something new?&lt;/p&gt;
&lt;p&gt;Side note: for a long time, since I discovered Lisp-like languages, I wanted to create a custom language that uses something similar to &lt;a href=&quot;https://en.wikipedia.org/wiki/M-expression&quot;&gt;M-expressions&lt;/a&gt; instead of S-expressions. Think: fewer parentheses. In other words, a sprinkling of syntax to make Lisp constructs easier to deal with, without sacrificing much in terms of parsing (and macro expressions!).&lt;/p&gt;
&lt;p&gt;But this is a tangent, a technical desire as opposed to a user need (and I&#39;m a user in this case, so it&#39;s doubly important to think about).&lt;/p&gt;
&lt;p&gt;What would the ideal language look like?&lt;/p&gt;
&lt;p&gt;It might be Lua. &lt;a href=&quot;https://blog.austinpocus.com/blog/i-wanna-know-what-love-is&quot;&gt;Lua has been used to great effect&lt;/a&gt; in the video game industry, so it&#39;s a pretty safe bet. Maybe I start with Lua and expand from there? Hypothetically of course -- I&#39;m not actually going to start building any of this yet.&lt;/p&gt;
&lt;p&gt;What if we followed the tangent? What would an ideal language look like?&lt;/p&gt;
&lt;p&gt;I do like the idea of using some form of M-expression, such that we could:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the outer layer of parentheses so &lt;code&gt;(+ 1 2)&lt;/code&gt; could be &lt;code&gt;+ 1 2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add a little syntactic sugar, like for dictionaries, as in Clojure.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is getting way into the weeds, but you get the idea. VMs are just fun to think about -- we can create little worlds. And that&#39;s the entire appeal of making games, so it seems appropriate. Signing off -- tune in next time, same bat-channel.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Zig as Implementation Language</title>
    <link href="https://blog.austinpocus.com/blog/zig-as-implementation-language/" />
    <updated>2022-03-21T22:09:11Z</updated>
    <id>https://blog.austinpocus.com/blog/zig-as-implementation-language/</id>
    <content type="html">&lt;p&gt;After a good sabbatical, I&#39;m back and writing. Lately, I&#39;ve been interesting in the &lt;a href=&quot;https://ziglang.org/&quot;&gt;Zig programming language&lt;/a&gt;, and how it might relate to &lt;a href=&quot;https://www.nesdev.org/wiki/Nesdev_Wiki&quot;&gt;NES development and 6502 assembly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Zig, for the uninitiated, is a small and fast C replacement and glue language. At least, that&#39;s how I&#39;ve been thinking about it. It&#39;s like Rust with the restrictions (and memory safety) removed, a tradeoff I favor, since I&#39;m developing games and I want to hack out a concept, not necessarily a production system.&lt;/p&gt;
&lt;p&gt;Let&#39;s back up. I&#39;ve been wanting to get back into NES development, making games for the original Nintendo system. It&#39;s a sparse environment, to say the least, but I think it can be made better in 2 respects: tooling, and language of implementation.&lt;/p&gt;
&lt;p&gt;Let&#39;s talk tooling first, since it&#39;s the shorter of the two topics, something I&#39;ve only briefly considered. Graphics and audio tools are plentiful for the NES, but finding something that works well, is updated regularly, integrates with the code you&#39;re writing...it&#39;s almost enough to make me want to develop modern tools for these old systems.&lt;/p&gt;
&lt;p&gt;Almost. Not quite, though. Existing tools work, but the biggest hurdle I&#39;m facing right now is writing 6502 assembly code. Thankfully there are resources, like &lt;a href=&quot;https://archive.org/details/Programming_the_6502_OCR&quot;&gt;Rodnay Zaks&#39;s &lt;em&gt;Programming the 6502&lt;/em&gt;, freely available on archive.org&lt;/a&gt; (legally, too!). I&#39;ve been going through the &lt;a href=&quot;https://nerdy-nights.nes.science/&quot;&gt;Nerdy Nights tutorials as well&lt;/a&gt;, which are indispensable for actually getting something on the screen.&lt;/p&gt;
&lt;p&gt;6502 is great as far as assembly languages go -- much better than modern x86, which is designed to be written by compilers. Even so, it can get tedious, and with the memory and computing limits of the NES, it&#39;s not so easy to just use C. There are a lot of things you just can&#39;t do, common constructs you can&#39;t use.&lt;/p&gt;
&lt;p&gt;That&#39;s where Zig could come in handy. One of Zig&#39;s greatest strengths is that the standard library is optional -- huge for embedded use cases, or limited-resource environments like this. There isn&#39;t a 6502 backend as of this writing, but there is &lt;a href=&quot;https://github.com/ziglang/zig/issues/6502&quot;&gt;a GitHub issue that requests this feature&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So that&#39;s one option. Of course, a language tailor-made for 6502 NES development would be ideal. Maybe I can build a set of macros on top of 6502, like a custom assembler...&lt;/p&gt;
&lt;p&gt;That&#39;s really what I&#39;m moving towards -- not using Zig directly, but rather, as the implementation language for another custom language, geared towards the NES.&lt;/p&gt;
&lt;p&gt;First, though, I should probably write a game actually using 6502 directly. I want to be able to make games for the NES more easily, but I need to take the hard route first. Learn my way around.&lt;/p&gt;
&lt;p&gt;Maybe I&#39;ll make a thin abstraction layer along the way. Who knows...either way, I should take a more minimal approach.&lt;/p&gt;
&lt;p&gt;I might pursue this, I might not, but either way it&#39;s fun to think about.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Designing Data For Games, Part 3: Dialogue Revisted</title>
    <link href="https://blog.austinpocus.com/blog/designing-data-for-games-part-3-dialogue-revisted/" />
    <updated>2021-12-22T20:35:45Z</updated>
    <id>https://blog.austinpocus.com/blog/designing-data-for-games-part-3-dialogue-revisted/</id>
    <content type="html">&lt;p&gt;I&#39;m building out &lt;a href=&quot;https://github.com/ajpocus/make-conversation&quot;&gt;the &lt;code&gt;make-conversation&lt;/code&gt; project&lt;/a&gt; to create dialogue trees for &amp;quot;Escape from Valis&amp;quot;, generating a Lua data structure from a Javascript object. Here, I&#39;d like to get into the details of dialogue trees and what I&#39;ve run into so far.&lt;/p&gt;
&lt;p&gt;Last time, I came up with a data structure like this:&lt;/p&gt;
&lt;pre class=&quot;language-lua&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;elderDialogue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  start &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hi, I&#39;m Foo, Mr. Elder.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;My father was Mr. Elder. You can call me sir.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      polite &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Of course sir. Do you know where the secret cave is?&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- response can be a table as well as a simple string&lt;/span&gt;
          text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;You&#39;re a nice kid, here&#39;s the map. Not much of a secret, really.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          item &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;thisIsAnItemId&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- this should refer to a canonical item table&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          sayThanks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Thank you!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;You are very welcome, friendly stranger.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            ending &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- this option will end the conversation with this NPC&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          walkAway &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;[Walk away]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            ending &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- if you walk away there shouldn&#39;t be a response&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      rude &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;I could, but I&#39;ll call you Slappy!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Well, you won&#39;t get anything from me! Go away.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        ending &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This data structure, as I noted last time, is a bit repetitive, needs data encapsulation (when there&#39;s an item), and so on.&lt;/p&gt;
&lt;p&gt;The biggest issue is the nesting. I&#39;d like to define types, using Typescript -- here I&#39;ll use a pseudo-Typescript style so I don&#39;t have to refer to a manual while I write.&lt;/p&gt;
&lt;p&gt;So what exactly is a &lt;code&gt;DialogueTree&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;DialogueTree&lt;/code&gt; should have an NPC identifier as the key, and an &lt;code&gt;Options&lt;/code&gt; object as the value.&lt;/p&gt;
&lt;p&gt;An NPC identifier will just be a slugified string, most likely the NPC name with hyphens in place of spaces, and the special characters escaped.&lt;/p&gt;
&lt;p&gt;What is an &lt;code&gt;Options&lt;/code&gt; object? Well, it might look like this:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;dialogueTree&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NPC_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;optionId&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      text&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      response&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Response
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;otherOptionId&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      text&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      response&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Response
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What is a &lt;code&gt;Response&lt;/code&gt; exactly? Maybe this:&lt;/p&gt;
&lt;pre class=&quot;language-typescript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  responseType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ResponseType&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  text&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  data&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  options&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Options
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we have a recursive data structure (which is what I&#39;d expect). React is conducive to recursive structures, sort of. So far, I have code that uses a &lt;code&gt;keys&lt;/code&gt; property in the React component to track how to get down to that particular option from the root state object (the &lt;code&gt;DialogueTree&lt;/code&gt; type we defined).&lt;/p&gt;
&lt;p&gt;What is a &lt;code&gt;ResponseType&lt;/code&gt;? That will be defined as an enum of sorts, a union of types in Typescript, that will declare constants that can be used to process the response object in the Lua code.&lt;/p&gt;
&lt;p&gt;From here, I think I have a better idea of where I&#39;m headed. I&#39;m going to start by converting my current code to Typescript, and start defining these types formally. Back to it!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Designing Data for Games, Part 2</title>
    <link href="https://blog.austinpocus.com/blog/designing-data-for-games-part-2/" />
    <updated>2021-12-20T21:41:25Z</updated>
    <id>https://blog.austinpocus.com/blog/designing-data-for-games-part-2/</id>
    <content type="html">&lt;p&gt;In &lt;a href=&quot;https://blog.austinpocus.com/blog/designing-data-for-games&quot; title=&quot;Part 1 of this blog series&quot;&gt;part 1 of this series&lt;/a&gt;, I wrote about a data structure for dialogue trees. Here, I&#39;d like to finalize that structure and discuss a data structure for RPG quests.&lt;/p&gt;
&lt;p&gt;First, some quest music:&lt;/p&gt;
&lt;div id=&quot;wf9Hh6pu78I&quot; class=&quot;eleventy-plugin-youtube-embed&quot; style=&quot;position:relative;width:100%;padding-top: 56.25%;&quot;&gt;&lt;iframe style=&quot;position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;&quot; width=&quot;100%&quot; height=&quot;100%&quot; frameborder=&quot;0&quot; title=&quot;Embedded YouTube video&quot; src=&quot;https://www.youtube-nocookie.com/embed/wf9Hh6pu78I&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;I couldn&#39;t resist. I regret nothing!&lt;/p&gt;
&lt;p&gt;Anyway, in the last post, I thought out a data structure for dialogue trees, and wrote out my thoughts as they came. I ended up with a relatively simple tree structure in a Lua table, where each entry is an option for what the player can &amp;quot;say&amp;quot; which contains responses. These options can lead to other options, and can include parameters for effects on the conversation.&lt;/p&gt;
&lt;p&gt;Here, I&#39;d like to think aloud about data for quests.&lt;/p&gt;
&lt;p&gt;For those not familiar with role-playing games: a quest is like a &amp;quot;mission&amp;quot; in the Grand Theft Auto games, a goal of some kind. You&#39;re given something to do in the game, and if you fulfill that goal, you&#39;re given a reward or the story progresses in some way.&lt;/p&gt;
&lt;p&gt;Often the state of the world will change if you complete a quest. For example, if you go to the past and steal the secret weapon from King Fuddlepants, he won&#39;t be able to use it if you challenge him in the future. That&#39;s a bit of a contrived example, but you get the idea.&lt;/p&gt;
&lt;p&gt;Quests often involve common components, which I plan on using to design quests. For example, most people absolutely despise &amp;quot;escort&amp;quot; quests, where you help a non-player character (NPC) get to a destination, usually someone who can&#39;t help you in battle. The worst part about the NPC escort quests is usually the movement AI...but I digress.&lt;/p&gt;
&lt;p&gt;Another common aspect of quests is items. You might be asked to retrieve the Legendary Sword of Power from the Bog of the Dead and return it to the Duke of Dingleberry.&lt;/p&gt;
&lt;p&gt;Quests also involve choices in some games. You may choose not to give the sword to the Duke, instead keeping it for yourself, and he might send soliders after you to retrieve it.&lt;/p&gt;
&lt;p&gt;Finally, quests have a reward of some kind. Either they give you an item, boost your stats, or progress the story in some way. Sometimes you get no reward, if the quest-giver is miserly.&lt;/p&gt;
&lt;p&gt;This gives us a decent structure for quests. We can use the &amp;quot;quest components&amp;quot; or types, like &lt;code&gt;FetchItem&lt;/code&gt;, &lt;code&gt;Escort&lt;/code&gt;, &lt;code&gt;DefeatEnemy&lt;/code&gt;, etc. to handle different quest types with common code. These components should lend themselves to combination. As in, you should be able to say &amp;quot;defeat this enemy, and escort the Village Elder back to the castle&amp;quot;, making multipart quests.&lt;/p&gt;
&lt;p&gt;So what will the data look like?&lt;/p&gt;
&lt;p&gt;First, a quest should have a type, and a data field:&lt;/p&gt;
&lt;pre class=&quot;language-lua&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;myQuest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  questType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Constants&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;QuestTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FETCH_ITEM&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    item &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Constants&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ItemTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LEGENDARY_SWORD
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see here I&#39;m referring to a seemingly global &lt;code&gt;Constants&lt;/code&gt; variable, which should contain a lookup table of all the item and quest types in the game. It doesn&#39;t have to be global at all -- it can be imported as a module.&lt;/p&gt;
&lt;p&gt;The purpose of the &lt;code&gt;questType&lt;/code&gt; field is what you might expect, to make it easier to split up code between types. The value should be a bit field, so I&#39;ll be able to combine different quest types with ease using the bitwise OR operator (the pipe character, &lt;code&gt;|&lt;/code&gt;, in Lua and most languages). This will also let me check the presence of a given quest type on a quest with bitwise AND (the ampersand, &lt;code&gt;&amp;amp;&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The data field bothers me because it&#39;s sort of a catch-all object and it&#39;s badly named. Maybe it should be &amp;quot;details&amp;quot;? I&#39;ll have to think on this.&lt;/p&gt;
&lt;p&gt;I&#39;m starting to get further along in my thoughts than I&#39;d like -- I need to embody some of these thoughts in code. I may write a &amp;quot;part 3&amp;quot; to this series, in the coming week, but for now I&#39;m going to get &amp;quot;Escape from Valis&amp;quot; ready to open-source (I want to code in the open). Tune in next time!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Designing Data for Games</title>
    <link href="https://blog.austinpocus.com/blog/designing-data-for-games/" />
    <updated>2021-12-20T01:15:04Z</updated>
    <id>https://blog.austinpocus.com/blog/designing-data-for-games/</id>
    <content type="html">&lt;p&gt;Designing data structures is one of the most important things we do as software developers -- it informs the structure and cadence of the code that follows.&lt;/p&gt;
&lt;p&gt;Here, I&#39;d like to think aloud about data structures for character dialogue and quests in the &lt;a href=&quot;https://blog.austinpocus.com/blog/i-wanna-know-what-love-is&quot; title=&quot;The first post I wrote about Lua and love2d&quot;&gt;game I&#39;m making&lt;/a&gt;. Let&#39;s start with dialogue, since I believe it&#39;ll be a simpler data structure.&lt;/p&gt;
&lt;p&gt;Dialogue is an interesting aspect of some games. Sometimes it&#39;s very straightforward: you ask and the character, the NPC (non-player character) answers. They say the same thing every single time and don&#39;t react to anything.&lt;/p&gt;
&lt;p&gt;If this were the simple case, I wouldn&#39;t need a data structure, except maybe a simple table to associate characters with their lines. If you know me, you know I&#39;m not going for the simple case.&lt;/p&gt;
&lt;p&gt;I like games like &lt;em&gt;Star Wars: Knights of the Old Republic&lt;/em&gt; or &lt;em&gt;Fallout 4&lt;/em&gt;, where you&#39;re given many options regarding what you can say to the character, and they in turn respond to what you choose. This can lead to other options, it can trigger a quest or give you an item, it can affect how much the NPC likes you (or not), and options may even go away when you choose one!&lt;/p&gt;
&lt;p&gt;The way I&#39;m thinking of dialogue, it can be represented as a tree of sorts. Of course, Lua only has one data structure, the table, which serves as array, hash map, and object all in one. I&#39;m picturing something like this so far (syntax is Lua):&lt;/p&gt;
&lt;pre class=&quot;language-lua&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;dialogueTree &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstOptionId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;This is the first option that will be displayed to the player.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Well that&#39;s neat!&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  secondOptionId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;This is the second dialogue choice, displayed alongside the first.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Yep, I&#39;m getting the picture.&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If there are options shown after you choose the first option, those should be nested under the first like you&#39;d probably expect (we&#39;ll use a real example this time):&lt;/p&gt;
&lt;pre class=&quot;language-lua&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;elderDialogue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  start &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hi, I&#39;m Foo, Mr. Elder.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;My father was Mr. Elder. You can call me sir.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      polite &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Of course sir. Do you know where the secret cave is?&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- response can be a table as well as a simple string&lt;/span&gt;
          text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;You&#39;re a nice kid, here&#39;s the map. Not much of a secret, really.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          item &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;thisIsAnItemId&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- this should refer to a canonical item table&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          sayThanks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Thank you!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;You are very welcome, friendly stranger.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            ending &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- this option will end the conversation with this NPC&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          walkAway &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;[Walk away]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            ending &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- if you walk away there shouldn&#39;t be a response&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      rude &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        optionText &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;I could, but I&#39;ll call you Slappy!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Well, you won&#39;t get anything from me! Go away.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        ending &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see how this is starting to evolve. There are a few potential issues with this.&lt;/p&gt;
&lt;p&gt;First, there should always be a &amp;quot;[walk away]&amp;quot; option, at least in this game. That could change later -- maybe you shouldn&#39;t be able to end a dialogue with your captor, if you&#39;ve been imprisoned or something, but I&#39;m not worried about that right this minute. It would certainly make the tree smaller and simpler, which would be nice, but let&#39;s bear in mind this isn&#39;t made for human consumption! This data will be &lt;a href=&quot;https://blog.austinpocus.com/blog/lua-as-data&quot; title=&quot;A post about translating Javascript objects into Lua tables&quot;&gt;generated by a web app&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That reminds me, we should be able to import as well as export from the web app! I should be able to pipe data back in, modify it, and get the result from the app. This is critical, otherwise I&#39;d have to input the dialogue tree every time or save it elsewhere, which is undesirable. I don&#39;t need a database for this app, or shouldn&#39;t yet.&lt;/p&gt;
&lt;p&gt;The other potential issue is the response structure: it could be a string or a table. This seems fine at first glance but requires either extreme caution at every point you plan to access the field, or a wrapper module that has a getter function for the response...and since this isn&#39;t made to be written or read by humans, it&#39;s not a huge deal to make it an object all the time, to make the code easier to deal with.&lt;/p&gt;
&lt;p&gt;This is getting long, I lost my pace, and the quest data structure will be even more complex, so I&#39;ll make a &amp;quot;Part 2&amp;quot; and link it here when it&#39;s done.&lt;/p&gt;
&lt;p&gt;[UPDATE: &lt;a href=&quot;https://blog.austinpocus.com/blog/designing-data-for-games-part-2&quot; title=&quot;Part 2 of this series&quot;&gt;Read part 2 here&lt;/a&gt;]&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Lua as Data</title>
    <link href="https://blog.austinpocus.com/blog/lua-as-data/" />
    <updated>2021-12-17T20:02:09Z</updated>
    <id>https://blog.austinpocus.com/blog/lua-as-data/</id>
    <content type="html">&lt;p&gt;I want to put a bunch of quest and dialogue data in the game I&#39;m working on, &lt;a href=&quot;https://blog.austinpocus.com/blog/i-wanna-know-what-love-is&quot; title=&quot;My previous post about love2d, Lua, and game development&quot;&gt;&amp;quot;Escape from Valis&amp;quot;&lt;/a&gt;, but I don&#39;t want to write it by hand. What if I could write a Lua data structure using a web app?&lt;/p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;/h2&gt;
&lt;p&gt;I&#39;m designing a game, &amp;quot;Escape from Valis&amp;quot;, and as an old-school RPG, it&#39;ll naturally include quests and dialogue. This would have to live in some sort of data structure...so how would I put this data in the system without writing it all myself?&lt;/p&gt;
&lt;h2 id=&quot;a-potential-solution&quot;&gt;A potential solution&lt;/h2&gt;
&lt;p&gt;The solution that comes to mind would be to write to a data structure using some application, which would have some sort of configuration interface, right? But, there&#39;s a catch.&lt;/p&gt;
&lt;p&gt;Lua isn&#39;t the best language for full-on application development. Sure, I could build an entire GUI in Lua with some of the libraries out there, but it&#39;s needlessly difficult.&lt;/p&gt;
&lt;p&gt;What if, instead, I could write a Lua data structure in a language better suited to app development? What if I used my Javascript skills, along with some sort of Lua translation tool, to create a data structure in a web app and write it to a &lt;code&gt;.lua&lt;/code&gt; file, much like &lt;a href=&quot;https://www.mapeditor.org/&quot; title=&quot;The Tiled map editor homepage&quot;&gt;Tiled&lt;/a&gt; does?&lt;/p&gt;
&lt;h2 id=&quot;the-plan&quot;&gt;The plan&lt;/h2&gt;
&lt;p&gt;This is entirely possible -- Lua lends itself well to data expression. The &amp;quot;table&amp;quot; data structure, Lua&#39;s only compound type, acts as a list, a dictionary, or an object (using &amp;quot;metatables&amp;quot;), all in one neat package.&lt;/p&gt;
&lt;p&gt;The format is actually quite similar to JSON, and I discovered through a bit of experimentation I don&#39;t even need a &lt;a href=&quot;https://fengari.io/&quot; title=&quot;lua.vm.js, the Lua virtual machine written and executed in the browser&quot;&gt;Javascript-based Lua VM&lt;/a&gt;! I wrote a simple regex or three that replace key characters in the &lt;code&gt;JSON.stringify&lt;/code&gt; output, namely the &amp;quot;:&amp;quot; character and the square array brackets, like this:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;luaData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&quot;(&#92;w+)&quot;:&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$1 =&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&#92;[&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&#92;]&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&#39;re not up on your regexes, the first one simply captures the value in double quotes, and unquotes it, replacing the &amp;quot;:&amp;quot; with a &amp;quot;=&amp;quot;. The other two replace the square brackets. Just like that, we have valid Lua!&lt;/p&gt;
&lt;p&gt;From there, you can write the contents to a file and trigger a download:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Code modified from https://stackoverflow.com/questions/13405129/javascript-create-and-save-file&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Licensed under CC-BY-SA 4.0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// where luaState is an object&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fileContents &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;luaState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&quot;(&#92;w+)&quot;:&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;$1 =&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// replace quoted properties with bare identifiers and an equals sign&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&#92;[&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// replace square brackets in these two regexes&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;&#92;]&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-flags&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; file &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Blob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;fileContents&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;text/plain&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// create a file object&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; filename &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;quests.lua&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;navigator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;msSaveOrOpenBlob&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// IE10+&lt;/span&gt;
  window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;navigator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;msSaveOrOpenBlob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; filename&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Others&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// creating a virtual &quot;link&quot; to download&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createObjectURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;download &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filename&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// this is what sets up the actual file download&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// trigger the download&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;revokeObjectURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// setTimeout(..., 0) will run on the next tick, ensuring the download runs&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From here, I&#39;ll probably have to cover some edge cases. Now that I look at the code, &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; would have to become &lt;code&gt;nil&lt;/code&gt; to be valid Lua (but that&#39;s not a problem in this case). Next, I have to create a dead simple UI using React and Next.js, my weapons of choice. This UI should let me add primitive values to compound objects, nested if I choose.&lt;/p&gt;
&lt;p&gt;I need to design a data structure first, though. My next post will most likely cover this in detail.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>I Wanna Know What LOVE Is</title>
    <link href="https://blog.austinpocus.com/blog/i-wanna-know-what-love-is/" />
    <updated>2021-12-14T04:51:20Z</updated>
    <id>https://blog.austinpocus.com/blog/i-wanna-know-what-love-is/</id>
    <content type="html">&lt;p&gt;In this post, I want to tell you about the LÖVE framework, and how I fell in actual love with a language called Lua.&lt;/p&gt;
&lt;p&gt;Fair warning: this post is heavy with puns on song titles, rambling technical esoterica, and a slight dose of lunacy.&lt;/p&gt;
&lt;h2 id=&quot;what-is-loeve&quot;&gt;What is LÖVE?&lt;/h2&gt;
&lt;p&gt;For the uninitiated, LÖVE (or &lt;a href=&quot;https://love2d.org&quot;&gt;love2d&lt;/a&gt; as I&#39;ll call it from here) is an excellent little Lua framework for making games. It&#39;s not an engine so much as a set of building blocks.&lt;/p&gt;
&lt;p&gt;This has led me down an interesting path regarding &lt;a href=&quot;https://blog.austinpocus.com/tags/adventure-kit&quot;&gt;Adventure Kit&lt;/a&gt;. Really, it could be built entirely on top of love2d, a set of modules that click together nicely and help you build an RPG using love2d under the hood.&lt;/p&gt;
&lt;p&gt;I could even potentially wrap or monkey patch the love2d APIs, to make them nicer to work with -- Lua, the lingua franca of the love2d world, is a very monkey-patchable language.&lt;/p&gt;
&lt;h2 id=&quot;whole-lotta-loeve&quot;&gt;Whole Lotta LÖVE&lt;/h2&gt;
&lt;p&gt;I&#39;d like to take a brief moment to talk about how awesome Lua is. It&#39;s this incredible little language, interpreted by the default implementation but also available in a compiled variety called &lt;a href=&quot;https://luajit.org/luajit.html&quot;&gt;LuaJIT&lt;/a&gt;. It&#39;s &lt;em&gt;fast&lt;/em&gt; and &lt;em&gt;small&lt;/em&gt; -- the whole LuaJIT VM weighs in at a featherweight &lt;strong&gt;115KB&lt;/strong&gt;. Stick that in your CPU pipeline and smoke it!&lt;/p&gt;
&lt;p&gt;Its influences can be felt, if you&#39;ve worked with a variety of languages. You can see the prototype-based OOP that&#39;s reminiscent of Javascript, for one (though Lua is a bit older, probably taking a cue from the Self language).&lt;/p&gt;
&lt;p&gt;It has some functional components, too! Functions are first-class objects, like most modern languages. Unlike some modern languages, though, it considers &lt;code&gt;goto&lt;/code&gt; not necessarily harmful, but &lt;em&gt;useful&lt;/em&gt;. (The book even gives a working example of a state machine using &lt;code&gt;goto&lt;/code&gt;!)&lt;/p&gt;
&lt;p&gt;The coolest thing about Lua is its incredible strength and speed for its size. It&#39;s completely disproportionate...it&#39;s like the Ant Man of programming languages. It&#39;s highly reminiscent of C (which makes sense because that was part of Lua&#39;s origins -- C is the language it was implemented in and whose APIs it borrowed).&lt;/p&gt;
&lt;p&gt;The Lua APIs are so simple, the language so intuitive, that I was able to pick it up &lt;em&gt;without reading a guide or book first&lt;/em&gt;. The language is &lt;em&gt;that good&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Instead of the laborious process I took when I most recently learned say, Rust, or C++, Lua was immediately apparent. It&#39;s clear what the code means, I simply read the example code, mimicked it, googled things as they came up, and I was away and writing code at a good clip within a couple of days.&lt;/p&gt;
&lt;p&gt;(Don&#39;t worry, I started reading the &lt;a href=&quot;https://www.lua.org/pil/contents.html&quot;&gt;official book&lt;/a&gt; in earnest after I spent a week or two writing Python-esque Lua.)&lt;/p&gt;
&lt;p&gt;It&#39;s a testament to the quality of the language, the readability and simplicity of most of what you&#39;d do in Lua. It speaks volumes that such a language can be picked up easily.&lt;/p&gt;
&lt;p&gt;I mean, you could pick up a simple but less powerful language quickly too (e.g. Markdown, yes it&#39;s a language) but what makes this amazing is that Lua is incredibly powerful for all this simplicity in its construction.&lt;/p&gt;
&lt;p&gt;But I digress.&lt;/p&gt;
&lt;h2 id=&quot;the-power-of-loeve&quot;&gt;The Power of LÖVE&lt;/h2&gt;
&lt;p&gt;The structure and cadence and flow of Lua weighs heavily in the implementation of love2d. You can see it in the module structure of the library, the APIs, the ecosystem, and how all of these feel when you&#39;re using them.&lt;/p&gt;
&lt;p&gt;(I realize I&#39;m using some intuitive, touchy-feely terms here to describe very deterministic and non-magical systems. But I feel expressive, and sometimes these things &lt;em&gt;are&lt;/em&gt; based in intuition. How it feels to use a system makes a difference.)&lt;/p&gt;
&lt;p&gt;The most striking thing about love2d is the sheer number of libraries that build on top of it. It&#39;s something I&#39;ve seen when using tools like jQuery, React, etc. in Javascript, but not quite to this degree.&lt;/p&gt;
&lt;p&gt;To get an idea of what I&#39;m talking about, check &lt;a href=&quot;https://github.com/love2d-community/awesome-love2d&quot;&gt;the awesome-love2d repo on Github&lt;/a&gt;. There, you&#39;ll see people have built libraries to deal with physics, audio, graphical effects, state management, GUIs...I can&#39;t even list all of the things the community has built on top of it!&lt;/p&gt;
&lt;p&gt;But I&#39;ve been working on Adventure Kit, right? You may be wondering:&lt;/p&gt;
&lt;h2 id=&quot;whats-loeve-got-to-do-with-it&quot;&gt;What&#39;s LÖVE got to do with it?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;(Got to do with it?)&lt;/em&gt; Ahem.&lt;/p&gt;
&lt;p&gt;It was suggested to me that, in order to build Adventure Kit, I should first build an actual game that resembles the style I&#39;m trying to target.&lt;/p&gt;
&lt;p&gt;As it turns out, this is an &lt;em&gt;excellent&lt;/em&gt; method for designing a tool. Who knew.&lt;/p&gt;
&lt;p&gt;I&#39;m already coming up with module ideas, as I progress. I have sprite loading, basic movement, physics, tile map loading using the &lt;a href=&quot;https://www.mapeditor.org/&quot;&gt;Tiled&lt;/a&gt; map format, and a few other odds and ends, like a &amp;quot;run&amp;quot; button I implemented during some testing frustration -- &amp;quot;necessity is the mother of invention&amp;quot;?&lt;/p&gt;
&lt;p&gt;But my proudest creation so far is a spritesheet loader that takes margins and padding between sprites into account. This is necessary due to the nature of OpenGL textures, as I understand it -- they &amp;quot;bleed&amp;quot;, such that the sprite next to your supposed boundaries will &amp;quot;leak&amp;quot; onto the screen by 1 pixel or so. The solution was to add transparent pixels as padding, so that the first sprite will be rendered in the correct position, the next tile will overlay the padding pixels, and so on.&lt;/p&gt;
&lt;h2 id=&quot;all-you-need-is-loeve&quot;&gt;All You Need is LÖVE&lt;/h2&gt;
&lt;p&gt;From here, I&#39;ll be continuing development on the game, which I&#39;ve tentatively named &amp;quot;Escape from Valis&amp;quot; (inspired by the Philip K. Dick book of the same name). The gameplay I&#39;ve planned so far involves plenty of 2D pixelated Fallout-style dystopian action, set in a fictionalized mega-city.&lt;/p&gt;
&lt;p&gt;I haven&#39;t gotten to the RPG-related parts of the development cycle, but the nice thing about game dev and the love2d framework in particular is: you kind of have to iterate quickly and keep the game playable, lest you fall into a pit of unrunnable code riddled with errors.&lt;/p&gt;
&lt;p&gt;It&#39;s getting late, or early, depending on your perception of time. Tune in next time, same bat-channel!&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://blog.austinpocus.com/blog/i-wanna-know-what-love-is/pzxDGUjV4I-480.avif 480w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://blog.austinpocus.com/blog/i-wanna-know-what-love-is/pzxDGUjV4I-480.webp 480w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://blog.austinpocus.com/blog/i-wanna-know-what-love-is/pzxDGUjV4I-480.gif&quot; alt=&quot;Batman doing the &amp;quot;batusi&amp;quot;&quot; width=&quot;480&quot; height=&quot;270&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Dev Journals 10: Yukon Vengeance</title>
    <link href="https://blog.austinpocus.com/blog/dev-journals-10-yukon-vengeance/" />
    <updated>2021-08-30T18:16:09Z</updated>
    <id>https://blog.austinpocus.com/blog/dev-journals-10-yukon-vengeance/</id>
    <content type="html">&lt;p&gt;The inspiration for today&#39;s title comes from a movie with the same name, but it also refers to a very real problem: I&#39;m kind of in the wilderness here.&lt;/p&gt;
&lt;p&gt;The wilderness being Typescript, but also Redux, and most of all, the type of UI I&#39;m trying to build.&lt;/p&gt;
&lt;p&gt;Adventure Kit, or at least &lt;code&gt;make-a-quest&lt;/code&gt; specifically, is all about visual programming at its core. This requires the design of an intuitive interface, naturally.&lt;/p&gt;
&lt;p&gt;Problem is, I haven&#39;t really done much actual design work. Sure, I work on the frontend constantly! But I&#39;m working from the designs of others.&lt;/p&gt;
&lt;p&gt;Generally I started my career more on the backend, and have been working toward more of a full-stack and frontend-heavy role, as that&#39;s where I saw the work going (look at all the &amp;quot;serverless&amp;quot; models now -- still needs backend work, but the focus is definitely on the frontend).&lt;/p&gt;
&lt;p&gt;All this is to say, I feel like I&#39;m out of my depth sometimes when it comes to designing interfaces. The problem can be solved, still...it just requires a lot of persistence.&lt;/p&gt;
&lt;p&gt;I&#39;ll have to go through a few bad interfaces to get to the good ones, and that&#39;s ok. Likewise, my Typescript probably won&#39;t be idiomatic or the &amp;quot;Right Way&amp;quot; to do things, but it&#39;ll improve over time.&lt;/p&gt;
&lt;p&gt;Typescript in particular is easier to solve than the design issue. Design takes practice, full stop. But Typescript? Along with regular coding, I just need to read the docs. Or, as the greybeards say, &amp;quot;RTFM&amp;quot; (Read the &amp;quot;Friendly&amp;quot; Manual).&lt;/p&gt;
&lt;p&gt;Anyway, if the interface works, even in brutalist form, if my code works, even if it&#39;s a bit ugly, &lt;em&gt;that&#39;s okay&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;After all, I&#39;m learning a few things here, and all at once. And I&#39;m writing it &lt;a href=&quot;https://github.com/pocuslabs/make-a-quest&quot;&gt;in the open&lt;/a&gt;! (Check the latest feature branch for my current code, literally the last code I wrote.)&lt;/p&gt;
&lt;p&gt;Writing in the open is deserving of a post all its own. It&#39;s changing the way I code! I second-guess things that I would otherwise do without hesitation, like &amp;quot;should I really do [x] to the code?&amp;quot;. Or I&#39;ll wonder if I should work on this or that particular feature, and so on. Plus, I get a little self-conscious about the code, to be honest.&lt;/p&gt;
&lt;p&gt;But forget all that -- I need to work on what needs to be done! And it&#39;s not like I&#39;m self-conscious about what I write here, so why should I worry about my code? It&#39;s a work-in-progress!&lt;/p&gt;
&lt;p&gt;So next up:&lt;/p&gt;
&lt;p&gt;First, I need to get quest creation going, allowing the user to build quests using common components.&lt;/p&gt;
&lt;p&gt;These components, which I&#39;ll write about in another post, basically boil down to quest &amp;quot;parts&amp;quot;, like &amp;quot;talk to the villager&amp;quot;, &amp;quot;fetch the item&amp;quot;, &amp;quot;destroy the monster&amp;quot;, and so on.&lt;/p&gt;
&lt;p&gt;At first, you&#39;ll just build simple quests out of these components, combining them to form parts of a story, writing dialogue and creating special items and dangerous enemies for the player to interact with.&lt;/p&gt;
&lt;p&gt;Of course, eventually, I want to get to &lt;a href=&quot;https://blog.austinpocus.com/blog/the-new-style&quot;&gt;more macro-level management of in-game resources, including players&lt;/a&gt;. But that&#39;s something that&#39;ll take a long, long time to develop. I need to first develop a very small part of a part of what will eventually be the macro-management interface.&lt;/p&gt;
&lt;p&gt;At some point after the quest management interface is at a good place, I&#39;ll probably start prototyping more of the macro stuff...but that&#39;s later.&lt;/p&gt;
&lt;p&gt;I should get back to it. &#39;Til then, I leave you with the Yukon Song from Calvin and Hobbes. Yukon ho!&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://blog.austinpocus.com/blog/dev-journals-10-yukon-vengeance/E6yeoKoA7h-1668.avif 1668w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://blog.austinpocus.com/blog/dev-journals-10-yukon-vengeance/E6yeoKoA7h-1668.webp 1668w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://blog.austinpocus.com/blog/dev-journals-10-yukon-vengeance/E6yeoKoA7h-1668.jpeg&quot; alt=&quot;&amp;quot;The Yukon Song&amp;quot; from Calvin and Hobbes, by Bill Watterston&quot; width=&quot;1668&quot; height=&quot;1668&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>The New Style</title>
    <link href="https://blog.austinpocus.com/blog/the-new-style/" />
    <updated>2021-08-28T19:37:18Z</updated>
    <id>https://blog.austinpocus.com/blog/the-new-style/</id>
    <content type="html">&lt;p&gt;Adventure Kit needs something to stand out. Now, I have something: macro party management. But what is it? Read on!&lt;/p&gt;
&lt;p&gt;Macro party management takes the traditional RPG concept, and flips it on its head.&lt;/p&gt;
&lt;p&gt;See, I was going to make a game creation toolkit where you make a traditional game, full stop. You might be able to play around with the party configuration, to make games like Pokemon. You might be able to script quests and pixel-level &amp;quot;cutscenes&amp;quot; ala Final Fantasy VI.&lt;/p&gt;
&lt;p&gt;But beyond that, the result would&#39;ve been a pretty standard SNES-level RPG.&lt;/p&gt;
&lt;p&gt;Instead...what if there were multiple characters or parties of characters, whose behavior you could manage at a high level? Where you can tell the fighter characters to go one place and make physical attacks, and you can tell the mage character to hang back and heal the others, but their granular behavior is automated?&lt;/p&gt;
&lt;p&gt;Imagine you&#39;re the ruler of a kingdom. The queen, king, emperor, grand pubaa, etc. You seek a mystical item, or to destroy your enemy&#39;s nation -- the details of the story will be provided by the game creator.&lt;/p&gt;
&lt;p&gt;What matters is, there&#39;s an overarching purpose to the story, the &amp;quot;main quest&amp;quot;. There should be subquests the user defines, some depending on others, and some being side quests entirely...this has been defined in previous dev journals.&lt;/p&gt;
&lt;p&gt;You should be able to send different parties on different quests. You should be able to manage resources that the party has. You should be able to define the user&#39;s behavior...you get the idea.&lt;/p&gt;
&lt;p&gt;More than just a simple resource management game, this could be an entire feudal system in a game. You can have lords below the queen or king, dukes, serfs, or different governmental structures...maybe there&#39;s a peasant revolution! Or someone ascends to the throne with an iron fist, and robs the treasury to wage war!&lt;/p&gt;
&lt;p&gt;It would be especially cool, if players could start out as an individual fighter and work their way up to being ruler of a kingdom!&lt;/p&gt;
&lt;p&gt;This could only happen if there&#39;s multiplayer, along with ascension (or descension) of ranks...which gets into a whole web of complexity.&lt;/p&gt;
&lt;p&gt;Even so, it&#39;s really fun to think about how multiplayer may work in this environment...that&#39;s another post, though.&lt;/p&gt;
&lt;p&gt;What&#39;s happening next is getting into more of the generation of quests, along with management of resources. I&#39;m thinking about splitting up the management of certain resources like parties, gold, items, quests, etc. and making it so you can automate away management of certain aspects...still a lot to think about here.&lt;/p&gt;
&lt;p&gt;Mainly, I wanted to record this idea after talking with my friend &lt;a href=&quot;https://twitter.com/duilen&quot;&gt;Dane&lt;/a&gt;, and wanted to develop on it a bit and get my thoughts sorted. I&#39;ll probably have more to write on the topic later -- for now, check out Dane&#39;s latest project, &lt;a href=&quot;https://raster.ly&quot;&gt;Rasterly&lt;/a&gt;!&lt;/p&gt;
</content>
  </entry>
</feed>