<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Mirai. Blog]]></title><description><![CDATA[Mirai. Blog]]></description><link>https://mirai.blog/</link><image><url>https://mirai.blog/favicon.png</url><title>Mirai. Blog</title><link>https://mirai.blog/</link></image><generator>Ghost 5.76</generator><lastBuildDate>Wed, 24 Jun 2026 19:25:44 GMT</lastBuildDate><atom:link href="https://mirai.blog/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[/r/osuplace Behind The Scenes: Technology]]></title><description><![CDATA[/r/osuplace had some projects running during the /r/place event on reddit to make things work well. Have a look behind the scenes of the tech we made and used.]]></description><link>https://mirai.blog/osuplace-behind-the-scenes-technology/</link><guid isPermaLink="false">6411daa32bd4ce0001583f90</guid><category><![CDATA[osu!]]></category><category><![CDATA[Technology]]></category><dc:creator><![CDATA[Subject]]></dc:creator><pubDate>Tue, 05 Apr 2022 23:16:33 GMT</pubDate><media:content url="https://mirai.blog/content/images/2022/04/Photoshop_2022-04-05_19-25-16.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://mirai.blog/content/images/2022/04/Photoshop_2022-04-05_19-25-16.jpg" alt="/r/osuplace Behind The Scenes: Technology"><p>The /r/osuplace community had a couple of technical projects running behind the scenes for making things work like the overlay on the /r/place canvas and the verification website. In this article I will talk about these projects and explain many of the components that were made and used. These tools are also made available for you to use, study and to potentially improve upon. I will apologise in advance for abundant usage of technical jargon in this article. I go pretty deep into the details for certain things we have done. I hope you will be able to get a rough idea of what we did. Firstly, I will talk about the verification site that was made to automatically verify users based on their Reddit account age. Secondly, I will talk about the overlay that was made for users so they know where to place the pixels on the canvas. Lastly, I will cover some of the Python scripts that were used to make the overlay work correctly. At the end I have also included some statistics and links to many of the people that worked on the projects. </p><h2 id="verification-site">Verification Site</h2><p>A couple of days before the start of r/place oralekin approached me about using my <a href="https://github.com/MiraiSubject/oth-verification/tree/universal-2?ref=mirai.blog">tournament verification system</a> (TVS) for the r/osuplace Discord server. I would help him out with the project and host it for them for free for the duration of the event. The TVS verifies a user by having them login with their osu! account and their Discord account on a website. After the user has done both, they will be checked against the criteria set in the backend. Then the Discord bot that sits in the same backend joins them to the Discord server and adds a role signifying that the user is verified now. The main advantage for this application is that staff members on medium to large servers do not have to manually verify the details of a user anymore. The application can also accommodate for edge cases where users do not meet the requirements, and they will be shown an error page or directed to the staff members of the respective discord server.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="2000" height="1261" srcset="https://mirai.blog/content/images/size/w600/2022/04/image.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/image.png 1600w, https://mirai.blog/content/images/2022/04/image.png 2075w" sizes="(min-width: 720px) 720px"><figcaption>The TVS deployment of the osu! tournament hub.</figcaption></figure><p>I modified this system recently for other people to be able to easily adapt and use in their own environments. So, I directed oralekin to this new version and he set it up with an additional path for the verification of a user&apos;s Reddit account and different verification criteria. I also assisted him with certain regressions that he came across when I changed the backend to be more universal. These changes will be added to the upstream repository as well. When it was finished we did a couple of test runs on the domain name and declared it ready for the event. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-1.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="1744" height="1307" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-1.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image-1.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/image-1.png 1600w, https://mirai.blog/content/images/2022/04/image-1.png 1744w" sizes="(min-width: 720px) 720px"><figcaption>/r/osuplace verification website</figcaption></figure><p>oralekin managed the DNS for his subdomain (<a href="https://o.ralek.in/?ref=mirai.blog">o.ralek.in</a>) and I gave him the IP of the proxy that this verification site was hosted behind. Due to the expectation of a high traffic flow and the potential of malicious actors trying to do something to it, we did the following things: </p><ul><li>Secured the backend using built-in security features</li><li>Implemented a rate limiter to prevent the server from being flooded</li><li>Used Cloudflare as a proxy to hide the server&apos;s IP and to also make use of their other security features like DDoS protection</li><li>Used HTTPS end-to-end from the origin to the user using a combination of Let&apos;s Encrypt and Cloudflare. In Cloudflare the security was set to Full (strict).</li></ul><p>We did not use HSTS, because if it is configured wrongly it could leave the domain unreachable for a long time. </p><p>It successfully verified more than 10.000 people during the event and it did not crash at all. We saw only two types of actions fail. From time to time Reddit&apos;s authentication would fail, because it could not obtain the access token for a user. This is likely because we were hitting rate limits on the Reddit API which caused the failures. The second action we saw fail was writing of cookies for certain users. This could be due to the fact that they have cookies or javascript blocked by default on their browser for privacy reasons, because both are required and we do not write the cookie without consent. </p><p>The final code base for this verification server can be found on <a href="https://github.com/oralekin/oth-verification/tree/place?ref=mirai.blog">GitHub</a>. We are proud that this project was successful and useful to the community. </p><h2 id="rplace-pixel-overlay">/r/place pixel overlay</h2><p>After publishing the verification project oralekin told me they were working on an overlay to show users where to place their pixels on the canvas of /r/place for the osu! logo. I joined their voice chat and they were initially having some problems finding the right spot to insert the overlay into. Their original plan was to hook into the canvas itself and track the movement and zoom level. However, I quickly found out they were overthinking the operation by inserting an image above the canvas inside the same container. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-2.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="839" height="204" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-2.png 600w, https://mirai.blog/content/images/2022/04/image-2.png 839w" sizes="(min-width: 720px) 720px"><figcaption>The container that the canvas sits is what scales and moves and whole thing.&#xA0;</figcaption></figure><p>By appending an element to that container it was possible to overlay an image that just worked without any extra effort needed. The first proper version of that element was the following: </p><figure class="kg-card kg-code-card"><pre><code class="language-html">&lt;img style=&quot;position: absolute;left: 677px;top: 677px;image-rendering: crisp-edges;width: 101px;height: 101px;&quot; src=&quot;https://cdn.discordapp.com/attachments/959453204163199056/959454670479298590/dotted_template_v3.png&quot;&gt;</code></pre><figcaption>Top and left 677 px because the image is top-left anchored, image-rendering: crisp-edges for nearest neighbour scaling. Lastly, width and height, because of the dotted spacing in 3x size.</figcaption></figure><p>The first version of the Tampermonkey script that came out of this was: </p><pre><code class="language-javascript">// ==UserScript==
// @name         osu! Logo template
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the canvas!
// @author       oralekin
// @match        https://hot-potato.reddit.com/embed*
// @icon         https://www.google.com/s2/favicons?sz=64&amp;domain=reddit.com
// @grant        none
// ==/UserScript==
if (window.top !==window.self) {
    window.addEventListener(&apos;load&apos;, () =&gt; {
            document.getElementsByTagName(&quot;mona-lisa-embed&quot;)[0].shadowRoot.children[0].getElementsByTagName(&quot;mona-lisa-canvas&quot;)[0].shadowRoot.children[0].appendChild(
        (function () {
            const i = document.createElement(&quot;img&quot;);
            i.src = &quot;https://cdn.mirai.gg/tmp/dotted-place-template.png&quot;;
            i.style = &quot;position: absolute;left: 0;top: 0;image-rendering: pixelated;width: 1000px;height: 1000px;&quot;;
            console.log();
            return;
        })())
    }, false);
}</code></pre><p><code>https://hot-potato.reddit.com/embed</code> was embedded as an iframe on the Subreddit, so we had to address it directly to be able to access the child <a href="https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot?ref=mirai.blog">ShadowRoots</a> of that embed. Reddit also used the <a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements?ref=mirai.blog">Custom Elements API</a> for the elements of r/place which they named <code>&lt;mona-lisa-embed/&gt;</code> ,<code>&lt;mona-lisa-canvas/&gt;</code> etc. This made it easy to traverse the DOM using JavaScript to get to the correct location for the element. After that many other contributors like LittleEndu, Wieku, ekgame and DeadRote added more features to this script. The very first versions can be found on <a href="https://gist.github.com/oralekin/240d536d13d0a87ecf2474658115621b?ref=mirai.blog">oralekin&apos;s GitHub Gist</a>. As you may have noticed I did not get co-credited for creating the script, but I do not mind it. Later, oralekin&apos;s gist got replaced with this script made by Wieku, Deadrote, and <a href="https://github.com/Anticept/httyd-place/pull/3?ref=mirai.blog">101arrowz</a>, hosted on <a href="https://gist.github.com/Wieku/7d5a88c0a34d5bdf0b6bd9959f7d5e1d?ref=mirai.blog">Wieku&apos;s GitHub Gist</a>. This takes a different approach using the normal version of the canvas. It masks and dots it in the browser without the need for separate python scripts. A user interface is also included for some level of control on how the overlay gets displayed. The screenshots showcasing the userscript have been taken after the wipe of /r/place.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/Photoshop_2022-04-05_18-55-37.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="2000" height="836" srcset="https://mirai.blog/content/images/size/w600/2022/04/Photoshop_2022-04-05_18-55-37.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/Photoshop_2022-04-05_18-55-37.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/Photoshop_2022-04-05_18-55-37.png 1600w, https://mirai.blog/content/images/size/w2400/2022/04/Photoshop_2022-04-05_18-55-37.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>A section of the &quot;undotted&quot; template (zoomed 400% on a 6000x6000 canvas)</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/Photoshop_2022-04-05_18-55-46.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="2000" height="836" srcset="https://mirai.blog/content/images/size/w600/2022/04/Photoshop_2022-04-05_18-55-46.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/Photoshop_2022-04-05_18-55-46.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/Photoshop_2022-04-05_18-55-46.png 1600w, https://mirai.blog/content/images/size/w2400/2022/04/Photoshop_2022-04-05_18-55-46.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>A section of the &quot;dotted&quot; template (zoomed 400% on a 6000x6000 canvas)</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-5.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="1633" height="918" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-5.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image-5.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/image-5.png 1600w, https://mirai.blog/content/images/2022/04/image-5.png 1633w" sizes="(min-width: 720px) 720px"><figcaption>Wieku and Deadrote&apos;s variant of the userscript, annotated is the user-interface that gets added</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-6.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="1633" height="918" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-6.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image-6.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/image-6.png 1600w, https://mirai.blog/content/images/2022/04/image-6.png 1633w" sizes="(min-width: 720px) 720px"><figcaption>With highlight zones set to 50% and dotted overlay on</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-7.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="1633" height="918" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-7.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image-7.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/image-7.png 1600w, https://mirai.blog/content/images/2022/04/image-7.png 1633w" sizes="(min-width: 720px) 720px"><figcaption>Highlight zones at 50% and full design on</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-8.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="1633" height="918" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-8.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image-8.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/image-8.png 1600w, https://mirai.blog/content/images/2022/04/image-8.png 1633w" sizes="(min-width: 720px) 720px"><figcaption>Same as above with with highlight zones at 100%</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-9.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="1633" height="918" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-9.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image-9.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/image-9.png 1600w, https://mirai.blog/content/images/2022/04/image-9.png 1633w" sizes="(min-width: 720px) 720px"><figcaption>Same as above but with just the masks visible (Dotted overlay off, full design off)</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-10.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="1633" height="918" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-10.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image-10.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/image-10.png 1600w, https://mirai.blog/content/images/2022/04/image-10.png 1633w" sizes="(min-width: 720px) 720px"><figcaption>Highlight zones off, just the full design.</figcaption></figure><p>Over the course of the event I heard that the script got used by many communities and even got expanded on by them with their own versions and image templates, which is awesome. However, there were also certain communities that used the code, but also took the effort to remove the original authors&apos; names from the script.</p><p>The image template that /r/osuplace used was hosted on my S3 space with CDN. So, while I was not credited, it was very obvious that I was involved with this script.</p><p>The following two files are hosted and served to hundreds of thousands of users across the world: </p><ul><li><a href="https://cdn.mirai.gg/tmp/dotted-place-template.1-1.png?ref=mirai.blog">https://cdn.mirai.gg/tmp/dotted-place-template.1-1.png</a> (full canvas with all the allies and friends of /r/osuplace)</li><li><a href="https://cdn.mirai.gg/tmp/dotted-place-template.1-1.png?ref=mirai.blog">https://cdn.mirai.gg/tmp/dotted-place-template.png</a> (full canvas as dotted template suited as overlay)</li></ul><p>The images are hosted on DigitalOcean Spaces but with Cloudflare functioning as the proxy for a secure CDN connection between the two. Initially, this caused a number of issues due to double caching happening. There was caching on the edge at Digitalocean, but Cloudflare also cached it. The solution was to create a page rule for the CDN subdomain and to set that to bypass all of Cloudflare&apos;s caching. This way we could keep using Cloudflare&apos;s proxy to keep a secure connection between it, DigitalOcean and the end user, as well as prevent any of the caching problems. We also set the edge caching TTL on DigitalOcean at 10 minutes and if quicker refreshes were needed we could manually purge the cache for the specific files as well. </p><p>The files were generated by LittleEndu using a couple of Python scripts. I have received his permission to document the scripts, so these will be listed below. Where applicable, instructions on how to run them are also given, with example output. I also added his name and the original filename at the top of every file. </p><pre><code class="language-python"># dotter.py by LittleEndu (2022)
import sys
from pathlib import Path

from PIL import Image
import numpy as np

target_filepath = Path(sys.argv[1])
img = Image.open(target_filepath).convert(&apos;RGBA&apos;)  # make sure image is RGBA
img_3x = img.resize((img.width * 3, img.height * 3), Image.NEAREST)
img_3x_arr = np.array(img_3x)

for i in range(img_3x_arr.shape[0]):
    if i % 3 == 0 or (i - 2) % 3 == 0:
        img_3x_arr[i, :, 3] = 0
for i in range(img_3x_arr.shape[1]):
    if i % 3 == 0 or (i - 2) % 3 == 0:
        img_3x_arr[:, i, 3] = 0

img_3x_back = Image.fromarray(img_3x_arr)
img_3x_back.save(f&apos;!dotted_{target_filepath.name}&apos;)</code></pre><p>This first script resizes the image to 3 times the original size in both axes with nearest neighbour scaling. After that makes every first and 3rd duplicate pixel blank to create a dotted template of pixel art. </p><p>Run instructions:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">&gt; pip install pillow numpy
&gt; python ./dotter.py file-to-dot.png</code></pre><figcaption>This outputs a <code>!dotted_file-to-dot.png</code> which is 3 times the size on both axes and dotted like the images shown below.</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-3.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="1075" height="787" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-3.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/image-3.png 1000w, https://mirai.blog/content/images/2022/04/image-3.png 1075w" sizes="(min-width: 720px) 720px"><figcaption>As you can see 2 pixels are skipped every time in both axes. (dotted-template at 1000% zoom in Photoshop with pixel grid active)</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/image-4.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="635" height="356" srcset="https://mirai.blog/content/images/size/w600/2022/04/image-4.png 600w, https://mirai.blog/content/images/2022/04/image-4.png 635w"><figcaption>Dotted template one more time at 200%</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/dotted-place-template-3.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="2000" height="2000" srcset="https://mirai.blog/content/images/size/w600/2022/04/dotted-place-template-3.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/dotted-place-template-3.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/dotted-place-template-3.png 1600w, https://mirai.blog/content/images/size/w2400/2022/04/dotted-place-template-3.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>The full dotted template (Use the context menu to view this image in a seperate tab)</figcaption></figure><p>LittleEndu also made a script that reverts the dotted template back to the original image: </p><pre><code class="language-python"># reverse_dotter.py by LittleEndu (2022)
import sys
from pathlib import Path

from PIL import Image
import numpy as np


def i_dot(target_filepath):
    target_filepath = Path(target_filepath)
    img = Image.open(target_filepath)
    img.paste(img, (-1, -1), img)
    img_array = np.array(img)
    small_img_array = img_array[::3, ::3, :]
    small_img = Image.fromarray(small_img_array)
    small_img.save(target_filepath.with_suffix(&apos;.1-1.png&apos;))


if __name__ == &apos;__main__&apos;:
    i_dot(Path(sys.argv[1]))</code></pre><p>Run instructions:</p><pre><code class="language-bash"># pip install pillow numpy
# python ./reverse_dotter.py dotted-template.png</code></pre><p>If you use the dotted template as input, the following output will be produced: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/dotted-place-template.1-1.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="2000" height="2000" srcset="https://mirai.blog/content/images/size/w600/2022/04/dotted-place-template.1-1.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/dotted-place-template.1-1.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/dotted-place-template.1-1.png 1600w, https://mirai.blog/content/images/2022/04/dotted-place-template.1-1.png 2000w" sizes="(min-width: 720px) 720px"><figcaption>The dotted template, reversed using the python script.</figcaption></figure><p>He also created a script that placed pixel art on the canvas at specific x and y coordinates. This was useful for setting the location of artwork on the canvas for the template. </p><pre><code class="language-python"># convert_to_2k.py by LittleEndu (2022)
import sys
from pathlib import Path

from PIL import Image

target_filepath = Path(sys.argv[1])
img = Image.open(target_filepath).convert(&apos;RGBA&apos;)

x = int(input(&apos;x coord: &apos;))
y = int(input(&apos;y coord: &apos;))
w, h = img.size

new_img = Image.new(&apos;RGBA&apos;, (x + w, y + h), (255, 255, 255, 0))
new_img.paste(img, (x, y))

new_new_img = Image.new(&apos;RGBA&apos;, (2000, 2000), (255, 255, 255, 0))
new_new_img.paste(new_img, (0, 0))
new_new_img.save(f&quot;2k_{target_filepath.name}&quot;)</code></pre><p>How to run (example with the first version of the /r/osuplace logo): </p><figure class="kg-card kg-code-card"><pre><code class="language-bash"># pip install pillow
# python ./convert_to_1k.py template_v3.png
x coord: 727
y coord: 727</code></pre><figcaption>This outputs a 2k_template_v3.png file, which is the size of the final /r/place canvas with the logo at the specified coordinates.</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2022/04/2k_template_v3.png" class="kg-image" alt="/r/osuplace Behind The Scenes: Technology" loading="lazy" width="2000" height="2000" srcset="https://mirai.blog/content/images/size/w600/2022/04/2k_template_v3.png 600w, https://mirai.blog/content/images/size/w1000/2022/04/2k_template_v3.png 1000w, https://mirai.blog/content/images/size/w1600/2022/04/2k_template_v3.png 1600w, https://mirai.blog/content/images/2022/04/2k_template_v3.png 2000w" sizes="(min-width: 720px) 720px"><figcaption>/r/osuplace logo on an empty 2000x2000 canvas</figcaption></figure><p>Lastly, he wrote a simple script to rename the files for the CDN and to generate a reverse dotted version.</p><pre><code class="language-python"># rename_for_cdn.py by LittleEndu (2022)
import shutil
import sys

shutil.copy(sys.argv[1], &quot;dotted-place-template.png&quot;)

import reverse_dotter

reverse_dotter.i_dot(&quot;dotted-place-template.png&quot;)</code></pre><p>The outputs of this script were the final files that were uploaded to the CDN for use by everyone using the Tampermonkey script. </p><h2 id="closing-words">Closing words</h2><p>It was honestly so awesome to see the /r/osuplace community work together, not just by themselves, but together with many other communities as well. Over the duration of the event over 436.000 requests were made to the cdn, with more than 2/3rd actually hitting the <code>png</code> content-type. About 100 GB of bandwidth was transferred between my servers and end-users (verification server data included too). Cloudflare also reports &quot;Web traffic requests by country&quot; over the past 7 days. Here are the top 5 countries: </p><ol><li>United States: more than 150.000 requests</li><li>Canada: more than 30.000 requests</li><li>Germany: ~30.000 requests</li><li>United Kingdom: more than 20.000 requests</li><li>Philippines: more than 15.000 requests</li></ol><p>Thank you for reading through this blog post. I hope that you have learned something new from this, or maybe this motivated you to use one of our projects for yourself. Either way, I think the efforts of this community were super cool and I look forward to next time.</p><h2 id="links">Links</h2><p>oralekin&apos;s GitHub: <a href="https://github.com/oralekin?ref=mirai.blog">https://github.com/oralekin</a><br>LittleEndu&apos;s GitHub: <a href="https://github.com/LittleEndu?ref=mirai.blog">https://github.com/LittleEndu</a><br>Wieku&apos;s GitHub: <a href="https://github.com/Wieku?ref=mirai.blog">https://github.com/Wieku</a><br>Deadrote&apos;s Twitch (has no GitHub): <a href="https://twitch.tv/deadrote?ref=mirai.blog">https://twitch.tv/deadrote</a><br>ekgame&apos;s GitHub: <a href="https://github.com/ekgame?ref=mirai.blog">https://github.com/ekgame</a><br>exdeejay&apos;s GitHub: <a href="https://github.com/exdeejay?ref=mirai.blog">https://github.com/exdeejay</a><br>101arrowz&apos;s GitHub: <a href="https://github.com/101arrowz?ref=mirai.blog">https://github.com/101arrowz</a><br>My GitHub: <a href="https://github.com/MiraiSubject/?ref=mirai.blog">https://github.com/MiraiSubject</a></p><p>Let me know if I forgot to credit anybody!</p><p>/r/osuplace verification stack: <a href="https://github.com/oralekin/oth-verification/tree/place?ref=mirai.blog">https://github.com/oralekin/oth-verification/tree/place</a><br>osu! tournament hub verification stack: <a href="https://github.com/MiraiSubject/oth-verification?ref=mirai.blog">https://github.com/MiraiSubject/oth-verification</a></p><p>First versions of the userscript: <a href="https://gist.github.com/oralekin/240d536d13d0a87ecf2474658115621b?ref=mirai.blog">https://gist.github.com/oralekin/240d536d13d0a87ecf2474658115621b</a><br>Most recent versions of the userscript: <a href="https://gist.github.com/Wieku/7d5a88c0a34d5bdf0b6bd9959f7d5e1d/?ref=mirai.blog">https://gist.github.com/Wieku/7d5a88c0a34d5bdf0b6bd9959f7d5e1d/</a><br>/r/httyd place userscript (source for masking/dithering by 101arrowz): <br><a href="https://github.com/Anticept/httyd-place?ref=mirai.blog">https://github.com/Anticept/httyd-place</a></p><p>Mention me on Twitter or Discord if you have something to say about the article! <a href="https://twitter.com/MiraiSubject?ref=mirai.blog">https://twitter.com/MiraiSubject</a></p><p>Apologies if the English is lacking here and there, if you find any mistakes, let me know and I will change it.</p><p><strong>Update 1 (2022-04-08 13:06 UTC)</strong>: Added 101arrowz&apos;s contribution to the blog, courtesy of <a href="https://twitter.com/anticept/status/1512395982536945666?s=21&amp;ref=mirai.blog">Anticept on Twitter</a>.</p>]]></content:encoded></item><item><title><![CDATA[How to control and personalise the osu!lazer tournament client]]></title><description><![CDATA[In this guide I will show you how to personalise the osu!lazer tournament client with graphics and what the controls do. ]]></description><link>https://mirai.blog/adding-graphics-to-your-osu-lazer-tournament-setup/</link><guid isPermaLink="false">6411daa32bd4ce0001583f8f</guid><category><![CDATA[osu!]]></category><category><![CDATA[Technology]]></category><dc:creator><![CDATA[Subject]]></dc:creator><pubDate>Sun, 16 Aug 2020 13:45:58 GMT</pubDate><content:encoded><![CDATA[<p>In the <a href="https://mirai.blog/osu-lazer-tournament-streaming-guide/">previous guide</a> we covered how to initially setup the lazer client and how to appropriately add the necessary sources for it in OBS. In this guide I will show you how to control these scenes and how to personalise them with videos and images. </p><p>All the assets that the client uses are placed according to the following directory structure:</p><!--kg-card-begin: markdown--><p>&#x1F4C2;tournaments<br>
&#x2523; &#x1F4C2;default<br>
&#x2503; &#x2517; &#x1F4C2;flags<br>
&#x2503; &#x2503; &#x2517; your flags here<br>
&#x2503; &#x2523; &#x1F4C2;mods<br>
&#x2503; &#x2503; &#x2523; DT.png<br>
&#x2503; &#x2503; &#x2523; FM.png<br>
&#x2503; &#x2503; &#x2523; HD.png<br>
&#x2503; &#x2503; &#x2523; HR.png<br>
&#x2503; &#x2503; &#x2523; NM.png<br>
&#x2503; &#x2503; &#x2517; TB.png<br>
&#x2503; &#x2523; &#x1F4C2;videos<br>
&#x2503; &#x2503; &#x2523; gameplay.mp4<br>
&#x2503; &#x2503; &#x2523; ladder.mp4<br>
&#x2503; &#x2503; &#x2523; main.mp4<br>
&#x2503; &#x2503; &#x2523; mappool.mp4<br>
&#x2503; &#x2503; &#x2523; schedule.mp4<br>
&#x2503; &#x2503; &#x2523; seeding.mp4<br>
&#x2503; &#x2503; &#x2523; showcase.mp4<br>
&#x2503; &#x2503; &#x2523; teamintro.mp4<br>
&#x2503; &#x2503; &#x2523; teamwin-blue.mp4<br>
&#x2517; &#x2517; &#x2517; teamwin-red.mp4</p>
<!--kg-card-end: markdown--><p>The images in the <code>mods</code> folder are used across the different scenes that display maps, like the Mappool scene and the Seeding scene. If you wish to create your own graphics, the dimensions that I recommend if you wish to create your own graphics is 180x100 for rectangles and 150x150 for squares and circles. </p><p>I will go through all of the screens one by one and also specify which video file it needs as its background. Feel free to use CTRL+F on this webpage if you&apos;re looking for the purpose of a specific file. </p><h2 id="schedule">Schedule</h2><p>The Schedule scene will display the matches that have recently happened and any planned matches in the future that have a specific date and time set in the Bracket Editor. It also displays the match that is coming up next with a countdown. </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/07/image-10.png" class="kg-image" alt loading="lazy"></figure><p>This scene uses <code>schedule.mp4</code> as its background video. </p><h2 id="teamintro">TeamIntro</h2><p>The TeamIntro scene displays the information about the match that is about to be played. It shows the current stage and the two teams facing off against each other. It also shows the flags for both teams. One column of players in this screen can fill up to 5 players and consecutive columns will be made for more players if necessary. &#xA0;</p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/08/image.png" class="kg-image" alt loading="lazy"></figure><p>This scene uses <code>teamintro.mp4</code> as its background video. </p><h2 id="seeding">Seeding</h2><p>The seeding scene displays one team and the information about the players and their ranks. You can use this screen to display the the results of the seeding and their placing in the last iteration of the tournament. </p><p>The seeding information can be edited in the Team Editor. I will go more in-depth about entering this information and more in the next guide. </p><h3 id="controls">Controls</h3><p>In the control panel, on the right side the streamer can switch between the two teams of the current match, so the viewers can get context on the team that the commentators are talking about. There is also a dropdown menu to select a specific team that is not participating in the same match. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/08/image-2.png" class="kg-image" alt loading="lazy"><figcaption>Seedings screen without seeding results</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/08/image-3.png" class="kg-image" alt loading="lazy"><figcaption>Seedings screen with one seeding result</figcaption></figure><p>The seeding scene uses <code>seeding.mp4</code> as its background video. </p><h2 id="mappool">Mappool</h2><p>The mappool screen takes the data you entered from the Rounds Editor and displays on screen for the viewers. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/image-19.png" class="kg-image" alt loading="lazy"><figcaption>A mappool screen</figcaption></figure><p>On this screen, the streamer can control the pick and ban phase. The former is usually to be manually input, because beatmap changes executed by the referee are automatically marked as picks. However, in the event that there are server issues or an exceptional situation happens during a match, the streamer can override this behaviour. These actions are only visual changes and will not affect the lobby. </p><h3 id="controls-1">Controls</h3><!--kg-card-begin: markdown--><p>The controls on the Mappool screen are pretty straightforward:</p>
<ul>
<li>Left click on a beatmap tile: execute the selected action in the control panel.</li>
<li>Right click on a beatmap tile: remove the marking.</li>
</ul>
<p>The control panel can be used to control the action you want to execute. It&apos;s recommended to select an action in the control panel before you click on the tiles, because the default flow is Red pick -&gt; Blue ban -&gt; Red ban -&gt; Red pick -&gt; Blue pick etc.</p>
<!--kg-card-end: markdown--><h3 id="graphics">Graphics</h3><p>The Mappool screen makes use of the images provided in the `mods` folder to mark the mod type used on a specified beatmap. The mods you define in the client should match the filenames of the images you&apos;re providing in the folder. </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/06/image-20.png" class="kg-image" alt loading="lazy"></figure><p>The Mappool screen uses <code>mappool.mp4</code> as its background. </p><h2 id="gameplay">Gameplay</h2><p>The gameplay screen is where the spectating of the match takes place. If you followed the <a href="https://mirai.blog/osu-lazer-tournament-streaming-guide/">previous guide</a>, then the green section is keyed out and replaced by the gameplay windows in your streaming program. </p><p>In the top centre, the text for the current round and the logo (if added) is displayed. Then on each side the team names, their scores and flag are displayed. In the bottom the chat and song info are displayed when a map is not being played. </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/07/image-3.png" class="kg-image" alt loading="lazy"></figure><p>When a map is being played the bottom side of the screen changes to display the score and the information about the current map. </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/07/image-2.png" class="kg-image" alt loading="lazy"></figure><h3 id="controls-2">Controls</h3><!--kg-card-begin: markdown--><p>On the right side there are the following controls:</p>
<ul>
<li>Toggle warmup: This toggles the visibility of the score counter of the teams and toggles the automatic score incrementing.</li>
<li>Toggle chat: This is needed if the chat doesn&apos;t automatically show up after a round. Clicking this button in any other case causes the chat window visibility to be toggled.</li>
<li>Chroma width: You can adjust the width of the green area that gets keyed out in OBS. It&apos;s recommended to keep this at the highest value.</li>
<li>Players per team: You can adjust the players per team between 3 and 4 here. For a 1v1 or 2v2 match  you&apos;d want to keep this on 4. For a 3v3 you&apos;d want this on 3.</li>
</ul>
<!--kg-card-end: markdown--><h3 id="graphics-1">Graphics</h3><p>An important difference between osu!lazer and Stable is that the positions of the Red Team and Blue Team are flipped. In the original Stable and Cutting Edge clients Blue Team is on the left and Red Team is on the right. </p><p>If you prefer being consistent, it&apos;s recommended to inform any referees and graphic designers about this so they can adjust for it.</p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/08/image-6.png" class="kg-image" alt loading="lazy"></figure><p>The Gameplay screen uses <code>gameplay.mp4</code> as its background. </p><h2 id="win">Win</h2><p>The Win scene is where the winner of the most recent match is displayed. It will automatically show after a delay when a team wins the match. It is also manually triggerable by left clicking on the score count in the gameplay scene until the maximum is reached. </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/07/image-5.png" class="kg-image" alt loading="lazy"></figure><h3 id="graphics-2">Graphics</h3><p>The Win scene uses <code>teamwin-blue.mp4</code> and <code>teamwin-red.mp4</code> depending on which team wins. As different files are used for the two possible winners, it&#x2019;s possible to make backgrounds specific to the winning team.</p><h2 id="showcase">Showcase</h2><p>The Showcase scene is used for mappool showcases. Most of the scene here will be chroma keyed, with only the bottom right corner showing for the background video. </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/07/image-6.png" class="kg-image" alt loading="lazy"></figure><p>To make optimal use of this scene, you need to manually set the resolution of osu!stable to <s>1920x980</s> 1920x978 or a different resolution that conforms to the <s>96:49</s> 320:163 aspect ratio. This makes the client perfectly fit inside the chroma keyed area. You can achieve this by opening your <code>osu!.&lt;username&gt;.cfg</code> file and editing the lines for <code>Width</code> and <code>Height</code> appropriately. </p><p>For the song info to show correctly you will need to use osu! in the Cutting Edge release branch.</p><p>In the next guide I will cover the Editor screens and you will learn about adding teams, rounds and how the bracket works in osu!lazer. </p><!--kg-card-begin: markdown--><p>You can follow the osu!lazer project here on GitHub: <a href="https://github.com/ppy/osu?ref=mirai.blog">https://github.com/ppy/osu</a><br>
Follow me on Twitter: <a href="https://twitter.com/MiraiSubject?ref=mirai.blog">https://twitter.com/MiraiSubject</a></p>
<p>Feel free to shoot me a tweet if you have any questions!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Suzune Dev Blog #1: Introduction]]></title><description><![CDATA[Welcome to the introduction on how Suzune, the discord bot of the You-Zitsu Community Server, came into existence. ]]></description><link>https://mirai.blog/suzune-dev-blog-1-introduction/</link><guid isPermaLink="false">6411daa32bd4ce0001583f8b</guid><category><![CDATA[Technology]]></category><category><![CDATA[General]]></category><category><![CDATA[Development]]></category><category><![CDATA[Suzune]]></category><dc:creator><![CDATA[Subject]]></dc:creator><pubDate>Sun, 28 Jun 2020 10:47:47 GMT</pubDate><content:encoded><![CDATA[<p>Suzune is a Discord bot I&apos;ve been working for a year and only now I&apos;ve started to document it. Progress has been going slowly, but there&apos;s a lot I want to do with it. Suzune comes from the name of a girl in Classroom of the Elite and the discord server that this bot is meant for is about series. &#xA0;</p><p>This post will serve as an introductory post that I will build upon later. </p><h2 id="the-beginning">The beginning</h2><p>So we needed a bot. Why not use an existing one? We have actually did in the past. Before Suzune we used a bot called the &quot;Reaction Role Bot&quot; and this was a closed-source bot by a third party developer. We noticed, however, that this bot had a lot of downtime. It froze a lot, took too long to add or remove roles or was just outright down. </p><p>Now, we already have a couple of bots that facilitate many different things, but none of the existing bots featured a reaction role feature (at the start of the development of this bot).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/03/image.png" class="kg-image" alt loading="lazy"><figcaption>Representation of the reaction roles in production.</figcaption></figure><h2 id="from-javascript-to-typescript">From Javascript to Typescript</h2><p>When I started making this bot I picked up one of my older bots and started coding in that, but I realised that the code was getting very cluttered. It used a lot of older Javascript features and I couldn&apos;t make use of the newer features without converting the whole codebase.</p><p>So, I started making this bot completely from scratch using Typescript and the result is a bot that is very modular and easily maintainable on the long term. Combine this with a stack on docker and all I had to do for an update was: </p><!--kg-card-begin: markdown--><pre><code class="language-bash">docker-compose pull
docker-compose down
docker-compose up -d
</code></pre>
<!--kg-card-end: markdown--><p>This was all backed by a self hosted GitLab and CI instance. The code gets pushed to GitLab, CI builds a docker image and then I do those commands on the node that runs the bot.</p><h2 id="features-that-got-added-over-time">Features that got added over time</h2><p>After having finished implementing the reaction roles, I started on the points system. The bot that managed that at the time had a role shop and a points system that users could use to buy coloured roles and exchange points between each other. It had many issues near the end of its lifespan, so I rewrote it into this bot. The original creator also passed the database on to me so I could migrate everyone&apos;s existing points over this bot. </p><p>There&apos;s more to come to this bot soon and we will also go in-depth about some of its features on a code level. So stay tuned!</p>]]></content:encoded></item><item><title><![CDATA[The definitive guide to streaming tournaments using osu!lazer]]></title><description><![CDATA[In this article, I will give you instructions on how to create a stream-ready tournament setup using the osu!lazer tournament client. ]]></description><link>https://mirai.blog/osu-lazer-tournament-streaming-guide/</link><guid isPermaLink="false">6411daa32bd4ce0001583f8e</guid><category><![CDATA[osu!]]></category><category><![CDATA[Technology]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Subject]]></dc:creator><pubDate>Sun, 28 Jun 2020 00:37:39 GMT</pubDate><media:content url="https://mirai.blog/content/images/2020/06/obs64_2020-06-28_02-51-15.png" medium="image"/><content:encoded><![CDATA[<img src="https://mirai.blog/content/images/2020/06/obs64_2020-06-28_02-51-15.png" alt="The definitive guide to streaming tournaments using osu!lazer"><p>A proper article/tutorial has been long due for streaming tournaments using osu!lazer. The only way to get this knowledge currently is through the word of mouth from people within the tournament community and an already outdated Russian video tutorial. So, here is a definitive guide on how to operate the lazer tournament client and stream it using OBS.</p><p><strong>Important note</strong>: osu!lazer tournament is only being used as an overlay for the existing tournament client. </p><h2 id="table-of-contents">Table of Contents</h2><!--kg-card-begin: markdown--><ol>
<li><a href="#prerequisites-requirements">Prerequisites &amp; Requirements</a></li>
<li><a href="#initial-setup-for-osu-lazer">Initial setup for osu!lazer</a></li>
<li><a href="#setting-up-osu-stable-to-work-with-lazer">Setting up osu! stable to work with lazer</a></li>
<li><a href="#configuring-the-tournament-clients">Configuring the tournament clients</a></li>
<li><a href="#setting-up-obs">Setting up OBS</a>
<ol>
<li><a href="#if-you-already-have-an-existing-obs-setup">If you already have an existing OBS setup</a></li>
<li><a href="#adding-the-necessary-items-for-your-stream">Adding the necessary items for your stream</a></li>
</ol>
</li>
<li><a href="#known-problems">Known problems</a></li>
</ol>
<!--kg-card-end: markdown--><h2 id="prerequisites-requirements">Prerequisites &amp; Requirements</h2><p>There are a couple of requirements and programs you need to have installed in advance.</p><!--kg-card-begin: markdown--><p>Software requirements:</p>
<ul>
<li>OBS Studio</li>
<li>osu! Stable, running on the Cutting Edge branch, this is required</li>
<li>osu!lazer, at least version 2020.623.1</li>
</ul>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Hardware requirements:</p>
<ul>
<li>At least 16 GB of RAM</li>
<li>A Powerful enough CPU/GPU combination to game and stream at the same time.</li>
</ul>
<p>Hardware recommendations:</p>
<ul>
<li>At least two 1080p (or higher resolution) screens.</li>
</ul>
<!--kg-card-end: markdown--><p>The amount of RAM and general horsepower your system needs from hereon depends on the teamsize you set for your client. On average one osu! stable instance uses ~300 MB of RAM and you need to incorporate some headroom for OBS and osu!lazer well. Some estimates for OBS and lazer are about 500-600MB each.</p><h2 id="initial-setup-for-osu-lazer">Initial setup for osu!lazer</h2><!--kg-card-begin: markdown--><p>First off to boot up osu!lazer into tournament mode you need to boot it up with the <code>--tournament</code> argument. You could achieve this by creating a shortcut that does this for you.</p>
<ol>
<li>Right click on your desktop, hover over &quot;New&quot; and then click on shortcut as shown in the screenshot below:<br>
<img src="https://mirai.blog/content/images/2020/06/2020-06-27_21-35-24.png" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></li>
<li>In the location field paste the following in: <code>%LOCALAPPDATA%\osulazer\osu!.exe --tournament</code>.<br>
The window should now look like this: <img src="https://mirai.blog/content/images/2020/06/explorer_2020-06-27_21-40-03.png" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></li>
<li>After clicking next you want to give it a name. Something like &quot;osu!lazer tournament&quot; would suffice.</li>
<li>You can now boot up osu!lazer in tournament mode using the shortcut you just made!</li>
</ol>
<!--kg-card-end: markdown--><h2 id="setting-up-osu-stable-to-work-with-lazer">Setting up osu! stable to work with lazer</h2><p>Go to the installation folder of the stable installation that you will be using. This will have to be cutting edge as well, so make sure you&apos;re on that branch!</p><p>You can do this over here in the options overlay: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/image.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>The section in the settings overlay where you can switch between Stable, Cutting Edge and Beta</figcaption></figure><p>After you&apos;ve confirmed this, you can close it. Once you&apos;ve closed it create an empty text file called <code>ipc.txt</code>. It will look like this in your installation folder: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/image-1.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>An osu! installation folder with the ipc.txt file added</figcaption></figure><h2 id="configuring-the-tournament-clients">Configuring the tournament clients</h2><p>Configuring osu! stable in tournament mode is already documented really well on the wiki, so set it up according to the instructions over there: <a href="https://osu.ppy.sh/help/wiki/osu%21tourney/Setup?ref=mirai.blog">https://osu.ppy.sh/help/wiki/osu!tourney/Setup</a></p><p>Take note of the <code>Height</code> that you set in your <code>tournament.cfg</code> file, because you&apos;re going to need this information a couple of times later in this guide. </p><p>After you have followed the instructions above, you can open osu!lazer tournament. You will be greeted by this screen: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/osu-_2020-06-27_22-53-03.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>osu!lazer tournament setup screen</figcaption></figure><p>Here is a short explanation of what all of these sections do:</p><ul><li><strong>Current IPC Source</strong>:<strong> </strong>Over here you set the location of your stable tournament client a.k.a the place where you made the <code>ipc.txt</code> &amp; <code>tournament.cfg</code>.</li><li><strong>Current User</strong>: You login over here with your osu! account so it can grab the information of the players and beatmaps in lazer.</li><li><strong>Ruleset</strong>: This decides what stats and which ranks are retrieved for players that will be shown in the client during matches.</li><li><strong>Stream area resolution</strong>: This is where you match the <code>Height</code> you set in the <code>tournament.cfg</code> file.</li></ul><p>You are now ready to connect all the pieces together in OBS.</p><h2 id="setting-up-obs">Setting up OBS</h2><p>If you have a completely new and clean installation of OBS you can skip this part!</p><h3 id="if-you-already-have-an-existing-obs-setup">If you already have an existing OBS setup</h3><!--kg-card-begin: markdown--><ol>
<li>
<p>Create a new scene collection in OBS using the following menu:</p>
<p><img src="https://mirai.blog/content/images/2020/06/obs64_2020-06-27_23-32-26.png" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></p>
</li>
<li>
<p>After you&apos;ve given it a name you will see a new empty collection of scenes. You will use these later to set up osu!lazer and stable together.</p>
</li>
<li>
<p>Create a new profile the same way you created a scene collection.</p>
</li>
</ol>
<!--kg-card-end: markdown--><p>You will now be greeted by a completely blank OBS canvas. You can now switch back and forth between your tournament profile and your other livestreaming profile and keep it separate for organizational purposes.</p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/06/obs64_2020-06-27_23-38-32.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></figure><h3 id="adding-the-necessary-items-for-your-stream">Adding the necessary items for your stream</h3><p>Open the OBS settings, go to the <strong>Video</strong> section and set the both the <strong>Base (Canvas) Resolution</strong> and the <strong>Output (Scaled) Resolution</strong> to the <strong>Stream Area Resolution</strong> that is being displayed in osu!lazer tournament. Remember that this should match the height you set in your <code>tournament.cfg</code>. </p><p>Apart from that set the video settings to the following: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/image-6.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>Make sure the Downscale Filter matches. The frame rate setting can be 59.94 or 60. It doesn&apos;t really matter nowadays.</figcaption></figure><p>Make sure you have osu!lazer tournament open so you can add it as a <strong>Window Capture</strong> source in the scene. Make sure the settings match like this: </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/image-3.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>Note that &quot;Window Title Must Match&quot; is set and Capture Cursor is turned off in the properties</figcaption></figure><p>After you click OK your OBS window will look like this: </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/06/image-7.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></figure><p>The osu!lazer tournament window is off-center. You can rectify this by going to the following context menus (by right clicking on the source in the canvas): </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/06/image-8.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></figure><p>When you have your window centered, head to the <strong>Gameplay</strong> scene in osu!lazer. You will see the screen, but the place where the gameplay is supposed to be is completely green.</p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/06/image-9.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></figure><p>Right click on the source you just added and go to <strong>Filters</strong></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/image-10.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>1. Right click on your window capture source. 2. Click on Filters.</figcaption></figure><p>After that a window will appear where you can add filters to your source. Click on the following buttons to add a <strong>Chroma Key</strong> filter to your window capture. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/image-11.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>1. Click on the + button. 2. Then click on Chroma Key</figcaption></figure><p>A new section will open on the right where you can configure the Chroma Key settings. As of right now the screenshot below is the ideal configuration that properly keys out all, if not most of the green pixels.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/obs64_2020-06-28_00-12-13.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>Make sure to match these settings: Similarity: 360, Smoothness: 30, Key Color Spill Reduction: 1</figcaption></figure><p>Click <strong>Close</strong> on all the windows until you get back to your canvas. Then click on the lock so you can&apos;t accidentally move or adjust the window any more.</p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/06/image-13.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></figure><p>Now you can add the windows for all the players that you spectate through osu! stable tournament, using the following settings. You have to repeat this for every player. &#xA0;</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/image-14.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>Make sure the settings are <strong>Window Title Must Match</strong> and <strong>Capture Cursor</strong> is turned <strong>Off</strong></figcaption></figure><p>Next up select all of them and drag them all below your osu!lazer window. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/06/2020-06-28_00-46-21.gif" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"><figcaption>You can easily do this by selecting these sources using <code>CTRL</code> or <code>SHIFT</code> and then dragging it below your lazer window.</figcaption></figure><p>It may look like the windows are getting cut off now, but you can use the <strong>Chroma Width</strong> &amp; <strong>Players Per Team</strong> to adjust it according to your needs. </p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/06/image-16.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></figure><p>Your OBS canvas will now look like this on a 2v2 setup:</p><figure class="kg-card kg-image-card"><img src="https://mirai.blog/content/images/2020/06/image-17.png" class="kg-image" alt="The definitive guide to streaming tournaments using osu!lazer" loading="lazy"></figure><p>Click on the lock icon on the sources for all the players when you&apos;re done.</p><p>All you need to do after this is enter your stream key in the settings and then you&apos;re ready to stream tournaments!</p><h2 id="known-problems">Known problems</h2><p>osu!lazer is still a work-in-progress so a lot of things are still incomplete or can break. Below I&apos;ve made a list of issues that I am aware of at the moment: </p><ol><li>Background videos in osu!lazer can cause memory consumption to never stop increasing while you stream. This is being tracked in <a href="https://github.com/ppy/osu-framework/issues/3519?ref=mirai.blog">this github issue</a>. Essentially, don&apos;t use videos in resolutions higher than 1080p and make sure you have more than enough RAM in case it does increase dramatically. Your whole operating system will come to a halt and OBS will crash if it fills your RAM up completely.</li><li>If you use a resolution height of 720 in osu!lazer tournament the component that shows the beatmap info may disappear the next time you start it up. I commented a workaround <a href="https://github.com/ppy/osu/issues/9200?ref=mirai.blog#issuecomment-650645722">on the issue</a> on how to get it working with 720p for now. </li></ol><!--kg-card-begin: markdown--><p>You can follow the osu!lazer project here on GitHub: <a href="https://github.com/ppy/osu?ref=mirai.blog">https://github.com/ppy/osu</a><br>
Follow me on Twitter: <a href="https://twitter.com/MiraiSubject?ref=mirai.blog">https://twitter.com/MiraiSubject</a></p>
<p>Feel free to shoot me a tweet if you have any questions!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[I made a music info tracker that I shouldn't have needed to make]]></title><description><![CDATA[<p>Lately, I&apos;ve been improving the production quality of my live streams, by utilizing transparent video through VP9 for my overlays in OBS and using stinger transitions. However, there was still an element missing that I used to have in my streams way back in 2014 and 2015. That</p>]]></description><link>https://mirai.blog/i-made-a-music-info-tracker-that-i-shouldnt-have-needed-to-make/</link><guid isPermaLink="false">6411daa32bd4ce0001583f8c</guid><dc:creator><![CDATA[Subject]]></dc:creator><pubDate>Sun, 12 Apr 2020 20:36:32 GMT</pubDate><content:encoded><![CDATA[<p>Lately, I&apos;ve been improving the production quality of my live streams, by utilizing transparent video through VP9 for my overlays in OBS and using stinger transitions. However, there was still an element missing that I used to have in my streams way back in 2014 and 2015. That is the information of the currently playing song. </p><p>There&apos;s many different ways to accomplish this. If you search &quot;now playing info obs&quot; you get a lot of information, programs and scripts that people use to accomplish this. Most of these are compatible with Spotify, Last.fm, Soundcloud, VLC and many others. I don&apos;t use any of these players for my music listening though. I use iTunes on my Windows PC.</p><h2 id="the-first-solutions">The first solutions</h2><p>There are two programs that I have found that are compatible with iTunes, that can export the song information and album art to files for OBS to read. These are <a href="https://github.com/dlrudie/Snip?ref=mirai.blog">Snip</a> and <a href="https://github.com/JimmyAppelt/Snaz?ref=mirai.blog">Snaz</a>. Snaz removed this functionality in the latest version, but older versions were still available. </p><p>I used to have Snaz running in the background to track the music information and display it in OBS, but yesterday it broke up to the point that I required a full reinstall of iTunes. I don&apos;t understand why it broke my install so horribly, because I also run Rainmeter and that uses the same COM API to fetch this information and it never caused this weird behaviour. </p><p>So first of all, Snaz isn&apos;t actually open-source, despite being hosted on GitHub. The creator just shares his binaries and updates the README file. So there was no way for me to cross reference the code with the library being used by <a href="https://github.com/rainmeter/rainmeter/tree/master/Library/NowPlaying?ref=mirai.blog">Rainmeter</a> and see how the implementations differ. But I honestly couldn&apos;t really be bothered.</p><p>I just wanted my stream to work. </p><p>I then randomly found Snip on one of my drives and decided to run that. </p><p>And no dice.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/03/Snip_2020-03-17_22-52-54.png" class="kg-image" alt loading="lazy"><figcaption>The error that Snip keeps throwing when having iTunes selected.</figcaption></figure><p>So then I thought, what if I just made a rainmeter &quot;widget&quot; that exports the info to a file?</p><h2 id="my-solution">My Solution</h2><p>When I first thought about this I thought I went crazy, but I did it anyway. I made a Now Playing tracker for OBS in Rainmeter. By using the data it gets from iTunes and passing it to PowerShell, so it writes to a file that OBS can read.</p><p>There&apos;s still a few edge cases that involves songs that have &quot; and &apos; in them because the value just gets passed raw to powershell. Powershell handles text input/echos very weirdly imo. I also tried passing it through WSL but that wasn&apos;t really a universally viable solution. </p><p>So I just stuck to PowerShell instead!</p><p>Anyway is the repo if you want to get it right away: <a href="https://github.com/MiraiSubject/NowplayingToTextRainMeter?ref=mirai.blog">https://github.com/MiraiSubject/NowplayingToTextRainMeter</a></p><p>If you have any comments about this article or want to talk about it feel free to reach out to me on these channels:<br>Twitter: <a href="https://twitter.com/miraisubject?ref=mirai.blog">https://twitter.com/miraisubject</a><br>Twitch: <a href="https://twitch.tv/miraisubject?ref=mirai.blog">https://twitch.tv/miraisubject</a><br>Discord: <a href="https://mirai.gg/discord?ref=mirai.blog">https://mirai.gg/discord</a></p><p>I also have a YouTube channel you should subscribe to if you&apos;re interested!<br>YouTube: <a href="https://youtube.com/mirai-s?ref=mirai.blog">https://youtube.com/mirai-s</a></p>]]></content:encoded></item><item><title><![CDATA[AirPods Pro After One Month.]]></title><description><![CDATA[After having used the original AirPods for two years, I shot for the AirPods Pro.  Learn about my experience with them, both negative and positive.]]></description><link>https://mirai.blog/airpods-pro-after-one-month/</link><guid isPermaLink="false">6411daa32bd4ce0001583f8a</guid><category><![CDATA[Technology]]></category><category><![CDATA[Apple]]></category><category><![CDATA[Review]]></category><dc:creator><![CDATA[Subject]]></dc:creator><pubDate>Mon, 09 Mar 2020 19:29:56 GMT</pubDate><media:content url="https://mirai.blog/content/images/2020/03/IMG_3415.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://mirai.blog/content/images/2020/03/IMG_3415.jpg" alt="AirPods Pro After One Month."><p>I&apos;ve been someone indulged in the Apple ecosystem for many years now. This doesn&apos;t mean I&apos;m limiting myself to devices of other ecosystems. I live in a mixed ecosystem. I have a Windows desktop, but also a Macbook Pro. I have an Apple TV, but also an NVIDIA Shield. I have an iPhone, but also Android phone. And then also an iPad Pro, but no Android equivalent.</p><p>As such, this review does not have a hard conclusion. There is no &quot;buy it&quot; &#xA0;or &quot;don&apos;t buy it&quot;, because of X, Y, Z. I will be giving my experience with the AirPods Pro and with this hopefully help you make an informed decision on buying a new pair of Bluetooth headphones.</p><h2 id="a-little-bit-of-history">A little bit of history</h2><p>Before using Apple&apos;s line of wireless earbuds, I used one of JBL&apos;s Reflect series and then the JBL Everest 100. The cable of the former started malfunctioning so the store gave me credit to pick a new one. My dad uses the Everest 100 every so often now and it still works!</p><p>I&apos;ve been using the original Airpods for about two years before swapping to the Airpods Pro in December. The originals were very convenient to use compared to any other pair of Bluetooth earbuds at the time and the absence of the wire made for a great experience while moving about with them. </p><p>The audio quality in the 1st gen Airpods wasn&apos;t exceptional. They were basically Earpods, the wired earbuds that Apple includes in the box, but with a little bit of extra oomph in the volume. It was good enough, because all the convenience factors made up for it. </p><h2 id="upgrade-from-first-gen">Upgrade from first gen</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/03/IMG_3415-1.jpg" class="kg-image" alt="AirPods Pro After One Month." loading="lazy"><figcaption>AirPods Pro playing music from an iPhone 11 Pro.</figcaption></figure><p>I&apos;ve been using the AirPods Pro since the end of December. I started writing this article at the beginning of February but, I only finished it another month later. So this is technically my 2 month experience!</p><p>When you first put in the Airpods they turn on the noise cancellation. The sound of the outside world fades away and it just gets quiet. It&apos;s ready for the media you&apos;re about to throw at it, is what you&apos;ll think when you get them in for the first time. </p><p>These Airpods feel more comfortable than the original ones. The silicone buds sit gently inside your ear without completely pressurizing the inside like other in-ears do. There&apos;s also no hard plastic rubbing against your ear, this made hard for me to keep the first gens in for long amounts of time, especially when you&apos;re moving about. </p><p>After the initial pairing process you can start playing around with the three different modes: Transparency, off and Noise Cancellation.</p><p>The last one makes the most sense. This is the ANC feature that everyone talks a lot about. Off is basically the same as having normal Airpods, except in-ear. I see honestly no reason why you&apos;d pick this option, because this one sounds the worst of the three. The sound is very muddy and feels like it&apos;s much worse than other two modes, but this does come with the benefit of increased battery life, because the microphone of the Airpods are not being used.</p><p>Transparency mode is what you could basically all the opposite of Noise Cancellation. Instead of using the microphones to cancel out the noise, the microphones are being used to capture the audio around of you and pass it through to your ears. This is especially useful when you&apos;re at a train station and want to hear announcements or the people around you without taking them out of your ear. This also *can* give the simulation of having a very open soundstage that you&apos;d get with open back headphones, but this is very much an exaggeration because it&apos;s noticable that the audio coming through is digital and not natural. Despite the audio sounding very digital, it&apos;s a very useful mode during commutes. </p><p>To switch between modes, &#xA0;just hold one of the stems and it switches between Noise Cancellation and Transparency. You can change the functionality of this in the Settings app on iOS. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/03/IMG_1011.PNG" class="kg-image" alt="AirPods Pro After One Month." loading="lazy"><figcaption>The settings panel with all the options you can adjust for the Airpods Pro. Omitted are the Disconnect button and the &quot;Forget this Device&quot; button. Accessible in Settings -&gt; Bluetooth -&gt; (i) button of your Airpods. (iOS 13.3)</figcaption></figure><p>Pressing the stem once toggles the play/pause functionality, pressing it twice skips a track forward and pressing it three times skips back a track. This is more intuitive than the touch areas on the original Airpods. I never got them to work consistently despite reading tutorials and attempting other people&apos;s solutions. </p><h2 id="issues">Issues</h2><p>Using the Airpods was certainly magical for the first week, but then reality hits. These are still pieces of technology that depend on software. And software can have bugs and other issues: </p><ul><li>The Airpods Pro were supposed to be paired to all my iCloud connected devices, but they didn&apos;t show up on my Macbook Pro or iPad Pro as available devices. So I had to unpair it on my phone and re-pair it so iCloud could try again. This only happened once.</li><li>My left Airpod sometimes feels like it isolates the noise out worse than my right one. Even after double checking it with the fit test that comes in the settings app. This is still an ongoing issue.</li><li>Sometimes only one of the two Airpods actually connects. I then have to put them both back in the case, make sure they&apos;re actually disconnected from my phone. Then pull them out and put the opposite one in my ear, the one that didn&apos;t connect. I always put my Airpods in left first, so it&apos;s always trouble with my right one.</li><li>Sometimes only one of the Airpods actually charges! I&apos;ve come to discover this the hard way. After one of my listening sessions I put them both in the case and my right Airpod was silently draining its battery while in the case, probably trying to maintain a connection to my Mac or iPhone, but neither actually showed them as currently selected audio devices. I only noticed later in the battery widget that the Right Airpod was just slowly draining battery. This is only fixable by actively checking the light on the Airpods charging case. It fading out and in once when an Airpod gets seated in actually confirms that it&apos;s charging. I&apos;ve made the habit now to double check the lights and the battery widget on my phone to see if they are actually charging. </li><li>Very rarely, one Airpod goes into transparency and the other in ANC. Switching back and forth between the modes put them back in sync. This also happens when somehow one connects to the Mac/iPad and the other the iPhone. So much for seamless switching.</li></ul><p>Sometimes bloggers say that a list like this would go on and on, but these are all the issues I have. Despite these issues these Airpods consistently provide by far the best user experience for bluetooth earbuds. And that is what it&apos;s all about in the end for something that you use on a daily basis. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/03/IMG_1010-1.jpg" class="kg-image" alt="AirPods Pro After One Month." loading="lazy"><figcaption>Airpods connected and charging properly!</figcaption></figure><h2 id="quality">Quality</h2><p>This is going to be a super short paragraph about the audio quality. There&apos;s a lot of YouTube videos and blog posts out there that describe the quality objectively, scientifically and also by their own taste. I will just do the latter.</p><p>I&apos;ve always liked the AKG M220 Pro. These are semi open backed headphones and they sound is very natural, wide and warm. I even think it sounds punchy enough with songs that have bass and beats going on. I only use these in my room and I&apos;ve never used them for travel because the audio leaks everywhere like mini speakers. </p><p>I also liked the first gen Airpods. I already described them as a normal Earpods, but with a little bit of extra oomph in the volume. These are nothing special and I&apos;d always prefer my AKGs over the first gens whenever I had the chance. </p><p>The Airpods Pro however somewhat changed that. In the ANC and Transparency modes, the highs are pretty clear, they&apos;re not the clearest. But clear enough for me. The bass is punch but it doesn&apos;t sound overwhelming at all. Like, it&apos;s not fatiguing. The mids are still a bit muddy but they&apos;ve improved a lot over the normal Airpods. I could keep these in for multiple hours without a problem. </p><p>Not to mention the ANC functionality can make you lower the volume of them preserving your hearing. With the first gens I usually had my volume slider on Apple Music at around 70%. With the pros I can keep them at around 50-60%. In the image below you can see the basic improvement of the audio levels when wearing these. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/03/IMG_1007.jpg" class="kg-image" alt="AirPods Pro After One Month." loading="lazy"><figcaption>The improvement of my average audio level. 2019 has been 95% first gen Airpods and 2020 was 99% Airpods Pro.&#xA0;</figcaption></figure><p>This is by no means a health recommendation, nor am I allowed to do such a thing. But seeing this improvement in the health app was pretty nice. Mind you that these values are only accurate with Apple or Beats headphones. The disclaimer on the page reminds you of that as well.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://mirai.blog/content/images/2020/03/IMG_1009.jpg" class="kg-image" alt="AirPods Pro After One Month." loading="lazy"><figcaption>&quot;These measurements are most accurate when using Apple or Beats headphones.&quot; - From Health.app on iOS 13.3</figcaption></figure><h2 id="conclusion">Conclusion</h2><p>After having used the original AirPods for two years and having experienced its convenience. I shot for the AirPods Pro. This was a great decision because I benefited not just from the increased comfort and audio quality, but also from the Noise Cancellation feature. I do not have any other audio devices that use ANC, so I can&apos;t test which is better than which. What I can tell you, however, is that these work really well.</p><p>At around $250 or &#x20AC;279, this is an expensive pair of wireless earbuds. In the Netherlands Sony&apos;s in-ear ANC wireless earbuds are commonly found cheaper for around &#x20AC;100 euro less than the AirPods Pro. These are the ones that are being the most against each other.</p><p>The whole ecosystem situation and the convenience factor is what made my decide to get these. Like the ability to seamlessly switch between Apple devices, while also retaining the ability for them to function as normal headphones (I also use them with my PS Vita). </p><p>This is something you as a reader has to think about.</p><p>On the go I only really carry my Apple devices and this is why it makes sense for me to get these. &#xA0;If you live in a similar situation and your on the go carry are Apple devices, then you should consider getting these. Try them out in a nearby Apple Store with the type of songs you listen to the most and judge for yourself if it&apos;s worth spending on. </p><p>If you carry no Apple devices, or these are the in minority. I encourage you to take a lot at other offerings as well. Try them out if possible and base your choice on what you prefer. </p><p>This isn&apos;t really a definitive conclusion, but I don&apos;t want you to blindly go out and buy something just because I say so. </p><p>If you have any comments about this article or want to talk about it feel free to reach out to me on these channels:<br>Twitter: <a href="https://twitter.com/miraisubject?ref=mirai.blog">https://twitter.com/miraisubject</a><br>Twitch: <a href="https://twitch.tv/miraisubject?ref=mirai.blog">https://twitch.tv/miraisubject</a><br>Discord: <a href="https://mirai.gg/discord?ref=mirai.blog">https://mirai.gg/discord</a></p><p>I also have a YouTube channel you should subscribe to if you&apos;re interested!<br>YouTube: <a href="https://youtube.com/mirai-s?ref=mirai.blog">https://youtube.com/mirai-s</a><br></p>]]></content:encoded></item><item><title><![CDATA[Welcome to my blog.]]></title><description><![CDATA[This is going to be my 5th attempt at maintaining a blog. Maybe this will stick? If this is your first time seeing any content from me, then welcome!]]></description><link>https://mirai.blog/welcome-to-my-blog/</link><guid isPermaLink="false">6411daa32bd4ce0001583f89</guid><category><![CDATA[General]]></category><dc:creator><![CDATA[Subject]]></dc:creator><pubDate>Wed, 26 Feb 2020 13:17:57 GMT</pubDate><media:content url="https://mirai.blog/content/images/2020/02/publication-cover-mirai-5.png" medium="image"/><content:encoded><![CDATA[<img src="https://mirai.blog/content/images/2020/02/publication-cover-mirai-5.png" alt="Welcome to my blog."><p>This is going to be my fifth attempt at maintaining a blog. Maybe this will finally stick?</p><p>If this is your first time seeing any content from me, then welcome! I am Mirai. I&apos;m (at the moment) &#xA0;a pretty sporadic content creator and I maintain a small community. </p><p>As of writing this blog post I&apos;m 21 years old and I&apos;m currently a university dropout. In the time I have now I work on getting consistency in creating content for YouTube, Twitch and other platforms. This blog being one of those platforms. </p><h2 id="backstory">Backstory</h2><p>I started live streaming as a casual hobby around 2013/2014. I used to stream a bit of League of Legends, but I wasn&apos;t serious about it at all. It was just a hobby for me. I also had a YouTube channel that I uploaded gameplay videos to from either streams or recordings I made of when I played games by myself. I really had no community back then and my communication whenever I published was well... worse than it is now! </p><p>The time after that is a bit of a blur. But thanks to past me for keeping a somewhat decent archive I do know that I basically didn&apos;t stream much (or at all) in 2015, but I did stream again in 2016! </p><p>Somewhere in 2017 I replaced my old brand, Subject4S, with &quot;Mirai.&quot;. This wasn&apos;t originally supposed to be a rebrand for me as a content creator, but for me as a developer. I was developing a futuristic platform-like game in Unreal Engine 4 and a friend of mine suggested this for the name. I stopped developing the game shortly after, because of time constraints and lack of proper assets. I did create another cinematic in UE4 that caused my gameplay channel to get banned and I created a video game for biology in it as an assignment. </p><p>During all of this I created a Discord account, back in 2015. I met a lot of people on it and I made my own server in 2016 and opened it up to the public in 2017. </p><h2 id="osu-tournament-life">osu! Tournament Life</h2><p>The same year I opened the server to the public I was asked to stream for an osu! tournament and I got in contact with this fantastic community of people hosting community tournaments. And I thought: </p><p>I want to do this too.</p><p>So I got in contact with a friend that knows people in the community and we made a tournament, called <a href="https://osu.ppy.sh/community/forums/topics/613076?ref=mirai.blog">Mirai. osu! Summer Tournament 2017.</a> That tournament was a great success and I learned a lot from everyone when it came to tournament management, bracketing etc. I hosted two more tournaments after that: <a href="https://osu.ppy.sh/community/forums/topics/650430?ref=mirai.blog">Mirai. osu! Winter Festival 2017</a> and the <a href="https://osu.ppy.sh/community/forums/topics/889089?ref=mirai.blog">Mirai. Idol Tournament 2019</a>. The former was pretty much a disaster on multiple fronts, but I learned from it. The latter was a small tournament that I used to test out a concept of verifying players using their Discord accounts. This was pretty successful and I am building upon that implementation for usage in future tournaments.</p><h2 id="the-present-the-future">The Present &amp; The Future</h2><p>As of now I have a few channels that I operate from mainly: Twitter, Discord, YouTube, Twitch and this blog. I&apos;ve been learning from various content creators on how to improve my video creation skills and increase the production quality of my live streams using my existing tools. </p><p>I have a few goals set to reach by the end of 2020 in regards to my growth on social media and this blog!</p><p>So yeah, this is pretty much who I am, what I&apos;ve done in the past and I&apos;m doing right now. </p><p>I hope you&apos;ll enjoy future posts!</p><p>These are my social media channels:<br>Twitter: <a href="https://twitter.com/miraisubject?ref=mirai.blog">https://twitter.com/miraisubject</a><br>Twitch: <a href="https://twitch.tv/miraisubject?ref=mirai.blog">https://twitch.tv/miraisubject</a><br>YouTube: <a href="https://youtube.com/mirai-s?ref=mirai.blog">https://youtube.com/mirai-s</a><br>Discord: <a href="https://mirai.gg/discord?ref=mirai.blog">https://mirai.gg/discord</a></p><p>P.S. I still don&apos;t know what to put in the SEO metadata so that will still be a mess...</p>]]></content:encoded></item></channel></rss>