More aside
classes and whatnot
This commit is contained in:
parent
d91b50e0df
commit
72aa525d77
content
public
src
|
@ -1,14 +1,11 @@
|
|||
# Hiii
|
||||
|
||||
Welcome to my ethereal realm (read: website). This place is still being conjured (read: under construction), so some things might be startlingly empty. Enjoy your stay on the moon!
|
||||
Welcome to my ethereal realm (read: website). This place is still being conjured (read: under construction), hence some things might be startlingly empty.
|
||||
|
||||
I'm known as `prescientmoon`, or sometimes `PGW`. I study mathematics, but I also really like coding and all computer-related sorcery. I love games of all kinds, although rhythm games have a special place in my heart.
|
||||
|
||||
{ title="Contact me" character="canyou" }
|
||||
::: aside
|
||||
You can message me in the following places \^-\^
|
||||
|
||||
- via email at `hi@thisdomain`
|
||||
- via email at <hi@moonythm.dev>
|
||||
- on discord as `@prescientmoon`
|
||||
- on the ~ IRC network as `prescientmoon`
|
||||
:::
|
||||
|
|
|
@ -2,8 +2,14 @@
|
|||
created-at = "2024-10-31T15:28:OO"
|
||||
```
|
||||
|
||||
[home](/)
|
||||
|
||||
----
|
||||
|
||||
# Why I love arcaea
|
||||
|
||||
_Tuesday, October 10, 2024_
|
||||
|
||||
## What is arcaea
|
||||
- explain the base mechanics
|
||||
|
||||
|
@ -17,21 +23,23 @@ created-at = "2024-10-31T15:28:OO"
|
|||
{% [[[ %}
|
||||
The game judges the way the player hits (or fails to do so) every note by quantizing the inputs into [a few judgements](https://arcaea.fandom.com/wiki/Scoring): a PURE judgement is awarded within a 50ms timing window, the more lenient FAR judgement has twice as much (100ms), with all the other notes being marked as LOST. Moreover, an optional tighter (25ms) timing window awards the MAX PURE (usually referred to as "shiny pure" by the community) judgement.
|
||||
|
||||
::: in-depth
|
||||
{ title="Lagrange's extras: Ghost tapping" character="lagrange" }
|
||||
::: long-aside
|
||||
The game only awards judgements for notes in the chart. That is, tapping while no notes are nearby will not influence the score in any way! This turns out to be quite useful, leading to what is referred to as "ghost tapping", which can be a useful way to keep the rhythm or have fun with the chart. An example of this in action can be seen in [this clip](https://youtube.com/clip/UgkxY9g3nlFz8ZnPDTcn4yIofGdrFIxP3mYz?si=yI6Vs-_qpztONwtu) of [@gba553](https://www.youtube.com/@Gba553) timing the final pair of tricky notes in [ℵ~0~](https://arcaea.fandom.com/wiki/Aleph-0).
|
||||
:::
|
||||
|
||||
The score is then calculated using a 2:1 PURE to FAR ratio (that is, every PURE is awarded 2 points and every FAR is awarded 1), the result of which is scaled up so $`10,000,000` is the maximum possible score. Finally, the game awards one additional point for each MAX PURE, which is why perfect scores are usually a bit over $`10,000,000`.
|
||||
|
||||
::: in-depth
|
||||
This exact form of scoring is present in many other rhythm games. For instance, [sound voltex](https://en.wikipedia.org/wiki/Sound_Voltex) also uses the exact same judgement ratio!
|
||||
::: aside
|
||||
This exact form of scoring is present in many other rhythm games. For instance, [sound voltex](https://en.wikipedia.org/wiki/Sound_Voltex) uses the exact same judgement ratio!
|
||||
:::
|
||||
|
||||
A play with no LOST judgements is called a "full recall" (also known as a "full combo" in other games). Furthermore, a play with no FAR judgements is called a "pure memory" (also known as an "all perfect" in other games, and commonly abbreviated as a "PM"). Finally, a play where every note was hit perfectly (that is, one where everything is a MAX PURE) is called a "max pure memory" (commonly abbreviated as "MPM" by the community).
|
||||
|
||||
While full recalls and max-PMs are certainly celebrated by players and the larger community alike, PMs are usually the sweet spot between accurate play and fun which many Arcaea players strive for. This is usually the case because the game hardly rewards (if acknowledge at all) plays that are better than a PM (this will become obvious when we discuss the game's rating system).
|
||||
|
||||
::: in-depth
|
||||
{title="Lagrange's extras: The scoring formula" character="lagrange"}
|
||||
::: char-aside
|
||||
Let's write the score formula in a nice, closed form!
|
||||
|
||||
Let $`m`, $`p`, $`f` and $`l` denote the amount of MAX PURE, PURE, FAR and LOST notes respectively. The final score can then be computed as
|
||||
|
@ -40,7 +48,7 @@ $$`m + \left\lfloor (2(m + p) + f) \frac{10'000'000}{2(m + p + f + l)} \right\rf
|
|||
:::
|
||||
|
||||
{title="Lagrange's extras: ζ-scoring" character="lagrange"}
|
||||
::: aside
|
||||
::: long-aside
|
||||
UWAAA, but what if we wanted MAX PURE notes to have a more major contribution to the score? For one, we could start by giving them their own place in the scoring ratio. What would a good ratio look like? A naive approach idea would be to keep the same rate of growth and go with a ratio of 4\:2\:1 for MAX PURE to PURE to FAR. Sadly, issues arise because this can lead to PMs possibly producing terrible scores — it's too big of a departure from the original formula. It turns out the aforementioned [sound voltex](https://en.wikipedia.org/wiki/Sound_Voltex) has already figured out a solution with their optional "EX-scoring" system, which uses a ratio of 5\:4\:2, thus awarding 1.25x the normal points for a MAX PURE.
|
||||
|
||||
Calling this "EX-scoring" in the context of Arcaea would be confusing (EX being an in-game grade and all), hence I decided to call the Arcaea equivalent of the system "ζ-scoring". In particular, we can compute the ζ-score by only knowing the base score and the number of notes in the chart (call it $`n`) as follows:
|
||||
|
@ -182,6 +190,7 @@ Overall, I think Arcaea's (and by extension, many other similar games') scoring
|
|||
- certain kinds of matte screen protectors fix the issue!
|
||||
|
||||
|
||||
::: in-depth
|
||||
- Not sure what the proper posture is, but I've found myself doing much better when putting some pillows on my chair so I sit slightly higher
|
||||
{ title="Arcaea and posture" character="lagrange" }
|
||||
::: aside
|
||||
Not sure what the proper posture is, but I've found myself doing much better when putting some pillows on my chair so I sit slightly higher
|
||||
:::
|
||||
|
|
14
content/posts/yugioh-my-beloved.dj
Normal file
14
content/posts/yugioh-my-beloved.dj
Normal file
|
@ -0,0 +1,14 @@
|
|||
[home](/)
|
||||
|
||||
# Why I love Yu-Gi-Oh!
|
||||
|
||||
Lorem ipsum odor amet, consectetuer adipiscing elit. Per lacus at sociosqu curae varius nunc; magnis elit. Dictum dis tristique semper velit montes eleifend suscipit taciti. Himenaeos nunc morbi litora mi at molestie porttitor non sit. Convallis cursus ante tincidunt suspendisse class lobortis. Sodales fusce congue aliquet; eros lectus enim ullamcorper. Aptent fames laoreet odio pretium fermentum pharetra nisl fames sem.
|
||||
|
||||
Phasellus hendrerit eleifend nibh cubilia accumsan bibendum donec. Etiam torquent consequat hendrerit rhoncus fringilla elit sociosqu habitasse. Sagittis interdum magna bibendum consectetur ante. Vivamus non ligula fusce parturient mattis vulputate potenti. Eleifend aenean imperdiet augue, velit cras ornare nam. Sociosqu malesuada potenti mattis primis sapien condimentum tempus. Magnis pellentesque gravida conubia mattis adipiscing dis pretium facilisi orci. Et interdum sodales curae porta facilisis; vehicula curae euismod. Cubilia diam sociosqu neque aliquam, elementum ullamcorper per iaculis. Ut conubia duis maximus hac urna amet euismod.
|
||||
|
||||
Quisque rhoncus vitae scelerisque nostra sit eros est congue conubia. Ligula fusce vehicula rhoncus hac vel lacinia nisi porttitor. Gravida nisl neque rutrum efficitur sed leo ligula adipiscing. Eget et habitasse semper cursus, dictumst ex dis. Erat habitasse natoque adipiscing nulla lectus metus neque. Dolor vehicula consectetur aliquam quam sem cubilia purus elit. Himenaeos mauris vulputate facilisis at maecenas lacinia arcu nisl. Eu euismod ac metus suscipit ante. Interdum vitae per pellentesque rutrum finibus nisi feugiat. Duis dapibus amet condimentum; platea vestibulum laoreet.
|
||||
|
||||
Eu facilisi in risus nulla posuere ultrices curabitur. Pharetra curae euismod dapibus venenatis lectus netus metus. Conubia conubia arcu dui, tempus quis mattis. Inceptos magna pretium consequat eleifend condimentum nibh. Neque lacinia suscipit dapibus nunc consequat. Rutrum leo senectus purus primis donec ornare faucibus sem. Maximus vitae inceptos ligula; luctus fusce eu.
|
||||
|
||||
Ex metus dis est nisl; elementum fames cursus ligula platea. Quis porta enim conubia fermentum suspendisse a. Conubia eros fermentum vestibulum ultrices cubilia vestibulum. Himenaeos himenaeos conubia nunc curae netus nibh ante? Dui ex scelerisque praesent ultrices libero nunc lectus mattis. Arcu suspendisse dictum orci vivamus pretium taciti iaculis. Cras tincidunt ullamcorper litora lobortis hac cras maecenas ornare.
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
html {
|
||||
font: 100%/1.5 sans-serif;
|
||||
}
|
||||
|
||||
#page-content {
|
||||
font: 100%/1.6 sans-serif;
|
||||
max-width: 70ch;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
@ -12,6 +9,7 @@ html {
|
|||
blockquote {
|
||||
padding-left: 1.25rem;
|
||||
border-left: 3px solid;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
ul,
|
||||
|
@ -24,31 +22,24 @@ ol {
|
|||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
/* {{{ Header*/
|
||||
.aside-header {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
img.aside-icon {
|
||||
/* display: inline-block; */
|
||||
height: 1.75rem;
|
||||
margin-right: 0.5rem;
|
||||
/* transform: translateY(-100px); */
|
||||
}
|
||||
|
||||
.aside {
|
||||
background: #ead3ed;
|
||||
border-radius: 3px;
|
||||
padding: 0.5rem 0.5rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.aside-summary {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
.aside-header > .aside-title {
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.aside-header > * {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
/* }}}*/
|
||||
/* {{{ Override marker*/
|
||||
.aside-summary::marker {
|
||||
display: none;
|
||||
}
|
||||
|
@ -60,20 +51,35 @@ img.aside-icon {
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.aside-summary > .aside-title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.aside-summary > * {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.aside[open] .aside_summary:before {
|
||||
.aside[open] .aside-summary:before {
|
||||
content: "▼";
|
||||
}
|
||||
|
||||
.aside > .aside-content {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
/* }}}*/
|
||||
|
||||
img.aside-icon {
|
||||
height: 1.75rem;
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
|
||||
.aside {
|
||||
background: #f4daf7;
|
||||
border-radius: 3px;
|
||||
|
||||
box-sizing: border-box;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.aside-short {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.aside-long {
|
||||
/* padding: 0.65rem; */
|
||||
|
||||
.aside-content {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* }}}*/
|
||||
|
|
47
src/html.rs
47
src/html.rs
|
@ -177,24 +177,38 @@ impl<'s> Writer<'s> {
|
|||
Container::Table => out.write_str("<table")?,
|
||||
Container::TableRow { .. } => out.write_str("<tr")?,
|
||||
Container::Section { .. } => out.write_str("<section")?,
|
||||
Container::Div { class: "aside" } => {
|
||||
let title = attrs.get_value("title").ok_or_else(|| {
|
||||
anyhow!("Cannot find `title` attribute on `aside` element")
|
||||
})?;
|
||||
let character = attrs.get_value("character").ok_or_else(|| {
|
||||
anyhow!("Cannot find `character` attribute on `aside` element")
|
||||
})?;
|
||||
Container::Div {
|
||||
class: class @ ("aside" | "long-aside" | "char-aside"),
|
||||
} => {
|
||||
if *class == "aside" {
|
||||
self.list_tightness.push(true);
|
||||
}
|
||||
|
||||
let mut renderer =
|
||||
TemplateRenderer::new(template!("templates/aside.html")?);
|
||||
let template = if *class == "aside" {
|
||||
template!("templates/aside.html")?
|
||||
} else if *class == "char-aside" {
|
||||
template!("templates/character-aside.html")?
|
||||
} else {
|
||||
template!("templates/long-aside.html")?
|
||||
};
|
||||
|
||||
let mut renderer = TemplateRenderer::new(template);
|
||||
|
||||
while let Some(label) = renderer.current(&mut out)? {
|
||||
if label == "character" {
|
||||
let character = attrs.get_value("character").ok_or_else(|| {
|
||||
anyhow!("Cannot find `character` attribute on `aside` element")
|
||||
})?;
|
||||
|
||||
character
|
||||
.parts()
|
||||
.try_for_each(|part| write_attr(part, &mut out))?;
|
||||
renderer.next(&mut out)?;
|
||||
} else if label == "title" {
|
||||
let title = attrs.get_value("title").ok_or_else(|| {
|
||||
anyhow!("Cannot find `title` attribute on `aside` element")
|
||||
})?;
|
||||
|
||||
title
|
||||
.parts()
|
||||
.try_for_each(|part| write_attr(part, &mut out))?;
|
||||
|
@ -227,7 +241,12 @@ impl<'s> Writer<'s> {
|
|||
}
|
||||
|
||||
let mut write_attribs = true;
|
||||
if matches!(c, Container::Div { class: "aside" }) {
|
||||
if matches!(
|
||||
c,
|
||||
Container::Div {
|
||||
class: "aside" | "long-aside" | "char-aside"
|
||||
}
|
||||
) {
|
||||
write_attribs = false;
|
||||
}
|
||||
|
||||
|
@ -388,7 +407,13 @@ impl<'s> Writer<'s> {
|
|||
Container::Table => out.write_str("</table>")?,
|
||||
Container::TableRow { .. } => out.write_str("</tr>")?,
|
||||
Container::Section { .. } => out.write_str("</section>")?,
|
||||
Container::Div { class: "aside" } => {
|
||||
Container::Div {
|
||||
class: class @ ("aside" | "long-aside" | "char-aside"),
|
||||
} => {
|
||||
if *class == "aside" {
|
||||
self.list_tightness.pop();
|
||||
}
|
||||
|
||||
let state = self.states.pop().unwrap();
|
||||
let State::Aside(mut renderer) = state else {
|
||||
panic!("Finished `aside` element without being in the `Aside` state.")
|
||||
|
|
|
@ -1,11 +1 @@
|
|||
<details class="aside">
|
||||
<summary class="aside-summary">
|
||||
<img
|
||||
class="aside-icon"
|
||||
alt="{{character}}"
|
||||
src="/assets/icons/characters/{{character}}.webp"
|
||||
/>
|
||||
<span class="aside-title">{{title}}</span>
|
||||
</summary>
|
||||
<div class="aside-content">{{content}}</div>
|
||||
</details>
|
||||
<div class="aside aside-short aside-content">{{content}}</div>
|
||||
|
|
11
src/templates/character-aside.html
Normal file
11
src/templates/character-aside.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<div class="aside aside-short">
|
||||
<div class="aside-header">
|
||||
<img
|
||||
class="aside-icon"
|
||||
alt="{{character}}"
|
||||
src="/assets/icons/characters/{{character}}.webp"
|
||||
/>
|
||||
<span class="aside-title">{{title}}</span>
|
||||
</div>
|
||||
<div class="aside-content">{{content}}</div>
|
||||
</div>
|
11
src/templates/long-aside.html
Normal file
11
src/templates/long-aside.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<details class="aside aside-long">
|
||||
<summary class="aside-summary aside-header">
|
||||
<img
|
||||
class="aside-icon"
|
||||
alt="{{character}}"
|
||||
src="/assets/icons/characters/{{character}}.webp"
|
||||
/>
|
||||
<span class="aside-title">{{title}}</span>
|
||||
</summary>
|
||||
<div class="aside-content">{{content}}</div>
|
||||
</details>
|
Loading…
Reference in a new issue