mirror of
https://github.com/sigmasternchen/mobmash.click
synced 2025-03-15 08:09:02 +00:00
feat: Add about page
This commit is contained in:
parent
469928e791
commit
d389bc3330
4 changed files with 180 additions and 5 deletions
8
html/about/index.php
Normal file
8
html/about/index.php
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
$title = "MobMash - About";
|
||||
$content = function () {
|
||||
require __DIR__ . '/../../view/pages/about.php';
|
||||
};
|
||||
|
||||
require_once __DIR__ . '/../../view/layout.php';
|
|
@ -15,6 +15,8 @@ nav {
|
|||
border-bottom: 1px solid black;
|
||||
margin: 0;
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
|
@ -69,12 +71,71 @@ nav a:hover, nav .active a {
|
|||
color: black;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
width: 70vw;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 40px;
|
||||
margin: 60px;
|
||||
}
|
||||
|
||||
.text-container p, .text-container a, .text-container li {
|
||||
font-family: "Arial", sans-serif;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.text-container a, .text-container a:visited {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
position: relative;
|
||||
transition: color 0.3s;
|
||||
padding-left: 6px;
|
||||
padding-top: 2px;
|
||||
padding-right: 6px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.text-container a::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background-color: black;
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
.text-container a::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
background-color: lightgrey;
|
||||
transition: width 0.3s;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.text-container a:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.text-container a:hover::before {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.choice {
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
@ -33,10 +33,12 @@
|
|||
<?php makeNavigationLink("Privacy", "/privacy"); ?>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php
|
||||
if (isset($content)) {
|
||||
$content();
|
||||
}
|
||||
?>
|
||||
<div id="content">
|
||||
<?php
|
||||
if (isset($content)) {
|
||||
$content();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
104
view/pages/about.php
Normal file
104
view/pages/about.php
Normal file
|
@ -0,0 +1,104 @@
|
|||
<h1>About</h1>
|
||||
|
||||
<div class="text-container">
|
||||
|
||||
<h2>The Story</h2>
|
||||
|
||||
<p>
|
||||
Back when I was in school I watched <a href="https://en.wikipedia.org/wiki/The_Social_Network">
|
||||
The Social Network movie</a>. I was fascinates by the scene in which Zuckerberg implemented Facemash in an
|
||||
eventing. So, I was kinda curious if I could manage that too. I didn't. I took me 3 days to implement a very
|
||||
<a href="https://github.com/overflowerror/promash">simple version</a>. (Writing this now, I also found out
|
||||
that it took Zuckerberg
|
||||
<a href="https://www.thecrimson.com/article/2003/11/19/facemash-creator-survives-ad-board-the/">a week</a>
|
||||
- not just an evening. Welp.) Instead of students, my version used pictures of my professors, that I scraped
|
||||
from my school's website - which, in retrospect, was morally a bit problematic.
|
||||
</p>
|
||||
<p>
|
||||
Recently, I found the old source code again, and I was thinking: Maybe I can rewrite it. Let's not use humans
|
||||
this time, and instead use something nerdy: Minecraft mobs. And while we are at it, let's also do it properly
|
||||
- the previous version really was quite bad from a technical perspective.
|
||||
</p>
|
||||
|
||||
<h2>Implementation</h2>
|
||||
|
||||
<p>
|
||||
The basic idea is to give the users the choice between mobs. The better one is selected and its internal
|
||||
rating increases. The algorithm used is the <a href="https://en.wikipedia.org/wiki/Elo_rating_system">Elo
|
||||
rating system</a>. I won't go into details here, but the basic idea is the following: It works by assigning
|
||||
each candidate a number, and calculate the winning probabilities for each match. This winning probability
|
||||
then determines how many points are gained/lost by each candidate.
|
||||
</p>
|
||||
<p>
|
||||
We can also use this rating to calculate the idea pairing. Mobs that have a similar rating might be more
|
||||
engaging to compare than mobs where it's obvious which one is better.
|
||||
</p>
|
||||
<p>
|
||||
The challenge here is twofold: First, we need to be able to asynchronously calculate and write the ratings to
|
||||
the database. This could theoretically be solved by utilizing transactions. The other problem is, that I want
|
||||
to be able to delete entries from the database in case I detect spam or "cheating". So, we need a list of all
|
||||
changes, so we can undo them if necessary - which would also mean we need to recompute all ratings.
|
||||
</p>
|
||||
<p>
|
||||
The way I chose to solve those problems, is by doing the calculations in on-the-fly in the database. The
|
||||
only thing we need to store, is the match-ups including the winner and the date for sorting. The rating
|
||||
calculation is then done by starting from a base rating for each mob (1500 in this case) and applying each
|
||||
match to the ratings in sequence using a recursive query. (Initially, I tried to keep each rating as its
|
||||
own row. However, I was not able to make it work. Not sure if that's a limitation of PostgreSQL or if I'm
|
||||
just not smart enough. ^^ Either way, the current solution uses <code>jsonb</code> objects for the rating
|
||||
state - which also turned out to be much faster than having each rating as its own object.)
|
||||
</p>
|
||||
<p>
|
||||
This approach works quite well and can handle a few thousands of votes with no issues. However, since we
|
||||
need to iterate over all matches every time we want to calculate the next pairing, it doesn't scale well
|
||||
beyond that. My solution for this was to introduce a caching table, that contains a recent snapshot of
|
||||
the ratings. The recursive calculation than seeds itself with the cache instead of starting from the
|
||||
beginning. This cache can be generated regularly (maybe once a day) to keep the responses snappy.
|
||||
</p>
|
||||
<p>
|
||||
The flip side of using this cache is, of course, that in case I need to delete some matches, I also need
|
||||
to delete the corresponding cache entries. It's not a huge deal, but certainly something to be aware of.
|
||||
</p>
|
||||
<p>
|
||||
If you want to learn more, check out the source code over on
|
||||
<a href="https://github.com/overflowerror/mobmash.click">Github</a>. Pull Requests are welcome!
|
||||
</p>
|
||||
|
||||
<h2>Credits & Tech Stack</h2>
|
||||
|
||||
<h3>Minecraft Related Content</h3>
|
||||
|
||||
<p>
|
||||
Minecraft content and materials are trademarks and copyrights of <a href="https://www.minecraft.net/">Mojang Studios</a>.
|
||||
</p>
|
||||
|
||||
<h3>Fonts</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://www.fontspace.com/minecraft-font-f28180">Minecraft Font by JDGraphics</a> (Public Domain)</li>
|
||||
<li><a href="http://fontawesome.io">Font Awesome v4.7.0</a> (OFL-1.1 & MIT)</li>
|
||||
</ul>
|
||||
|
||||
<h3>Frontend Frameworks</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://htmx.org/">HTMX</a> (0-Clause BSD)</li>
|
||||
<li><a href="https://www.chartjs.org/">Chart.js</a> (MIT)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Backend Technologies</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://www.php.net/">PHP</a></li>
|
||||
<li><a href="https://www.postgresql.org/">PostgreSQL</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Special Thanks</h2>
|
||||
|
||||
<p>
|
||||
I'd like to thank the <a href="https://minecraft.wiki/">Minecraft Wiki</a> for letting me let use their API to
|
||||
automatically update the mobs in the vote. The pictures for the mobs are also provided by them.
|
||||
</p>
|
||||
|
||||
</div>
|
Loading…
Reference in a new issue