<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">

<channel>
<title>DistractedMOSFET's Blog</title>
<link>https://mosfetarium.com/</link>
<description>DistractedMOFSET's Stuff</description>

<item>
<title>Noirmancer August Update: Visuals and Loot</title>
<link>https://mosfetarium.com/blog/noirmancer-august-update/</link>
<description>
<![CDATA[
<p>
<p>This a monthly development update for my mind-erasing stealth game <a href="https://store.steampowered.com/app/3674590/Noirmancer/?utm_source=nblog">Noirmancer</a>. I usually give some brief status on how development is going and ramble about some aspects of game dev I've been thinking about.</p>
<h2>STATUS UPDATE</h2>
<p>These past few weeks I've been going through this most recent level and dressing it up a bit and filling out the loot. Trying to generally get it towards a presentable state so that I can make a demo in the not too distant future. Fortunately, there's not really been any surprises in that. And has largely gone how I expected.</p>
<p><img src="/images/noirmancer_vindicate_aug_demo_wip.png" alt="A screenshot depicting a work-in-progress building" /></p>
<p>The ideal process for making a game would be making the whole thing in placeholder art first, but I can't deny that it does a lot for my motivation to see a level get to a presentable state. It feels a lot more real. I also kinda feel that presentation affects your feelings about a gameplay experience a lot. It can be hard to really test some games without the aesthetic captured to get the right vibes. Visuals aren't just for eye-candy either, they can be important for gameplay.</p>
<h2>VISUAL COMMUNICATION</h2>
<p><img src="/images/noirmancer_vindicate_lab_office.png" alt="A screenshot of a small lab office with a diagional square tile floor pattern" /></p>
<p>So like many stealth games since the release of Thief: The Dark Project, my game has some floors that you will make loud footsteps on. It's nice for creating some variation of danger in a space, as long as you don't overuse it. Another danger when using it is making sure it's obvious to the player that the floor they're about to step on is a loud surface. My game doesn't make use of a lot of textures, I'm trying to keep a quite simplistic moody art style where I don't feel that fits. It also happens to save me a bunch of time which is useful as a solo developer. This means lots of floors are just the material that I use everywhere, and therefore, meaningfully distinguishing between a hard surface and a soft surface isn't something I get for free. So I've decided to try building up some visual design language that the player can learn to recognize to help them out.</p>
<p>If you see some kind of diagonal detailing on a floor surface, that surface will almost certainly react to your footsteps in some notable way. Diagonal tiles are the obvious one. I'm not entirely settled on it yet, but I'm also trying out using these little tufts in carpeted areas to try to suggest some slightly worn down carpet fibers:</p>
<p><img src="/images/noirmancer_vindicate_cubicle_farm.png" alt="A screenshot of a small office cubicle farm area with a carpetted floor" /></p>
<p>The idea is to put these in anywhere where the surface changes to help the player identify what they're getting into.</p>
<h2>DESIGN RAMBLE</h2>
<p>Y'know, I imagine there's someone out there working an office job, staring at excel all day and hating spreadsheets, who loves video games and wishes they were making video games. Well, hypothetical person, I have some bad news: You may end up spreadsheeting anyway. Creative work is all about decision making, and you need some basis to make your decision otherwise you're just kinda thrashing around. And when that design involves numbers, that means accounting. And accounting means spread sheets.</p>
<p>I feel like the roll of spreadsheets in game design is a little unknown to most game players. So I'm gonna ramble about it.</p>
<details>
<summary>LOOT POPULATION, AKA: SPREADSHEETING</summary>
In my game one of the bread-and-butter mechanics is looting, specifically, stealing "intel". Each level has an intel goal you have to reach to finish it. Fairly standard stuff, inherited straight from Thief: The Dark Project. But that introduces new questions: how much intel you should add, and how much should the goal be? Some of this is partially answered in kinda obvious and intuitive ways: if you have large areas inside with no loot, that probably is gonna feel wrong, so make sure to fill up that space a bit. If it's particularly hard to get into an area, the player is gonna be expected to be rewarded so put some darn loot in there. But the goal number doesn't really have an immediate obvious answer, but I have a current theory I'm going by.
<p>Some loot in the game is simply expected. It's out in the open on the critical path, and there's minimal chance you'll miss it. So I list out all the intel in the level in a spreadsheet, and I mark whether or not I expect the player to find that intel, and all the expected intel is pooled into a base &quot;expected amount&quot;. This is the absolute floor for the loot goal, and now the question is how much of the non-expected stuff do I want to ask the player to find. 100% is probably the wrong choice in most games. You could pick a simple ratio like 50% or 70% of the optional stuff and move on. For now I'm doing something a little more complicated. Currently there's only really two &quot;sizes&quot; of intel in the game. Common &quot;&quot;&quot;trash&quot;&quot;&quot; loot that is worth 5 points, and &quot;big&quot; loot that is worth 25. Now, outside of &quot;expected&quot; big intel on the critical path, all the other big intel is behind some kind of optional challenge. Hard to find, requires finding some key, finding some way in, requires interpreting a clue. You get the idea. Now, depending on the ratio of optional big intel to optional trash intel and the target number you pick you will get slightly different gameplay experiences. You have to ask yourself what do you want the game to be like, what play-styles do you want to facilitate.</p>
<p>Personally, I like the idea that a player can do all the tough stuff or at the extreme other end they can be really thorough about the easy stuff. This makes intuitive sense to me. It's basically a soft difficulty system. If you find the game kinda hard, well you can focus on being thorough rather than figuring everything out and you'll probably reach the intel goal easily enough. But if you find combing over rooms for individual loose notebooks and business cards really boring, well then you can just focus on the tougher stuff.</p>
<p>This produces two equations, one is that the total of optional trash should be fairly equal to the total of optional big stuff, and the goal should be the expected total plus half the optional total. That half could either be all the trash or all the big stuff, or a mixture of the two. It doesn't matter. With that design decision made I've now made it much easier to think about whether or not a level has enough intel. Just do the accounting and check that the equations are balanced, and check that there aren't areas of the map that feel like they should have more stuff. If you add more trash you should probably add more stuff behind challenges, and vice versa.</p>
</details>
<h2>So what's next</h2>
<p>So, this level is finally broadly wrapping up. I'm sure I'll find some random stuff I want to change but it is a playable level. Next up I want to design out and build a short little tutorial, that also acts as the hook into this mission. In terms of working towards a first little public demo, here's what I'm thinking about:</p>
<ul>
<li>Make a short tutorial level</li>
<li>Make some semi-okay start screen (the current one is a black screen and two buttons, lmao)</li>
<li>I currently only use one set of NPC graphics, I'd really like to have another 2 before releasing the demo but it might be better to just swallow my pride</li>
<li>I feel like I'd like to replace/expand the vocal sounds I currently use for the NPCs, but I may just end up skipping that.</li>
<li>Make an ability menu that works with only the few abilities that'll be featured in the demo.</li>
<li>Any random changes to the level that I think will really make a difference, particularly based on some private playtesting.</li>
</ul>
<h2>Follow along</h2>
<p><a href="https://store.steampowered.com/app/3674590/Noirmancer/?utm_source=nblog">Wishlist the game on Steam</a>. You can follow this project via <a href="https://mosfetarium.com/blog/rss.xml">RSS</a> (<a href="https://ncase.me/rss/">Don't know RSS?</a>), or by following me on <a href="https://mastodon.gamedev.place/@distractedmosfet">Mastodon</a>. And of course feel free to contact me via <a href="https://mosfetarium.com/about/">email</a>, or Mastodon with any comments or questions.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">197819eb-ef22-5303-53c0-6fe637b5e5e9</guid>
<pubDate>Tue, 26 Aug 2025 00:00:00 +0000</pubDate>
</item>
<item>
<title>Noirmancer July update: Progress, but hard-earned</title>
<link>https://mosfetarium.com/blog/noirmancer-july-update/</link>
<description>
<![CDATA[
<p>
<p>LAST TIME ON NOIRMANCER DEV BLOG:</p>
<blockquote>
<p>I'm still on pace to hopefully have a demo out in late July or early August.</p>
</blockquote>
<p>Uhhhh, yeah that ain't happening.</p>
<p><img src="/images/noirmancer_vindicate_wip_chalkboard.png" alt="A work-in-progress screenshot for noirmancer depicting some chalkboards covered in photos and scribbled writings" /></p>
<p>This a monthly development update for my mind-erasing stealth game <a href="https://store.steampowered.com/app/3674590/Noirmancer/?utm_source=nblog">Noirmancer</a>. I've decided to not be precious and show you some screenshots and clips of areas that are very unfinished, so please take the opportunity to smugly judge as much as possible.</p>
<h2>STATUS UPDATE</h2>
<p>So I spent the time since the last post working on this new level. All the rooms in the level are blocked out and have their distinct bits of gameplay implemented although I still need to fill most of them with actual intel (loot), that's not the hard part though. All the level's objectives are rigged up. While most of the level is still greybox and underdecorated, I have started working a bit on the aesthetics of the exterior:</p>
<p><img src="/images/noirmancer_vindicate_wip_ediface.png" alt="A screenshot depicting a work-in-progress building" /></p>
<p>I got to implement a bunch of fun little ideas for the level, including the unique objects mentioned in the last blogpost. One idea that I had thought of a while ago and wanted to incorporate into the levels at some point was the ability to escape a space via turning to mist and getting sucked up an extraction fan:</p>
<video width="427" height="240" autoplay loop>
    <source src="/videos/noirmancer_mist_through_fan.webm" type="video/webm">
</video>
<p>As with every month, the game's repertoire of pre-built gameplay components has increased. So I end another month with a more fleshed out game than I started.</p>
<p>But, I'm behind where I wanted to be. Why? When I left off last time I was still ideating about gameplay ideas for different parts of the level and that took me longer than I hoped, so that was one part.</p>
<p>Last time I talked about making some unique objects with unique effects related to the level's story as a way to give this level some unique toys when it otherwise lacks many of the game's supernatural powers. But the objects I chose affect NPC behaviour and so it required a fair bit of programming to get them in, which caused a bit of a slow down.</p>
<p>And third was just I was fairly unproductive. This was surprising to me because I had been really productive in the 2 months before launching the game's steam page and my expectations were for that to continue. But no, I really dragged my heels on a lot of this. Perhaps part of it was a winter slump (I'm in New Zealand) but I suspect a big part of it is my personal tendency to hesitate in the face of uncertainty. This was really annoying because again, it wasn't a problem I encountered in the 2 months before the Steam page launch, and I wasn't expecting it to be a problem during this phase of development either. This is something I need to be stricter on myself about; just bloody do it. It's pretty rare that I actually find a problem that turns into a real quagmire. Even my design gaps tend to be resolved quickly when I commit to sitting down and not getting up until I have a solution.</p>
<p>This past two weeks has been fairly productive again in part because I went back to my old faithful technique of self-manipulation: the <a href="https://en.wikipedia.org/wiki/Pomodoro_Technique">pomodoro technique</a>. It just really clicks with my brain; &quot;Clock says I gotta stay working!&quot;. I started using this technique a number of years ago at a job and I've always found it effective. But for whatever reason I've been bad about employing it in my own endeavours? That seems... stupid? I guess in summary, I am a stupid baby.</p>
<h2>DESIGN RAMBLE</h2>
<p>For this post's design ramble I talk a bit about ability design. If you just wanted to know how the game was going, feel free to skip it. Or, click below if you too enjoy overthinking things:</p>
<details>
<summary>The Square Peg Problem</summary>
A big part of the gameplay identity of Noirmancer is your repertoire of supernatural abilities and therefore a core design challenge for this project is trying to make those abilities interesting. An observation I have is that it's very easy to encounter what I'll call "the square peg problem", in reference to the famous type of children's toy about fitting wooden shapes into specific holes.
<p>A Square Peg Problem is when a mechanic in a game is:</p>
<ul>
<li>Only intended to be used in specific and narrow circumstances, often only when the designer decided to even add the thing it interacts with.</li>
<li>When to use it is obvious; see square hole, insert square peg.</li>
</ul>
<p>The reason I regard this as a problem is that I think there's no mechanical interest there. You simply walk from one room to another, see the obstacle in the new room, use the obstacle-defeating mechanic, and move to the next room. Sort of a glorified &quot;Simon Says&quot;.</p>
<p>The first bullet-point is somewhat easy to address. You can add nuances to abilities that make them useful in multiple contexts. Ideally try to give it a use that applies to the game's core gameplay rather than simply applying to situations where the designer has put some down some specific object. In an FPS something that interacts with enemies is probably frequently going to be usable, compared to something that only interacts with say, pits of lava. Unless pits of lava are roughly as common in your game as enemies.</p>
<p>The second bullet-point is a little trickier. I think one of the most common things for a game designer to do is to add a resource-system to try to make you think about whether or not you should use that ability. This often works but the rest of the design needs to support that. Particularly you need to ask what happens when the player simply doesn't have that resource and <em>needs</em> it. A resource system isn't just a feature for a designer to add, it's a commitment that the designer has to manage.</p>
<p>I already made the choice several months ago that generally I don't think resource-limitations are the way I want this game to work; I want the player to use the abilities, and to feel encouraged to use them. Resource limits are discouragement. So currently, only one ability in the game is resource limited, and that ability is designed to be completely optional.</p>
<p>Instead, I've been coming back to this idea of Opportunity Identification; breaking up the square-peg gameplay arc by obscuring the square-hole. This isn't the right call for every game or perhaps even most games, but I think it works for a Thief-like. The gameplay is already about skulking around an area you are entirely unfamiliar with and searching for loot. It's very natural then to make opportunities to use your abilities something that you sometimes need to search for. Using the ability becomes the pay-off for being thorough.</p>
<p>This time, a specific ability I wanted to reform a bit is this ability you have to throw a little force-field on the ground. This ability was inspired by Thief's &quot;Moss arrows&quot; that allowed you to soften the ground at certain locations so that you did not generate as much noise when walking over it. And that is one of the ways you can use this ability too. But it also acts as a general floor-hazard evader. The game has pressure plates and this ability evades them. That's sort of neat in that it allows the player to live out some infiltration fantasies. I can create rooms that are meant to feel very secure and dangerous, such as via alarmed floors, but for the player, that's actually a fairly easy problem to solve. It seems counter-intuitive, but for this game having some obstacles that are entirely for show makes <em>sense</em>, it's part of the experience that I'm selling.</p>
<p>But, looking at that description you might think &quot;that sounds awfully like a square-peg&quot; and I agree. So I wanted to find a way to use this where I could obscure the use-case a bit. And in this case, one of the options I came up with was fairly simple: use it to make some tricky or impossible platforming much more viable, via simply expanding the surface area to stand on.</p>
<video width="427" height="240" autoplay loop>
    <source src="/videos/noirmancer_pillar_hopping.webm" type="video/webm">
</video>
<p>To me, this seems like something you reasonably can obscure sometimes, and therefore reward the player for noticing it. In this case, simply putting the opportunity up on some columns is more obscured than you may immediately realize. Players are typically pretty bad about looking up and thinking of the space above them. Worst-case scenario, I've given the player a tool to help alleviate platforming which is one of the worst things in a first-person game.</p>
</details>
<h2>So what's next</h2>
<p>So the next week or two will be making the level not a whole bunch of grey, filling it with decoration and actually putting down all the intel.</p>
<p>In terms of moving towards a first public demo, there is sadly something else I must do. I decided I didn't want to burden this level with introducing the core gameplay. That means I need to make a short linear tutorial level that'll introduce the basic ideas and the hook for this level I'm working on right now. So I think at the moment I'm hoping for early September for that demo. Which sucks, but that is the reality of it. I'm glad I started working towards that much earlier than I really needed to. Hopefully I'll feel more certain about when that is coming in the mid-August update.</p>
<p>Apologies this update is at the last minute for July. I decided I at least wanted to get all the unique gameplay stuff and mission objectives in for this level before bothering to make a post in which I mostly just said I wasn't done.</p>
<h2>Follow along</h2>
<p><a href="https://store.steampowered.com/app/3674590/Noirmancer/?utm_source=nblog">Wishlist the game on Steam</a>. You can follow this project via <a href="https://mosfetarium.com/blog/rss.xml">RSS</a> (<a href="https://ncase.me/rss/">Don't know RSS?</a>), or by following me on <a href="https://mastodon.gamedev.place/@distractedmosfet">Mastodon</a>. And of course feel free to contact me via <a href="https://mosfetarium.com/about/">email</a>, or Mastodon with any comments or questions.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">dcc7e168-63fe-4dc6-3f7c-ea6781d01d67</guid>
<pubDate>Thu, 31 Jul 2025 00:00:00 +0000</pubDate>
</item>
<item>
<title>Noirmancer June update: Lucky Horseshoe</title>
<link>https://mosfetarium.com/blog/noirmancer-june-update/</link>
<description>
<![CDATA[
<p>
<p>Time for an obligatory monthly update for my mind-erasing stealth game <a href="https://store.steampowered.com/app/3674590/Noirmancer/?utm_source=nblog">Noirmancer</a>. In this blog post I ramble a bit about what I've been working on in the past month, and some thoughts about level shape. If you don't feel like reading, a TL;DR is that horse-shoe = good and that I'm still on pace to hopefully have a demo out in late July or early August.</p>
<p><img src="/images/sly_horseshoe.png" alt="A cropped image from the cover of Sly Cooper, a PS2 game about a thief, where a horseshoe can be seen on the protagonist's backpack" />
<em>Where do you keep your lucky horseshoe?</em></p>
<h2>Dopamine Economy In Crisis</h2>
<p>Sadly, I have no funny moving pictures to show you for this month. Apologies for the shortfall in your projected dopamine activation. This isn't going to be the most gripping update but hopefully July's one will see your brain engagement juices skyrocket, so look out for that.</p>
<p>Let's get the boring stuff out of the way: I reworked some guard AI search point selection to remove some manual work from me and also improve it generally. I did some performance work that I had procrastinated. Specifically tooling stuff related to merging a bunch of level geometry brushes to reduce the number of draw calls. I just wanted to check that it would work out the way I hoped so that I can go forward with making levels with the knowledge that that should be all good. I also upgraded the version of Godot I was using. This conveniently solved a crash I occasionally was encountering right around the time of the last blog post.</p>
<h2>Story Time</h2>
<p>After doing that, I spent quite a while working on writing stuff, mostly being creatively blocked on writing stuff specifically. I had procrastinated a lot of writing decisions in favour of focusing on general game-play up to this point. I had many ideas but not that much concrete, but I've settled on a goal for the story now. It may change later, but I'm optimistic and it gives me something to go forward with. This was important as part of starting the design for upcoming public demo level; I needed to know what story the demo was going to tell.</p>
<p>Finding that story was also key to solving a game-play problem: I want the player to have more abilities during the course of the game rather than just dumping them all on the player immediately. Which means less game-play ideas to design the level with, and there's a concern about there not being enough variety in the level.</p>
<p>My solution to this is to have some unique objects with some unique effects in this level, related to its story. It both helps make the level more distinct generally and can help with the shortfall in player options created by the lower number of abilities.</p>
<p>And no, I won't be spoiling the story for now. Sorry :)</p>
<h2>Level Shape</h2>
<p>With my level's story and game-play identity decided, next I needed to define the geometric identity. This is often called a <a href="https://en.wikipedia.org/wiki/Parti_(architecture)">parti</a>. I don't know if the parti of a level is really noticeable to the player, but in the worst case it's at least a helpful tool for the designer; it gives you something to fill in. And while I'm not sure players can really identify the parti, I suspect they'd realize if your levels all have the <em>same</em> shape. So it's good to make sure you use a different one each time.</p>
<p>At first I kinda wanted to do a ring-shaped building and you emerged in the court yard in the middle at the start. This design means I can spread some ingress points around the player's starting location and give them very different angles of attack for them to discover and choose from. But, since this level is a key early level, and meant for this public demo, I kinda want to give the player a cityscape vista, so I decided to break the ring shape, producing something more like a horseshoe.</p>
<p>Now, horseshoe shapes are NOT uncommon in level design. Here's E1M1 of Doom.</p>
<p><img src="/images/doom_e1m1.png" alt="An isometric view of Doom's E1M1" />
<em><a href="https://www.doomworld.com/forum/topic/126329-top-down-isometric-view-from-a-wad-file/">Thanks to Doomer GCP for the isometric map</a></em></p>
<p>Here's E1M1 of Quake.
<img src="/images/quake_e1m1.png" alt="A 3d view of Quake's E1M1" />
<em><a href="https://www.models-resource.com/ms_dos/quake/model/40481/">Taken from the models resource</a></em></p>
<p>I noticed a familiar shape in the first level of Thief 2 last time I played it.</p>
<p><img src="/images/thief2_m1.png" alt="A screenshot of the map screen from Thief 2's first level" /></p>
<p><a href="https://www.youtube.com/watch?v=rV6HlBa88js&amp;t=42s">John Romero has talked a bit about the Horseshoe before</a>. My usage of the horse-shoe is a little different though. I think the reason why it works well often for first levels is that it's basically as simple as possible without being boring; it's a line, but a curved one. So you don't feel like you're just walking down a line. It's easy to position some little tangents coming off it, easy to allow you to see the start of the level from the end which is always a strong feature in level design. But I'm using it for the previous mentioned goal of surrounding the player different ways to get inside.</p>
<p>I'm enjoying getting to play around with breaking symmetry. Symmetry is very normal in many of the large buildings I look at for architectural reference but it can also be very boring. The obvious tricks are about having symmetry but avoid homogeneity; use a broadly symmetric shape but fill that shape with extremely different components, or subdivide them in different ways.</p>
<h2>The Next Month</h2>
<p>So, at this point I have the core ideas for the demo and have the rough shape of the level blocked out in the editor. I'm now going through and breaking it up into smaller rooms and thinking of the game-play ideas to fill them with. Sadly, the ideation process has gone slower than my last time making a level, I think a large reason is that I simply feel a lot more pressure for this one to be good. The July target still seems doable though.</p>
<h2>Follow along</h2>
<p><a href="https://store.steampowered.com/app/3674590/Noirmancer/?utm_source=nblog">Wishlist the game on Steam</a>. You can follow this project via <a href="https://mosfetarium.com/blog/rss.xml">RSS</a> (<a href="https://ncase.me/rss/">Don't know RSS?</a>), or by following me on <a href="https://mastodon.gamedev.place/@distractedmosfet">Mastodon</a>. And of course feel free to contact me via <a href="https://mosfetarium.com/about/">email</a>, or Mastodon with any comments or questions.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">a3b5b37b-6b16-9bad-7480-1b9e79db5949</guid>
<pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate>
</item>
<item>
<title>NOIRMANCER LIVES</title>
<link>https://mosfetarium.com/blog/noirmancer-lives/</link>
<description>
<![CDATA[
<p>
<video width="427" height="240" autoplay loop>
    <source src="/videos/noirmancer_early_montage.webm" type="video/webm">
</video>
<p>Long time no see. My mind-erasing noir stealth game previously codenamed &quot;MaskedDetective&quot; lives. And I've been working on pretty consistently for the past year. There's a Steam page up now!</p>
<p><a href="https://store.steampowered.com/app/3674590/Noirmancer/?utm_source=nblog">WISHLIST IT. CONSUUUUUME</a></p>
<h2>State of the game</h2>
<p>The game has basically passed the <a href="https://en.wikipedia.org/wiki/Vertical_slice">vertical-slice</a>. The core gameplay loop is in: guards wander around doing their stuff, you get spotted, run away, use your mind erasing powers to reset them. You collect intel, keys, read notes. Discover new objectives mid-level. You can use nine different powers to break-in, sneak around, and lose guards. There's a bunch of interactable props and other features to make levels from. I have made two complete levels and playtested both of them. Many things have been refined and reworked based on that progress. It's not as nice-looking as I'd like, but the art is generally representative of the intended look. It needs a lot of fleshing out, but it's a playable, real game.</p>
<p><img src="/images/noirmancer_art_1.png" alt="Noirmancer promo image featuring masked detective figure and their magical hand gestures" />
<em>Big shout out to artist Giovanni Fim, who I commissioned to make this promo art</em></p>
<h2>What's Next? Public Playtest</h2>
<p>I've spent the past two weeks since getting the steam page up doing some tasks I had neglected in favour of doing that. A big one was reworking some of the guard AI; it's a tough thing to get right and I imagine it'll probably get continously revised throughout the development of the game. But I'm ready to target the next milestone.</p>
<p>I want to make a small playtest demo and get it out there. It'll allow people to see what the game is really like, it'll hopefully allow me to get feedback, and it'll be useful in terms of promotion: having something playable can be very helpful for coverage and access to events.</p>
<p>I'm thinking a first playtest may need to be two levels, a short one that introduces core gameplay ideas and a second one that is a bit meatier. The last level I made took me less than 3 weeks, but I probably want to be a little more ambitious for this one; flesh out the game a bit more, take some time to refine it, etc. So I'm <em>hoping</em> to have something in July but obviously that'll depend a lot on how the creative process goes, how ambitious I get, how things go in an initial private playtest, etc.</p>
<p>I intend this to probably be the first of at least two demos. This first one will probably be a bit rough; it's about getting feedback and building interest. And there'll probably be another one for a Steam Next Fest closer to release. It probably wouldn't fit into the timeline but it would be great to do one in between those two; that would hopefully be a refinement based on feedback from the first one, but yeah it probably can't be done time-wise. I quite like the idea of developing a game with regular playtest demos; it's kinda like doing Early Access without the perils surrounding it.</p>
<h2>Where the hell have I been</h2>
<p>I have not touched this blog in ages. There's a lot of reasons for that. I spent many months with my focus elsewhere, and obviously a lot of time working on the game. But a big part of that time was me working through my pretty bad relationship with the creative process. I had some really bad priortization. I didn't push hard enough. And probably most importantly, I allowed myself to get paralyzed by uncertainty far too often.</p>
<p>Definitely heaps of good work happened in that time, but it happened at a far slower pace than ever should be ideal. Recently I feel I've gotten better at all the mentioned areas: priorization, producitivty, and working through uncertainty. Creativity can and should be very playful but sometimes it's work and I feel like I've finally gotten good at the work part.</p>
<p>Additionally, I really wanted to work on the game and work through those problems rather than just blog and social media post about it. And I think that was a good choice. I'm now ready to talk about the game, because it now feels pretty real and inevitable.</p>
<p>I'd like to blog more. I want to commit to a monthly update. So I guess you'll be hearing from me again in June.</p>
<h2>Follow along</h2>
<p><a href="https://store.steampowered.com/app/3674590/Noirmancer/?utm_source=nblog">Wishlist the game on Steam</a>. You can follow this project via <a href="https://mosfetarium.com/blog/rss.xml">RSS</a> (<a href="https://ncase.me/rss/">Don't know RSS?</a>), or by following me on <a href="https://mastodon.gamedev.place/@distractedmosfet">Mastodon</a>. And of course feel free to contact me via <a href="https://mosfetarium.com/about/">email</a>, or Mastodon with any comments or questions.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">1256c36e-e18e-67f1-1427-15d932a8ed13</guid>
<pubDate>Fri, 02 May 2025 00:00:00 +0000</pubDate>
</item>
<item>
<title>How to get ideas using the Design process (MaskedDetecitve Devblog #3)</title>
<link>https://mosfetarium.com/blog/masked-detective-dev-3/</link>
<description>
<![CDATA[
<p>
<p>Hi, I'm working on a stealth game were you play a comicbook detective who uses superpowers to sneak, spy, steal, and escape. <a href="/blog/masked-detective-dev-2/">Last time</a> I set myself the goal to work on a first test level and blog about it in December. This was a terrible choice given uhhh, its december and I was moving. But now that things are settling down a bit more I can get back to it.</p>
<p>In this blog post I want to start sharing my process of attempting to create this test level, and talk about the power of the Design process.</p>
<p><img src="/images/btas_5.png" alt="Picture of a gloomy street from Batman: The Animated Series" /> <em>(© Warner Bros. Animation)</em></p>
<h2>Form Follows Function</h2>
<p>Creative tasks like Level Design are plagued with one famous problem; the blank-canvas. The simple lack of knowing what to make. How do you know what to do from infinite options?</p>
<p>In practice the options aren't quite as infinite as they seem. You probably want to make something that at least you consider good, and ideally others do too. Additionally, you're trying to make a good level for <em>your</em> game. Doom's E1M1 is a great level, but it likely wouldn't be a good level for your game. You're also probably not trying to just make <em>any</em> good level for your game but perhaps a good <em>first</em> level, or a good level following a certain twist in the story, or after the introduction of a particular mechanic, etc. These elements constrain the possibilties. You're not just being creative; you're trying to fulfill a need.</p>
<p>This is the essence of Design: &quot;Form Follows Function&quot;. Identify the function of what you're creating, and create to fit that need. Now you've gone from what felt like aimlesly considering infinite possibilities to working towards a defined goal. Design isn't some magic of summoning an idea from the void; it's a process, like Science is a process.</p>
<h2>Promises and Values</h2>
<p>A good place to start thinking about design for a game is to specify the Promises and Values of your game. Promises are the hooks, the pitch, the thing that gets players to play. They are an incredibly important part of the relationship with your audience; without making promises the audience simply doesn't know if they care about what you've made. They want to know if it's something they're interested in. What are my promises? Well I've already been repeating them in this blog series.</p>
<ul>
<li>Comic-book feel and aesthetic</li>
<li>Detective</li>
<li>Stealth</li>
<li>Powers</li>
</ul>
<p>They're simple ideas that can be easily communicated, and someone can instantly start to get a sense of whether or not they're interested. They're very important context for designing your game because if you make some promises to your audience and they don't feel like you fulfilled them, then they're going to find your game very unsatisfying. In fact the same piece of content with a different promise can receive radically different appraisals from the same people.</p>
<p>Values are different; they are more nuanced. They're not really meant to be in marketing material, instead they are opinions about how your game should be. They're a philophy. A subjective taste or a theory on how to make something good. Sometimes they're near universally accepted theories such as &quot;the main character of a story should have goals and things they care about&quot;. They constrain and guide you. Here are some values for this game:</p>
<ul>
<li>Feel sneaky even after being discovered
<ul>
<li>(I cover this as a problem I have with stealth games in <a href="/blog/new-project-masked-detective/">the first blog post</a>)</li>
</ul>
</li>
<li>Every mission is a story.
<ul>
<li>They should be surprising, develop in complexity, unfold.</li>
</ul>
</li>
<li>The levels should say something about the fictional world.</li>
<li>Exploration is key
<ul>
<li>You should generally be at least a little non-linear.</li>
</ul>
</li>
<li>Navigate without UI markers or a map screen.
<ul>
<li>I really dislike pausing to check the map screen in Thief, it ruins the flow of the game. As much as possible I want the player to be able to orient themselves using cues from the environment. And probably just remove the map screen entirely.</li>
</ul>
</li>
<li>Every Level should have a unique identity, and have its own hook and interest</li>
</ul>
<p>By identifying my Promises and Values, I now have a lot of context to feed into this test level.</p>
<h2>Level Function</h2>
<p>So, what's the function of this level I'm making? There's a number of things I want to achieve.</p>
<ul>
<li>Show off all the promises of the game
<ul>
<li>I need to test that I can deliver on the promises. Ideally this is also a hypothetical &quot;first level&quot; for the final game (unlikely to end up being so in reality) and a good idea for a first level in a game is to do a little bit of all of your promises. Allow people to understand what the game is really about.</li>
</ul>
</li>
<li>Teach the basic gameplay, including the memory erase feature
<ul>
<li>The memory erase feature is meant to be a big value of the game and a core part of the gameplay loop, the player absolutely needs to learn it.</li>
</ul>
</li>
<li>Introduce a world and a setting</li>
<li>Be surprising. Wow the player a little.</li>
<li>Interest the player in seeing more of the game.</li>
</ul>
<p>By fleshing out these requirements I can start turning my task from &quot;Make a level&quot; into the more specific task of &quot;Make a level with these particular properties.&quot; I'll try making a list.</p>
<ul>
<li>Things to communicate
<ul>
<li>The player is a vigilante detective</li>
<li>The world does not look kindly on vigilante detectives</li>
<li>The big corps of the world are in-fighting. Having successfully co-opted or suppressed regulators and unions their only opposition is now each other.</li>
</ul>
</li>
<li>Key moments
<ul>
<li>Feel very sneaky</li>
<li>Use some cool powers</li>
<li>Discover something and feel like a detective.</li>
<li>A &quot;twist&quot;. A moment where everything gets a bit more complex. Things can't just go according to expectations. Ideally this moment changes the pacing of the level, which also often means the gameplay.</li>
</ul>
</li>
<li>Things the player must learn
<ul>
<li>The basic controls</li>
<li>How to sneak</li>
<li>How to interact with objects</li>
<li>How to erase memories</li>
</ul>
</li>
<li>Some key details
<ul>
<li>The player should always have some kind of goal, give them a mission statement right away. But as mentioned above, there needs to be a twist, there should be more to it than the original goal.</li>
<li>A feeling of mystery</li>
<li>Feel like a comic-book, or specifically Batman the Animated Series.</li>
<li>Some non-linearity, to help you feel like you're exploring.</li>
<li>Has a unique identity. Something about it that no level after it would be allowed to do.</li>
</ul>
</li>
</ul>
<p>With this list I can begin to brainstorm specific ideas of how to do each of these things, and build things into a layout.</p>
<p>When you look at this list you can begin to identify some things that seemingly must be true. I have some things the player must learn, which means they probably need to be the first things in the level and there needs to at least be a bottle neck to prevent you from getting into the meat of the level without learning those. This &quot;comic book&quot; or &quot;Batman the Animated Series&quot; specific feel is interesting. I really associate BTAS with its cityscapes, which really suggests I should do a cityscape level. Which could be the unique identity this level gets to have. I probably don't want to do too many cityscape levels.</p>
<p>For it to be a cityscape there needs to be multiple buildings. So I probably need to avoid putting the player into one specific building for too much of the level. And should probably make use of a lot of big windows, balconies, walkways, and rooftops. If you are going between multiple buildings I probably want there to be some cohesion between these buildings world-building wise. Ideally I want things in some building to relate to things in another building. And I probably want the player to feel like all the buildings collectively make the level a single shared space, rather than just the levels being a series of individual buildings you break into one after another.</p>
<p>In terms of the relationship between buildings, I do have an option here I can pull from else where in the list: &quot;The big corps of the world are in-fighting&quot; perhaps this is some CBD area of a big city and there's several competing corps all within a block or two of each other, and your infiltration into these buildings leads to you realizing the extent of the rilvary between these companies. Perhaps even between their owners as people. I can put penthouses in as a neat difference in space and to pull in those more personal elements of their owners or employees. And while I do want the buildings to have a story relationship, I don't want them all to look the same; each company could have its own architecture aesthetic or interior design aesthetic.</p>
<p>For the &quot;twist&quot; or big pace change, I can again look to that rilvary. What if one corp secretly hired a group to kidnap the head of another? They'll make it look like environmentalists or &quot;Extremist Unionists&quot; or whatever. Notably, if this happens while the player is in the building, then the security situation in that building instantly changes. Everyone is on high alert, which makes things very hard for you. But also you have a big corporate secret to try and find proof of.</p>
<p>There is an upside to moving this beat forward a bit into the level: perhaps the victim knows it's bullshit, and says something like &quot;Who hired you? Was it &lt;competitor name&gt;? Maybe &lt;another name&gt;?&quot; and this sets up the player to break into the near by competitors and identify which one has organized the kidnapping. This gives the player goals and can create some obvious non-linearity potential. However I probably want the increased security to be something later in the level. Perhaps the player has to circle back and when they get back, the kidnapping has been discovered by the personal security of the victim and a conflict is escalating. That sounds like it could work.</p>
<p>The above is a great example of the Design process in action. I identified the function of my level, and from only a few of those specific goals I have derived a setting or &quot;stage&quot; I guess you might call it, some basic plot, and a loose structure for the level. I went from a blank canvas to a sketch. Still a lot of work to do, but a big hurdle is overcome.</p>
<p>If you'd like to hear more about this sort of process from someone with real professional Level Design experience, you should check out <a href="https://www.youtube.com/watch?v=fv8i4IBdAHI">videos from Steve Lee</a>, who I've found extremely helpful.</p>
<h2>Dev planning!</h2>
<p>So what's next? The near-term goals are still:</p>
<ul>
<li>Get a few powers in</li>
<li>Make a test level</li>
</ul>
<p>This process has helped a bit with the first one: if I want to enable some rooftops gameplay, I may need abilities that specifically help with that. The second one still needs more design work, so the next post will simply be further refinement on this idea, and some early work thinking about the level layout.</p>
<p><img src="/images/btas_6.png" alt="Picture of a tall city building from Batman: The Animated Series" /> <em>(© Warner Bros. Animation)</em></p>
<h2>Follow along</h2>
<p>You can follow this project via <a href="https://mosfetarium.com/blog/rss.xml">RSS</a> (<a href="https://ncase.me/rss/">Don't know RSS?</a>), or by following me on <a href="https://fosstodon.org/@distractedmosfet">Mastodon</a>. And of course feel free to contact me via <a href="https://mosfetarium.com/about/">email</a>, or Mastodon with any comments or questions.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">21120926-9d22-4b7c-17a8-af60346703bd</guid>
<pubDate>Mon, 27 Feb 2023 00:00:00 +0000</pubDate>
</item>
<item>
<title>Making guards search in a stealth game (MaskedDetecitve Devblog #2)</title>
<link>https://mosfetarium.com/blog/masked-detective-dev-2/</link>
<description>
<![CDATA[
<p>
<video width="640" height="360" autoplay loop>
    <source src="/videos/maskeddetective_2022_dec_montage.webm" type="video/webm">
</video>
<p>Hi, I'm working on a stealth game were you play a comicbook detective who uses superpowers to sneak, spy, steal, and escape. It's been a productive time since my <a href="/blog/new-project-masked-detective/">first blog post</a> about this project, and I want to talk a bit about the AI in the game, particularly thoughts on searching behaviour both from the perspective of design and programming.</p>
<h2>What have I done since last time?</h2>
<br>
<video width="640" height="360" controls>
    <source src="/videos/maskeddetective_2022_dec_short_demo1.webm" type="video/webm">
    <i>Seems you don't have video support, try downloading <a href="/videos/maskeddetective_2022_dec_short_demo1.webm">this then</a>.</i>
</video>
<p><em>A short video of the this very early Alpha, extremely subject to changes.</em></p>
<p>Since last time I finished some work on the AI around things like searching and their simple punch attacks. I also worked on a very early version of the memory-erase ability.</p>
<p>Game Design is often about push and pull; finding that sweet spot where the player feels they can influence their destiny, while still feeling contention from the game. For my memory-erasing gameplay I need the player to experience a simple loop:</p>
<ul>
<li>Sneaking</li>
<li>Being discovered</li>
<li>Evading</li>
<li>Hunting</li>
</ul>
<p>Sneaking and being discovered should be the easy parts, it's balancing the evasion and hunting steps that matters. First, I need the memory-erase ability to actually require &quot;hunting&quot;. I decided to make it a short-distance ability that works only on enemies facing away from you. This means you can't just run up to an enemy and get them; you need to carefully stalk them.</p>
<p>Additionally, it means you can't immediately use it after discovery; you have to lose them first. That's the evasion step.</p>
<video width="640" height="360" controls>
    <source src="/videos/maskeddetective_2022_dec_erase_demo.webm" type="video/webm">
    <i>Here's <a href="/videos/maskeddetective_2022_dec_erase_demo.webm">another video.</a> Are you browsing on a Mac OS9 machine? Can you even play these? Oh well.</i>
</video>
<p>To help get the balance on this right, the NPCs run very fast if they can see you, go at a medium speed for a bit after losing you, but then slow down again a short while later as they're combing around for you. This way you're not having to chase an enemy who is always sprinting. The player is faster than the NPCs, but has a stamina pool that becomes visible after 20% depletion; this gives you a window of time to lose the NPCs.</p>
<p>The memory-erase ability causes the NPCs to become stunned for a period of time. This time period effectively acts as a soft-window in which you likely need to get all currently alert NPCs, otherwise they will just re-alert each other when they leave the stun. Getting the balance on that correct may prove challenging, but that'll be a future task. I suspect I may end up with a secondary memory-erase ability that is resource limited but a bit more flexible, to help with some of the stickier situations with multiple NPCs. The search behaviour tries to spread the NPCs out, which is both believable and gives the player a helping hand.</p>
<p>I expect this area of the design to need a lot of iteration as I develop the game, find new problems, try to make it more interesting, or try to find ways to keep it fresh. But for now, it works, and it's already a little challenging. So I'm hopeful that I'll be able to get something interesting as I refine it and flesh it out more.</p>
<h2>Searching</h2>
<p>Searching presents a number of interesting challenges to designers and programmers. It influences how players feel about the NPCs because it's very easy to write search behaviour that feels very stupid; in Thief for example the guards quite often search around in ways that have them mostly staring at walls from a point-blank distance. But on the other hand, if you make it <em>too</em> smart you actually create a problem.</p>
<p>About a decade ago I hit on this exact issue with a little Guard AI test I programmed for a top-down game. I wanted guards that felt like they were actually intelligent, and therefore made escaping from them feel special.</p>
<p>Rather than picking random near points to wander to a better approach seemed pretty obvious: when the AI loses sight of the player, track the space they could possibly be. I did this by dividing the world into a grid, and the AI knows the player had to start from that grid position. From there, you have the AI expand the possibility space in the grid at roughly the running speed of the player. You remove spots they can see from the possibility space, and obviously make the space only expand into grid positions that can actually be walked through (so not into walls).</p>
<p>This way, if the AI sees the player run down a dead end corridor, and has sight of the only exit/entrance, they'll know the player can only be in the corridor. From there, searching is as simple as picking a point in the possibility space (generally the oldest) and sending the NPC to go look at it. I recently learned that this approach appears to be quite similar to <a href="https://youtu.be/VoXSJBVqdek?t=1889">the one used by Dishonored 2</a>.</p>
<h2>Too Smart For Its Own Good</h2>
<p>This works extremely well, and isn't too crazy for a computer to compute. But I had a problem: now the guards were <em>too</em> good at finding the player. The game requires the chance that you can get away, and AI that perfectly determines where the player can and can't be often lowers that chance too much! Giving the player powerful means of evasion can help counter this, but I found it difficult to do so in that old prototype without giving the player too much power. It seems particularly hard to balance evasion.</p>
<p>This is part of my reason for picking the memory-erasing idea. For my game the push-and-pull is more around the pressure to erase memories before time runs out, rather than the pressure to not be found. This means I can make the player pretty good at evasion, as they have to actively put themselves back into danger in order to erase memories.</p>
<p>So, I used a similar search approach for this prototype. However, rather than a grid, I used the points of the navigation mesh, and rather than slowly expanding the area, I simply give every near nav-point a score based on its proximity to the player's starting point. When the NPCs see a point they mark it as low-score, and the scores grow back up as long as they aren't being looked at. A key difference is this means the search area is never actually fully erased, and if they check every where they simply will start to re-check everything.</p>
<p>As with everything, there's a likelyhood of me tweaking this more later, but for now I'm quite happy with the approach.</p>
<h2>Dev planning!</h2>
<p>So what's next? The near-term goals at this stage are:</p>
<ul>
<li>Get a few powers in</li>
<li>Make a test level</li>
</ul>
<p>Obviously that second one is easier said than done. I'll also probably do other small tweaks and additions as I feel like it. In the next three weeks I'll make another blog post about my thoughts on designing this test level, and how it's going. I expect to be a bit of a mid-way progress report.</p>
<p><img src="/images/btas_crowd.png" alt="Picture of an audience from Batman: The Animated Series" /></p>
<h2>Follow along</h2>
<p>You can follow this project via <a href="https://mosfetarium.com/blog/rss.xml">RSS</a> (<a href="https://ncase.me/rss/">Don't know RSS?</a>), or by following me on <a href="https://fosstodon.org/@distractedmosfet">Mastodon</a>. And of course feel free to contact me via <a href="https://mosfetarium.com/about/">email</a>, or Mastodon with any comments or questions.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">e4868d77-9139-5736-cb69-643624223f58</guid>
<pubDate>Thu, 01 Dec 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>MaskedDetecitve Devblog #1: A superpowered detective stealth game</title>
<link>https://mosfetarium.com/blog/new-project-masked-detective/</link>
<description>
<![CDATA[
<p>
<p><img src="/images/btas_4.png" alt="A frame from Batman: The Animated Series" /></p>
<p>I've been tinkering on a project I currently codename &quot;MaskedDetective&quot;, and I've decided to start journaling its development on here, in hopes that it'll help me organize my thoughts and maybe provide some interest to others. This post is about the project, its influences, goals, and how I hope to address what I consider a core problem with stealth games.</p>
<h2>So what's the idea?</h2>
<p><strong>&quot;A stealth game where you play a comicbook detective who uses powers to sneak through shadows, climb skyscrapers, turn into mist, and erase the memories of his pursuers, as he investigates dangerous powerful people.&quot;</strong></p>
<p>It can take a while to find a good hook for your game and as a game evolves you often need to evolve the hook, but this is probably a decent starting point. I think it does a decent job of communicating the general tone, and gives a vibe of what the gameplay may be like. And in this case, hopefully gives readers of this blogpost an idea of what to expect.</p>
<h2>Influences: what to copy, what to change.</h2>
<p><img src="/images/thief.jpg" alt="The Cover of Thief: The Dark Project" /></p>
<p>The biggest influence on this project is the classic stealth game <a href="https://en.wikipedia.org/wiki/Thief:_The_Dark_Project">Thief</a>, and probably more specifically its sequel, Thief 2. The bits of interest to me are its system-and-tool driven gameplay, its focus on stealth over combat, and how level design really sits at its heart.</p>
<p>Those familiar with the term &quot;immersive sim&quot; probably know what I mean by &quot;system-and-tool driven gameplay&quot;, but for those who don't; what I mean is that Thief gives the player a bunch of different gadgets and puts them in a big map to explore and let's them go nuts. Levels aren't really about the player figuring out the specific way they're supposed to overcome them, but rather letting the player find their own way to infiltrate a space. In MaskedDetective the main character possesses and acquires a number of supernatural abilities that you can then use to find your way around the games obstacles, and I'm hoping to capture some of this same feeling from Thief.</p>
<h3>A problem with stealth games, and how I hope to fix it.</h3>
<p>I like Thief's focus on stealth over combat. However, there are some problems with how Thief does this. When you are discovered you either need to evade your captors or subdue them. And neither of these really match the reason I play Thief; I want to feel sneaky.</p>
<p>It's no secret that many players aggressively use quicksaves in stealth games to avoid ever being detected. And while this is sometimes perfectionism, I suspect a major motivator is that being discovered in stealth games is <em>boring</em>. I'm not playing these games to fight people so I don't want to do that. Waiting for guards to give up searching is tedious and takes the player out of the driver's seat; you no longer solve your problems actively, instead you wait for them to go away. I don't think player's use quicksaves here because they can't handle failure, I think they do it to get back to having fun.</p>
<p><img src="/images/mib.jpg" alt="A character from the film Men In Black uses their mind-wiping device" /></p>
<p>Fortunately the idea of using supernatural powers affords me a lot of flexibility, so here's a unique gameplay twist; you have 60 seconds to use your powers to erase the short-term memory of NPCs, and therefore make them forget that they saw you. But if you fail to do so in time, then you have failed the mission.</p>
<p>So now rather than having a gameplay loop around Sneaking-&gt;Discovery-&gt;Waiting, it's Sneaking-&gt;Discovery-&gt;Erasing. And while it'll take some effort to make sure the memory-erasing is fun, it should be sigifnicantly more enjoyable than waiting in closets for guards' goldfish memory limit to kick in.</p>
<h3>Level Design is king</h3>
<p>Something that I think doesn't get addressed enough with Thief is how much of the appeal is about levels. I think the audience understands this on some level; it is reflected in the fact that the games still have a community making levels for them today. But I don't think I've seen anyone else say it so concretely; Thief's stealth gameplay is just a really good match for exploratory levels. You really find yourself focusing on the space. Looking for hidden things, ways to access areas, spots to hide. Additionally, the somewhat voyeuristic nature of secretly reading notes and letters lines up with the wider sneaky-fantasy that this kind of game sells.</p>
<p>Level Design is an artform, one that I have little-to-no experience in, but I hope to do my best in creating levels that are fun adventures, and really act as the heart of the game.</p>
<h2>The amazing backgrounds of Batman The Animated Series</h2>
<p><img src="/images/btas_2.png" alt="A background from Batman: The Animated Series" /></p>
<p>The goal that I expect to struggle with the most— and to fall very short of— is to try and create a 3d game that evokes the aesthetic of Batman The Animate Series' amazing backgrounds.</p>
<p><img src="/images/btas_1.png" alt="A background from Batman: The Animated Series" /></p>
<p>I'm very underequiped to pursue this task, but I have some thoughts that I plan to share in later blogposts.</p>
<p><img src="/images/btas_3.png" alt="A background from Batman: The Animated Series" /></p>
<h2>So, where is the project currently?</h2>
<p>Very early days. The character controller is in, visibility levels are calculated, some early work on the AI, readable notes, lockable/unlockable doors, a WIP power or two. This is very must a pile of tech and feature tests at this stage and not a game. I hope to use these devblogs to organize this development a bit, speaking of which:</p>
<h2>Dev planning!</h2>
<p>The current near term goals are:</p>
<ul>
<li>Have basic NPCs that can detect the player, chase them, search for them, subdue them.</li>
<li>Implement memory-erasing gameplay and lose-condition</li>
<li>Get a few powers in</li>
<li>Make a test level</li>
</ul>
<p>Technically speaking, once you have a game where you can hide and be found, you have a stealth game. But I need to make a tiny test— dare I say, &quot;a vertical slice&quot;— of level design, powers-driven sneaking, and that Sneaking-&gt;Discovery-&gt;Erasing loop. Game design is a process of hypothesis-&gt;test-&gt;iterate; I need to check that I can make that memory-erasing gameplay fun at all.</p>
<p>Working on the aesthetics is not really a goal in the short term, so please expect screenshots to look <em>AWFUL</em>.</p>
<p>Let's set a goal, in the next two week I'll post about the NPCs. I already have them pathing, patrolling, detecting the player, chasing the player. And by then I hope to have them attacking the player, and a reasonable first-pass at their search behaviour. Both of which I'm already working on.</p>
<h2>Follow along</h2>
<p>You can follow along with this effort via <a href="https://mosfetarium.com/blog/rss.xml">RSS</a> (<a href="https://ncase.me/rss/">Don't know RSS?</a>), or by following me on <a href="https://fosstodon.org/@distractedmosfet">Mastodon</a>. And of course feel free to contact me via <a href="https://mosfetarium.com/about/">email</a> with any comments or questions.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">4c3856d1-6a04-0dd1-339e-c08e1104a95d</guid>
<pubDate>Thu, 17 Nov 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>Mosiki update: The anti-climax of software that just works</title>
<link>https://mosfetarium.com/blog/mosiki-update-2/</link>
<description>
<![CDATA[
<p>
<p><em>(In this blog series I attempt to develop a wiki server that tries to be respectful of computer resources, as part of a self-assigned <strong>Modest Programming Challenge</strong>, the series starts <a href="/blog/modest-programming-part1">here</a>)</em></p>
<p>A while ago I set out to make a small wiki ideal for niche communities. Easy to administer, reliable via low number of parts, respectful of computer resources both on the server side and on the client side, with little code to make it easy to pick up and maintain on one's own. It's been a while since my last update but not because I stopped the project. Actually, the wiki is up live and has been for months. So how have things turned out?</p>
<p><img src="/images/mosiki.png" alt="A small screenshot of a default mosiki welcome page" />
<em>I never said I was a webdesigner btw. But you can probably tell that from my blog.</em></p>
<h1>Mission success</h1>
<pre class="code-block"><code>-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Python                          15            612            467           1821
HTML                            24             14              0            792
CSS                              3             83              1            395
-------------------------------------------------------------------------------
SUM:                            42            709            468           3008
-------------------------------------------------------------------------------
</code></pre>
<p>Mosiki has shaped up reasonably well. It has users, sign-up via an invite system, password reseting, page creation, editing, conflict management, permissions, renaming pages with URL redirects, image uploading with thumbnail generation, markdown syntax with some additions, some simple mobile responsive css, page locks, and page keys.</p>
<p>At idle the server uses about 90 MB of RAM, including mosiki, OS (Alpine Linux), and Nginx proxy. A reasonable example of a fairly simple page tracks in at 22KB of HTML and CSS, with obviously any attached images dwarfing that. There's no JS anywhere. It comes out at an absolutely tiny 3k lines. I feel like I can very confidentally call this some Modest™ software.</p>
<p>Before I finish up though, here's some more technical junk.</p>
<h1>Yet more dependencies</h1>
<p>Last time I went over some early choices: Flask, Gevent, Markdown via markdown-it-py, SQLite, Argon2. And all of those have ended up in. I did end up adding in a few more though.</p>
<h2>mdit-py-plugins</h2>
<p>This module comes from the same org as markdown-it-py and allowed me to quickly add anchor-links (as in, linking to sections of a page) and footnotes. This is perhaps one of the more dubiously low-value dependencies of the entire project, but it didn't seem fundamentally unreasonable.</p>
<p>I also added spoiler sections and other minor markdown tweaks myself. Additionally I found a bug in the module and <a href="https://github.com/executablebooks/mdit-py-plugins/pull/43">submitted a fix</a> so this silly little project has officially contributed to the ecosystem.</p>
<h2>libvips (via the pyvips binding)</h2>
<p>I knew I wanted image uploading in the wiki, and it seemed reasonable to want thumbnail generation to save a little on bandwidth. This is the sort of thing that when designing your software should ring bells as a potential memory hog point; if you're not careful it's easy to end up in a situation where your image processing solution loads the entire image into RAM and then processes it. Several megabyte images are fairly common, and so this could easily consume a lot of RAM with a large userbase. In practice I won't have many users so the only concern would be a denial-of-service attack, which is also very unlikely. But, this is easy enough to work around that I might as well anyway; it's good to take pride in programming resilient solutions.</p>
<p>Image processing is a complex enough problem that you probably <em>should</em> use a dependency and you should probably just pick one that removes the memory hog vector. I went with <a href="https://github.com/libvips/libvips">libvips</a>. Libvips is <a href="https://github.com/libvips/libvips/wiki/Speed-and-memory-use">much faster and less memory intensive</a> than other solutions. The speed is largely due to use of SIMD, and the low memory usage is because it works on streams. This allows me to feel some confidence that Mosiki should be reasonably resilient to high file-uploading load. Honestly much higher than I ever expect it to experience.</p>
<p>The one thing to be careful about here is that libvips is written in an unsafe language, runs on client-controlled input and this is a server. In this situation you should always at least check that the library is fuzz-checked which will help identify security issues. Google, as much as I take issue with them as a company, does a nice public service with the oss-fuzz project and they <a href="https://github.com/google/oss-fuzz/tree/master/projects/libvips">fuzz test libvips</a>. I checked its history of <a href="https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures">CVEs</a>s and it seems <a href="https://nvd.nist.gov/vuln/search/results?form_type=Basic&amp;results_type=overview&amp;query=libvips&amp;search_type=all&amp;isCpeNameSearch=false">reasonable</a>. Obviously not perfect but it seems reasonably infrequent and lots of what's there is specific limited danger issues. Hopefully distribution package maintainers stay quick on the draw there. Contrast <a href="https://nvd.nist.gov/vuln/search/results?form_type=Basic&amp;results_type=overview&amp;query=imagemagick&amp;search_type=all&amp;isCpeNameSearch=false">ImageMagick</a> which seems like should never be used in a server.</p>
<h2>Diff-match-patch</h2>
<p>Another obvious area of potential performance concern was text-diffing on conflict. Python provides a semi useful diff module called difflib, but it's quite slow. I considered writing my own stuff on top of it to recursively break the sequences up in order to prevent any individual diff-step getting to complex and slow, but honestly, this is the sort of thing you want to get right. And Google's diff-match-patch module seems very reasonable. It's a single file, although reasonably complex at 2k lines. It's pure python but much faster. And even supports a time limit after which it gives the diff to the current-best granularity.</p>
<p><img src="/images/diff_match_patch.png" alt="A screenshot showing an example of conflict in mosiki" />
<em>An example of a diff on Mosiki's simple conflict page.</em></p>
<p>The module hasn't received any updates in three years. I don't consider that a bad sign. It's something with a closed scope. It simply doesn't need to do anymore, and it's something that can be verified reasonably in-depth via generative testing. As such, I have simply included the module in a &quot;thirdparty&quot; folder. I don't see any reason not to as I don't expect future fixes or security problems, and it's a single file. Package managers like pip are hoenstly themselves a quite dangerous <a href="https://drewdevault.com/2022/05/12/Supply-chain-when-will-we-learn.html">point of security failures</a> and I feel when it seems reasonable to just ship the dependency you should consider it, because package hijacking does happen. Relying on distribution package maintainers though seems to have a good track-record and so getting libvips that way for example likely increases security over shipping a fixed dependency.</p>
<p>And that's it. The total dependencies for this at this stage seem to be:</p>
<ul>
<li>Sqlite (provided by python but installing it separately for the command line programs is still helpful)</li>
<li>Flask</li>
<li>Markdown-it-py</li>
<li>Gevent</li>
<li>Argon2-cffi</li>
<li>Nginx</li>
<li>Mdit-py-plugins</li>
<li>Pyvips/Libvips</li>
<li>Diff-match-patch</li>
<li>zope-interface (a dependency by something else here but I forget which one)</li>
</ul>
<p>I feel these generally all pull their weight with maybe the exception of mdit-py-plugins.</p>
<h1>No email</h1>
<p>To simplify the needs of the server, no workflow in the wiki uses email. Instead users sign up via invite codes given by admins. If a user can't log in they can ask an admin to generate them a password reset link. Obviously this adds a bit of overhead but for a niche community I suspect it's reasonable. Using emails adds a whole other layer of stuff that can go wrong, and this project was specifically about making the minimal thing for my use case.</p>
<h1>Iframes, really useful for JS-less pages?</h1>
<p>Developing this without JS was interesting in some areas. For example, with image uploads I don't really want the entire page refreshing just because you uploaded something. The solution I went with was just that the uploads are handled in an iframe, and the iframe refreshes. And honestly it just works very well? I'm not a front-end guru though so maybe this is weird, feel free to send me scathing emails to educate me.</p>
<h1>Accretion-only db</h1>
<p>As a general rule, the wiki doesn't use much of UPDATE or DELETE. Instead new records are inserted and differentiated via an &quot;updated_at&quot; column. Current is selected via &quot;SELECT * FROM pages ORDER BY updated_at DESC LIMIT 1&quot;, which indexes should make reasonable. This is a slightly unusual choice but I find it a safer design in general. Additionally, you usually want to keep records of what things were anyway, and this is just a very simple way to achieve that. The most notable exception is passwords, of which I only keep the most recent.</p>
<h1>Hard limits in software are good, actually.</h1>
<p>While programming I identified a few places where large amounts of requests could blow the server up, such as conflict resolution, image upload, password hashing (because of argon2). While this will likely never be a problem I actually have, I decided to go ahead and address them anyway. A big part of this experiment is being respectful of computer resources, and I think it takes more than just measurement; you need to proactively consider what could go wrong, and how to deal with it.</p>
<p>Image uploading was largely handled by libvips and wrangling file uploading to use streams rather than keeping the entire file in memory. But for password hashing and conflict resolution I decided to go ahead and use a lock to simply limit it to one request doing such work at anytime.</p>
<p>This may seem like an odd thing to do and yes, one at a time is definitely going to be unnecessarily limited for many real-world use-cases. Fortunately, I don't really have those use cases, but I would also argue that limiting the number of memory-intense requests is a <em>good</em> thing. It's tempting to write software without hard limits, but I think this is an illusion. You <em>do</em> have hard limits. At some point, memory runs out. If you want to feel reasonably confident that your memory usage will be low you need to pick a target, and the only way to reliably hit your target is via limits.</p>
<h1>Things are boring when they just work.</h1>
<p>It took me a while to get around to writing this update for perhaps the best possible reason: honestly everything went quite boringly well. The server <a href="https://kirameki.mosfetarium.com/">went up</a> (warning: nerd shit, but it's not much to see at the moment) and has stayed up for months. It requires no effort on my part, other than the occasional OS update for security patches. I should count this a total success, but man, it makes for boring blogging!</p>
<p>Despite the fact that I tried to write it small in order to be understandable, I'm not entirely sure that I'll ever share Mosiki; The point of this blog series was not &quot;hey, you should use my wiki server&quot;. It was an experiment in a way of thinking, and an attempt to promote that way of thinking. I successfully made something that is useful for me and I basically don't have to worry about it, and that is honestly kind of unusual with software, but I think it shouldn't be.</p>
<p>I think it'd be possible to have more things that Just Worked™ if we valued different things. Conscious scope management, careful technology choices, respect for computer resources. Not everything can be as simple as my toy wiki implementation, but many could be a lot simpler than they are. And a lot more mindful of where things could go wrong.</p>
<p>This may well be it for this blogging series. Thank you, dear reader, for following along. I hope you found it interesting. And I hope to have more things to blog about soon that are a bit more interesting than a toy wiki.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">97a95f92-3dcf-ec88-1f1f-17696ffa12a8</guid>
<pubDate>Thu, 27 Oct 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>Mosiki, the Modest wiki. Early tech choices</title>
<link>https://mosfetarium.com/blog/mosiki-early-tech-choices/</link>
<description>
<![CDATA[
<p>
<p><em>(In this blog series I attempt to develop a wiki server that tries to be respectful of computer resources, as part of a self-assigned <strong>Modest Programming Challenge</strong>, the series starts <a href="/blog/modest-programming-part1">here</a>)</em></p>
<p>Alright so I want to develop a wiki— which for now I shall call Mosiki— with speed and lightness. A sensible first question is what am I gonna be writing this in? The tried-and-true high performance language C++? The classic and original C? Or perhaps rewrite all of modern software itself in Rust?</p>
<p>But no, I'm probably just gonna use Python.</p>
<h2>Let's just drop our standards way low now</h2>
<p>Now, there's a chance someone saw the first post and went &quot;<span class="tiltr">YES!</span> You're right! All these <span class="cloud">lumberjack</span> programmers need to stop using JS and transition to something actually capable of making good utilization of resources!&quot; and that sort of person would now promptly call me out for being a poser right now.</p>
<p>I do want to clarify, if you want to truly approach the height of what is really possible with a computer, then you're almost certainly going to want to use a statically compiled language. One where you can reason about how your program is actually going to work in memory, care about cache locality, and maybe break out some SIMD instructions. Certainly if your language has some kind of runtime, uses garbage collection, and a JIT, it's literally doing more than is necessary to actually just run the program, of course it's not going to be as resource efficient as something that isn't doing that stuff.</p>
<details>
<summary>(Click here for an optional tangent about Zig)</summary>
<p>I actually quite like the idea of programming a web-server in Zig. Specifically because of it's allocator system. Zig strives to not do any memory allocation without your knowledge. If a standard-library function allocates memory, you have to pass an allocator to it and this allows you to do some thoughtful optimizations. In particular, I actually really like the idea of having one allocator per request, because then you can trivially track how much memory the request uses and if it passes a threshold, just kill it. A good feature for server reliability.</p>
</details>
<p>But no. I'm not gonna use one of those languages. I'm not even gonna use one of the fast JIT languages. I'm gonna try Python. The thing with the damn Global Interpreter Lock that has prevented good multiprocessing for years. Why would I do this? There's several reasons.</p>
<ul>
<li>Speed of development. It's pretty fast to hack something up in Python.</li>
<li>It helps with one of the project's major goals: be easily modifiable. Python is widely understood and considered unintimidiating. If I wrote it in a manual memory management language some would (probably quite rightly) feel concerned that if they modified it they'd introduce some variety of security error. It also has a nice tweaking experience: just open the damn file and edit it and run the program, no needing to set up a complex dev environment.</li>
<li>It's just a wiki, I mean come on.</li>
</ul>
<p>I'm serious about that last one. A wiki is a simple CRUD app that takes a markup and renders static pages. It should be largely I/O-bound. Python is computationally slow but what computations is this thing going to even be <em>doing</em>?</p>
<p>I think that while yes a lot of Modesty™ can be found in choosing the right programming language, I think you can also achieve a lot just via careful programming, and mindful solution choices. People don't check their memory usage, people reach for large complex solutions to problems that they just don't have. I want to test the idea that people don't have to change absolutely everything about the way they program to end up with better software. I'm going for <em>modest</em> not optimal.</p>
<p>A thing I think more people should care about though is choice of dependencies. Speaking of which...</p>
<h2>You should consider SQLite for your website</h2>
<p>For those of you unaware, let me introduce you to SQLite. SQLite is the <a href="https://sqlite.org/mostdeployed.html">most deployed SQL DB</a>, estimated at over a trillion instances. It's used in aeroplanes and is tested to that industry's standard. The devs care about it's size, speed, backwards compatibility, and reliability. They've pledged compatibility until the year <em>2050</em>. Python comes with bindings for it in the standard library. And it will be the storage mechanism for Mosiki.</p>
<p>It's considered an unorthodox choice for a webserver DB but that's actually not outside of it's goals; the SQLite website itself uses SQLite as its backing, and cites it being a good choice for small-to-medium traffic servers. So should be perfect for my target use case. It also should lower the spec requirements a lot compared to using something like Postgres.</p>
<p>Additionally, SQLite is actually quite fast. DokuWiki just uses files but <a href="https://sqlite.org/fasterthanfs.html">SQLite will probably be faster than I ever will be at that</a>. And what may come as a shock: SQLite is actually <em>faster</em> than typical DBs, at least for simple cases with low write-concurrency.</p>
<p><img src="/images/dbbench.png" alt="A graph comparing database speeds of different operations, showing SQLite in WAL mode coming out on top." />
<em>(Source: <a href="https://sj14.gitlab.io/post/2018/12-22-dbbench/">https://sj14.gitlab.io/post/2018/12-22-dbbench/</a>)</em></p>
<p>By turning on one setting, Write-Ahead Log mode, SQLite outshines popular web server dbs for simple cases. And this really shouldn't be that suprising because it's just doing <em>less work</em> than typical DBs. There's no server, no seperate process, it's an API that reads and writes data to a file in an atomic ACID-conforming way. And yes it won't handle the same sort of concurrent writer load as Postgres but I don't <em>have</em> that problem, and neither do many websites.</p>
<p>If there's anything you take away from this post, it should be that you should consider SQLite a real option for web-servers.</p>
<h2>Markdown</h2>
<p>So I need a markup for Mosiki. I could invent one. But honestly, why? Markdown is pretty good. It's pretty simple. And there's highly tested implementations. <a href="https://github.com/executablebooks/markdown-it-py">markdown-it-py</a> is the one you're meant to use for Python these days. It has some HTML safety features, they've benchmarked it against other solutions, it is even extensible. There's a footnote extension, and I'll definitely use that. Overall, seems like a reasonable solution that even allows for some expansion in the future. I am trying to be careful about dependencies. I don't want to accumulate 1000s of dependencies NPM-style. But this seems like a reasonable choice, and worst-case scenario it could always be replaced with an even lighter Markdown parser.</p>
<h2>The troubles with security</h2>
<p>An area of conflict I wasn't expecting for this project was between Modesty and Security. I decided to look into state of the art password encryption and found that part of it now is deliberately high memory usage. That sounds weird at first but it makes sense on further pondering. Computers these days can do a whole lot of work in parallel, particularly on GPUs. If you want to make sure that your encryption method is safe from large scale brute force attacks you want to make sure it's hard to defeat through all our new parallelized programming power.</p>
<p>And the logical way to do that is to simply use memory. Parallelization has improved much faster than memory sizes. <a href="https://www.rfc-editor.org/rfc/rfc9106.html">Argon2</a> is seemingly the state of the art these days. And it's primary recommended setting uses <a href="https://www.rfc-editor.org/rfc/rfc9106.html#name-recommendations">2GB of RAM</a>. Good luck launching a parallelized brute-force attack against that. It does have a low-memory recommendation that uses 64MB but... honestly that still feels a bit much? I'm trying to target 512MB VPSs here, so 64MB is a lot. But I'm not a security expert, and so I probably shouldn't tamper. I can make a lock and limit it to verifying one login at a time which should make it fine for my use case.</p>
<details>
    <summary>(An optional tangent about an entirely other solution)</summary>
    <p>So what's the easiest way to get around good security being RAM expensive? Plain text password storage!</p>
    <br>
    <p>Yes that was a joke. Please don't ever do that. No, the alternative that occured to me is... maybe don't use passwords? Hypothetically you could just use some email-you-a-code solution, and not ask the user to trust you with a password at all. Although that would mean requiring some sort of mail server, which is somewhat of a complicating matter. You could also use some SSO which obviously involves cryptography but shouldn't be as burdensome. But then you have to saddle people with some SSO restriction. Tough trade-off.</p> 
</details>
<h2>Flask? Maybe?</h2>
<p><a href="https://palletsprojects.com/p/flask/">Flask</a> is a webframework for Python that clearly had some amount of Modesty™ in it's design. It's not trying to do everything but rather be an alright starting point and let people solve the rest of it with extensions if they want. It comes with a templating library, a request life-cycle, routing, some logging stuff, and really not much else. It has about <a href="https://www.openhub.net/p/flask">17k lines</a> to it so it's far from the worst. Strictly speaking I think I could likely not use this and go for something a even more barebones, but it seems like a reasonable-enough starting point. Django is the &quot;industry standard&quot; Python web framework and is huge. ~400K lines to Flask's ~17K. Bottle is another one, quite like Flask to my understanding, and even smaller, has no dependencies. But is fairly niche and doesn't seem the most actively developed. Quart was another Flask-like that is smaller than the original and also uses asyncio (more on that later) but it's also in very low development. I'll go with Flask for now, but moving to Bottle or Quart could make sense.</p>
<h2>Gunicorn? Gevent? Eventlet? Stackless? Reverse proxies?</h2>
<p>The Python ecosystem has a lot of web server options and even an entire web server interface standard called WSGI. I have been doing a lot of reading and comparing options. Flask comes with a development server, but it's not seriously tested as a production HTTP solution and so you can't complain if it has some obscure vulnerabilities and problems.</p>
<p>A common setup seems to be Nginx-&gt;<a href="https://gunicorn.org/">Gunicorn</a>-&gt;Flask. Nginx acts as a reverse-proxy: a server that will act as a bouncer. It's highly tested for security and will provide buffering and other features that can be used to improve stability. I can find <a href="https://iwf1.com/apache-vs-nginx-vs-lighttpd-comparing-performance-resource-usage-and-features/2">benchmarks</a> of it handling 10 thousand concurrent connections with 18 MB of RAM so it should be light enough for my case. I was tempted by lighttpd but I decided to go with the more known thing. Gunicorn provides a worker-model and some supervision but honestly, I probably will be single threaded and don't care about the worker model, so screw it, I won't use Gunicorn. I'm not hugely convinced it'll add much other than complexity.</p>
<p>Additionally, Python has a number of things to help with doing a crap tonne of requests. Particularly they make requests asynchronous via things like coroutines or green-threads, basically light-weight alternatives to threads that you can scale up into the thousands or even tens of thousands. There's a lot of options in this space, Stackless, Gevent, Eventlet, Asyncio. Asyncio is in the standard library and will likely be the popular one in the long term.</p>
<p>Now, I don't really plan to have 1000s of users at anytime for Mosiki, but I think it's good to try and be reliable. Additionally, I'm hoping these systems will help prevent stalls caused by slow I/O requests from one user impacting every other user. For now, I will try using Gevent because it's quite easy to add to a flask program and Eventlet didn't want to work for whatever reason so I can't really compare.</p>
<p>Now, perhaps one of the technologies I have chosen to use is a bad bet. But the beauty of making a Modest Program is that you try to keep the code so simple that anyone with familiarity with the programming language can quite easily maintain it themselves. If I've made a poor choice for Mosiki, it should be easy to change later.</p>
<h2>Testing time</h2>
<p>So my flask+Gevent server with a WIP Markdown page renderer pulling pages from SQLite consumes 35 MB at idle. Combined with nginx doing its 18MB from that benchmark earlier and let's assume Argon2 is using that 64MB setting. That's 117 MB so far on the server stack. And over half of it simply reserved for security reasons.</p>
<p>Alpine Linux is a Linux distribution designed to be tiny and secure. It's based around the impressive musl and busybox projects (I'll let you research those if you feel like it). At boot it uses 41 MB in a virtual machine, at least it does if you're in text only mode. If you're trying to go for an extremely cheap server, using such a distribution helps. For the sake of safety, let's double it's memory usage to 82 MB for my equation. 82+117=199 MB of RAM. That does feel a little on the high side of what is likely hardware-optimal, but let's see how it scales under load simulation. I chose to use <a href="https://github.com/rakyll/hey">hey</a> as my benchmark tool for no particular reason.</p>
<p><strong>20 Concurrent Users doing 2000 (total) simple page loads</strong></p>
<pre class="code-block"><code>Summary:
  Total:	3.1373 secs
  Slowest:	0.0536 secs
  Fastest:	0.0118 secs
  Average:	0.0312 secs
  Requests/sec:	637.4907
  
  Total data:	2452000 bytes
  Size/request:	1226 bytes

Response time histogram:
  0.012 [1]	|
  0.016 [1]	|
  0.020 [2]	|
  0.024 [2]	|
  0.029 [2]	|
  0.033 [1650]	|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  0.037 [246]	|■■■■■■
  0.041 [58]	|■
  0.045 [24]	|■
  0.049 [11]	|
  0.054 [3]	|


Latency distribution:
  10% in 0.0291 secs
  25% in 0.0296 secs
  50% in 0.0304 secs
  75% in 0.0315 secs
  90% in 0.0345 secs
  95% in 0.0368 secs
  99% in 0.0438 secs

Details (average, fastest, slowest):
  DNS+dialup:	0.0000 secs, 0.0118 secs, 0.0536 secs
  DNS-lookup:	0.0000 secs, 0.0000 secs, 0.0003 secs
  req write:	0.0000 secs, 0.0000 secs, 0.0002 secs
  resp wait:	0.0311 secs, 0.0115 secs, 0.0533 secs
  resp read:	0.0000 secs, 0.0000 secs, 0.0003 secs

Status code distribution:
  [200]	2000 responses

</code></pre>
<p>So, at 20 concurrent users, probably quite high for the intended use case, this simple page load is basically instant by internet standards. I saw no real perceptible memory increase. Now, let's try a more proper stress test.</p>
<p><strong>1000 Concurrent Users doing 2000 (total) simple page loads</strong></p>
<pre class="code-block"><code>Summary:
  Total:	7.4600 secs
  Slowest:	7.3279 secs
  Fastest:	0.0631 secs
  Average:	1.3052 secs
  Requests/sec:	268.0980
  
  Total data:	2452000 bytes
  Size/request:	1226 bytes

Response time histogram:
  0.063 [1]	|
  0.790 [1016]	|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  1.516 [303]	|■■■■■■■■■■■■
  2.243 [310]	|■■■■■■■■■■■■
  2.969 [41]	|■■
  3.695 [271]	|■■■■■■■■■■■
  4.422 [41]	|■■
  5.148 [0]	|
  5.875 [0]	|
  6.601 [0]	|
  7.328 [17]	|■


Latency distribution:
  10% in 0.2357 secs
  25% in 0.3473 secs
  50% in 0.5573 secs
  75% in 1.9608 secs
  90% in 3.3497 secs
  95% in 3.5311 secs
  99% in 3.7537 secs

Details (average, fastest, slowest):
  DNS+dialup:	0.0201 secs, 0.0631 secs, 7.3279 secs
  DNS-lookup:	0.0028 secs, 0.0000 secs, 0.0582 secs
  req write:	0.0021 secs, 0.0000 secs, 0.0471 secs
  resp wait:	1.2688 secs, 0.0110 secs, 7.3278 secs
  resp read:	0.0001 secs, 0.0000 secs, 0.0025 secs

Status code distribution:
  [200]	2000 responses
</code></pre>
<p>Obviously the average load speed here gets a bit bad, but it handled it, didn't max out a CPU core, and most importantly, memory usage didn't go nuts. Nginx seemed to end up only using about 15 MB, and my flask+Gevent server got to 36 MB, 1MB greater than idle. Setting aside some memory for Argon2 and my Alpine ballpark with it's extra sapce, that's 197MB of RAM for what is likely a very high load scenario for what I'm making. Scaling well so far then. That 1 MB increase conveniently is around about the number of current users times the payload size, I suspect that is not an accident. If I keep my page sizes small, via tightly curated CSS, no JS, and sensible image formats such as PNG, then this all should scale quite well.</p>
<p>Weirdly, the <em>peak</em> memory usage according to <code>grep ^VmPeak /proc/pid/status</code> of the flask+Gevent server was around 215 MB but it has that peak seemingly immediately. I know Gevent does monkey patching on the standard library to work, and maybe that causes an initial memory surge, which sucks, but it's probably managable. The server is possibly still usable on a 256 MB RAM VPS with some Swap?</p>
<p>Point is though, memory usage seems low and so far the Python bit is only 36MB. You can only really improve the RAM substantially by using an even tinier OS, or compromising on password security. All of the Modesty so far has been about careful choices in what I'll build on; trying to add things that seem like good bang-for-buck and avoid things that seem like too much for my problem. I did a lot of looking around online for benchmarks where possible. So far, I think it's working out quite alright.</p>
<h2>Goodbye for now</h2>
<p>My work on Mosiki is no where near done; it's basically a simple markdown-from-sqlite renderer at the moment. And as I flesh it out more I'll be able to make tests with more representative pages. In theory you could benchmark an edit work load, but honestly I don't think that's likely very relevant to my use case? I'll probably do it anyway for completeness sake.</p>
<p>The next post I do in this series I'll show off where Mosiki is at feature wise, go over some random engineering decisions I made and some actual code. It'll probably be a post less relevant to the performance goals of Mosiki.</p>
<p>Thanks again for reading. If you have any comments, questions, or suggestions feel free to reach out.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">a83ea1d9-fe09-d0c0-59ec-161e6d69ddea</guid>
<pubDate>Sun, 15 May 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>Modest Programming Challenge: Let's try to write software that sucks less</title>
<link>https://mosfetarium.com/blog/modest-programming-part1/</link>
<description>
<![CDATA[
<p>
<p>I've heard it, you've heard it, there's absolutely no news in saying &quot;<span class="tilt">WOOOW</span> computer hardware sure is impressive these days! You can put a <span class="tiltr">super-computer</span> in your pocket!&quot;</p>
<p>Sadly, an observation not quite as common is &quot;and yet everything kinda sucks to use.&quot; It's true that common smartphones are incredible machines by the standards of computer history and much more powerful than home desktop computers were in the 90s. But there's a growing sentiment amoungst many variety of whiney programmers— which I <em>definitely</em> am by the way— that our field squanders this potential.</p>
<h2>Don't mind me, just gonna make a sweeping statement based mostly on gut feel and anecdote, no biggie</h2>
<p>I'm going to make a somewhat <strong>bold statement</strong>: I personally do not see any reason for the average consumer, and even most enthusiasts, to have computer hardware seriously improve from this point. I even feel that had our industry tried harder, computers from ten years ago would have easily fufilled the majority of needs. There are definitely exceptions to this such as video editors, but again they are exceptions.</p>
<p>Conceptually, when you think about the size of 16GB of RAM.... is a <em>lot</em> of information. That's 4 <em>billion</em> 32 bit numbers. If a common user workload can seriously approach that amount of data I feel like <em>something</em> is up.</p>
<p>And this isn't just pointless complaining— although that is one of my favourite passtimes. No, this is quite impactful. The world is effectively wasting large amounts of energy, industrial capacity, rare minerals, consumers' time and money on what really feels like nothing; we upgrade our computers and yet we don't have a snappier experience than we did 10 years ago. They say we do this because hardware is cheap and programmer time is expensive, but I'm curious if the cost of that hardware really factors in all the lost-opportunity cost and negative externalities. We don't have an endless supply of minerals, and hell, we're even in a silicon chip shortage <em>right now</em>. Additionally, this is often a negative externality: the cost is on the <em>user's</em> hardware. It's easy to say it's cheap when you don't pay for it.</p>
<p>Now, I could just sit here and complain. After all, what's the fun of a blog if not engaging in grossly oversimplified criticisms. But I think if we want things to change, we need to participate in and foster a culture of <em>trying</em>. I'm not gonna say absolutely everything <em>must</em> be done in the most optimized way ever. But I think it'd be good to begin a culture of <em>checking</em> these things, paying attention to our software's resource usage and asking &quot;Does that seem reasonable?&quot;. I think that mindset alone would go a long way. Here on this blog I'm going to call this &quot;Modest Programming&quot;: simply asking yourself if your program is reasonable in what it asks of the user's computer, and really trying at all.</p>
<p>This idea is far from unique. We've got <a href="https://suckless.org/philosophy/">suckless</a>, we've got <a href="http://viznut.fi/texts-en/permacomputing.html">permacomputing</a>, we've got <a href="https://100r.co/site/uxn.html">uxn</a>. I could name more. I don't claim to have invented this notion, and I'm not pitching &quot;Modest Programming&quot; as the term that should be used around the net. It's just the wording I like, and so I'll use it on this blog.</p>
<p>But enough with that. It's time to practice what I preach. Emphasis on practice.</p>
<h2>The Experiment</h2>
<p>Recently I was talking in a discord server that I frequent, and commonly exchange information and opinions about deeply obscure japanese video games. In case you had not figured it out so far: yes, I am in fact a filthy nerd.</p>
<p>There's a question that gets asked there reasonably often, that has no simple answer, and it raised to my mind the thought of &quot;Man, it'd be kind of nice to have a community wiki for some of that stuff.&quot; Now, obviously random free wiki hosts like Fandom™ (formerly Wikia®) exist, but personally, I like <em>owning</em> community spaces. And setting up your own sites is fun. So I found myself looking into what wiki software is out there, and how cheap I could reasonably run a small community wiki.</p>
<p>Sadly, I couldn't really get much of a solid answer on how low-spec existing wiki software went. I'm sure they're not <em>insane</em> but if I could get this thing running very reliably on a 512 MB RAM VPS I'd very much appreciate that. And looking around it felt like none of the many perfectly high quality solutions had really been paying attention to this particular point. There is <a href="https://www.dokuwiki.org/dokuwiki">DokuWiki</a> and don't get me wrong. It looks pretty solid. It doesn't even use a DB which I think is a good choice for both being light-weight and simple; the qualities someone would want for a small community wiki. But again, I couldn't really find exact details on just how low I could turn this thing down, and how well it'd handle it. Generally using little memory is one thing, but can it resist collapse in the face of some reasonable traffic?</p>
<p>Now, I haven't done too much web server programming in a wee while, and I felt like I should get some practice. Also, I'd like to give myself a <strong>Modest Programming Challenge</strong>™. So, why not try making a modest wiki implementation? A wiki is not the most impressive thing ever, and so you may think that that makes them not a great example for Modest Programming. I disagree. I think because wikis are so simple in their general function it should be reasonable to run one on some innanely small devices.</p>
<p>I will also admit, and I'm sorry if there's any PHP fans reading this, but a very large portion of established wiki server options use PHP, and quite frankly. I'm just prejudiced against <em>any</em> software built on that technology. I don't want to run it, I don't want to administer it. I'm absolutely sure you can point to perfectly good examples of PHP server software. Even wikipedia is one of them. <a href="https://news-web.php.net/php.internals/70691">But I've read too many things to feel comfortable touching it</a>. Forgive me for my paranoia.</p>
<p>The product of this will have reasonably little use case. DokuWiki is likely a generally good solution for the small community case, and obviously MediaWiki is extremely battle-tested. But this is partially for practice, fun, and there are a few things I'd like to do different.</p>
<p>Speaking of which, let's lay out some goals.</p>
<h2>Goal 1: Should run on extremely cheap VPSs</h2>
<p>The specific use case I'm targeting is moderately technically capable people who want to quickly set up a small community wiki at extremely low cost. This site is hosted on Neocities so you can probably guess that I'm somewhat opposed to the &quot;BigTech&quot; CorpoWeb™. I think if we want more community-owned spaces, we need to make them as cheap to run as possible.</p>
<p>Additionally, as I have already stated. A wiki really is an extremely simple app in terms of what it actually does, sure it's not <em>technically</em> a static site but it's <em>very</em> close. I feel it should be possible to run on pathetic hardware.</p>
<h2>Goal 2: Should be very simple to administer</h2>
<p>Again, community-owned spaces online run largely on volunteer labour so we need to respect that labour. I think the general set of things someone should need to learn to use this and administer it long term is:</p>
<ul>
<li>What a VPS is and how to set one up</li>
<li>Some bash</li>
<li>Maybe some SQL</li>
<li>An extremely simple configuration setup for the wiki settings</li>
</ul>
<p>The last one is fairly important. Most small communities don't really need complex access rules. They want a wiki that is easy to set up and then gets out of their way.</p>
<h2>Goal 3: Should be very easy to modify</h2>
<p>Now, this one is something that DokuWiki does not satisfy in my opinion. I am a big believer in simple software for technical users who can come to understand the entire thing in quite some detail. I use a custom modification of <a href="https://github.com/sunainapai/makesite">makesite</a> to generate this blog (okay, it's not the most impressive blog, I will admit) and I love the solution. It's a dirt simple python script with a template that generates a static site. If it doesn't do something you want, you can make it do it because it's so simple that you can read through the entire thing and its templates in a lunch break. And honestly, for a reasonably technical person that might be a better solution for customizability sometimes. Contrast trying to make a complex piece of software that can do everything as long as you want to invest the time in figuring out how you make it do anything. Then you pray to god that it doesn't surprise you with anything weird at some point that you can't debug because it's far too complex to just solve trivially.</p>
<p>So that's a thing I want for this modest wiki. DokuWiki doesn't fit the bill because according to OpenHub it's <a href="https://www.openhub.net/p/dokuwiki">233K lines of code</a>. That's not a tool you can understand entirely.</p>
<h2>Goal 4: Should deliver trivially small payloads, fast</h2>
<p>I'm going to layer more stereotypes on to myself here and say that the web is a goddamn mess. Pages are unreasonably huge for most purposes. Things take way too long to load. I use Google's <a href="https://pagespeed.web.dev/">Pagespeed Insights</a> to evaluate performance of my blog and I'm happy that it's a solid 100. It could be even more streamlined; most of my website's by filesize is fonts when I could just use fonts that come with most operating systems. But it's still pretty good.</p>
<p><a href="https://pagespeed.web.dev/report?url=https%3A%2F%2Fwww.dokuwiki.org%2Ffeatures">DokuWiki does not perform well on this metric for phones</a>. Additionally a very simple page <a href="https://gtmetrix.com/reports/www.dokuwiki.org/HC7YC63L/">comes in at 1.35MB</a> and I'm just unimpressed. 1.15MB of that is just Javascript. <a href="https://gtmetrix.com/reports/en.wikipedia.org/1ZIuE4i4/">Wikipedia does better</a> with 526KB on a reasonably simple page, one with pictures even. But 309KB of it is Javascript.</p>
<p>I'm not some hard-core NoScript kinda guy but I have to ask: what on earth are these pages <em>doing</em> with so much javascript? They're server-rendered pages. Why do they even use Javascript at all? I can understand why a wiki may have them in editor pages or admin pages, but for <em>viewing a page?</em> Why? This is what I mean by software needs to be more modest; try asking <em>why</em> you are introducing some requirement, whether it be on hardware, internet connections, or just some additional bit of technology. In this case, I can't really see much of a justification.</p>
<p>Now I might end up changing course on this but I'm going try for zero javascript. There are definitely useful things you can do with JS on the editor side, but fundamentally, I don't see a hard need. So why not? And it makes this project potentially more useful for someone. Sure that someone is NoScript weirdos, but I <em>am</em> a weirdo. Not that exact kind, but us weirdos gotta stick up for each other.</p>
<noscript>
<strong>SECRET NOSCRIPT TRANMISSION</strong>
<p>Hey there. This message is placed inside of a noscript tag and so should only appear on some JS-less environment. And it's sort of funny that I can just like, sneak a message in here and know that probably only one kind of person will see it. Anyway, NoScript People: I hope you're not offended by me calling you weirdos. I consider that a compliment. Weird people make the world interesting, and do the things that other people don't want to do but others benefit from.</p>
<p>I can't live like you, NoScript People. I'm not your exact kind of weirdo. Not yet anyway. But I respect your commitment, and likely paranoia. From one freak to another, I salute you. o7</p>
<p>If you see this, send me an email or message me on Mastodon. It'd be funny just to know that this message was received. Should I keep adding NoScript secrets in the future? Maybe. Anyway, let's return to your regularly scheduled blogramming.</p>
<p><strong>END OF TRANMISSION</strong>
</noscript></p>
<h2>Goal 5: Put in a reasonable effort to make it reliable</h2>
<p>So this one is probably the most iffy goal of the lot. But ideally, the wiki should be able to survive some surges and not get taken out by weird edge cases. Now, high-availability is an entire subfield of software engineering, and it's very hard. Realistically I'm not gonna achieve that much on this front; I don't want to put the expectation on users to set up several nodes in a redundant server network.</p>
<p>But I should pay attention and do some tests. Try to make sure that there aren't obvious early bottlenecks and areas where the memory usage could spike high and have a single bad request take down the server for everyone. I consider this a side-aspect of Modest Programming: puting in some effort to try to preemptively eliminate degenerate situations that will cause instability for ends users.</p>
<h2>Goal 6: Blog about it, for fun</h2>
<p>I want to promote this idea of <em>even trying</em> to make software reasonable in it's demands. Doing it in silence is well... obviously impossible. So I'm going to share the adventure here, and some of my decision making process. Perhaps some of you will like the idea of the <strong>Modest Programming Challenge</strong> and try to make some modest software of your own, perhaps you'll like to ask questions or propose alternatives to my decisions. If you do either, <a href="/about">tell me about it</a>. I'd love to hear from you, see what you do, and if you give me permission I'll mention it here in the blog.</p>
<p>If you want to follow along with this journey, remember to put my RSS feed into your newsreader. And <em>yes</em> that sentence <span class="tilt"><strong>SHOULD</strong></span> be the new &quot;like and subscribe.&quot;</p>
<p>The next post will be on my early technology choices. I think they'll be a little surprising, because I won't be going with a low-level language. I know the software could be even more optimized if I did, but I feel there's real headroom for modesty from just trying at all, without having to change entire technology stacks. Anyway, thanks for reading and see you next time.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">8c7437fe-d082-e2ae-8788-32b83151b019</guid>
<pubDate>Thu, 12 May 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>Quick Tip: Validate your site's RSS feed with XML Starlet</title>
<link>https://mosfetarium.com/blog/quick-tip-rss-validation/</link>
<description>
<![CDATA[
<p>
<p>Hey internet. Here's a quick tip. If you're reading this you've probably found my website through neocities. Maybe Mastodon. This means there's a very high chance that you're a nerd who has/is considering getting your own website, maybe you like zines, might have strong appreciation of font choices, perhaps opinions about text editors, and you probably like RSS feeds.</p>
<h2>Don't know what RSS is?</h2>
<p>If you're unaware of what an RSS feed is, I'm going to go ahead and say the fact that you're even <em>at</em> this page means you're probably exactly the sort of person who would enjoy RSS feeds. <a href="https://aboutfeeds.com/">Read about 'em here</a>. If you have your own Neocities site, you actually already <em>have</em> an RSS feed of your site updates, provided by Neocities. But, maybe you maintain your own one separately. Maybe you use some sort of program or script to generate one for you. If you run a site/blog but don't have a feed, you should get one! It's a cool feature of the independent web.</p>
<h2>Oh fickle technology</h2>
<p>In the past week I have on two different occasions encountered a broken feed. RSS (and Atom) are making a bit of a come back it seems, but they're still a little niche and often people don't get any metrics on activity there. So if it breaks, unless someone in the probably smallish audience says something you just might not know. I know one of those two cases was someone hand-editing their feed, I don't know what the other case was. And personally, this made me a little paranoid. I use (a cutomized version of) <a href="https://github.com/sunainapai/makesite">makesite</a> to generate this blog and it works pretty damn well but it's not impossible that there's some niche case where I'll break my damn feed and maybe not notice (Although, I do keep my own feed in my own newsreader. I'm just that egomaniacal).</p>
<p>So, I added a quick validation check to my deploy script. And thought I'd share this with anyone else out there using bash as part of their static site generation, and appreciates a good validation check (I already established that if you're reading this, you're probably a damn nerd, don't deny it).</p>
<h2>You said this was a 'quick tip', give me the goods!</h2>
<p>Fine here's the gist. There's an XML tool called XML Starlet. Get it via your apt-get, flatpak, snap, dnf, brew, pkg, pkg_add, wget, or rm command. Once you do we're going to get an XML schema so that XML Starlet knows the RSS rules. <a href="https://github.com/musiKk/rss-schema/blob/master/src/main/xsd/rss-2.0.xsd">I found this one here.</a> <a href="https://github.com/docjason/XmlValidate/blob/master/schemas/atom.xsd">Here's another I found for Atom, if you use that</a> Go ahead and put that in some file called rss.xsd or whatever, in an appropriate folder for your website's build system. All you need to do now, is put into your bash file:</p>
<pre class="code-block"><code>set -e
xmlstarlet val -e -s path/to/rss.xsd path/to/rss.xml
</code></pre>
<p>With the appropriately edited paths there instead obviously. The &quot;set -e&quot; means the script will abort if your check fails. Note that this will cause your script to abort if any following command errors. That seems like reasonable behaviour to me but if that isn't good for you, you can research how to abort on a specific failure. &quot;An exercize for the reader&quot;, as we lazy authors say.</p>
<p>That's it. You're done. Congrats. Why don't you reward yourself by, hmmm, perhaps adding this link to your newsreader? <a href="https://mosfetarium.com/blog/rss.xml">https://mosfetarium.com/blog/rss.xml</a>. I wonder what it could be! Could great wisdom and entertainment come from this feed in the future?! Only one way to find out!</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">1e06b5e2-3b7b-1aa6-d605-c467ca42203a</guid>
<pubDate>Wed, 04 May 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>Cool Stuff, 2nd Edition</title>
<link>https://mosfetarium.com/blog/cool-stuff-2nd-ed/</link>
<description>
<![CDATA[
<p>
<p>Time for another &quot;Cool Stuff&quot; post. Where I just share neat things I've found from around the net. Been meaning to do more of these but better later than never.</p>
<h2>Marginalia Search: a fun niche search engine.</h2>
<p>There's no shortage of interest in alternative search engines these days. Some are motivated by concerns about tracking, others are motivated by a feeling that Google search result quality has dropped massively. And obviously the second sentiment is ridiculous! Why, Google offers the finest selection of ad-riddled, SEO-spam! Made from regurgitated text harvested from other sources. Truly the cream of the crop.</p>
<p>Okay, I'll put the sarcasm away. The fact is that these days Google is very bad at certain topics. You'll find a lot of ads, corporate websites, content mills, information regurgitators. But some things are very hard to find. Things that feel human, things written by enthusiastic individuals highly invested in a subject. Somehow through searching all available human information, the collective efforts of human culture and endeavour, Google search results manage to be... dull. Boring! And who has time to for that?</p>
<p>In comes Marginalia Search. A search engine with a strong opinion. It prefers pages that are mostly text, simple in design; it's biased heavily towards personal websites, and not corporate ones. It's not a general Google replacement. You can't use it to find a flight to visit your parents, nor could you use it to ask an open question for it to interpret, but for it's specific tasks, finding human pages and communities, finding personal websites of dedicated specialists, it easily beats Google.</p>
<p>Of particular joy to me is the Random Pages feature. Which will pull a collection of random pages from Marginalia's index. The average personal website is admittedly a bit bare and pointless (not unlike mine, to be honest), so the average page you'll find probably won't be particularly enthralling, but refresh the page enough and eventually you'll find something quite curious. It's certainly helped me build up my RSS feed.</p>
<p>Anyway, there's a good chance if you're here you've found me through Neocities. So this should be exactly your sort of thing.</p>
<p><a href="https://search.marginalia.nu/">Marginalia Search</a> <a href="https://search.marginalia.nu/explore/random">Random Pages</a></p>
<h2>Noclip site: fly around video game worlds in your browser!</h2>
<p>Noclip is a website that allows you to check out levels from an assortment of different 3d games, and fly around in them unconstrained (this is often called &quot;noclipping&quot; in the games industry). For many of you, this will just be a neat small thing you might play around with for five minutes. But if you're interested in game dev, this is actually incredibly useful as reference to professional quality (if sometimes old) video game environments.</p>
<p><a href="https://noclip.website/">Noclip Homepage</a></p>
<h2>SELF PROMO ALERT: In Reverence For A Captain</h2>
<p><em>After a while of working a job she hates, she fears she's having a mental breakdown...</em></p>
<p>There is an annual event called Inkjam. A gamejam in which contestents make a small game using the Ink narrative scripting system in 3 days. I made an entry last year, and it took 2nd place!</p>
<p>There's no prize for that, other than bragging rights. So here I am. Bragging!</p>
<p>It's free, short, you can play it entirely in your browser. I wrote it in three days so temper your expectations, but people seemed to really enjoy it. Maybe you will too.</p>
<p><a href="https://distractedmosfet.itch.io/in-reverence-for-a-captain">Play In Reverence For A Captain</a></p>
<h2>ACTION BUTTON REVIEWS: Tokimeki Memorial</h2>
<p>So it feels pretty cheap to reccomend a youtube video here. Part of my explicit point of making this site and doing this blog series is to contribute to the growing independent web revival, but I think this video is very special. Easily in my personal top 10 youtube videos ever.</p>
<p>In this video Tim Rogers, the most interesting person to ever review video games, spends <em>six hours</em> talking about legendary untranslated japanese dating simulator game Tokimeki Memorial.</p>
<p>Now, you have likely never heard of this game and perhaps do not care about untranslated japanese dating simulators and so see no point in watching a six hour video about it. But just listen to me. This video <em>is so good</em> it will not feel like six hours. It is meticulously edited and lovingly embelished with personal anecdotes, essay worthy social commentary, industry insights, and hilarious shitposts.</p>
<p>You should watch this video. I have watched this video like four times since it came out nearly a year ago. It's just that good. You will find yourself invested in a tale about a game you previously never heard of, invested in the personal anecdotes of a particular strange game reviewer, and accidentally mimmicking his speech patterns for several weeks.</p>
<p>However this is a Neocities site and linking to Youtube on here feels sort of... wrong. So I'll give you a link that uses an alternative front-end. If this link ever goes down, you should be able to find the video by title.</p>
<p><a href="https://piped.kavin.rocks/watch?v=xb-DtICmPTY">Watch on Piped</a></p>
<h2>Libreddit: when you want the content of Reddit but not the website of Reddit.</h2>
<p>Last time I shared Nitter. An alternative frontend to Twitter. This time I'm sharing libreddit, an alternative frontend to Reddit. These sites and others are part of a growing tiny movement in <a href="https://drewdevault.com/2021/09/23/Nitter-and-other-internet-reclamation-projects.html">&quot;internet reclamation&quot;</a>. Basically, people who don't like all the tracking and user hostile design the major sites partake in. So instead you can use these alternative frontends to access all the same content without tracking, in a lighter website that will often load much faster.</p>
<p>In the case of Libreddit, it's very useful on mobile because the page is very light and loads fast, but also it doesn't engage in all the hostile nagging to install the app that the Reddit mobile site does.</p>
<p><a href="https://github.com/spikecodes/libreddit">Libreddit github</a> (Check out the instances list to try a server. Different servers can be quite a bit slower or faster in my experience.)</p>
<p>Anyway. That's all for this time. Got some random cool thing you've found on the internet? Maybe something you've made? <a href="/about/">Share it with me</a>! See ya next time.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">eb21e4ce-a929-d34a-a801-c8d09c0d562e</guid>
<pubDate>Mon, 18 Apr 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>The X-Files makes the 90s feel foreign</title>
<link>https://mosfetarium.com/blog/xfiles-foreign/</link>
<description>
<![CDATA[
<p>
<p>Hey there Internet. Recently I have been watching the X-Files, for basically my first time. I had seen a few episodes in the past and obviously was aware of the show and it's popularity and influence. For those who aren't: the X-Files is an american science fiction drama series that started in 1993 and produced over 200 episodes. It was a big hit and is referenced regularly even today. What I want to talk about is how the show feels like it comes from a very different world.</p>
<h2>Cultural differences in space and time</h2>
<p>&quot;The past is a foreign country: they do things differently there&quot; is a quote I've heard a lot in my life although in a shortened form, but never before have I felt this way about the 90s until watching this show. Some of the reasons for that are straight-forward such as depictions of people smoking in office settings. Depicting a man's office cubicle as having a bikini model calendar really stood out as a thing I wouldn't even consider someone doing. But there's a deeper and more subtle difference in this show. It doesn't simply have small antiquated details but rather is inherently built out of an old worldview.</p>
<p>The show starts with one FBI investigator, Agent Dana Scully, being told she will be assigned to work with Agent Fox Mulder. She has heard of Mulder by reputation. He is considered a brilliant psychological profiler, and was a rising-star for the bureau, but has become a subject of tension and concern in the department. Mulder believes in paranormal origins of unexplained phenomena, and has taken up the X-Files, a fictional designation for cases to mark them as unsolvable and low priority. Scully has a medical background; she is a woman of science and is very grounded and skeptical in her thinking. As such, the director is pairing her with Mulder, not only to temper his unusual lines of inquiry, but it is implied they want her to work towards building a case that the X-Files are not worth investigating at all, and that Mulder is spending bureau resources on his paranoid delusions.</p>
<h2>David vs Goliath, but about conspiracy theories</h2>
<p>This tension really is at the heart of the show, not just between Mulder and Scully, but between Mulder and almost everyone else. Mulder is a thought-deviant, who doesn't fall within the boundaries of the orthodox worldview. And generally episodes feature someone on at least one occassion expressing humour or strong disapproval of Mulder's theories or implied lines of reasoning. Mulder is in conflict with the rest of society, constantly. The only exceptions are the victims of paranomal phenomena and hobbyists who report them. They are the true believers, those who believe &quot;The Truth Is Out There&quot;, and the show depicts them usually as the sympathetic underdogs in this cultural conflict.</p>
<p>And this cultural conflict the show is built around feels completely unusual today. People don't feel like there's one &quot;undisputed world view&quot; and a weird fringe. In fact a major worry is that <em>too many</em> people believe in paranoid and unsubstantiated conspiracy theories, or assign far too much weight and importance to largely perceived but meaningless issues. Everyone simply rolls their eyes at Mulder, but today his sort of behaviour represents a serious social disease that is regularly seems comparable in harm as things like problem gambling. Imagine a show that affirmed someone's alcoholism as moral and downtrodden.</p>
<h2>They're here</h2>
<p>I feel like a modern work made in response to the X-Files would not make use of the same sort of &quot;the rare truth-seeker against the world&quot; mentality, but rather would have to engage with the fact that most of what is &quot;out there&quot; is most certainly not the truth, but rather dangerous thought-entities that wish to make you their host; our own real-world alien body-snatchers.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">33d9fcd9-8386-9029-be7c-c1e3ebab19ad</guid>
<pubDate>Sat, 16 Apr 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>Leveling up is such a pain as a game designer.</title>
<link>https://mosfetarium.com/blog/leveling-up/</link>
<description>
<![CDATA[
<p>
<p>One of the things I think that players of games don't appreicate is just how hard game design <em>is</em>, personally I find it much harder than to learn than programming or art creation. Even extremely common game features create a lot of challenges for designers. Take for example, games in which the player customizes their characters strengths and skills.</p>
<p>Controlling a character that you selectively improve the skills of is an extremely popular game design trend. The trend is so popular it's slipped it's way into basically every other genre, and I think for good reason. But it often creates really fundamental challenges by existing at odds with other player desires.</p>
<h2>Broken Promises</h2>
<p>You can think of video games as making promises to players, and generally speaking any game with character skill customization has these implied promises to the player:</p>
<ul>
<li>The player chooses which skills the character improves at.</li>
<li>Skills are needed to progress in the game.</li>
<li>I will not be able to get myself into some unwinnable situation where I must restart the game.</li>
</ul>
<p>The last one is obviously nothing to do with skill progression specifically, but rather just design value that entered the minds of game-likers <a href="https://grumpygamer.com/why_adventure_games_suck">from as early as the 80s</a>. However, it creates a huge problem with the first two promises. If the player can choose the skills, and skills are needed for progress, it is now up to the game designer to make sure that no matter what combination of specialization choices the player makes, that they will still be able to finish the game. Any RPG of even moderate complexity will have thousands of possible variations in exact stat levels and skill selections. Far more than a designer could ever account for.</p>
<p>The job as a designer becomes to find some clever tricks that allows the game to be doable even though there are more possibilities than you could ever consider, which encourages the designer to try and build a system that undermines the importance of what options the player picked. In many RPGs you often find yourself picking between what exact way your character deals points of damage: melee, ranged weapons or spells, but ultimately you're just dealing damage, and there's isn't really a difference. But this also backfires, as it turns out the player had another expectation: we expect our choices to be meaningful. A choice with no consequence doesn't feel like a choice at all.</p>
<p>And here you have a real design trap. Players like and frequently expect the ability to customize character skills, they expect that they can't get it wrong, but it needs to convince them that what they picked mattered. This isn't entirely impossible, but it's a really strong conflict of desires that can be quite difficult to manage.</p>
<h2>But wait, there's more</h2>
<p>This isn't even the only common issue with leveling up. A different problem occurs when you are attempting to make a game that is non-linear or open-world with player-chosen skill progression. Let's look at the promises:</p>
<ul>
<li>The player chooses which skills the character improves at.</li>
<li>Skills are needed to overcome challenges and obstacles.</li>
<li>The player chooses where they go.</li>
</ul>
<p>This won't exactly be a plot-twist, but obviously if there are obstacles the player can't overcome because of their skills choices, then the player doesn't choose truly where they go. This wouldn't be that much of a problem, because players are usually happy with just some amount of freedom rather than absolute, however it is often the case that a player may not understand that they have not leveled-up enough for an area, and instead get frustrated and assume the game is simply unfair.</p>
<p>In addition to that, the player can also be extremely overleveled for a challenge, and blow right through it in a way that wasn't very interesting. And depending on the order they've done things, it might take them a while before they find something challenging again.</p>
<h2>Solutions</h2>
<p>These two problems are hardly new, and any actual professional game designer reading this will probably be like &quot;yeah duh&quot;. But for the rest of you out there, here are some solutions to these problems.</p>
<p>The way I like to think about character progression it is that instead of skills determining &quot;whether&quot; you progress. They determine &quot;how&quot; you progress. You attempt to design your scenarios, your quests, such that there are frequently fallbacks and options that make use of other skills, or lack any specific skill requirement at all, but that these different routes feel different due to a difference in roleplaying, story, and consequences. If you can't best an antagonist in combat, maybe you need to trick them, find some poison to sneakily assassinate them with, or bribe them to get them out of your hair. These all progress the scenario, but they do it in ways that feel different to the player because they all tell a slightly different story that say different things about their character. And they could have different small consequences that appear in the story later.</p>
<p>This is far from the only solution. Some games simply are structured such that the player can always grind for experience and level up more until they can overcome the obstacle. But the difference in &quot;how&quot; is my favourite solution. I find grinding just feels like a chore the game says you have to do before it'll let you play the rest of the game.</p>
<p>For the second problem, designers usually use a mix of layout and teaching. First laying out out the game world such that as you get further from the starting point it gets harder, in any direction you go. And with the second, they try to make sure the player understand that they're just not high level enough for a challenging area. This can be done even in the art, such as by having an extreme contrast of environments where one looks scarier than anything you've yet seen. Another is to force the player into a difficult situation where they must simply run away early into the game, Dark Souls' first boss fight is a pretty famous example of this.</p>
<p>Another trick open world RPGs sometimes use is to have enemies automatically increase in strength if the player is higher level, in order to always be challenging. But this feels like it undermines the leveling up mechanic. Is your character really getting stronger, if everything else will just get stronger in response?</p>
<h2>Closing</h2>
<p>I've been working on a game prototype recently and I felt like writing these down for anyone out there who hadn't been exposed to these challeneges. I might write a post soon about how I'm intending to approach leveling-up and stats in general in this prototype.</p>
<p>If the thought of &quot;contradictory game promises&quot; interests you, I reccomend the talk &quot;Cursed Problems In Game Design&quot; by Alex Jaffe. You can watch it <a href="https://yewtu.be/watch?v=8uE6-vIi1rQ">here</a> on the Youtube-mirror Yewtube, or on original Youtube <a href="https://www.youtube.com/watch?v=8uE6-vIi1rQ">here</a>.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">acb3e2b2-2221-1c2c-3da2-203f6cfe3449</guid>
<pubDate>Fri, 25 Mar 2022 00:00:00 +0000</pubDate>
</item>
<item>
<title>Fediplex: Follow the local timelines of many mastodon servers</title>
<link>https://mosfetarium.com/blog/fediplex/</link>
<description>
<![CDATA[
<p>
<p>I've been using <a href="https://joinmastodon.org/">Mastodon</a> a lot more recently. For those unaware it's basically like twitter, but anyone can host their own server and build their own community, but people can still follow and interact across server providers. I quite like it, and I like having a 'local timeline'. That's a timeline of all public posts people in the same server are making. It's neat because often you join a server based on interests and so it allows you to find people with the same interests. However, there are many servers, and I wanted to follow many local timelines easily.</p>
<p>There didn't seem to be an easy way to do this. So I made one.</p>
<h2>Fediplex</h2>
<p><a href="https://mosfetarium.com/fediplex/">Fediplex</a> is a pretty simple page to address this issue. It's still pretty limited. Notably there's no media previews, custom server emojis don't work, and if you want to reply to a post you kinda have to go through the cumbersome process of clicking through to the status, etc etc. But it was quick to write, easy to maintain, and does the core job.</p>
<p>It's pretty straight forward. Chuck mastodon server links into the box on the left and click add to list. Your list is remembered in your browsers local storage, so even if you close the tab and come back it'll be here.</p>
<p>Hopefully this page is of use to somebody else too, and if you have any feedback, <a href="/about.html">hit me up</a>.</p>
<p>For now, I only have a few servers in my list, feel free to recommend to me more!</p>
<ul>
<li>fosstodon.org</li>
<li>hackers.town</li>
<li>mastodon.technology</li>
<li>social.linux.pizza</li>
</ul>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">efa800ea-ba12-0a6e-0c57-67a58b44dfc0</guid>
<pubDate>Sat, 21 Nov 2020 00:00:00 +0000</pubDate>
</item>
<item>
<title>Cool Stuff, 1st Edition</title>
<link>https://mosfetarium.com/blog/cool-stuff-1st-ed/</link>
<description>
<![CDATA[
<p>
<p>So, part of the appeal of making my own blog was getting away a bit from the major platforms. The downside of getting away from the major platforms is that it's often harder to find stuff that you like, unless people actively try to cross-promote things they thought were cool. I decided to be part of the solution and so every so often I'm just gonna blog some of cool stuff I've found recently. They'll likely be games, tech things, bizarre niche websites I've found. I'd love to see more people do the same, so <a href="https://mosfetarium.com/about/">reach out</a> if you're doing a similar thing on your blog! And drop me tips about cool stuff you've found recently :) I'd really appreciate it!</p>
<h2>Games</h2>
<h3>The Night Is Darkening</h3>
<p>The Night is Darkening is a short and bizarre light-horror game that's primary appeal is it's aesthetic. In such a short bit of time creator LovelyHellplace manages to craft a world with a surprising amount of atmosphere. Good for maybe 30 minutes of play. But worth it.</p>
<p><a href="https://lovelyhellplace.itch.io/the-night-is-darkening">Get from Itch</a></p>
<h3>Barkour</h3>
<p>Barkour is a fun but incredibly challenging dumb game that feels like something that Bennet Foddy (QWOP, &quot;Getting Over It&quot;) would make. If you are like me, you'd never have the patience to just sit there and play this game on your own. I recommend taking turns with a friend, and you get to share in your suffering, and the nihilism of futily barking into the void as you pummet to your death.</p>
<p><a href="https://waynetron.itch.io/barkour">Get from Itch</a></p>
<h3>MetaWare Highschool (demo)</h3>
<p>This visual novel is not a demo. But it is hilarious, basically immediately. Drips with style in a way that most amateur projects don't. Exploring the different routes is fun and playful in a way that reminds you that visual novels really aren't multi-media books. Or at least, they don't have to be.</p>
<p><a href="https://not-fun-games.itch.io/metaware-high-school">Get from Itch</a></p>
<h2>Technology</h2>
<h3>KISS Linux</h3>
<p>As technology progresses and attempts to become available to less technically educated people, it often increases greatly in complexity in order to be usable to that audience. A lot of intelligence has to be baked into the technology itself in order to make up for the user's own lack of knowledge. And there's no doubt that this philosophy has really allowed things to become mass market on a level that was unimaginable to many in the 70s and 80s.</p>
<p>However, complex machines are often unreliable, and extremely hard to troubleshoot in the situations where their own intellgience fails. If you are a technically capable person, all this extra complexity is actually a big part of the road-block to you being able to understand and reason about the system on your own. You become dependant on the wider community to take interest in solving your issues for you, since there is simply too many things for any one person to understand.</p>
<p>KISS Linux is a rejection of that trade-off entirely. It is a minimal Linux distribution in the most extreme sense. Not only is it based on <a href="https://www.musl-libc.org/">musl</a> and <a href="https://www.busybox.net/">BusyBox</a>, providing an incredibly lightweight core OS, it deliberately includes as little default software as possible, and for the problems it must solve it tries to solve them with the simplest software possible.</p>
<p>The most extreme part of this is the package manager. Which is a ~1000 POSIX bash script. Yes seriously. All it needs is POSIX bash, git, and curl. The benefit of this is a package manager any reasonable programmer could come to understand inside and out, and change for their own purposes.</p>
<p>I don't know if I'd ever use KISS Linux, and it definitely is not the right choice for many. But it appeals strongly to my sensibilities.</p>
<p><a href="https://k1ss.org/">KISS Homepage</a></p>
<h3>VOSK voice recognition library</h3>
<p>I recently played around with this a bit and it's actually <a href="https://github.com/alphacep/vosk-api/blob/f97383c17f463d5ac2ea49ebf430f7f25a1dc0f5/python/example/test_microphone.py">shockingly easy</a> to get up in playing around with voice recognition functions. Transcription isn't perfect (is any voice recognition?) but for command-stuff it is VERY accurate. Hoping to do something with this myself soon.</p>
<p><a href="https://alphacephei.com/vosk/">VOSK Homepage</a></p>
<h3>makesite</h3>
<p>Makesite is a simple static site generator in ~200 lines of Python 3. It doesn't do much, but that's precisely why I like it. It appeals to me in the same way as KISS Linux does. I want a simple system that I can understand entirely and come to modify if it suits my needs. The FOSS promise of &quot;software you can modify&quot; is lost if the software is so complicated only a few people will have the time or domain knowledge to learn how to customize the tool.</p>
<p>It's very simple. It comes with a sample site, with a content folder and a layout folder. The script searches for HTML and Markdown files in the content folder and uses the HTML templates in the layout folder to generate sites with simple find-replace on some tags. It does the bare minimum of what you need, thus kick-starting a generator fit for your own needs, written in perhaps the most approachable programming language.</p>
<p>At time of writing, it's actually what I'm using to generate this site.</p>
<p><a href="https://github.com/sunainapai/makesite">Makesite github</a></p>
<h2>From around the Internet</h2>
<h3>The Whale-Lines</h3>
<p>The whalelines is a hilarious satirical little &quot;news&quot; site. I quote &quot;news&quot; because rather than being say a full news site, it's just fictional cut out segments from a newspaper. Generally making fun of current affairs. If you're totally sick of news and politics, even things making fun of it, you should probably stay away. It's a bit like a mini-The Onion. Shorter, punchier. A nice supplement to your doomscrolling.</p>
<p><a href="https://thewhalelines.com/">The Whale-Lines Homepage</a></p>
<h3>Poolside.fm</h3>
<p>A web radio station with a faux-retro aesthetic. Music, video, chat, mixtapes. But really it's all in the aesthetic and design of the site. Just click the link for yourself.</p>
<p><a href="https://poolside.fm/">Poolside Homepage</a></p>
<h3>Bongo Cat</h3>
<p>It's bongo cat.</p>
<p><a href="https://bongo.cat/">Bongo Cat</a></p>
<h3>Desert Bus For Hope</h3>
<p>My favourite annual charity fundraiser is on at the the time of writing. A bunch of mostly canadians are forced to stream longer the more money they raise, one of them must always be playing Desert Bus, a god awful boring video game about driving down a straight road for eight hours (real time). There's lots of raffles, live auctions, mostly nerd crap. But mostly they just verbally shitpost for nearly a week straight.  Check it out, it's unbelievably stupid.</p>
<p><a href="https://desertbus.org/">Desert Bus For Hope Homepage</a></p>
<h3>Nitter</h3>
<p>Nitter is an alternative front-end to Twitter. You can put in any standard twitter account and get their feed in a minimalist HTML form, all content scraped by the Nitter server meaning that Twitter doesn't have any room to track you at all. Additionally it provides RSS feeds. So you can do all your twitter following via RSS.</p>
<p><a href="https://nitter.net/">Nitter Homepage</a></p>
<p>Anyway. That's all I'll put in for this time. <a href="https://mosfetarium.com/about/">Get in touch</a> with things you think are cool, or if you have your own blog doing similar sharing.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">8110b4cf-f83a-e290-4a04-bcc3864e9b34</guid>
<pubDate>Sun, 15 Nov 2020 00:00:00 +0000</pubDate>
</item>
<item>
<title>Gemini Ink Server: Play choice text adventures over the gemini protocol!</title>
<link>https://mosfetarium.com/blog/gemini-ink-server/</link>
<description>
<![CDATA[
<p>
<p>Yesterday I spent a few hours creating a nodejs server that you can use to play <a href="https://github.com/inkle/ink">Ink</a> games over the <a href="https://gemini.circumlunar.space/">Gemini protocol</a>. Combining two somewhat obscure technologies meaning that both groups don't really know what this entails!</p>
<p><img src="https://mosfetarium.com/images/gemini-ink-screenshot.png" alt="Image of Gemini Ink Demo Server in AV-98" /></p>
<h2>Gemini Protocol</h2>
<p><a href="https://gemini.circumlunar.space/">The Gemini Protocol</a> is sort of like a modern day BBS. A text-only internet alternative to the web, made pretty much by and for computer weirdos. These days it appears to mostly be an internet underground of text blogs.</p>
<p>Tech-wise it's experiment in &quot;how simple of a protocol could you make and still be useful&quot;. It uses TCP connections, a markdown-like document format (but even simpler, there's no in-line links for example), TLS for encryption and authorization, and simple URIs for all the requests. It's simple enough to understand that I could write a gemini server in a few hours having known nothing before hand.</p>
<h2>Ink</h2>
<p>Ink is <em>the best</em> scripting language for narrative games — choice-driven ones at least — that you can find. Made by <a href="https://www.inklestudios.com/">Inkle</a> and used in a number of their own games <a href="https://github.com/inkle/ink-library#ink-games-and-non-games">and more</a>. I'd recommend checking out the amazing Heaven's Vault from inkle.</p>
<p>Ink is text-centric but the intent is that it's a text-engine that is easily driven by other systems. So games like Heaven's Vault aren't pure text; it's a Unity game driving the text engine under the hood. This design makes it very easy to integrate with pre-existing engines, and in this case it makes it very easy to write into a Gemini server.</p>
<p>My demo server is just playing the Incercept — a demo game made by Inkle — but it can hypothetically be used to create your own new games from scratch, and would be very easy to do so!</p>
<h2>The demo server</h2>
<p>You can check this out live at <a href="gemini://gemini.ink.mosfetarium.com/">gemini://gemini.ink.mosfetarium.com/</a> [UPDATE: I've taken it down for now. But the code lives in if someone else wants this :)] but you'll need a <a href="https://gemini.circumlunar.space/clients.html">gemini client</a>. And you'll need to set up a client certificate for that client. <a href="https://www.marmaladefoo.com/pages/geminaut">GemiNaut</a> looks pretty normie-friendly. But I don't know how easy that makes generating your own certificate. <a href="https://tildegit.org/solderpunk/AV-98">AV-98</a> can handle the certificate generation for you with the cert command, but using that might be a time for most windows users. But let's be real. If you're even considering using this you're a hopeless tech nerd anyway and you should be able to figure this out. I'm trusting you.</p>
<h2>The code</h2>
<p>You can get the code for this <a href="https://mosfetarium.com/stuff/gemini-ink-20201114.zip">here</a>. If you do end up doing something with this, <a href="https://mosfetarium.com/about/">please tell me!</a></p>
<h2>Why?</h2>
<p><em>shrug</em> Why not? I find gemini kinda cute and wanted to contribute to the space in some way. I briefly considered trying to get Z-machine games running on it but ink was a much simpler task.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">68d0c873-146b-40b6-d11d-301e332f1e85</guid>
<pubDate>Sat, 14 Nov 2020 00:00:00 +0000</pubDate>
</item>
<item>
<title>If you think business is a bad word, I want you do to business</title>
<link>https://mosfetarium.com/blog/if-you-think-business/</link>
<description>
<![CDATA[
<p>
<p>Creators of all stripes — artists, writers, musicians, hackers, you name it — have often maligned business and many of the things associated with it such as marketing and sales.</p>
<p>This is out of some belief that business corrupts everything that it touches, and it's a justified fear. You are right to be defensive, but I think we are capable of so much more. I think instead of shunning business, people with strong beliefs and concerns should attempt to learn from their enemy.</p>
<p>In fact I think it is important that you, my reader, learn how to make the world a better place through business.</p>
<h2>Business is as inevitable as life</h2>
<p>Many people malign business but I think if you managed to seriously get what their unspoken definition of business is out of their head you'd be left with something factually incorrect. It'd go something like this:</p>
<blockquote>
<p>Business means doing something just for money.</p>
</blockquote>
<p>This is a completely fair definition given most people's lived experience. But this is just a very common pattern; it is not the definition of a business.</p>
<p>I think a more englightening definition would go something as follows:</p>
<blockquote>
<p>A business is any human activity that has reached a self-sustaining cycle.</p>
</blockquote>
<p>If you have some action that you can perform, that fulfills all the needs for you to perform that action again — including sustaining your life — then that is a business. This definition is not entirely in line with how people most use this word; specifically most of the time we mean that money is involved. But by ommitting this feature we highlight a deeper truth: the point is the cycle, not the money.</p>
<p>And once you understand this it allows you to see all other elements of business in a different light. Everything in typical business wisdom is all knowledge about how to create a self-sustaining cycle.</p>
<p>Now yes, much of people's reasoning for creating one of these self-sustaining cycles is to skim value out of it and use that on other things that they find rewarding. But this does not preclude the possibility of creating a cycle simply because you enjoy the cycle. In fact, from what I can tell of entrepreneurs: you have to enjoy the cycle itself. Starting a business is too hard to be overcome simply for money.</p>
<p>The challenge of finding fulfillment in the cycle itself is perfectly analogous to the challenge of finding life fulfilling for its own sake. Life itself is just another self-sustaining cycle, and as such I think life and business are an inevitable pair. In fact, since life requires a self-sustaining cycle, by the definition I have presented human life requires business.</p>
<p>For those of us with some creative desire — regardless discipline — if we want to be able to explore that desire to its fullest then we require it to become a self-sustaining cycle. If we don't it simply means dedicating part of our time to some different cycle that we care for less.</p>
<h2>Marketing is sharing</h2>
<p>I have participated for a number of years in the independant game development community in various different forms, and one of the most hated things in the entire culture is the concept of marketing.</p>
<p>It seems that many devs believe that it is a great injustice that in order to achieve success that they must spend some of their time on marketing instead of working more on the game. Just as before we could extract some false defintion from their mind:</p>
<blockquote>
<p>Marketing is attention-seeking, vanity, intrusion.</p>
</blockquote>
<p>This is again a fair definition to have given a consumer's typical lived experience, but it is wrong. If you shared this definition to anyone actually good at marketing they'd scoff and say &quot;Perhaps, if you suck.&quot;</p>
<p>Again I argue that there exists a more enlightening definition:</p>
<blockquote>
<p>Marketing is about how to identify who wants what you've made, and how you can find them.</p>
</blockquote>
<p>And I argue that this is an innately noble act. If someone wants a thing and you provide them with it, have you not done them a favour? There are a few exceptions related to addiction and the like, but they are few and far between.</p>
<p>If you are attention-seeking, you've missed the point. You've made it about yourself and not them, and their wants. Any marketing containing such vanity or intrusion is ineffective. They will snub you for your self-absorption.</p>
<p>For creators the thing to learn from marketing is how to make the world a better place by sharing your creation with people who would actually be interested.</p>
<h2>Marketability means caring about more than just yourself</h2>
<p>A closely related concept is marketability. We can imagine a similarly pessimisstic defintion:</p>
<blockquote>
<p>Marketability means chasing trends, in order to do what is already popular.</p>
</blockquote>
<p>Again a much more informative definition exists:</p>
<blockquote>
<p>Marketability means making things that have a premise that speaks to other people</p>
</blockquote>
<p>Now, this is totally optional. If you want to make things for yourself, do so. But do not fool yourself into thinking that it is the noble path. It is a path of self-isolation. If you desire to make your creation a self-sustaining cycle however, you must do this. It is simply a requirement of society: you must provide things that others actually want. It is a selfish stance to demand that society support you in order that you do a thing that only you care about.</p>
<h2>Sales is helping</h2>
<p>This is a complaint that might be more foreign to other creators reading this, but is common to software developers and other creators of functional products. The definition goes something like this:</p>
<blockquote>
<p>Sales is the practice of rudely trying to pressure people into getting things they don't want.</p>
</blockquote>
<p>As with marketing, a good sales person will tell you: &quot;Only if you're bad at it&quot;. No one likes a pushy sales person, and that ire makes them highly ineffective.</p>
<p>A more enlightening definition:</p>
<blockquote>
<p>Sales is the practice of finding people who you could potentially help, and asking them what they need help with.</p>
</blockquote>
<p>I trust the nobility of such a practice is apparent to you, my reader.</p>
<h2>We need noble people persuing these acts</h2>
<p>Since business is simply a way of sustaining human activity, marketing merely sharing, marketability is making things that people want, and sales is helping. We don't want the people who worry about the corruption of business choosing to not do those things.</p>
<p>If every good person on the planet shunned these things then the people who it would be left to would cause incredible harm to our society. Since life requires self-sustaining cycles, it'd leave choosing those cycles that we all form our lives around to the people who don't care about the conditions of those involved in the cycle.</p>
<p>If all sharing was done by people who did not care about the impact of what they shared, then our culture would become filled with messages promoting things that are toxic or shallow.</p>
<p>If all sales was done by people who did not want to genuinely help, then we'd squander so many great opportunities to make each others lives better.</p>
<p>If we want business to stop being a source of corruption, we need the people opposed to that corruption to learn business.</p>
&nbsp;
</p>
]]>
</description>
<guid isPermaLink="false">1876189e-ba24-67fe-1de0-8b9a55fefea8</guid>
<pubDate>Wed, 11 Nov 2020 00:00:00 +0000</pubDate>
</item>


</channel>
</rss>
