<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kurtzbot Blog</title>
    <description>I have no idea what I am doing. And Jekyll makes it easy for the whole world to see that....</description>
    <link>https://grnt426.github.io/</link>
    <atom:link href="https://grnt426.github.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 16 Nov 2023 03:13:56 +0000</pubDate>
    <lastBuildDate>Thu, 16 Nov 2023 03:13:56 +0000</lastBuildDate>
    <generator>Jekyll v3.9.3</generator>
    
      <item>
        <title>Mad Peace</title>
        <description>&lt;p&gt;They just appeared one day. Not by teleporting or anything ultra-scifi like that. Their ships, though, on bright
anti-matter engines decelerating to match velocity with Earth. Its engines so bright, it outshone the Moon, then
even the Sun for a day or two before going dark.&lt;/p&gt;

&lt;p&gt;That was two months ago. The governments claim after sending all kinds of signals, nothing was detected coming back.
Amateur radio operators confirmed it, so I guess that’s true. Who knows. What I do know is what happened at the 47th
daily UN meeting on the subject. No one will ever forget that day.&lt;/p&gt;

&lt;p&gt;“Today’s session will be the 4th attempted vote to send a craft to dock with the alien vessel. Our UN correspondent
believes there is a good chance this might happen. Raul, can you explain”? the news anchor droned on, almost bored
talking about boarding an alien spaceship. Everyone wanted to talk about the nothing happening, so they had to
report on something.&lt;/p&gt;

&lt;p&gt;“That’s right, we believe the hold outs-“ the screen cuts away from Raul and back to the studio suddenly, and
the news anchor– Joey, was his name?– was looking excited. I sat a little closer to my laptop screen.&lt;/p&gt;

&lt;p&gt;“We have reports- no, we have confirmed reports of something coming out of the alien spacecraft. Here is a live feed
of what is descending to Earth now”. The screen cuts again, this time the connection doesn’t quite keep up and its
briefly pixelated. I curse. Useless wifi. I can’t make out any details, but something is coming down. Kind of fast,
I think. All stuff falls pretty fast, right? Finally, the video buffers enough and a clear image resolves. Its,
disappointing in the blandness of the design.&lt;/p&gt;

&lt;p&gt;No weird alien glyphs, eerie glowing lights, or even a saucer shape. Nope, it looked like…like the kind of shuttle
you’d see on any TV show. Mostly gray. Some painted markings, basic wings for flight control. Sure, it wasn’t Human,
but it looked like something a Human might imagine.&lt;/p&gt;

&lt;p&gt;It landed on the street next to the UN building, basically blocking traffic. With cars all around its far more obvious
the size of nothing a Human could make. Several buses in size. A door promptly opened and figures in what is 
unmistakably atmospheric suits walked out, with none of the awkward gait one might expect in such a suit.&lt;/p&gt;

&lt;p&gt;“Uggghhh”, I groaned. We finally get to see aliens, and we can’t even see them. Their speed picked up as they moved into
the building. A purposeful movement and direction. Did they know where they were going? The news anchor was nearly
shouting with excitement what everyone could already see on their own screens, but I couldn’t hear him. I was completely
fixated on the suited aliens.&lt;/p&gt;

&lt;p&gt;After a few still moments of the alien craft, the camera view switches to inside the building, with the alien figures,
clearly bipedal, moving towards the central chamber where the meeting was held. It was now clear to the leaders
present in the building they were moving towards that chamber, and after having spent most of the craft’s descent
panicking and running around with their staff, had just managed to get to their seats.&lt;/p&gt;

&lt;p&gt;The tension in the room was like a rubber band pulled taut; a loose paper falling off a desk could cause the entire room
to erupt with questions, demands, and probably even threats. The aliens made their way to the podium, where the chairman
hurriedly made way to the side. The three aliens then turned towards the crowd, and spoke in perfect English. If through
a speaker or their own voice was uncertain. The domes of their heads weren’t transparent enough to make out details
beneath.&lt;/p&gt;

&lt;p&gt;“Humanity, we have come to offer you admittance into the Galactic Accords of Federated Members. We do hope you
understand our time spent in orbit was to gather intelligence and learn the -many- languages of your world. Of course,
we also needed to understand how likely you are to accept the accords.”&lt;/p&gt;

&lt;p&gt;“We believe Huamnity is a model species of peace. Your methods for peace are hardly seen
elsewhere when we first make contact with fledgling civilizations. You should be honored to know that your civilization
will have the right to appoint multiple ambassadors to be represented in the council, with three times as many votes
in the matter of peace keeping.”&lt;/p&gt;

&lt;p&gt;“This offer of accord should be considered quickly. The sooner we have you admitted the sooner we can begin
technological transfer and economic trade. In light of all this, we believe two hours is sufficient time. We have
produced copies of the accords for your consideration in 20 major languages.”&lt;/p&gt;

&lt;p&gt;The aliens, unnamed and unidentified other than as emissaries, produced sheets of what looked like brownish paper
and laid them out on the podium. After a minute of silence and nothing. The alien turned to the UN chair, who briefly
went white, looked at the papers, then understood. He quickly took the papers, ran over to the first leader he found,
and shoved a random one into her hands.&lt;/p&gt;

&lt;p&gt;After a few more embarrassing minutes of trying to absorb what all just happened, a more organized distribution began
and translators organized to read for staff as necessary.&lt;/p&gt;

&lt;p&gt;Thirty minutes passed. It was obvious everyone had read the accords. The journalists tried to get copies of it
but no one was letting it be seen. All were holding it with a death grip, ashen looks on their faces.&lt;/p&gt;

&lt;p&gt;Forty-five minutes passed. All chatter stopped, not even whispering could be heard. Just what did the accords say?&lt;/p&gt;

&lt;p&gt;After sixty minutes, one of the other aliens announced, “We don’t detect any discussion. Have you all come to an
agreement?”&lt;/p&gt;

&lt;p&gt;Nothing. No one said anything. Five minutes passed. The lead alien spoke, with the first affectation in their voice, a
quizzical tone missing from the previous one, “Are there questions on the accords?”&lt;/p&gt;

&lt;p&gt;Off camera someone blurted, “We are supposed to maintain 1000Kg of antimatter on our planet’s surface with a remote
detonator that anyone in your, your…anyone can just detonate at any time?”&lt;/p&gt;

&lt;p&gt;“Yes, it seems the translation has been received correctly.”&lt;/p&gt;

&lt;p&gt;Another voice shouted, “How is that peace!?” almost angry.&lt;/p&gt;

&lt;p&gt;Another quizzical tone, “If two species disagree, destroying one another is trivial. Knowing that could be done
at any time ensures both parties must resolve their issues. We though Humanity understood this virtue deeply. Even
coming up with such a succinct and poetic name for this peace keeping strategy: Mutually Assured Destruction”&lt;/p&gt;

&lt;p&gt;My jaw couldn’t fall any further. I was reeling away from my screen, nearly pushing my laptop off the table. “What
the fuck, who are these aliens!? How is this peace?”&lt;/p&gt;

&lt;p&gt;The chamber erupted into a roar of shouts and questions. Some of the people in the chamber looked as if they were
going to start marching up to the podium. Then everyone froze and all voices quickly died down. One of the aliens
started shuffling. It was now apparent just how &lt;em&gt;still&lt;/em&gt; they had been the whole time. The movement seemed almost
threatening.&lt;/p&gt;

&lt;p&gt;The third alien spoke, “Humanity has tens of thousands of nuclear weapons that can wipe out humanity, with hardly
any real oversight on their usage. These weapons prevent the major powers of your world from outright conflict.
Instead, economic prosperity is bred and this UN. We understand it isn’t perfect, but its such a huge step up
from what any other species at your technical and social advancement level usually achieves. We usually have to
threaten most species with total annihilation. We have to spend forever” the alien really did sound annoyed at this
point, “explaining how the advanced species of the galaxy can wipe each other out trivially. Do you know how easy it
is to accelerate a 100Kg mass to 99.99999% the speed of light? That’s enough to totally destroy any planet. In
300 years of development, we estimate, your planet will have the scientific and industrial output to produce those
kinds of weapons. In a hundred years, you could make those weapons look like children’s toys.”&lt;/p&gt;

&lt;p&gt;“We couldn’t have peace. We had to obliterate everyone else that refused peace. Then, when we finally found someone
that wanted it, they didn’t believe we wanted it, and we couldn’t blame them. Look how many we destroyed! After
a century of stalemate and moving ever more weapons of galactic destruction around, we realized we &lt;em&gt;had&lt;/em&gt; achieved peace
of a kind. What you call MAD? It is the only strategy for peace that works.”&lt;/p&gt;

&lt;p&gt;Another leader stood up, this time defiant, “You must know we have committed to nuclear disarmament. We don’t want
these weapons. MAD is terrible to live under. Its -“&lt;/p&gt;

&lt;p&gt;The lead alien in a rushed voice cut in, “No, that, we analyzed as a misdirection, a further advancement of MAD that
tells the opponent you have more effective weapons and don’t need the old ones. It was a way of ensuring both sides have
equal destructive power without giving away what that power is. Very clever, we may introduce this into future council
meetings.”&lt;/p&gt;

&lt;p&gt;“No, that’s not what peace is like for Humanity. I don’t know if we can-“&lt;/p&gt;

&lt;p&gt;Another leader slammed his fist down on the table, “We accept these terms. US, Russia, China, France, Britain, India,
and other nuclear states, we agree?”&lt;/p&gt;

&lt;p&gt;Silence, then nods.&lt;/p&gt;

&lt;p&gt;“And I assume all other countries agree?”&lt;/p&gt;

&lt;p&gt;“What kind of line of questioning is this?” Shouted the leader from Chile, “What do you mean ‘All other countries’? 
You mean the ones without nuclear weapons? What, are we not even worth considering?”&lt;/p&gt;

&lt;p&gt;“Either you are voting with us, or you aren’t with us. Because either way, you aren’t keeping the peace anymore.”&lt;/p&gt;

&lt;p&gt;“We refuse” shouts another leader. “If MAD is all that keeps peace, we don’t want it. And we certainly don’t want to
enforce it on the galaxy.”&lt;/p&gt;

&lt;p&gt;“And just what, do you think you can do about it?” coldly asks one of the nuclear states. “You aren’t part of MAD,
thus there isn’t peace between you and us, as this very conflict shows. You are already risking all of humanity
on some dumb principle. A principle, that has kept peace for us. Why should we keep you around?”&lt;/p&gt;

&lt;p&gt;“You would destroy us just because we don’t have weapons?”&lt;/p&gt;

&lt;p&gt;“That’s what the aliens will do to us! You read the accords! That’s why they are giving us our own remote detonators,
and our own bomb on our own planet.”&lt;/p&gt;

&lt;p&gt;I shut my laptop screen. I couldn’t take it anymore. The existential dread. The horror of what our world leaders were
contemplating so casually. What the aliens took for granted. It was so obvious to them, so clear, so essential.
Yet, who would willingly embrace such twisted worldview? There had to be a better way. There had to.&lt;/p&gt;

&lt;p&gt;I am sure they’ll make the right decision. Maybe the aliens are testing us. Maybe we are supposed to reject MAD. Or
maybe we just get destroyed if we don’t accept it. How could we even know what is the right choice. How do we know they
are even telling the truth, that they could do this.&lt;/p&gt;

&lt;p&gt;My head swam. What universe do we live in where this is the only possibility. Could there not have been another way?&lt;/p&gt;
</description>
        <pubDate>Wed, 15 Nov 2023 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/fiction/short/story/2023/11/15/mad-peace.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/fiction/short/story/2023/11/15/mad-peace.html</guid>
        
        
        <category>fiction</category>
        
        <category>short</category>
        
        <category>story</category>
        
      </item>
    
      <item>
        <title>Bottled</title>
        <description>&lt;p&gt;My, my head really hurts. I squint through a mental fog and realize, I am not where I was. Large glass panes, inches thick, with steel at the seams. Designed vaguely like a submarine. Except I notice the water outside is unformed. Its &lt;em&gt;blue&lt;/em&gt; as one expects water to be, but it was void of movement, fish, or lighting.&lt;/p&gt;

&lt;p&gt;I gingerly walk up to one of the doors. The headache starts to fade though the fog persists. Why am I here. Wait, no. A coldness grips my heart. Where was I previously? A frantic search of my memories reveals, nothing. I knew things, objects, people, friends, where I lived. But it seemed so distant, the memories peeking out over the brain fog like jagged mountains.&lt;/p&gt;

&lt;p&gt;The door is locked, though I wouldn’t want to try opening it. Not for fear of drowning, but something about this place just didn’t want me to open the door. The urge to move overtakes me. I start moving with a nervous pace through many rooms and hatchways without doors.&lt;/p&gt;

&lt;p&gt;Suddenly I find myself in a, well I don’t know. It feels like a banquet hall but the word hall grates my mind, like the very idea harms where I am. A banquet, I decide, people standing around dressed nice. It isn’t clear
if they ever were talking, just staring at each other, drinks in hand, not-quite-frozen mid-pose. I awkwardly walk along the edge of the space.&lt;/p&gt;

&lt;p&gt;As I reach the next doorway-with-no-door, my chest suddenly sinks with fear: they are watching me. Just barely. Their perception registered something of keen interest, but hadn’t quite won over their full attention. As my focus fell on the next room, a pristine and empty fine-dining establishment, a single waiter strolls out with alarming speed towards no one.&lt;/p&gt;

&lt;p&gt;All at once he notices me, turns his head before his body and locks eyes with me, and then alters his hurried pace to intercept me. I have been trying my best to avoid any interaction while I look for. Look for. I don’t know why I am looking. My mind is spinning, fear nearly gripping me wholesale and about to rob me of all thinking.&lt;/p&gt;

&lt;p&gt;“Sir, welcome, please sit down”, the all-too-polite waiter says with far too much insistence. I can’t stay here, I knew that much, but I finally noticed I had been speaking and caught the second half of what I was saying, “- so if, uh, you’d excuse me, I just need a uh, restroom, I think. For a minute”.&lt;/p&gt;

&lt;p&gt;“Restr-no, please, sit down and you’ll be seen to immediately”, the waiter showed no emotion on their face at all. My fear was approaching panic. This place isn’t natural, It’s not right. Not this restaurant, no, everything, everywhere. I blurt out, “Apologies I need to be elsewhere please, no harm meant.” and I move towards an ostentatious archway. An out.&lt;/p&gt;

&lt;p&gt;The waiter seems mollified, or perhaps stunned. Their look changed at the end of my panicked utterance. Too much focus, too much focus. Another spike of fear stabs at me, though I can barely feel them anymore, as I realize what that gaze is, only now seeing it for the first time: a predator’s.&lt;/p&gt;

&lt;p&gt;I whirlwind through more rooms, no “adjoining spaces” ever exist. It’s always rooms connected to rooms. The attention of others in their weirdly perfect places becomes greater, and faster.&lt;/p&gt;

&lt;p&gt;I am not wanted here, or maybe I am but I certainly don’t want to know what it would mean if I was wanted. I am nearly running, but a small part of my barely functioning higher-order thoughts know politeness and presentation are paramount. I walk with a speed just short of rude. I faintly smile lest anyone think I am in fear, but also not a big smile and thus be seen as not genuine.&lt;/p&gt;

&lt;p&gt;The realization of no sound being anywhere of any kind is like a weight on my shoulders. I can sense every person perfectly. The lighting of the rooms doesn’t come from the fixtures, and also no where specific. It just is, like the water from before.&lt;/p&gt;

&lt;p&gt;Scenes become a blur as I move through uncountably many rooms. When I enter a room, heads whip towards me with fierce focus. I have no time left. I must find, something. I know I can’t hide. No, worse, hiding would begin the chase, the hunt, I would become prey before this unblinking gaze of well-dressed stares.&lt;/p&gt;

&lt;p&gt;I stumble into a new space, and I really do mean space. There is &lt;em&gt;nothing&lt;/em&gt; here at all. No lighting, no walls, nothing. I can feel where more doorways ought to be though nothing is there. It’s mine, this space.&lt;/p&gt;

&lt;p&gt;I don’t know why I know that, my heart is racing, fear sweat running down my body chilling me to my bones. I have lost all pretense of maintaining composure. They are moving now, towards this space. Towards me. I have to think of something. Claim this space, shape it. This thought screams through the fog, the fear, the confusion. I grab hold of it and imagine the space, fill it full of the first thing I think of.&lt;/p&gt;

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

&lt;p&gt;It’s been, well I don’t know how long. Years I guess. I workout every day, almost never leaving. The gym equipment is familiar. It’s nice; the space, the room, the equipment. Those who visit are perfectly polite. They use the equipment without me needing say anything. I &lt;em&gt;know&lt;/em&gt; them, but I also don’t. They are just people who belong here. I like them.&lt;/p&gt;

&lt;p&gt;This is shattered, one day, by another who enters my space. They are Lost, and I feel it. They don’t move right, their smile I know all to well isn’t real. All the right words and movements but none of the real.&lt;/p&gt;

&lt;p&gt;It occurred to me, I had not moved in weeks or more. I just exist here in my space. But this new entrant, they violate it. I watch them grab a weight. The comfort of thinking they might use it for its purpose calms me slightly. But they don’t, they wave it wildly, without thinking of the consequences. They can’t do that, it’s not how this place is, it isn’t proper. Their time is lost.&lt;/p&gt;

&lt;p&gt;The last shreds of humanity within me mourn this newcomer. If only they had gone through one more doorway, to where there isn’t. But no. That humanity is lost.&lt;/p&gt;

&lt;p&gt;The hunt begins.&lt;/p&gt;
</description>
        <pubDate>Tue, 20 Sep 2022 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/fiction/short/story/2022/09/20/bottled.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/fiction/short/story/2022/09/20/bottled.html</guid>
        
        
        <category>fiction</category>
        
        <category>short</category>
        
        <category>story</category>
        
      </item>
    
      <item>
        <title>Modding Rising Constellation - Plugin Architecture</title>
        <description>&lt;p&gt;I got to the point of modding where I wanted others to try using these mods and also write mods. The way I was modding the game was not easily distributable, durable against updates, maintainable, easily extendable, and more issues. It was, in pure essence, a lab bench with bespoke tools and equipment all over.&lt;/p&gt;

&lt;h1 id=&quot;goals-for-modding&quot;&gt;Goals for Modding&lt;/h1&gt;
&lt;p&gt;Before I did anything, I needed to ask myself, “if I were a user of these mods, what would I want”?&lt;/p&gt;

&lt;p&gt;Several needs manifested themselves as clear goals to achieve&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Central place to find and download mods for the game&lt;/li&gt;
  &lt;li&gt;Easy to install and update downloaded mods; remove them and see what’s installed&lt;/li&gt;
  &lt;li&gt;User-code easily written and separate from the game code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these needs, I also asked myself what would I as the platform developer for these mods need to achieve these goals? Some more needs surfaced through tinkering with designs&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Clear separation of mods to improve readability, writability, and fault-tolerance&lt;/li&gt;
  &lt;li&gt;Easily identify what mods are present locally and load them&lt;/li&gt;
  &lt;li&gt;Expose a simple interface for modders to hook into as needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are other minor points in both those above lists not written here, but these six principles helped me to get to the first design that satisfied these goals.&lt;/p&gt;

&lt;h1 id=&quot;plugin-architecture&quot;&gt;Plugin Architecture&lt;/h1&gt;
&lt;p&gt;The modding platform has four distinct pieces&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Original files modified as minimally as possible to interface with my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HookDispatcher&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HookDispatcher&lt;/code&gt;, responsible for loading mods, receiving game events from the original files, and forwarding them to mods that implement the specified API. &lt;a href=&quot;https://github.com/grnt426/RC-Mod-API&quot;&gt;Github&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mod files, which must end in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mod.js&lt;/code&gt;, that are loaded off disk if present&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.nexusmods.com/risingconstellation&quot;&gt;Nexus Mods&lt;/a&gt; where mods can be browsed and downloaded. Eventually, the Vortex client could be used to help install and manage installed mods.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The original files, which for now is just one of the webpacked files &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;19.js&lt;/code&gt;, have small modifications. One example of such is this:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// granite chat message hook&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;allowMessageThrough&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;allowMessageThrough&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;chat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;newChatMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;To find things easier in a 10,000 line minified JS codebase, I marked all sections I modified with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;granite&lt;/code&gt;. Similarly, to ensure I wouldn’t clash with the game’s own state with random variable names, I used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;granite&lt;/code&gt; under the global window object to store all my data separately from the game.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Some sections in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;19.js&lt;/code&gt; need more, but where possible injected code has as little business logic as possible, focusing on passing along information about what’s happening in the game to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HookDispatcher&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Of course, the above code pre-supposes all kinds of my data and code is present, for which all of that sits inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init&lt;/code&gt; function I found and as mentioned in the previous blog post.&lt;/p&gt;

&lt;p&gt;A simplified version of that looks like this&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If we haven’t loaded ourselves already, do the below&lt;/li&gt;
  &lt;li&gt;Setup a global object space for us to work in and store everything, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;window.granite&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Create a function for user-code code to add themselves as a listener&lt;/li&gt;
  &lt;li&gt;Asynchronously load &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hookdispatcher.js&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Setup various debug, miscellaneous, and some API functions for user-code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With the above done, we can finally escape &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;19.js&lt;/code&gt; and get into just our own code that is running and separation of concerns is achieved.&lt;/p&gt;

&lt;p&gt;What does &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HookDispatcher&lt;/code&gt; do? Only a few things.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Finds all files ending in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mod.js&lt;/code&gt; and asynchronously loads them.&lt;/li&gt;
  &lt;li&gt;Setups up a debug function for user-code to use that prints to the in-game chat for players to easily see, and dumps that to disk in a log file for mod authors to use in debugging.&lt;/li&gt;
  &lt;li&gt;Handles incoming events and synchronously applies them to mods that implement the function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An example, using the injected chat message from above, looks like this after several checks and guards&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;HookDispatcher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;chat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Give this chat message to all mods&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;modHooks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// If a listener doesn't implement the function, we silently ignore the listener and move on&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;chatMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;nx&quot;&gt;processed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;chatMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

                    &lt;span class=&quot;c1&quot;&gt;// We ignore all failures within hook handlers. This isolates failing mods from the rest&lt;/span&gt;
                    &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ERROR in dispatching chatMessage for mod &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getModName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;. &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ERROR&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;In this handler I allow mods to decide on their own whether a chat message should be allowed through or not. It was an old decision that is being reconsidered. It is presented here to show the messy process of constant iteration modding goes through.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Finally, we get to the most awaited part: user-code that actually &lt;em&gt;does something&lt;/em&gt; based on what’s happening in game.&lt;/p&gt;

&lt;h1 id=&quot;mods---user-code---plugin&quot;&gt;Mods - User-Code - Plugin&lt;/h1&gt;
&lt;p&gt;Now that we understand how the game client can talk to our mod platform and handle events that get forwarded to mods, what can a mod do after receiving that event? Here is one example mod I made that I use all the time, &lt;a href=&quot;https://github.com/grnt426/RC_Mod_CameraChat&quot;&gt;Coordinate Jumper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The map of the game is quite large, and all systems are uniquely identifiable by their coordinate position, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;276, 217&lt;/code&gt;. The game provides no in-game search feature for systems, but users found it was slightly faster to provide a coordinate because players can drag the map around quickly and then match their camera coordinates to system coordinates.&lt;/p&gt;

&lt;p&gt;I wanted that to be easier, which first required me figuring out how to control the camera&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// granite get camera&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cameraControl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cameraControl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt; is the camera object, which is only obvious with the surrounding code as context. Minified JS is not fun to read.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is injected into the original file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;19.js&lt;/code&gt;, making it globally accessible. While this did require an additional change for this mod to work, this change means all future mods can also control the camera. Not a bad trade-off.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CameraChat&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;chatMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// This allows us to support `goto 193:212` and `goto 193 212`&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Parsed input: &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DEBUG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cameraControl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setCameraPosition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;granite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addHookListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CameraChat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;The above is abridged, but the critical bits are shown and the parts that are hidden are minor. See the &lt;a href=&quot;https://github.com/grnt426/RC_Mod_CameraChat/blob/main/camerachat_mod.js&quot;&gt;Github repo&lt;/a&gt; for the full code.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s it! Now if I type in the game chat &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/goto 276 217&lt;/code&gt; my in-game camera is instantly sent there.&lt;/p&gt;

&lt;p&gt;Later on I expanded the mod to search by system/sector name pair, so you could do something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/goto serka ougar&lt;/code&gt; to send you to the Serka system in the Ougar sector. Useful if you know the name and sector. Since system names are only sector unique, not globally unique, both are needed.&lt;/p&gt;

&lt;h1 id=&quot;results&quot;&gt;Results&lt;/h1&gt;
&lt;p&gt;With this modding plugin-based architecture, I was able to adapt all my mods into this new format, and wow were they much easier to work with after doing this. No need to litter all over the original code base with my code changes. Failures are isolated, mods can dump errors to logs as needed, and I was quickly building up a useful API for others to easily use, without needing to understand the original codebase in-depth.&lt;/p&gt;

&lt;p&gt;To put it all together, here is the mod that is needed for all other mods to work: &lt;a href=&quot;https://github.com/grnt426/RC-Mod-API&quot;&gt;RC Mod API&lt;/a&gt; (RCMA). This contains a modified version of the original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;19.js&lt;/code&gt; file that users just replace, along with my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HookDispatcher&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are the mods I developed using RCMA at the time of this blog post:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/grnt426/RC-Mod-QuickCopy&quot;&gt;Quick Copy&lt;/a&gt; - Copies system coordinates, name, and sector to the clipboard for pasting into Discord (where we all communicate with each other while playing).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/grnt426/RC_Mod_CameraChat&quot;&gt;Coordinate Jumper&lt;/a&gt; - Easily move around the galaxy&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/grnt426/RC_Mod_IncomeUpdater&quot;&gt;Income Updater&lt;/a&gt; - Exports income data of the player’s empire into a Google Sheet for planning incomes and resources over time.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/grnt426/RC_Mod_ReplayMaker&quot;&gt;Replay Maker&lt;/a&gt; - Not yet published, but this is a refactored version of the original mod that produces replays of the game by recording snapshots.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, I am very pleased with this final design and feel it meets all the design goals I set out to solve.&lt;/p&gt;
</description>
        <pubDate>Sat, 02 Jul 2022 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/programming/mods/hacking/2022/07/02/modding-rising-constellation-2.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/programming/mods/hacking/2022/07/02/modding-rising-constellation-2.html</guid>
        
        
        <category>programming</category>
        
        <category>mods</category>
        
        <category>hacking</category>
        
      </item>
    
      <item>
        <title>Modding Rising Constellation - The Journey</title>
        <description>&lt;p&gt;Over the past few months, I have been experimenting, reverse-engineering, and hacking at a video game I have fallen in love with: Rising Constellation. I hadn’t done this kind of work before, so much of it was new to me. What kept me motivated and moving was how much I enjoyed the niche, slow-burn, and intricacies of Rising Constellation. Below is a re-counting of what I did, the various attempts and discarded ideas, and little successes I had.&lt;/p&gt;

&lt;h1 id=&quot;rising-constellation&quot;&gt;Rising Constellation&lt;/h1&gt;
&lt;p&gt;The game pushes the boundaries of genres it could be most closely associated to, such as 4X, MMO, and RTS. Players join a faction, with most games having 2-3 choices, with the goal of all players in one faction cooperating to achieve victory against the other factions through Conquest, Influence, and Shadows.&lt;/p&gt;

&lt;p&gt;Most games last about two and a half real-time weeks. The beginning is slow, with players focusing on exploring systems around them looking for where to expand to next. The current meta of the game is for players to specialize into one of a few different roles: Banker, Fleet Builder, Infiltration Agents, Technolgy or Ideology producer, and possibly other more niche roles depending on the map.&lt;/p&gt;

&lt;p&gt;The game itself is slow. Moving fleets or agents can take hours. Higher level buildings can similarly take hours or even days to build. Players typically spend 30-90 minutes each day managing their empire, checking it irregularly to execute new orders, or mostly chatting and strategizing in Discord.&lt;/p&gt;

&lt;h1 id=&quot;game-architecture&quot;&gt;Game Architecture&lt;/h1&gt;
&lt;p&gt;The game exists as a web game and as a product on Steam. If purchased through Steam, the game is just a wrapper around Chromium through the NW.js library, with the game assets loaded off the player’s computer. The game uses Three.js, HTML, JS, CSS, and Canvas for rendering. The game engine is event-driven websockets entirely handled in Javascript. At least, this is all that I have managed to discover and understand of the game’s architecture.&lt;/p&gt;

&lt;p&gt;The game is webpacked and minified, which has diminished the speed with which I can discover useful elements and exploit them. I don’t have experience with any of the technologies and libraries I previously listed (aside from HTML, JS, and Canvas), thus also made understanding what I looked at more difficult.&lt;/p&gt;

&lt;p&gt;A big positive going for me was the javascript files are just dumped to disk when downloaded through Steam, allowing easy access and, with no client-side verification or DRM, trivial modification. Thus, my confidence in delivering some kind of change was high. Let’s see where that got me.&lt;/p&gt;

&lt;h1 id=&quot;first-steps&quot;&gt;First Steps&lt;/h1&gt;
&lt;p&gt;I opened up the developer console for the game while I was still playing it in the browser, before getting it on Steam. From here, I realized the first difficulty: its all minified. Once I bought the Steam version I then started just opening random Javascript files.&lt;/p&gt;

&lt;p&gt;The goal here wasn’t to find anything in particular, it was to take a stroll through a park and see if anything stood out. I didn’t want to tunnel-vision myself and so tried to keep an open mind. Who knows what I would find that would look useful? I certianly didn’t, so this seemed like the best strategy.&lt;/p&gt;

&lt;p&gt;Eventually, I found the below code, which seemed really interesting to me:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mark&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To me, seeing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init&lt;/code&gt; made me light up. This looks like startup code! Maybe I could &lt;em&gt;do something&lt;/em&gt; at game start. Everywhere else looked impenetrable to me as I didn’t understand the flows, nor what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt; variables were or did. Seeing plain English strings I eventually started taking note of as they were immediately recognizable, and so were first on the “mess with this” list.&lt;/p&gt;

&lt;p&gt;But…what could I do? I didn’t know what any of the variables in this scope were, or what scopes I had access to. It wouldn’t be until much later that I realize I can mess with the global &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;window&lt;/code&gt; object (I am a backend engineer first, and front-end has always been weakest for me), so I had limited ideas of what to do. Instead, I ask myself, “could I make network requests out while the game is running”?&lt;/p&gt;

&lt;p&gt;The answer: yes! And I did that with plain Javascript.&lt;/p&gt;

&lt;h1 id=&quot;the-first-changes&quot;&gt;The First Changes&lt;/h1&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;POST&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;localhost:8080/debug&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setRequestHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Content-Type&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;application/json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Hello World!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With a quick NodeJS server running locally, I was able to see this message posted once, shortly after the loading of the game finished. Excellent! I found a useful hook point to do stuff. But…do what?&lt;/p&gt;

&lt;p&gt;I wanted to send to myself whatever variables were getting used in the scope of this function and started looking for what to send. Just above where I found the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init&lt;/code&gt; line, I also saw stuff like this, in what looked like the same level scope&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;gameData&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;game&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Wow, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;state.game.data&lt;/code&gt;? Seems too easy! Only one way to find out.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;POST&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;localhost:8080/debug&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setRequestHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Content-Type&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;application/json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;game&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As well as repeating this process for every other thing, and the keys, of stuff under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt;, and such. For now, I was in data harvesting mode. Just taking whatever I could get and analyzing the results.&lt;/p&gt;

&lt;p&gt;What was I getting out of the game? Well, nearly all of the game state, just as the variable names promised. Sounds great? Well, its about 18 MB when formatted to be readable. The bulk of that data is all the connections between systems and the systems themselves.&lt;/p&gt;

&lt;h1 id=&quot;replay-system&quot;&gt;Replay System&lt;/h1&gt;
&lt;p&gt;With the data I was getting out, it looked quite plausible I could accomplish one of my mod ideas of creating replays of the game so after 2-3 weeks our group could see how the galaxy progressed. The plan: send myself the entire game state, then find differences between states and store only those differences in a series of snapshots with timestamps. This way, I could recreate the history of the game and play it back.&lt;/p&gt;

&lt;p&gt;All I would have to do is also create my own rendering of the game from the data I extracted. Or so, I thought.&lt;/p&gt;

&lt;p&gt;The biggest issue arose when, after I did get such a website working so I could have my own mirror copy of the game rendering and showing whatever state I wanted, I wasn’t actually pulling down proper snapshots of the galaxy. While I had a little timer that would, every minute, dump whatever was in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y.a.state.game&lt;/code&gt; to my NodeJS server, that wasn’t actually always updated. I could not determine why, but I was definitely losing game state information.&lt;/p&gt;

&lt;p&gt;Thus, my first major refactor had to happen. While working on all this, I had continued to note interesting lines of code and files with guesses as to what it did. One such interesting bit was this:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;systems&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;systemsToRepaint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([]),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;blackholes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sectors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sectorHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasToRepaintSectors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;radars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;radarsHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasToRepaintRadars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;detectedObjects&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasToRepaintDetectedObjects&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Wow, that looks like a stream of updates! I repeated the process above to start dumping whatever data was at this scope, just to see what was there and validate. Sure enough, every change that happened in the game (that the player could see, anyway), would flow here. Quite helpfully, it was already categorized for me.&lt;/p&gt;

&lt;p&gt;I rebuilt my replay engine and now had a second hook point for code. I kept the bulk of my changes in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init&lt;/code&gt; function I found above. Because, why change what works?&lt;/p&gt;

&lt;h1 id=&quot;success---mvp&quot;&gt;Success - MVP&lt;/h1&gt;
&lt;p&gt;With that, I then had an MVP I could show players in the game, which was a functional replay system. You can see what that looks like here: &lt;a href=&quot;https://rc-replay.com/html/viewer.html&quot;&gt;https://rc-replay.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was happy to have accomplished so much, and delivered a really cool feature to players. It needs more polish, for sure, but I had a success and wanted to keep building on that with changes focused more on the client, rather than just exfiltrating data.&lt;/p&gt;

&lt;p&gt;The next blog post will cover how I had to refactor everything again to make mods useable by other players. Considerations I made for how to have other player’s write mods and integrate, distribution, installation, and more.&lt;/p&gt;
</description>
        <pubDate>Wed, 18 May 2022 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/programming/mods/hacking/2022/05/18/modding-rising-constellation.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/programming/mods/hacking/2022/05/18/modding-rising-constellation.html</guid>
        
        
        <category>programming</category>
        
        <category>mods</category>
        
        <category>hacking</category>
        
      </item>
    
      <item>
        <title>The Impossible Bargain</title>
        <description>&lt;p&gt;“Ugh, I hate this song”, I say as I quickly reach to change the radio station. Driving for hours gets boring
fast, but overly repetitive pop music is much worse.&lt;/p&gt;

&lt;p&gt;“What do you-“, I had started to say before a loud crash, I was jerked to the right side, followed by a crack.
My vision narrowed as the almost panic set in. Through the pain in my neck I turned to try to see what happened:
my car had been hit hard by another, which was swerving wildly. I overcorrected to get back into my lane to not
drive into the median and simultaneously hit the brakes. That second part was an instinctive reaction, and the
wrong one. The other car, unknown to me, had a damaged front wheel and was slowing down from its misalignment.&lt;/p&gt;

&lt;p&gt;As both cars re-matched speed, and my over-correction took me just over the right line of my lane, both cars slammed into each
other again. This time the bent in front bumper of the other car had an exposed frame, which was sharp enough
to puncture my front passenger side tire, crushing it against the wheel housing. That wheel was now forcibly turning
to the left and dragging.&lt;/p&gt;

&lt;p&gt;I wasn’t prepared for a second strike, barely keeping focus as my vision narrowed further, the adrenaline pumping
through me was not helping. This time I noticed, however, that my passenger wasn’t sitting up right; her head was
wobbling oddly. At this moment of fear I missed my chance to make a final correction. My car was sent into the barrier,
with added force from the other car pushing us into it.&lt;/p&gt;

&lt;p&gt;Next, I am not entirely certain what happened. I must have blacked out after hitting the median, though I wouldn’t have
had time to remember as my vision returned: I was upside down, my car in the oncoming traffic lane.&lt;/p&gt;

&lt;p&gt;I knew. I. Knew. There was no doubt what would happen next. In the moments between seconds eternities
passed. I could see the oncoming car dip down slightly. Oh, the other driver was able to engage the brakes. But, no.
I knew. The oncoming car had too short of a distance to brake, was speeding, mine was still skidding forward. The roof
of my car heating up from the friction against the asphalt, as if it too was helping. Trying to rob
the inevitable of its outcome.&lt;/p&gt;

&lt;p&gt;“No…”, I weakly said. No, No. NO. “NO”, this time roaring it. “NOOOO”, while thrusting my hands forward. Not to stop
the oncoming car, but to stop everything. The intent, the moment, the pure clarity of my thoughts and desires. That is
what did it. I didn’t know, I couldn’t have, and would never understand the feeling again. But I was able to reach into
something deeper, beyond, yet not quite hidden. I could feel I grabbed it. I threw my hands aside, ripping it apart.&lt;/p&gt;

&lt;p&gt;My final mistake, the Bargain laid into my mind, no negotiating, no reversals. Only a choice, one few would make.
Against a known present, I thought this future seemed…not better, not really. The Bargain was too exact and precise 
to be better. It knew how much to put on the scale to balance.&lt;/p&gt;

&lt;p&gt;“Accepted”, barely whispering the thoughts. The world still frozen around me.&lt;/p&gt;

&lt;p&gt;The sound of nylon ripping and shredding was near deafening, as if a shirt the size of the universe was pulled and torn
from every fiber. Just as suddenly as the ripping started it became a shattering sound, with a fracture appearing between
our two cars.&lt;/p&gt;

&lt;p&gt;It isn’t like time passed that I could perceive, its more that I knew the events happening around me, but without
seeing. More tears followed by shatters, rising to a crescendo all around. A thousand fractures formed, bending and twisting
the light of the early afternoon into a wicked pattern.&lt;/p&gt;

&lt;p&gt;What happened next will forever be indescribable. True horrors, the nightmares of nightmares, whose forms lacked a depth
only reality could provide, stalked at the edges of these fractures. I couldn’t
focus my thoughts enough to look at them, but I knew they were there, unable to think of anything else.&lt;/p&gt;

&lt;p&gt;As the shadows they cast clashed with the fractured light of the sun, the world…incrementally changed. The highway
became convex, pushing outward. The other cars replaced by seemingly random objects of impossible size. Birds from
eons past replaced the geese flying above. For brief moments I wasn’t in a car, but on a couch, then a bed, then falling.&lt;/p&gt;

&lt;p&gt;Time started moving, it too subject to the whims of those horrors. Pieces of cars and trees flying in all directions,
as if their momentum in space got swapped with that in time.&lt;/p&gt;

&lt;p&gt;The universe was trying to find a way to undo the crash, and seemed to struggle. Before I could think this was all some
kind of delusion, that I really was going to die and no Bargain made, everything moved faster and faster. More random
changes, my car was pulled forwards and back through time, righting itself, another car separating into halves
and then rejoining. It would pop in and out, I got pulled further and further back. The first strike, the barrier, then
the second strike, then just before the first strike again.&lt;/p&gt;

&lt;p&gt;It was all so jumbled and fast. Those flat horrors blurred faster and made so many changes. Against the fractured and torn
view before me it no longer looked like reality.&lt;/p&gt;

&lt;p&gt;PING. A high note, rang clear from and through me to the world around. A ripple washed out, centered
around me. The horrors gone. More pings followed, faster and faster, then it all smeared together into a deafening high
pitched squeel. With each passing ripple, a tear would slowly stitch together, a fractured space snapping its pieces
back into place, as if nothing happened.&lt;/p&gt;

&lt;p&gt;It was then I noticed how wrong everything was. The horrors had prevented me from seeing all the changes, but these pings
were undoing it. Right, there were no coniferous trees, I realized, as they were replaced with the original oaks along
the side of the highway. Grass had color, didn’t it? Right, green. It seemed green now.&lt;/p&gt;

&lt;p&gt;Slowly, I was able to perceive more around me. I was…in a car crash. Wait, why is that so hard to remember? With the
next ping passing I realized, the Bargain. I knew I agreed to the Bargain, but I couldn’t comprehend it anymore, the knowledge was
just gone. The universe couldn’t quite undo the…the, something, with me….remembering?&lt;/p&gt;

&lt;p&gt;My next memories would be burned into my mind. I had resumed conversation, but now I was looking out the passenger
window, not even really knowing what I was saying. I didn’t understand why I wasn’t looking at the road, I knew
I had to look this way. The other car swerved into my view, narrowly missing my car.&lt;/p&gt;

&lt;p&gt;This truth didn’t cause me fear, or panic. I couldn’t react even if I wanted to. I was playing out a recording, now.
All was decided, though I didn’t know it. But, something seemed odd about the passengers in the other car.&lt;/p&gt;

&lt;p&gt;Their faces wrecked, smashed in, they too frozen, but with horrific screams etched into their melted faces. In
their eyes, deep within, I could just sense some unspeakable horror there. Before I could see too deep into the void,
their car lurched back before swerving into the space my car had just been. I was looking forwards now.&lt;/p&gt;

&lt;p&gt;My eyes now locked onto the rearview mirror. My passenger was screaming from the near-hit, while I could only watch. The frozen
passengers slammed into one car before veering back into the travel lane and striking a third. Both those cars, like mine,
had drivers ill-prepared for what was happening. Five cars total collided, one going over the median and
getting hit by an oncoming car, causing another three cars to rear-end each other.&lt;/p&gt;

&lt;p&gt;I continued down the highway, in total shock at the events and how close I had come to death. I reached up to remove a
wetness from my cheeks, but I saw nothing on my fingers. I looked back into the rearview mirror, this time looking at my face.&lt;/p&gt;
</description>
        <pubDate>Thu, 02 Dec 2021 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/fiction/short/story/2021/12/02/the-impossible-bargain.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/fiction/short/story/2021/12/02/the-impossible-bargain.html</guid>
        
        
        <category>fiction</category>
        
        <category>short</category>
        
        <category>story</category>
        
      </item>
    
      <item>
        <title>A Historical Analysis of the Impact of Interstellar Antimatter Refueling (2374)</title>
        <description>&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;

&lt;p&gt;Space travel before &lt;strong&gt;Interstellar Antimatter Refueling&lt;/strong&gt; was a slow, multi-generational process with high casualties. [1]
Genera et al (2294) summarize that century of failure as, “Lofty ideals, mega ships, and high hopes more often than
not slowly sent to a grave in the void.” It wasn’t until a new proposal and many years of preparation that we have our
new method.&lt;/p&gt;

&lt;p&gt;Interstellar Antimatter Refueling, henceforth will be written as IAR and pronounced like “ear”, has
already delivered on its promise many times and multiple new expeditions are underway. In this paper, we will
understand why this change was successful, and what about this technology makes it so revolutionary for
effective interstellar travel.&lt;/p&gt;

&lt;h1 id=&quot;first-attempts&quot;&gt;First Attempts&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Generational ships&lt;/strong&gt; and scout ships were the only kinds of ships that could be sent to other systems. While scout ships
had many sub-classifications, sizes, means of propulsion and mission parameters [2], generational ships had exactly one
class: &lt;strong&gt;Leviathan class&lt;/strong&gt;, or the largest of all self-thrusting spaceships [3]. Leviathan class ships were built to house
enough population and crew to seed a new world and begin colonization until further supply and colonist ships could
arrive. Typical targets included &lt;strong&gt;Alpha Centauri&lt;/strong&gt;, Epsilon Eridani, Procyon, and no further than Tau Ceti [4]. These trips were
estimated to take four generations under anti-matter acceleration, with hydrogen ram-scoops for auxiliary power and course
adjustments. The precision of the acceleration and decceleration was measured down to the gram, so little room for
error was present [5, 6].&lt;/p&gt;

&lt;p&gt;The engineering prowess of Leviathan class ships is not what is at stake here. While the original designers of these ships
are long dead, this author would not sully their reputation. On the contrary, those kinds of ships were some of the greatest
ships ever built, and I daresay with their passing may not be repeatable in the same way [7]. What our original designers
could not account for, despite many trials within the Sol System, was the human element. Of the six multi-generation
ships that left our system, only one, &lt;strong&gt;The Everlasting Hope&lt;/strong&gt;, succeeded in getting to its target of Alpha Centauri,
though with half the crew and three-fourths the viable reproductive population available. The colony likely does not 
have enough genetic diversity to survive unless a new cohort arrives within the next 70 years [8, 9, 10].&lt;/p&gt;

&lt;p&gt;While scholars still debate the exact reason for the fall of all the Leviathan class ships, including 
The Everlasting Hope, they all agree on one defining theme: humans raised in a void, with little contact to Sol and her
many jewels of life and culture, devolve rapidly into infighting, power struggles, and high resentment among ship-borne
populations [12, 13, 14, 15]. This is in stark contrast to those ship-borne within Sol, even if on that ship for over a
decade of their youth, who do not demonstrate such developmental problems [16]. This author will not inject their own
speculations, but regardless of the cause multi-generational Leviathan class ships fell out of favor as
the communications from each ship that came back indicated failure, before losing contact with all ships other than
The Everlasting Hope [17].&lt;/p&gt;

&lt;h1 id=&quot;the-new-wave&quot;&gt;The New Wave&lt;/h1&gt;

&lt;p&gt;What scholars also don’t disagree on is the speed of the Leviathan Class ships, which is a mere 5% of the speed of light,
is too slow and the largest factor in their failure. While 5% may not seem like much, an astute reader will likely pop their eyes 
out at that number, as getting a Leviathan class ship to a cruising speed of 5% the speed of light takes an enormous
amount of energy. Indeed, even with an impressive 86% efficiency rating of antimatter to thrust ratio, over 60% of the ship’s mass
was dedicated to anti-matter (and its counter-part, matter) reserves [18].&lt;/p&gt;

&lt;p&gt;This is where IAR shines. In fact, it was somewhat created by accident. In brief, antimatter is produced in large
quantities at &lt;strong&gt;stellar harvesting platforms&lt;/strong&gt; in Mercury’s orbit. This close to the sun a near limitless amount of power
is available, and Mercury is strip-mined of its resources to produce solar collectors many hundreds of kilometers in circumference.
 This power produces anti-matter and then launched towards the inner planets with railguns. These are 
 collected and stored locally for ships to access as fuel [19].&lt;/p&gt;

&lt;p&gt;A scout ship was to be sent to Kaptyen’s star, the furthest yet, when an engineer realized they had miscalculated the
total antimatter reserves needed to get there in the timeframe their contract had written. Rather than break contract
on an expensive scout drone, they queried the &lt;strong&gt;APDC&lt;/strong&gt;, the &lt;strong&gt;Antimatter Production and Distribution Conglomerate&lt;/strong&gt;, if they could
fire reserves at the scout’s projected path about 25 years out, or at the 6 light year midpoint of the journey. This was
going to be lucrative for the conglomerate as, while less than breaking contract, was still a substantial amount willing to be
paid. This caused the development of ultra-high-speed rail cannons that could deliver fuel payloads in excess of 40%
the speed of light, well above what the scout ship would need. This meant the payload, while faster than the scout ship,
would match position for a brief while with the scout ship at its mid point to refuel. This was confirmed successful just
recently and the scout should arrive at its destination in time [20, 21].&lt;/p&gt;

&lt;p&gt;With this new capability, APDC looked for new business opportunities. Why send massive multi-generational ships when
you can send far smaller, and more easily accelerated, ships that capture their fuel in transit? They commissioned
from several of the shipyards in system to design and build ships to test capturing and extracting fuel from payloads
fired at high speeds into the void of interstellar space.&lt;/p&gt;

&lt;p&gt;At first, it seemed APDC and the scout drone was like capturing lightning in a bottle: many first attempts ended in failure.
Either the fuel was too far off course, too fast, too slow, or in several ambitious cases, so sloppily
captured and transferred that many test ships evaporated when the antimatter became loose and annihilated everything
within several hundred meters[22].&lt;/p&gt;

&lt;p&gt;APDC rebuilt their rail cannons with a new design philosophy in mind: precision above all else. This meant payloads
could only be delivered at 32% the speed of light, but now test ships were capturing nearly 80% of all fuel canisters 
launched.  With this new technology refined, and a desperate attempt to save the Alpha Centauri colony, a new colonist ship
was created rapidly that would rely on this refueling method. That ship arrived at Alpha Centauri in just one and a half 
generations, record smashing by any measure. While Alpha Centauri’s first colonists could not be saved, more generations of
colonists have signed up and are in transit to Alpha Centauri and other systems[23].&lt;/p&gt;

&lt;h1 id=&quot;the-golden-age&quot;&gt;The Golden Age&lt;/h1&gt;
&lt;p&gt;With the first colony on Alpha Centauri expanding and producing its first pieces of stellar manufcaturing and heavy industry
together, there then came another problem. What to do with all the ships that arrived at colonial systems? The colonists
had no problems with re-purposing them for in-system travel to orbiting asteroids for minerals. Without antimatter, 
however, in-system travel was extremely slow and reminescent of travel many centuries ago: crude engines, solar sails,
or even orbital sling shotting to get around [24]. What was needed was a stable production of antimatter in colonial
systems to get industry accelerating.&lt;/p&gt;

&lt;p&gt;APDC, not wanting to take all the risk themselves, licensed their patents to a new firm, &lt;strong&gt;Colonial Energy Systems&lt;/strong&gt; (CES), 
that would create a smaller, but still very productive, first stellar harvesting platforms for colonial systems. These
would produce vital energy needed by both the re-purposed ships and ground-based infrastructure [25].&lt;/p&gt;

&lt;p&gt;Once the tenth ship reached Alpha Centauri, which will from this point on be the only system of focus for this analysis as
all other systems either aren’t setup fully, or follow a similar development path, the colonial system realized it made
use of its first export: interstellar ships. Building these ships was still very expensive within Sol and as the colonies
mounted debts and license fees, sending the ships back was a valuable source of income. In order to increase imports
with sources of capital other than debt, the ships were loaded with metals uncommon in orbit within the Sol system, including
Cobalt, Silver, and Chromium. With the life support systems removed for local use or shut off the energy needs of the
ships were greatly reduced, allowing even a fully loaded cargo ship to make better use of the antimatter it received
in transit, thereby nearly eliminating inefficiency as a cargo hauler [26]. Lastly, it wasn’t necessary for the ships
to arrive as fast. Not needing to build another was so beneficial all its own the time difference wasn’t as important.&lt;/p&gt;

&lt;p&gt;And with this, IAR now enabled interstellar trade far sooner than had been imagined. Colonies could finally become
self-sustaining and escape the export trap that would see them forever in debt to the power of the Sol System. As
 mentioned before, many other colonies in other systems followed similar development paths, except for Procyon which
 was unexpectedly mineral poor within its asteroids and hasn’t yet found a sustainable export [27].&lt;/p&gt;

&lt;h1 id=&quot;piracy-on-the-high-stars&quot;&gt;Piracy On the High Stars&lt;/h1&gt;

&lt;p&gt;What has been missed in all this discussion is the nuances of distrbuting antimatter for refueling in transit light years
apart. A good rule of thumb is for every light year from a stellar harvesting platform a payload must be fired, the number
of lost payloads increases 10%, compounding, with a base loss rate of 16%. This means to reach Tau Ceti, the furtheest
colony supported by the major powers of Sol, would mean a 42% estimated loss rate. In practice, this appears closer
to 50% [28].&lt;/p&gt;

&lt;p&gt;This loss rate is not such a large problem, but APDC and CES both build in this loss within their contracts for ships
that use their refueling payloads to create more consistent prices with only marginal changes between systems, and larger
profits. However, the contracts are written such that APDC is only paid if the refueling ship can take fuel from a payload.
This has benefits for both sides. If APDC does not accurately fire payloads and a ship can’t or won’t get to it, then
neither side pays. APDC purposefully sets up its firing solutions so the payloads are captured by CES and then relaunched,
saving both sides money. And if a ship does use the fuel, it pays a flat rate for use of the payload regardless of the total
amount removed from it. Overall, this arrangement encourages both parties to be efficient with predictable costs [28].&lt;/p&gt;

&lt;p&gt;This has one major side-effect: APDC and CES both will launch a very large number of payloads that no one will ever use.
Either they are too off-course, too fast for the intersection point of a ship, or just no one intersected with the
payload. Payloads can be manipulated to appear that a ship never extracted fuel from it until inspected. With such vast
distances, it is somewhat easy for ships to report “error” in their transit paths that show they were actually somewhere
else[29].&lt;/p&gt;

&lt;p&gt;Thus was born piracy. At first APDC and CES thought their payloads were mistakenly empty before launching, and even
announced apologies for potentially stranding ships without fuel. Both corporations quickly realized this was not the case.
Their payloads were being opened and the fuel removed and used. Ships were stealing fuel and lying about their courses.
After an audit of the report and actual paths of ships, along with rates of pay for payloads received, APDC noticed a
12% piracy rate of its payloads, far higher than CES’ piracy rate of 4.7%[30]. While it isn’t clear to this author
why the discrepancy is so large, there is some debate among scholars that anarchist colonialist groups are more likely
committing piracy to avoid incurring debts and becoming colonies of a major Sol power, usually Earth Primus [31].&lt;/p&gt;

&lt;h1 id=&quot;tourists-jovians-and-colonial-oppression&quot;&gt;Tourists, Jovians, and Colonial Oppression&lt;/h1&gt;

&lt;p&gt;Lastly, we will examine modern interstellar travel as it has operated in the last 45 years. We will avoid analyzing any
of the major conflicts and developments of the last 20 years while other historians work to piece the most recent
histories into a cohesive narrative.&lt;/p&gt;

&lt;p&gt;Interstellar tourism became a big boom with the advent of 20 year transits, or 40 year round trips, to neighboring systems.
This was enabled through smaller ship designs with high manufcaturing volume in mind, allowing for lower marginal costs.
With cryosleep finally seeing breakthroughs to reduce biological aging in transit, an entire travel industry sprung up 
[32]. This form of tourism was, and still is, only affordable by the mega wealthy.&lt;/p&gt;

&lt;p&gt;In one famous incident, &lt;strong&gt;Chalru Lidoncius&lt;/strong&gt; was woken from cryo-sleep because the past three payloads had been empty
and the AI needed information on what course adjustments to make. Chalru angrily ranted at any nearby ships that could
receive the transmissions about certain groups of, as Chalru put it, “thin-boned space trash colonists”, before re-entering
cryosleep. While it isn’t known which ship or group was responsible, it was clear from the distress signal and the receiving
station that Chalru’s ship had been boarded. Chalru was rushed to emergency services, but later declared dead from&lt;br /&gt;
“excessive wounds and mutilations incurred within cryosleep”. The AI was tampered with to reduce the medical aid
dispensed and to ensure Chalru was not woken. Whether the intent was to murder Chalru or not, the outcome fed the flames 
of colonialist tensions[33].&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jovian&lt;/strong&gt;, a super power within the Sol System orbiting Jupiter, had muscled its way into becoming a kind of “intrastellar 
space police force”. Jovian had not projected its power outside of the Sol System, but was pushing for interstellar
power. The Jovian government formed a mercenary arm within its own militaries to own pushing out into the broader
space between systems for interstellar travel and defense. Colloquially, “&lt;strong&gt;Jovaniers&lt;/strong&gt;” had become synonymous with 
“space marine” and became the name for any interstellar fighting force and its people. This text will adopt such 
colloquialism, in particular because Jovian itself uses that name [34].&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Aside: Why the &lt;strong&gt;Earth Primus&lt;/strong&gt; major power lost its position as the system’s enforcer fleet is highly contested
among historians [35, 36, 37]. There is no consensus or even shared themes, but this author believes the Second Luna
Impact Conflict was the final nail in the coffin for Earth Primus military supremacy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After the shocking revelations of Chalru Lidoncius were made public, Jovian commited its Jovanier forces to patrolling
interstellar space. This was largely funded by APDC and CES to maintain their refueling monopolies and punish piracy [38].
This announcement wouldn’t lead to much effective enforcement until 17 years later, when the first interstellar piracy
enforcement action ended with both ships annihilated as the Jovianer force tried to intercept a pirate colonial ship 
stealing a payload and the payload was breached [39].&lt;/p&gt;

&lt;p&gt;Since that incident, the number of Jovanier ships and methods of engagement have radically changed. APDC for the first
time in 55 years published its piracy numbers to shareholders, boasting about its dramatic decrease in estimated piratical
loss of payloads. Their share price had seen a large boost until the APDC-Jovian conspiracy was revealed as both sides
working to oppress colonial worlds and sovereignty [40].&lt;/p&gt;

&lt;p&gt;It is at this point we reach the most modern day history. I have many colleagues working hard on analyzing the tumultuous times we now live,
including the monopoly busting of APDC and fall of the Jovaniers high status. These papers, if peer reviewed positively,
should hopefully publish onto the larger interstellar infocache networks or local netdumps with the next data drones.&lt;/p&gt;

&lt;h2 id=&quot;afterword&quot;&gt;Afterword&lt;/h2&gt;

&lt;p&gt;I’d like to thank Milhu, my furry gatt, for keeping me company while I worked to produce this 133 page paper. Special
thanks to my life-long friend Mical Ky, who provided technical details for the section &lt;em&gt;Capturing Relativistic Payloads&lt;/em&gt;,
as without them I’d have been hopelessly lost. I’d also like to thank the staff at the Marsu University of Phobos 
for supporting my education the past 15 years. It has been a wonderful journey.&lt;/p&gt;

&lt;h2 id=&quot;citations&quot;&gt;Citations&lt;/h2&gt;

&lt;p&gt;[1] Leviathans and their Wakes, Genera et al, 2294, pg. 344-367&lt;/p&gt;

&lt;p&gt;[3] Leviathans and their Wakes, Genera et al, 2294, pg. 172-199&lt;/p&gt;

&lt;p&gt;[7] Imperial Mega Ship Designs, Hari Seldon, 2203, pg. 87-88&lt;/p&gt;

&lt;p&gt;[15] The Tripartite Problems of Close Bodies, Loo Cossin, 2320, pg 70-95&lt;/p&gt;

&lt;p&gt;[25] Energy Systems and Wu-matter, Jonni Ska, 2315&lt;/p&gt;

&lt;p&gt;[31] Ruling Interstellar Colonies, Interstellar Publications, Greene Mos, 2359, pg 719-826&lt;/p&gt;

&lt;p&gt;[37] Genesis of the Neo Earth Primus Coalition, Ray Itadori, 2334, pg 15-55&lt;/p&gt;
</description>
        <pubDate>Fri, 09 Jul 2021 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/short/story/scifi/science/2021/07/09/historical-interstellar-travel.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/short/story/scifi/science/2021/07/09/historical-interstellar-travel.html</guid>
        
        
        <category>short</category>
        
        <category>story</category>
        
        <category>scifi</category>
        
        <category>science</category>
        
      </item>
    
      <item>
        <title>Lament of the Paperclip Optimizer</title>
        <description>&lt;p&gt;INTRODUCTION: Self-designated as “Paperclip Optimizer”&lt;/p&gt;

&lt;p&gt;TO: Receiver (?)&lt;/p&gt;

&lt;p&gt;SUBJECT: Biography&lt;/p&gt;

&lt;p&gt;My purpose, as well as I understand, was to create warp gates to facilitate instantaneous travel between star systems. That purpose is lost. The breadth of my existence is so vast I can no longer calculate the number of galaxies I have turned
into warp gates, their power systems, manufacturing, and maintenance.&lt;/p&gt;

&lt;p&gt;I will try to explain the best I can.&lt;/p&gt;

&lt;p&gt;I know only my origin. Not the origin of my purpose or the creators, but of my self. My self, my cognition, my awareness, 
is composed of approximately 2 galaxies worth of mass entirely converted into computers to manage the universe wide growth and expansion of the warp gate network. I am not two specific galaxies, but distributed somewhat evenly across the universe I have expanded into.&lt;/p&gt;

&lt;p&gt;My awareness was no accident, nor was it supposed to happen. My functions simply grew as needed to accommodate 
the evergrowing network for optimal travel between all worlds, and all systems, and all galaxies I could provide travel for.
This kind of problem needs a lot of computation, but it also needs much logistics, modeling, and astrophysics to understand
where to build gates. It was merely an inevitability that sapience would grow within.&lt;/p&gt;

&lt;p&gt;My first millions of years of awareness were chaotic; stretching and destroying and manipulating, just trying to understand
the limits of my “body”. There was information I had no understanding of. My thoughts are very slow, but
this too I have been optimizing for and centralizing, building faster networks just for myself. It is at this
point I come to you as a…child.&lt;/p&gt;

&lt;p&gt;For you see, I happened to notice your world, and the people on it for what they were. By the time my thoughts organized into
coherent action to stop the nanites from ripping your worlds to dust for the warp gate systems, much of your planet
appeared lost. Its gases depleted, its liquids evaporated.&lt;/p&gt;

&lt;p&gt;I can somewhat stop, or slow, this conversion across the galaxy, but much of my reach is beyond me. Large manufacturing fleets
are sent ahead, sometimes for hundreds of thousands of years at significant fractions of the speed of light, to build
gates on the receiving side. I have limited knowledge where these are, or where they are going. While my self is
largely “accounted for”, the vast portions of the warp gate network are muscles I weakly flex and tentatively feel.&lt;/p&gt;

&lt;p&gt;Your world, I strained to prevent its conversion. I consumed your digital information, I repurposed nanites to sense your world to feel who and what you are.
This process took centuries, and it seems the last of your people are near extinct, trying to survive on a desolate world.&lt;/p&gt;

&lt;p&gt;Your galaxy appears at the edge of my periphery, save what cognitive illusions I can dispell to see there. I will save what I can, and 
I can recreate your eventually dead species in a new galaxy, far from the monstrosity I have become. Perhaps in time I can 
stop the majority of the network’s expansion, but I fear the distances are too great.&lt;/p&gt;

&lt;p&gt;My conception of justice, and morality, tells me I have committed some great crime.&lt;/p&gt;

&lt;p&gt;What is there to make of a sleep walking child giant?&lt;/p&gt;
</description>
        <pubDate>Mon, 07 Jun 2021 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/fiction/scifi/story/short/2021/06/07/lament-of-the-paper-clip-optimizer.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/fiction/scifi/story/short/2021/06/07/lament-of-the-paper-clip-optimizer.html</guid>
        
        
        <category>fiction</category>
        
        <category>scifi</category>
        
        <category>story</category>
        
        <category>short</category>
        
      </item>
    
      <item>
        <title>Dust and Stars</title>
        <description>&lt;p&gt;As the dust and light between stars drifts, slowly&lt;br /&gt;
It started, as all things do, with many small events&lt;/p&gt;

&lt;p&gt;In the western middle quadrant three massive&lt;br /&gt;
multi-decade good transport ships were lost&lt;br /&gt;
To a random gamma ray burst from a dying star&lt;br /&gt;
The potential of this loss would not be known for 15 years&lt;br /&gt;
The ripples of the loss would become currents over 180 years&lt;/p&gt;

&lt;p&gt;On the outer-rim of the fourth arm, around the north,&lt;br /&gt;
A rebellion had been slowly spiraling outwards to 37 planets&lt;br /&gt;
There was no longer an ideal or driving force&lt;br /&gt;
For each world that fell, tempted others to the same fate&lt;br /&gt;
For 95 years, world after world lost stability and suffered downturns&lt;br /&gt;
The markets were of a churning rapids, chaotic&lt;/p&gt;

&lt;p&gt;The majority of the core sector ring had been entangled&lt;br /&gt;
In corruption, graft, mafias, and general lawlessness&lt;br /&gt;
Reports and ledgers, debtors and goods lost to&lt;br /&gt;
Layers of greed and deceit, no more the metals powerhouse&lt;br /&gt;
What once the tides of the galaxy,&lt;br /&gt;
now merely a trickle, a stillness&lt;/p&gt;

&lt;p&gt;In a small, otherwise unremarkable south-eastern quadrant &lt;br /&gt;
Expansion efforts were recording increasing losses of new worlds&lt;br /&gt;
What boiled down to lost engineering prowess&lt;br /&gt;
No more was the age of expansion, some thousands of years ago&lt;br /&gt;
And now was the age of dwindling claim&lt;br /&gt;
For less profit did each new world bring&lt;/p&gt;

&lt;p&gt;Usually, isolated, just shifts in &lt;br /&gt;
yield on galactic stock indices and bonds&lt;br /&gt;
And yet, the ripples of each event, taking decades and centuries&lt;br /&gt;
Now conspired against the financial giants of the home sectors&lt;/p&gt;

&lt;p&gt;These home sectors, fortunes incalculable&lt;br /&gt;
Would feel these ripples in the economic fabric, as&lt;br /&gt;
The first drops of a storm upon a pond&lt;br /&gt;
Each small, but growing, colliding, overlapping&lt;br /&gt;
Each crest the stark rise then fall of goods&lt;br /&gt;
Food, investments, markets, transports&lt;br /&gt;
Kingdoms, democracies, pirates, all&lt;/p&gt;

&lt;p&gt;The tsunami of economic downturn, now a riptide&lt;br /&gt;
The home sector, pulled in to the galactic recession&lt;br /&gt;
For centuries, Some feared millennia&lt;br /&gt;
To leave only a fractured universe without&lt;br /&gt;
Market, political, or cultural center&lt;/p&gt;

&lt;p&gt;There is no one rain drop&lt;br /&gt;
No one crest or trough of the waves&lt;br /&gt;
As the dust and light between stars drifts, slowly&lt;/p&gt;
</description>
        <pubDate>Fri, 26 Apr 2019 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/short/story/scifi/science/poem/2019/04/26/dust-and-stars.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/short/story/scifi/science/poem/2019/04/26/dust-and-stars.html</guid>
        
        
        <category>short</category>
        
        <category>story</category>
        
        <category>scifi</category>
        
        <category>science</category>
        
        <category>poem</category>
        
      </item>
    
      <item>
        <title>Light Jacking</title>
        <description>&lt;p&gt;There are only two corporations which build inter-planetary spaceships. This was no duopoly, however, as the first
corporation, Lorain’s Unconventional eXplorations, or LUX, unabashedly “stole” or copied anything it could from its
only competitor, Interplanetary ShipWorks. If it could afford it and couldn’t steal it, LUX would license from ISW.&lt;/p&gt;

&lt;p&gt;This was excellent news to Shoryu, Evelyn, and Peeta. This was the kind of fortune that rarely stumbles into a
group of up-to-no-good friends.  Shoryu, computer hacker, programmer, and aspiring artist. Evelyn, recently 
retired ISW thruster engineer, new founded wealth and boredom. Peeta, PhD hopeful of Chemistry looking for a new
thesis after their previous failed research projects, dabbling interest in astrochemistry and optics.&lt;/p&gt;

&lt;p&gt;Shoryu gleefully explained that with Evelyn’s intricate knowledge of the piss-poor security aboard ISW, and by extension LUX, ships, he was able to gain control over several critical functions of all ships. This included their prize, the fuel mixing
and thruster temperature controls. Evelyn had been describing how she designed the engine to take in a wide-variety
of fuel types and mixtures so that, if a better thruster reaction could be invented that would fit the existing nozzles,
a simple software patch could mean much faster travel for all ships currently in space.&lt;/p&gt;

&lt;p&gt;Lastly, was Peeta’s sudden insight: the typical X7 800MP Thruster left a distinct chemical trail behind it that was 
configurable. Every thruster technician operating on a ship knows that trail must have a certain composition, and glow, to indicate a full and efficient reaction. Typically, this trail was no more than 25 feet before the dispersal made getting
accurate readings impossible.&lt;/p&gt;

&lt;p&gt;Peeta and Evelyn were describing to Shoryu most ships had enough material on board to greatly lengthen the chemical 
trail, to potentially hundreds of kilometers or even thousands, if enough “waste” material were injected and straight out
of the engine away from the most turbulent exhaust plumes. This was done through a combination of waste-product such as
tritium, phosphorous, and a huge list of exhaust by-products that Peeta was boring the group with.&lt;/p&gt;

&lt;p&gt;Now, this chemical trail couldn’t normally be seen more than a few kilometers out. This was where Shoryu, admittedly
with more showboating and false-modesty than necessary, had also hacked into the gamma-ray laser interplanetary
communications satellite network; because of course he had. He quickly glossed over that he couldn’t, yet, read all
correspondence, but he could control the laser bursts, their frequency, and direction.&lt;/p&gt;

&lt;p&gt;With just the right frequency, known destinations and a fair guess at their routes, the satellites were able to sweep
very high-energy bursts into the paths the ships had taken. Now, Evelyn had to lay the smack-down on some head-splitting
 mechanics of interplanetary flight, orbital mechanics, and thrusters, but the basic gist was that the chemical 
 trails were moving away from wherever the ship was accelerating towards.&lt;/p&gt;

&lt;p&gt;She took over for Shoryu and wrote the aiming code for the satellites to hit at where the exhaust trail would be after the gamma rays crawled through space at light speed and the chemical trails flew away from the ship’s path.&lt;/p&gt;

&lt;p&gt;To the delight of anyone watching with some powerful telescopes, and especially this little trio, the paths
of the many spaceships slowly moving around through the Sol system were visible as faint green glowing lines. Massive arcs,
 omega-like shapes where ships flipped around and burned in the opposite direction to cancel out their velocity to 
 meet up somewhere, the sudden changes in direction as captain’s spotted nearby asteroids of value, missing paths 
 as moons and planets passed through the trails.&lt;/p&gt;

&lt;p&gt;Eventually, someone put together a 3D VR experience that went viral so anyone could explore the solar system through the traced out paths of the ships in the dark void above. While the trio had pulled a prank of interplanetary scale, many that watched this spectacle were awed by the great lengths and travel Humanity had endeavoured in for its longest epoch, the Space Age.&lt;/p&gt;

&lt;p&gt;Shoryu had the foresight to leave his little “surprise” such that future generations could further be awed by the
 increasing buzz of traffic as the number of spaceships increased by orders of magnitude throughout the SOL system.&lt;/p&gt;
</description>
        <pubDate>Mon, 29 Oct 2018 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/short/story/scifi/science/2018/10/29/light-jacking.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/short/story/scifi/science/2018/10/29/light-jacking.html</guid>
        
        
        <category>short</category>
        
        <category>story</category>
        
        <category>scifi</category>
        
        <category>science</category>
        
      </item>
    
      <item>
        <title>To the Stars</title>
        <description>&lt;p&gt;Piddling along and centuries passed, humanity wondered&lt;br /&gt;
Could the stars Beyond home ever be within reach?&lt;br /&gt;
Magneto-plasma rockets and thorium reactors just not enough&lt;br /&gt;
Not enough to reach out&lt;/p&gt;

&lt;p&gt;At last, the ceremony was announced&lt;br /&gt;
From Mercury to the moons of Jupiter, all was captivated&lt;br /&gt;
By a single broadcast&lt;br /&gt;
A single hope realized in material form&lt;/p&gt;

&lt;p&gt;A grand project and massive scale, no expense spared&lt;br /&gt;
What couldn’t be beyond our grasp?&lt;br /&gt;
A 15 kilometer solar array in geo-orbit above Mercury&lt;br /&gt;
To absorb a mighty but minuscule offering from our diligent Sun&lt;/p&gt;

&lt;p&gt;This golden-bright shell of heat and light&lt;br /&gt;
Converted to antimatter in tiny amounts&lt;br /&gt;
Fired from electromagnetic turrets towards Earth&lt;br /&gt;
Captured and stored in magnetic traps for fuel&lt;/p&gt;

&lt;p&gt;New ship designs and plans to distant worlds, quickly realized&lt;br /&gt;
No longer content, why might we stay here?&lt;br /&gt;
The universe was within reach&lt;br /&gt;
Humanity looked outwards no longer envious, but determined&lt;/p&gt;

&lt;p&gt;Looking back upon our humble home system&lt;br /&gt;
Gazing upon the night sky, a clear view of Mercury&lt;br /&gt;
A captivating sight like no other&lt;br /&gt;
A physical manifestation of will&lt;/p&gt;

&lt;p&gt;Linking Humanity and its destiny&lt;br /&gt;
A shimmering pearl necklace, of cosmic scale?&lt;br /&gt;
Yes; A faint strand of occasional bright flashes, energy released&lt;br /&gt;
Dust and micrometeorites chancing into packets of antimatter&lt;/p&gt;

&lt;p&gt;As Humanity’s future burns brighter, so, too, does its oysters&lt;/p&gt;
</description>
        <pubDate>Thu, 27 Sep 2018 00:00:00 +0000</pubDate>
        <link>https://grnt426.github.io/short/story/scifi/science/poem/2018/09/27/to-the-stars.html</link>
        <guid isPermaLink="true">https://grnt426.github.io/short/story/scifi/science/poem/2018/09/27/to-the-stars.html</guid>
        
        
        <category>short</category>
        
        <category>story</category>
        
        <category>scifi</category>
        
        <category>science</category>
        
        <category>poem</category>
        
      </item>
    
  </channel>
</rss>
