<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://enderspearl184.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="http://enderspearl184.github.io/" rel="alternate" type="text/html" /><updated>2026-06-02T23:52:27+00:00</updated><id>http://enderspearl184.github.io/feed.xml</id><title type="html">Enderspearl184</title><subtitle>hi i do things</subtitle><author><name>me</name></author><entry><title type="html">Polyceon Bot V2</title><link href="http://enderspearl184.github.io/polyceon-v2/" rel="alternate" type="text/html" title="Polyceon Bot V2" /><published>2026-06-02T00:00:00+00:00</published><updated>2026-06-02T00:00:00+00:00</updated><id>http://enderspearl184.github.io/polyceon-v2</id><content type="html" xml:base="http://enderspearl184.github.io/polyceon-v2/"><![CDATA[<p>&gt; /badge badge_id:1986638781753490
<img src="/images/polyceonv2/chaosdemon.png" alt="Badge leaderboard for the CHAOS DEMON badge in Nullscape" /></p>

<h1 id="background">background</h1>
<p>The Polyceon bot in <a href="https://discord.com/invite/eczHxsDfCS">Roblox Discussion</a> already existed, it’s not brand new.
It was a bit of an open secret that the original version of the bot was not <span class="wavy">very well maintained</span>, though. A lot of features
used cookie based authentication to access Roblox API endpoints. While mostly <em>documented</em>, those endpoints were <span class="rainbow">not officially
supported</span>, and thus were prone to <span class="rainbow wavy">change at any time</span>. Not ideal.</p>

<h1 id="ok-but-like-what-is-it">ok but like what is it</h1>
<p>Since the RD server generally was focused on events and general competitveness, a lot (but not all!) of the features were very centered around Roblox. They include:</p>
<ul>
  <li>The badge leaderboards, originally used by sending a message formatted like -badge 1986638781753490</li>
  <li>A few animal commands like -bird that embedded random images from <a href="https://unsplash.com">Unsplash</a></li>
  <li>Commands that replaced people’s messages with webhooks, which forced them to talk in uwu speak and/or with far too many emojis <span class="rainbow wavy">we did not include these in the rewrite</span></li>
  <li>Trackers for game updates and badge owner counts (which also were not included as of writing, but may return)</li>
  <li>Vanity roles (icons and colors) for players who own specific badges which could be equipped at will</li>
  <li>Giveaways and “badge bounty” contests which had requirements to enter (that Polyceon validated), picking either random winners or the first n valid entrants to win things such as item codes or Robux</li>
</ul>

<h1 id="how-did-it-work-before">how did it work before</h1>
<p>Pretty badly! The old version did not actually control any user account linking, it used the RoVer API to get the Roblox account a user was verified with,
and required their Roblox inventory to be fully public to submit badge times or enter giveaways with badge requirements.
Also, the badge leaderboard didn’t even use a <span class="wavy">proper database</span>, it used a persistent Redis volume to store each podium.
Near the end, the ratelimits for cookie-authenticated endpoints were lowered a <em>lot</em>, which caused issues whenever many users tried to enter a giveaway or claim a bounty at the same time.</p>

<h1 id="so-what-did-the-rewrite-do-better">so what did the rewrite do better</h1>
<p>For one, it uses Discord.js instead of the fragmented (I think? That’s what glatch told me) Python Discord packages. 
All the commands were migrated to slash commands since Discord wants bot developers to do that now. (Except for one but <em>you</em> can’t use it anyways)
I created an OAuth flow to allow users to <span class="rainbow wavy">actually link their account</span> instead of using a different verification bot.
As a bonus, this gave us access to scopes such as inventory-item:read which allowed us to entirely remove the public inventory requirement!!</p>

<p>Using the Open Cloud APIs also increased the ratelimits significantly, as Open Cloud handles ratelimits per-user as opposed to per-ip/per-account depending on if the endpoint required authentication or not. This made giveaway entries WAY more reliable, since it got overloaded quite often!</p>

<p>In addition, we used an <span class="wavy">actual</span> (postgres) database for everything this time, instead of a persistent Redis volume. I’m not the most
experienced with SQL, so glatch did a lot of the heavy lifting there. (read: basic setup)</p>

<h1 id="wait-did-you-actually-just-delete-all-the-badge-leaderboard-times-dating-back-to-2018">wait did you actually just delete all the badge leaderboard times dating back to 2018</h1>
<p>No, all the podium times were migrated to the new system! The old version only stored the top 3 times instead of every submitted time though,
so any entries that weren’t visible on the podium at the time we shut down Polyceon V1 were lost. Old times are even marked with an asterisk to show
that they are old. (and also since the timestamps for them are only accurate to the second)</p>

<p>It was weird to migrate them though, since they were stored in a pretty scuffed format. I was given a large JSON file with the podiums for
every badge that had a podium entry.
<img src="/images/polyceonv2/badgejson.png" alt="Example of the JSON" />
Only one entry exists for this badge, obtained at unix timestamp 1550958919. I removed his discord User ID from the image, but the badge was obtained by <a href="https://www.roblox.com/users/41789/profile">Feodoric</a>.</p>

<p>Even with the weird format it still only took like 30 seconds to upload all the entries to the new DB though once the script was ready lmao</p>

<h1 id="so-how-do-i-use-this">so how do i use this</h1>
<p>Right now, the contest and vanity role commands are locked to RD only. The badge leaderboards, and other fun stuff <em>aren’t</em>, though, you can use them yourself right now!!
If you want to see the quickly thrown together homepage, you can find it <a href="https://polyceon-production.up.railway.app">here</a></p>]]></content><author><name>me</name></author><category term="Roblox" /><category term="JavaScript" /><category term="SQL" /><category term="Code" /><summary type="html"><![CDATA[/badge badge_id:1986638781753490]]></summary></entry><entry><title type="html">Cheating In Bad Discord Games</title><link href="http://enderspearl184.github.io/cheating-in-bad-discord-games/" rel="alternate" type="text/html" title="Cheating In Bad Discord Games" /><published>2025-11-26T00:00:00+00:00</published><updated>2025-11-26T00:00:00+00:00</updated><id>http://enderspearl184.github.io/cheating-in-bad-discord-games</id><content type="html" xml:base="http://enderspearl184.github.io/cheating-in-bad-discord-games/"><![CDATA[<p>so there’s this discord activity called farm merge valley i saw some of my friends playing.
its quite a bad game. i decided to cheat in it.</p>

<h1 id="how-do-you-cheat-in-a-web-game-again">how do you cheat in a web game again</h1>
<p>well this game <em>looks</em> like wasm so i should be able to use cetus and maybe learn how that works</p>

<h2 id="its-not-wasm-also-your-browser-has-crashed-lol-lmao-even">its not wasm. also your browser has crashed lol lmao even</h2>
<p>for some reason this game is written entirely in typescript. and it manages to nearly crash my browser (both the electron app and firefox)
when i run it with devtools open. how do you even manage to do that. it spams breakpoints too but you can just disable those.</p>

<h1 id="the-network-tab">the network tab</h1>
<p>one of the first things that caught my eye was a <a href="https://1187013846746005515.discordsays.com/.proxy/json/progression/progression_per_level.json?v=1.70.7">level up rewards json file.</a>
most of the json files were for like <span class="rainbow">sprite info</span> but this one wasnt.</p>

<p>can i use fiddler classic to replace this with like infinite gems when i reach level 5?</p>

<p><b class="rainbow wavy" style="font-size:32pt; display: table; margin: 0 auto;">of course you can</b>
<img src="/images/baddiscordgame/levelupwow.png" alt="level 5 reward with like 9 morbillion gems" /></p>

<h1 id="the-end-lmao">the end lmao</h1>]]></content><author><name>me</name></author><category term="JavaScript" /><category term="Hacking" /><category term="Videogames" /><summary type="html"><![CDATA[it was really easy lol]]></summary></entry><entry><title type="html">Rewriting a Dumpster Fire Codebase</title><link href="http://enderspearl184.github.io/rewriting-a-dumpster-fire/" rel="alternate" type="text/html" title="Rewriting a Dumpster Fire Codebase" /><published>2025-11-21T00:00:00+00:00</published><updated>2025-11-21T00:00:00+00:00</updated><id>http://enderspearl184.github.io/rewriting-a-dumpster-fire</id><content type="html" xml:base="http://enderspearl184.github.io/rewriting-a-dumpster-fire/"><![CDATA[<p>i was brought along to help with a rewrite for the roblox game <a href="https://www.roblox.com/games/113323927469374/Musical-Chairs">Musical Chairs.</a> 
if the game seems very simple, thats because it is.</p>

<p><span class="rainbow wavy">the original codebase was from 2018 btw</span></p>

<h2 id="the-datastores">THE DATASTORES</h2>
<p>i don’t know where to start so i’ll mention the datastores first.=
other games usually store data in tables, some even have session locking (usually via libraries such as ProfileStore or the older ProfileService)</p>

<p>so this game stores your data in a folder of ValueBase instances.
some games do this, it’s not catastrophic yet.
btw the inventory is stored as lists of literally all the item data in the game, just the ones you actually own have “Owned” set to true.
btw the item ids are the index into these arrays. whioch are json encoded. into a StringValue
and your actual datastore is also JSON encoded before being uploaded (roblox already does this; but converts it back to a table on load so you wouldnt notice in most cases. its bad here because it makes datastore editors treat it as a giant string)</p>

<p>by the way, there’s some <span class="rainbow">buggy jsonencode behaviour</span> that arises if you do such crimes</p>
<div class="language-lua highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">game</span><span class="p">.</span><span class="n">HttpService</span><span class="p">:</span><span class="n">JSONEncode</span><span class="p">({</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="kc">nil</span><span class="p">,</span><span class="kc">nil</span><span class="p">,</span><span class="mi">5</span><span class="p">}))</span> <span class="c1">-- [1,2,null,null,5]</span>
<span class="nb">print</span><span class="p">(</span><span class="n">game</span><span class="p">.</span><span class="n">HttpService</span><span class="p">:</span><span class="n">JSONEncode</span><span class="p">({</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="kc">nil</span><span class="p">,</span><span class="mi">4</span><span class="p">}))</span> <span class="c1">-- [1,2,null,4]</span>
<span class="nb">print</span><span class="p">(</span><span class="n">game</span><span class="p">.</span><span class="n">HttpService</span><span class="p">:</span><span class="n">JSONEncode</span><span class="p">({[</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="p">[</span><span class="mi">4</span><span class="p">]</span><span class="o">=</span><span class="mi">4</span><span class="p">}))</span> <span class="c1">-- [1,2,null,4]</span>
<span class="nb">print</span><span class="p">(</span><span class="n">game</span><span class="p">.</span><span class="n">HttpService</span><span class="p">:</span><span class="n">JSONEncode</span><span class="p">({[</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span><span class="mi">1</span><span class="p">,[</span><span class="mi">2</span><span class="p">]</span><span class="o">=</span><span class="mi">2</span><span class="p">,[</span><span class="mi">5</span><span class="p">]</span><span class="o">=</span><span class="mi">5</span><span class="p">}))</span> <span class="c1">-- [1,2] ????</span>
</code></pre></div></div>

<p>the issues:</p>
<ul>
  <li>no session locking so its quite easy to lose data</li>
  <li>also all the IDs have to be sequential otherwise youll run into issues with HttpService:JSONEncode that aren’t documented properly</li>
  <li>the weird jsonencode issues which cause headaches when adding items (and make it nigh impossible to remove them without hacky workarounds)</li>
</ul>

<h2 id="the-everything-else">THE EVERYTHING ELSE</h2>
<p>was just really badly structured, error-prone, and overall poorly programmed; its not that interesting to go over the other glaring issues.
the datastores make up the bulk of the problems i think anyways</p>

<p>ill list a few other miscellaneous things that each gave me a mild aneurysm though, in no particular order</p>
<ul>
  <li>the chair model is scaled at 0.001 (and so are a lot of the chair skins)</li>
  <li>cosmetics have inconsistent and often broken hierarchy structures</li>
  <li>simple custom gamemodes manage to be very confusing to read – <span class="wavy">comments be damned</span></li>
</ul>

<h2 id="the-fixing">THE FIXING</h2>
<p>now it uses <a href="https://rojo.space/">rojo</a> and git instead of just roblox studio. that doesnt make the programming instantly better it just makes it nicer to work with imo.
EVERYTHING WAS REWRITTEN UNDER THE HOOD. <span class="rainbow wavy">EVERYTHING.</span> we went scorched earth with it.
user data now uses ProfileStore so we have session locking, and dataloss is mitigated !!
most importantly, THE STRINGVALUES ARE NO MORE!!!!!!!!!!!!!!!!!</p>

<h1 id="so-now-what">so now what</h1>
<p>the rewrite not actually finished yet as of now. but like we have lives sooooooooooooo yeah.</p>]]></content><author><name>me</name></author><category term="Roblox" /><category term="Code" /><category term="Luau" /><summary type="html"><![CDATA[This might have been the worst codebase of any roblox game that had > 0 players]]></summary></entry><entry><title type="html">Hello, world!</title><link href="http://enderspearl184.github.io/hello-world/" rel="alternate" type="text/html" title="Hello, world!" /><published>2025-11-20T00:00:00+00:00</published><updated>2025-11-20T00:00:00+00:00</updated><id>http://enderspearl184.github.io/hello-world</id><content type="html" xml:base="http://enderspearl184.github.io/hello-world/"><![CDATA[<p>I started editing this theme to try and make a decent github pages!!!</p>

<p>in short, i saw a modified version of the Reverie theme on <a href="https://pwoofy.me">pwoofy.me</a> and thought it looked cool. sooooooooooo i forked <a href="https://github.com/amitmerchant1990/reverie">the original</a> and started changing it ^-^</p>

<p>rn i ended with like a larp hackerman style solely because i think its funny. maybe ill add like a glitch text effect as text scrolls off screen or smth idk</p>

<p>dont expect to see much of anything here soon.</p>]]></content><author><name>me</name></author><category term="HTML" /><category term="Code" /><summary type="html"><![CDATA[I started editing this theme to try and make a decent github pages!!!]]></summary></entry></feed>