Skip to content

Commit

Permalink
Add epilepsy warnings + better alt text formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
purplesyringa committed Oct 9, 2024
1 parent f8d5100 commit d6b85a8
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 23 deletions.
11 changes: 10 additions & 1 deletion blog.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ pre code {

.diagram {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
margin-left: -7rem;
margin-top: 1rem;
margin-bottom: 1rem;
Expand All @@ -106,6 +107,14 @@ pre code {
max-width: 100%;
height: auto;
}
.epilepsy::before {
content: "This video contains flashes that might trigger seizures in people with photosensitive epilepsy. Stop watching if you experience any symptoms. For convenience, the title text for the video explains the action in prose.";
display: block;
background-color: #db4f37;
color: #ffffff;
padding: 1rem;
margin-bottom: 1rem;
}

blockquote {
border-left: 0.375rem solid #ed79a9;
Expand Down
12 changes: 9 additions & 3 deletions blog/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,23 @@ html = html.replace(
.replace(/<h3>(.*?)<\/h3>\s*<div class='aside-group'><aside>([\s\S]*?)<\/aside>/g, "<div class='aside-group'><aside>$2</aside><h3>$1</h3>")
.replace(/<h3>(.*?)<\/h3>\s*<p>/g, "<p class='next-group'><span class='side-header' role='heading' aria-level='3'><span>$1</span></span>")
.replace(/<img src="(.*?)" alt="(.*?)">/g, (tag, src, alt) => {
let className = "diagram";
if (src.indexOf("/") === -1 && src.endsWith(".svg")) {
// Inline svg
tag = fs.readFileSync(`${articleDirectory}/${src}`, "utf-8").replace(/<\/svg>/, `<title>${alt}</title></svg>`);
} else if (src.indexOf("/") === -1 && src.endsWith(".webm")) {
} else if (src.indexOf("/") === -1 && src.replace(/#.*/, "").endsWith(".webm")) {
// Use video
tag = `<video autoplay loop muted playsinline src="${src}" alt="${alt}" title="${alt}"></video>`;
if (src.endsWith("#epilepsy")) {
className += " epilepsy";
tag = `<video preload="auto" controls loop muted playsinline src="${src}" alt="${alt}" title="${alt}"></video>`;
} else {
tag = `<video autoplay loop muted playsinline src="${src}" alt="${alt}" title="${alt}"></video>`;
}
} else {
// Add title
tag = `<img src="${src}" alt="${alt}" title="${alt}">`;
}
return `<div class="diagram">${tag}</div>`;
return `<div class="${className}">${tag}</div>`;
})
);

Expand Down
6 changes: 3 additions & 3 deletions blog/we-built-the-best-bad-apple-in-minecraft/index.html

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions blog/we-built-the-best-bad-apple-in-minecraft/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ Theoretically, [zero-ticking](https://minecraft.wiki/w/Tutorials/Zero-ticking) s

These structures should be built under `/tick freeze`, so that the repeaters are turned off. This way, when the structure is loaded, there's a 1 redstone tick delay before replacing the structure:

![The structure from above alternating between red and yellow wool every redstone tick.](working-structure-blocks-red-yellow-running.webm)
![The structure from above alternating between red and yellow wool every redstone tick.](working-structure-blocks-red-yellow-running.webm#epilepsy)


### Activation
Expand All @@ -206,13 +206,13 @@ So far, we've seen colors alternating 10 times per second. For 20 fps, we need 4

![4 structures, now 2 block deep. The red and yellow structures are just like before, with the far layer being empty. The new blue and green structures have the redstone blocks, repeaters and structure blocks in the far layer, with the near layer being empty except for the wool block.](4-colors-components.png)

![The same structures from above](4-colors-components-up.png)
![The same structures from above.](4-colors-components-up.png)

The small pink cubes indicate *structure voids*: blocks that aren't replaced when the structure is loaded. By default, even air can replace blocks, so these voids let us overlap structures.

The red and yellow structures form one 10 Hz clock, while the blue and green structures form another 10 Hz clock. Both clocks place the wool at the same position, so if the structures are activated at the right offset, four colors alternate at 20 Hz:

![The two structures overlapped, visibly alternating between green, yellow, blue, and red](4-colors.webm)
![The two structures overlapped, visibly alternating between green, yellow, blue, and red.](4-colors.webm#epilepsy)

This video was recorded by manually activating the two clocks at different times so that they run in different phases. To streamline this process, we can use a long-standing bug where pistons pushing redstone blocks take 3 game ticks to extend when activated directly by user input. This way, pressing a single button activates the mechanism with 100% success:

Expand All @@ -223,7 +223,7 @@ This video was recorded by manually activating the two clocks at different times

To make a screen, all we have to do is place a large grid of wool instead of just one block.

![Five 48-block-tall towers: four for the original components, updating at 10 Hz, and the fifth one combined, updating at 20 Hz](towers.webm)
![Five 48-block-tall towers: four for the original components, updating at 10 Hz, and the fifth one combined, updating at 20 Hz.](towers.webm#epilepsy)

Oof, that was tiresome, and that was just 48 block tall towers. I need... 384 blocks vertically? Wait, how tall are Minecraft worlds, anyway? That's 384 blocks, i.e. 24 chunks. And it's going to be 32 chunks horizontally. The maximum render distance is 32 chunks, so I'll probably have to play around with FOV...

Expand All @@ -245,9 +245,9 @@ That's as impossible as placing blocks automatically. In other words, it's possi

Minecraft supports custom textures through resource packs (not to be confused with datapacks). We can replace the textures of several -- say 16 -- distinct blocks. 16 variants translate to 4 bits, which correspond to "subpixels" of a block:

![16 blocks of wool of different colors, using default Minecraft textures](wool-untextured.png)
![16 blocks of wool of different colors, using default Minecraft textures.](wool-untextured.png)

![The same blocks of wool, with textures replaced by 2x2 black-and-white pictures with different pattern for each "color"](wool-textured.png)
![The same blocks of wool, with textures replaced by 2x2 black-and-white pictures with different pattern for each "color".](wool-textured.png)

We can go futher. By taking $4^4 = 256$ blocks and adding two more colors to the subpixels, we can shift from black-and-white to grayscale.

Expand All @@ -268,7 +268,7 @@ If there are $N$ threads and the $N$ chunks closest to the player are updated so

You can partially observe this effect here:

![Five towers from before, recorded while standing at the bottom. The red-yellow tower glitches occasionally, rendering as partially red and and partially yellow at times.](towers-glitch.webm)
![Five towers from before, recorded while standing at the bottom. The red-yellow tower glitches occasionally, rendering as partially red and and partially yellow at times.](towers-glitch.webm#epilepsy)

The towers clearly glitch in the middle occasionally because they span three chunks, so sometimes only two chunks are rendered in time.

Expand Down Expand Up @@ -420,7 +420,7 @@ Yuki helped me devise a way to create instant wire using structure blocks. It's

Whenever the button is pressed, the structure block loads a *powered* redstone torch over the unpowered torch in the middle component. This torch gets unpowered on the next tick because it's sitting on a redstone block, but before that happens, it activates another structure block. This structure block spawns a powered redstone torch in the third component, triggering the lamp.

![The same three components, showing what happens when the button is pressed](instant-wire.webm)
![The same three components, showing that the lamp is activated with zero delay when the button is pressed.](instant-wire.webm#epilepsy)

A structure block spans up to $48$ blocks, so this method helped me transfer startup signals across a grid of $48 \times 48$ subscreens.

Expand Down Expand Up @@ -472,39 +472,39 @@ Some people believe "Bad Apple!!" is purely black-and-white, but there are *many

Motion blur:

![A girl raising a hand with an apple at large velocity, with the apple and the hand blurred significantly](grayscale-apple-original.png)
![A girl raising a hand with an apple at large velocity, with the apple and the hand blurred significantly.](grayscale-apple-original.png)

Glow and objects of different brightness:

![A girl flying on a broom towards a castle under a night sky](grayscale-sky-original.png)
![A girl flying on a broom towards a castle under a night sky.](grayscale-sky-original.png)

Gradients between scenes:

![A transition from a black-background scene to a white-background scene with a gradient](grayscale-gradient-original.png)
![A transition from a black-background scene to a white-background scene with a gradient.](grayscale-gradient-original.png)

In high-speed scenes, the motion blur is enchanced by overlapping 5 frames of an $\approx 200$ fps video with different opacity, leaving a trace:

![A girl spinning, with arms leaving a trace](grayscale-trace-original.png)
![A girl spinning, with arms leaving a trace.](grayscale-trace-original.png)

Blur (the girl in the background) and gradients:

![A girl swiping a sword, with the sword leaving a gradient trace. Another girl in the background is blurred, as if out of focus.](grayscale-blur-gradient-original.png)

Fire:

![A girl with fire emanating from her hands](grayscale-fire-original.png)
![A girl with fire emanating from her hands.](grayscale-fire-original.png)

The sun:

![A girl and the sun, with a radial gradient around the sun](grayscale-sun-original.png)
![A girl and the sun, with a radial gradient around the sun.](grayscale-sun-original.png)

Shadows:

![Three girls playing instruments, with shadows](grayscale-shadows-original.png)
![Three girls playing instruments, with shadows.](grayscale-shadows-original.png)

Ripples in water:

![Ripples spreading from a falling drop](grayscale-water-original.png)
![Ripples spreading from a falling drop.](grayscale-water-original.png)

Simply rounding to the nearest representable color doesn't do these frames justice, introducing [banding](https://en.wikipedia.org/wiki/Colour_banding):

Expand Down

0 comments on commit d6b85a8

Please sign in to comment.