Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions app/games/yaml-parsing-simulator/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import type { Metadata } from 'next';
import YamlParsingSimulator from '@/components/games/yaml-parsing-simulator';
import { SimulatorShell } from '@/components/games/simulator-shell';
import { generateGameMetadata } from '@/lib/game-metadata';

export async function generateMetadata(): Promise<Metadata> {
return generateGameMetadata('yaml-parsing-simulator');
}

const seoLearningPoints = [
'Why `country: NO` becomes the boolean false, and which parsers do it',
'Why `version: 1.10` is a lower number than `version: 1.9`',
'How YAML 1.1 and YAML 1.2 disagree about the same file, and why that matters',
'The difference between an empty value, `~`, `null` and an empty string',
'When a leading zero means octal and when it means decimal',
'What `|` and `>` do to the newlines in a CI script',
'Why a repeated key silently overwrites the one above it',
'How anchors, aliases and merge keys work in a CI config',
'Why a tab in indentation is rejected and so hard to spot',
'Why quoting is the fix for nearly all of it',
];

function YamlEducational() {
return (
<>
<h3 className="mb-4 text-xl font-semibold">About this YAML parsing simulator</h3>
<div className="grid gap-6 md:grid-cols-2">
<div>
<h4 className="mb-3 text-sm font-semibold">What you&apos;ll learn</h4>
<ul className="space-y-2 text-sm text-muted-foreground">
<li>That YAML resolves your untagged values into types, and which ones surprise people</li>
<li>That YAML 1.1 and YAML 1.2 disagree, so the same file means different things in different tools</li>
<li>Why the failures are quiet: nothing errors, a value just stops being what you meant</li>
<li>The two-character fix, and when you actually need it</li>
</ul>
</div>
<div>
<h4 className="mb-3 text-sm font-semibold">How it works</h4>
<ul className="space-y-2 text-sm text-muted-foreground">
<li>The parser is real and runs in your browser. Nothing here is a canned answer.</li>
<li>Every document is read twice, once under each spec, and the differences are listed.</li>
<li>Edit any example. Your own YAML is resolved by the same rules.</li>
</ul>
</div>
</div>
<p className="mt-6 text-sm text-muted-foreground">
The behaviour shown here follows the{' '}
<a href="https://yaml.org/spec/1.2.2/" target="_blank" rel="noopener noreferrer" className="underline">
YAML 1.2.2 specification
</a>{' '}
and the older{' '}
<a href="https://yaml.org/type/bool.html" target="_blank" rel="noopener noreferrer" className="underline">
YAML 1.1 boolean type
</a>
, which is the one that turns Norway into false. Most tools still ship a 1.1-era resolver:
that is not a bug in your file, it is a disagreement between versions of the format.
</p>
<p className="mt-4 text-sm text-muted-foreground">
Related: the{' '}
<a href="/games/kubernetes-terminal-simulator" className="underline">
Kubernetes terminal simulator
</a>{' '}
for the manifests this bites hardest, and the{' '}
<a href="/games/git-concepts-simulator" className="underline">
Git concepts simulator
</a>{' '}
for the other thing everyone learns by breaking it.
</p>
</>
);
}

export default function Page() {
return (
<SimulatorShell
slug="yaml-parsing-simulator"
educational={<YamlEducational />}
seoLearningPoints={seoLearningPoints}
>
<YamlParsingSimulator />
</SimulatorShell>
);
}
2 changes: 2 additions & 0 deletions components/games-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ import {
Gamepad2,
FlaskConical,
LucideIcon,
FileCode,
} from 'lucide-react';
import Link from 'next/link';

// Icon mapping for serializable icon names
const iconMap: Record<string, LucideIcon> = {
Bug,
FileCode,
MailWarning,
Network,
Trophy,
Expand Down
2 changes: 2 additions & 0 deletions components/games/game-component-registry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ComponentType } from 'react';
import AgenticLoopSimulator from '@/components/games/agentic-loop-simulator';
import YamlParsingSimulator from '@/components/games/yaml-parsing-simulator';
import HerokuStyleNameGenerator from '@/components/games/heroku-style-name-generator';
import BinaryByteSimulator from '@/components/games/binary-byte-simulator';
import BounceTriageSimulator from '@/components/games/bounce-triage-simulator';
Expand Down Expand Up @@ -57,6 +58,7 @@ import WebhookDeliverySimulator from '@/components/games/webhook-delivery-simula

export const GAME_COMPONENTS: Record<string, ComponentType> = {
'agentic-loop-simulator': AgenticLoopSimulator,
'yaml-parsing-simulator': YamlParsingSimulator,
'binary-byte-simulator': BinaryByteSimulator,
'bounce-triage-simulator': BounceTriageSimulator,
'docker-under-the-hood-simulator': DockerUnderTheHoodSimulator,
Expand Down
Loading
Loading