Merge branch 'pages/nethack-logfile'

This commit is contained in:
Eryn Wells 2022-04-24 17:28:05 -07:00
commit bf5174d82a
11 changed files with 1633 additions and 0 deletions

38
content/nethack/index.md Normal file
View file

@ -0,0 +1,38 @@
---
title: "Nethack"
description: In which I play way too much of a silly command line Rogue-like game.
date: 2022-04-13T08:43:46-07:00
draft: false
type: simple
---
Every so often I get hooked on [this game][nethack]. It's a command line
Roguelike adventure game with rules based on Dungeons & Dragons. You play a
character on a mission for their deity to retrieve the Amulet of Yendor from an
evil Wizard and bring it back to the surface. The game gives you very little to
go on when you start, and it teaches you almost nothing except the basic
controls. Famously, almost every item you encounter or action you can take can
go wrong in some catastrophic way and cause
{{< abbr title="Yet Another Stupid Death" >}}YASD{{</ abbr >}}.
The more you play, the more you learn, and the more you begin to understand the
risks and consequences.
In short: it's very hard, you die a lot, and it's quite easy to lose hours
delving deeper and deeper into the Dungeons of Doom, dying, and starting again.
It's also really fun.
Here's my best game so far:
{{< nethack/best_game >}}
## A Game Log
The game logs every play-through, along with a bunch of data about your
character and how you did.
Herein is a chronological accounting of my last ten descents into the Dungeons
of Doom.
{{< nethack/logfile >}}
[nethack]: https://www.nethack.org

78
content/nethack/style.css Normal file
View file

@ -0,0 +1,78 @@
/* Eryn Wells <eryn@erynwells.me> */
:root {
--logentry-background-color: var(--tag-background-color);
--logentry-foreground-color: var(--tag-text-color);
}
ol.logfile {
margin-block-start: 0;
padding-inline-start: 0;
}
.logentry {
align-items: first baseline;
color: var(--logentry-foreground-color);
background-color: var(--logentry-background-color);
border-radius: 6px;
display: grid;
grid-template-columns: 32px auto auto;
row-gap: 1rem;
margin-block-start: 2rem;
padding: 3rem;
}
.logentry .date {
grid-column-start: 2;
grid-row-start: 1;
}
.logentry h4.date {
margin: 0;
padding: 0;
}
.logentry .character-descriptor {
color: #aaa;
font-size: 1.5rem;
font-weight: 700;
grid-column-start: 3;
grid-row-start: 1;
text-align: right;
text-transform: uppercase;
}
.logentry p {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 2;
margin: 0;
}
.logentry .stats {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 3;
}
.logentry table.stats {
border: 0;
width: 100%;
-webkit-border-horizontal-spacing: 0;
-webkit-border-vertical-spacing: 0;
}
.logentry table.stats td {
color: #aaa;
font-size: 1.5rem;
font-weight: 700;
padding: 0;
text-transform: uppercase;
}
.logentry table.stats td.score,
.logentry table.stats td.hp,
.logentry table.stats td.level {
width: 16rem;
text-align: right;
}

View file

@ -0,0 +1,381 @@
{
"generated": "2022-04-24T17:06:29.396576",
"logfile": [
{
"score": 0,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 1,
"descriptive": "Level 1"
}
},
"end_date": "2022-04-05",
"start_date": "2022-04-05",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 1,
"hp": {
"n": 15,
"max": 15
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 0,
"cause": "quit"
},
"system": {
"hostname": "aquarius",
"user_id": 501,
"nethack_version": "3.6.6"
}
},
{
"score": 1309,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 7,
"descriptive": "Level 7"
}
},
"end_date": "2022-04-05",
"start_date": "2022-04-05",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 7,
"hp": {
"n": 0,
"max": 46
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a pony"
},
"system": {
"hostname": "aquarius",
"user_id": 501,
"nethack_version": "3.6.6"
}
},
{
"score": 148,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 2,
"descriptive": "Level 2"
}
},
"end_date": "2022-04-05",
"start_date": "2022-04-05",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Mon-Hum-Fem-Neu",
"max_level": 2,
"hp": {
"n": 0,
"max": 20
},
"role": {
"short": "Mon",
"descriptive": "Monk"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Neu",
"descriptive": "Neutral"
}
},
"death": {
"n": 1,
"cause": "killed by a water moccasin"
},
"system": {
"hostname": "aquarius",
"user_id": 501,
"nethack_version": "3.6.6"
}
},
{
"score": 2,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 1,
"descriptive": "Level 1"
}
},
"end_date": "2022-04-05",
"start_date": "2022-04-05",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Mon-Hum-Fem-Neu",
"max_level": 1,
"hp": {
"n": 8,
"max": 14
},
"role": {
"short": "Mon",
"descriptive": "Monk"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Neu",
"descriptive": "Neutral"
}
},
"death": {
"n": 0,
"cause": "quit"
},
"system": {
"hostname": "aquarius",
"user_id": 501,
"nethack_version": "3.6.6"
}
},
{
"score": 370,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 4,
"descriptive": "Level 4"
}
},
"end_date": "2022-04-07",
"start_date": "2022-04-05",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 4,
"hp": {
"n": 0,
"max": 28
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a coyote, while fainted from lack of food"
},
"system": {
"hostname": "aquarius",
"user_id": 501,
"nethack_version": "3.6.6"
}
},
{
"score": 0,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 1,
"descriptive": "Level 1"
}
},
"end_date": "2022-04-09",
"start_date": "2022-04-09",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 1,
"hp": {
"n": 15,
"max": 15
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 0,
"cause": "quit"
},
"system": {
"hostname": "aquarius",
"user_id": 501,
"nethack_version": "3.6.6"
}
},
{
"score": 737,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 4,
"descriptive": "Level 4"
}
},
"end_date": "2022-04-10",
"start_date": "2022-04-04",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Rog-Hum-Fem-Cha",
"max_level": 4,
"hp": {
"n": 0,
"max": 31
},
"role": {
"short": "Rog",
"descriptive": "Rogue"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Cha",
"descriptive": "Chaotic"
}
},
"death": {
"n": 1,
"cause": "killed by a dwarf, while fainted from lack of food"
},
"system": {
"hostname": "aquarius",
"user_id": 501,
"nethack_version": "3.6.6"
}
},
{
"score": 1460,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 6,
"descriptive": "Level 6"
}
},
"end_date": "2022-04-18",
"start_date": "2022-04-12",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 6,
"hp": {
"n": 0,
"max": 58
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a killer bee"
},
"system": {
"hostname": "aquarius",
"user_id": 501,
"nethack_version": "3.6.6"
}
}
]
}

View file

@ -0,0 +1,804 @@
{
"generated": "2022-04-25T00:08:29.573259",
"logfile": [
{
"score": 2652,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 7,
"descriptive": "Level 7"
}
},
"end_date": "2022-04-03",
"start_date": "2022-01-16",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 7,
"hp": {
"n": 0,
"max": 60
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a Woodland-elf"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 40,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 1,
"descriptive": "Level 1"
}
},
"end_date": "2022-04-03",
"start_date": "2022-04-03",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 1,
"hp": {
"n": 0,
"max": 15
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by an electric shock"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 1973,
"dungeon": {
"n": 2,
"name": "The Gnomish Mines",
"level": {
"n": 6,
"descriptive": "Level 6"
}
},
"end_date": "2022-04-03",
"start_date": "2022-04-03",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 6,
"hp": {
"n": 0,
"max": 57
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "poisoned by a rotted gnomish wizard corpse"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 898,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 4,
"descriptive": "Level 4"
}
},
"end_date": "2022-04-04",
"start_date": "2022-04-03",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 5,
"hp": {
"n": 0,
"max": 36
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "died of starvation, while fainted"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 399,
"dungeon": {
"n": 2,
"name": "The Gnomish Mines",
"level": {
"n": 3,
"descriptive": "Level 3"
}
},
"end_date": "2022-04-04",
"start_date": "2022-04-04",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Pri-Elf-Fem-Cha",
"max_level": 3,
"hp": {
"n": 0,
"max": 21
},
"role": {
"short": "Pri",
"descriptive": "Priest"
},
"race": {
"short": "Elf",
"descriptive": "Elf"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Cha",
"descriptive": "Chaotic"
}
},
"death": {
"n": 1,
"cause": "killed by a dwarf"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 138,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 2,
"descriptive": "Level 2"
}
},
"end_date": "2022-04-05",
"start_date": "2022-04-05",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Ran-Gno-Fem-Neu",
"max_level": 2,
"hp": {
"n": 0,
"max": 14
},
"role": {
"short": "Ran",
"descriptive": "Ranger"
},
"race": {
"short": "Gno",
"descriptive": "Gnome"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Neu",
"descriptive": "Neutral"
}
},
"death": {
"n": 1,
"cause": "killed by a jackal"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 455,
"dungeon": {
"n": 2,
"name": "The Gnomish Mines",
"level": {
"n": 4,
"descriptive": "Level 4"
}
},
"end_date": "2022-04-07",
"start_date": "2022-04-05",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 4,
"hp": {
"n": 0,
"max": 37
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a little dog"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 397,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 4,
"descriptive": "Level 4"
}
},
"end_date": "2022-04-07",
"start_date": "2022-04-07",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Rog-Hum-Fem-Cha",
"max_level": 4,
"hp": {
"n": 0,
"max": 15
},
"role": {
"short": "Rog",
"descriptive": "Rogue"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Cha",
"descriptive": "Chaotic"
}
},
"death": {
"n": 1,
"cause": "killed by a cave spider, while frozen by a monster's gaze"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 2552,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 6,
"descriptive": "Level 6"
}
},
"end_date": "2022-04-09",
"start_date": "2022-04-08",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 6,
"hp": {
"n": 0,
"max": 44
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a violet fungus"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 391,
"dungeon": {
"n": 2,
"name": "The Gnomish Mines",
"level": {
"n": 3,
"descriptive": "Level 3"
}
},
"end_date": "2022-04-09",
"start_date": "2022-04-09",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 3,
"hp": {
"n": 0,
"max": 36
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a gnome king"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 567,
"dungeon": {
"n": 2,
"name": "The Gnomish Mines",
"level": {
"n": 5,
"descriptive": "Level 5"
}
},
"end_date": "2022-04-09",
"start_date": "2022-04-09",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 5,
"hp": {
"n": 0,
"max": 34
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a little dog called Hachi, while fainted from lack of food"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 0,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 1,
"descriptive": "Level 1"
}
},
"end_date": "2022-04-11",
"start_date": "2022-04-11",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 1,
"hp": {
"n": 15,
"max": 15
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 0,
"cause": "quit"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 866,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 4,
"descriptive": "Level 4"
}
},
"end_date": "2022-04-12",
"start_date": "2022-04-11",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 6,
"hp": {
"n": 0,
"max": 43
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a bolt of cold"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 4143,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 6,
"descriptive": "Level 6"
}
},
"end_date": "2022-04-13",
"start_date": "2022-04-12",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 7,
"hp": {
"n": 0,
"max": 64
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a plains centaur"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 4171,
"dungeon": {
"n": 0,
"name": "The Dungeons of Doom",
"level": {
"n": 9,
"descriptive": "Level 9"
}
},
"end_date": "2022-04-16",
"start_date": "2022-04-14",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 9,
"hp": {
"n": 0,
"max": 63
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a Green-elf"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 2690,
"dungeon": {
"n": 2,
"name": "The Gnomish Mines",
"level": {
"n": 7,
"descriptive": "Level 7"
}
},
"end_date": "2022-04-18",
"start_date": "2022-04-16",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 7,
"hp": {
"n": 0,
"max": 64
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a Woodland-elf, while fainted from lack of food"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
},
{
"score": 9401,
"dungeon": {
"n": 2,
"name": "The Gnomish Mines",
"level": {
"n": 11,
"descriptive": "Level 11"
}
},
"end_date": "2022-04-24",
"start_date": "2022-04-19",
"character": {
"name": "Eryn",
"descriptor": "Eryn-Sam-Hum-Fem-Law",
"max_level": 11,
"hp": {
"n": 0,
"max": 67
},
"role": {
"short": "Sam",
"descriptive": "Samurai"
},
"race": {
"short": "Hum",
"descriptive": "Human"
},
"gender": {
"short": "Fem",
"descriptive": "Female"
},
"alignment": {
"short": "Law",
"descriptive": "Lawful"
}
},
"death": {
"n": 1,
"cause": "killed by a troll"
},
"system": {
"hostname": "nutmeg",
"user_id": 1002,
"nethack_version": "3.6.6"
}
}
]
}

View file

@ -0,0 +1,131 @@
{
"records": [
{
"nethack_version": "3.6.6",
"score": 4143,
"dungeon_number": 0,
"dungeon_name": "The Dungeons of Doom",
"level": 6,
"level_descriptive": "Level 6",
"max_level": 7,
"hit_points": 0,
"max_hit_points": 64,
"number_of_deaths": 1,
"end_date": "2022-04-13",
"start_date": "2022-04-12",
"user_id": 1002,
"role": "Samurai",
"race": "Human",
"gender": "Female",
"alignment": "Lawful",
"name": "Eryn",
"reason_for_death": "killed by a plains centaur"
},
{
"nethack_version": "3.6.6",
"score": 2652,
"dungeon_number": 0,
"dungeon_name": "The Dungeons of Doom",
"level": 7,
"level_descriptive": "Level 7",
"max_level": 7,
"hit_points": 0,
"max_hit_points": 60,
"number_of_deaths": 1,
"end_date": "2022-04-03",
"start_date": "2022-01-16",
"user_id": 1002,
"role": "Samurai",
"race": "Human",
"gender": "Female",
"alignment": "Lawful",
"name": "Eryn",
"reason_for_death": "killed by a Woodland-elf"
},
{
"nethack_version": "3.6.6",
"score": 2552,
"dungeon_number": 0,
"dungeon_name": "The Dungeons of Doom",
"level": 6,
"level_descriptive": "Level 6",
"max_level": 6,
"hit_points": 0,
"max_hit_points": 44,
"number_of_deaths": 1,
"end_date": "2022-04-09",
"start_date": "2022-04-08",
"user_id": 1002,
"role": "Samurai",
"race": "Human",
"gender": "Female",
"alignment": "Lawful",
"name": "Eryn",
"reason_for_death": "killed by a violet fungus"
},
{
"nethack_version": "3.6.6",
"score": 399,
"dungeon_number": 2,
"dungeon_name": "The Gnomish Mines",
"level": 3,
"level_descriptive": "Level 3",
"max_level": 3,
"hit_points": 0,
"max_hit_points": 21,
"number_of_deaths": 1,
"end_date": "2022-04-04",
"start_date": "2022-04-04",
"user_id": 1002,
"role": "Priest",
"race": "Elf",
"gender": "Female",
"alignment": "Chaotic",
"name": "Eryn",
"reason_for_death": "killed by a dwarf"
},
{
"nethack_version": "3.6.6",
"score": 397,
"dungeon_number": 0,
"dungeon_name": "The Dungeons of Doom",
"level": 4,
"level_descriptive": "Level 4",
"max_level": 4,
"hit_points": 0,
"max_hit_points": 15,
"number_of_deaths": 1,
"end_date": "2022-04-07",
"start_date": "2022-04-07",
"user_id": 1002,
"role": "Rogue",
"race": "Human",
"gender": "Female",
"alignment": "Chaotic",
"name": "Eryn",
"reason_for_death": "killed by a cave spider, while frozen by a monster's gaze"
},
{
"nethack_version": "3.6.6",
"score": 138,
"dungeon_number": 0,
"dungeon_name": "The Dungeons of Doom",
"level": 2,
"level_descriptive": "Level 2",
"max_level": 2,
"hit_points": 0,
"max_hit_points": 14,
"number_of_deaths": 1,
"end_date": "2022-04-05",
"start_date": "2022-04-05",
"user_id": 1002,
"role": "Ranger",
"race": "Gnome",
"gender": "Female",
"alignment": "Neutral",
"name": "Eryn",
"reason_for_death": "killed by a jackal"
}
]
}

View file

@ -0,0 +1,18 @@
{{ $level := (cond (gt .dungeon.level.n 0) (.dungeon.level.descriptive | lower) .dungeon.level.descriptive) }}
<div>{{ if .death.cause }}🪦{{ end }}</div>
<h4 class="date">{{ time.Format "January 2, 2006" .end_date }}</h4>
<div class="character-descriptor">{{ .character.abbreviated }}</div>
<p>{{ .character.name }}, a {{ .character.alignment.descriptive | lower }} {{ .character.race.descriptive | lower }}
{{ .character.gender.descriptive | lower }} {{ .character.role.descriptive }},
died {{ if gt .death.count 1 }}for the last time{{ end }} in <span class="nobreak">{{ .dungeon.name }}</span>
on <span class="nobreak">{{ $level }}</span>.
She was {{ .death.cause }}.</p>
<table class="stats">
<tr>
<td class="began">Began {{ time.Format "January 2, 2006" .start_date }}</td>
<td class="score">{{ .score }} points</td>
<td class="level">Level {{ .character.max_level }}</td>
<td class="hp">{{ cond (gt .character.hp.n 0) (printf "%s / %s" .character.hp.n .character.hp.max)
.character.hp.max }} hp</td>
</tr>
</table>

View file

@ -0,0 +1 @@
<abbr {{ with .Get "title" }}title="{{ . }}"{{ end }}>{{ .Inner }}</abbr>

View file

@ -0,0 +1,8 @@
{{ $nethack_data := $.Site.Data.nethack.logfile }}
{{ $logfile := slice }}
{{ range $nethack_data }}
{{ $logfile = $logfile | append .logfile }}
{{ end }}
<div class="logentry">
{{ partial "nethack/logentry.html" (index (sort $logfile "score" "desc") 0) }}
</div>

View file

@ -0,0 +1,14 @@
{{ $nethack_data := $.Site.Data.nethack.logfile }}
{{ $logfile := slice }}
{{ range $nethack_data }}
{{ $logfile = $logfile | append .logfile }}
{{ end }}
<ol class="logfile">
{{ range first 10 (sort $logfile "end_date" "desc") }}
{{ if ne .death.cause "quit" }}
<li class="logentry">
{{ partial "nethack/logentry.html" .}}
</li>
{{ end }}
{{ end }}
</ol>

151
scripts/import-nethack-logfile.py Executable file
View file

@ -0,0 +1,151 @@
#!/usr/bin/env python3
# Eryn Wells <eryn@erynwells.me>
'''
Converts a Nethack logfile (or record file) to JSON for easier parsing by my
website's templating engine.
See https://nethackwiki.com/wiki/Logfile for information about the format of these
logfiles.
'''
import argparse
import datetime
import json
from locale import normalize
import os.path
import subprocess
import sys
DUNGEONS = {
0: 'The Dungeons of Doom',
1: 'Gehennom',
2: 'The Gnomish Mines',
3: 'The Quest',
4: 'Sokoban',
5: 'Fort Ludios',
6: "Vlad's Tower",
7: 'The Elemental Planes',
}
# The "dungeon level" field is normally positive, but negatives indicate one of these
# levels.
SPECIAL_DUNGEON_LEVELS = {
-5: 'Astral Plane',
-4: 'Plane of Water',
-3: 'Plane of Fire',
-2: 'Plane of Air',
-1: 'Plane of Earth',
}
RACES = {
'Elf': 'Elf',
'Gno': 'Gnome',
'Hum': 'Human',
}
ROLES = {
'Mon': 'Monk',
'Pri': 'Priest',
'Ran': 'Ranger',
'Rog': 'Rogue',
'Sam': 'Samurai',
}
GENDERS = {
'Fem': 'Female',
}
ALIGNMENTS = {
'Law': 'Lawful',
'Neu': 'Neutral',
'Cha': 'Chaotic',
}
def parse_args(argv, *a, **kw):
parser = argparse.ArgumentParser(*a, **kw)
parser.add_argument('-o', '--output',help='Path to the output file')
parser.add_argument('logfile', help='Path to the Nethack log file to convert')
args = parser.parse_args(argv)
return args
def main(argv):
args = parse_args(argv[1:], prog=argv[0])
if not os.path.isfile(args.logfile):
print('Given path is not a real file!', file=sys.stderr)
return -1
hostname = subprocess.check_output(['hostname', '-s']).decode('ascii').strip()
records = []
with open(args.logfile) as logfile:
for record in logfile:
fields = record.split(maxsplit=15)
dungeon_number = int(fields[2])
dungeon_name = DUNGEONS[dungeon_number]
dungeon_level = int(fields[3])
if dungeon_level > 0:
dungeon_level_descriptive = f"Level {dungeon_level}"
else:
dungeon_level_descriptive = SPECIAL_DUNGEON_LEVELS[dungeon_level]
start_date = datetime.datetime.strptime(fields[9], '%Y%m%d').strftime('%Y-%m-%d')
end_date = datetime.datetime.strptime(fields[8], '%Y%m%d').strftime('%Y-%m-%d')
name, cause_of_death = (s.strip() for s in fields[15].split(',', maxsplit=1))
role = fields[11]
race = fields[12]
gender = fields[13]
alignment = fields[14]
records.append({
'score': int(fields[1]),
'dungeon': {
'n': int(fields[2]),
'name': dungeon_name,
'level': {'n': dungeon_level, 'descriptive': dungeon_level_descriptive},
},
'end_date': end_date,
'start_date': start_date,
'character': {
'name': name,
'descriptor': f'{name}-{role}-{race}-{gender}-{alignment}',
'max_level': int(fields[4]),
'hp': {'n': int(fields[5]), 'max': int(fields[6])},
'role': {'short': role, 'descriptive': ROLES[role]},
'race': {'short': race, 'descriptive': RACES[race]},
'gender': {'short': gender, 'descriptive': GENDERS[gender]},
'alignment': {'short': alignment, 'descriptive': ALIGNMENTS[alignment]},
},
'death': {'n': int(fields[7]), 'cause': cause_of_death},
'system': {
'hostname': hostname,
'user_id': int(fields[10]),
'nethack_version': fields[0],
}
})
output_object = {
'generated': datetime.datetime.now().isoformat(),
'logfile': records,
}
output_path = args.output
if output_path and output_path != '-':
output_file = open(output_path, 'w')
else:
output_file = sys.stdout
json.dump(output_object, output_file, indent=2)
output_file.write('\n')
output_file.close()
return 0
if __name__ == '__main__':
import sys
result = main(sys.argv)
sys.exit(0 if not result else result)

View file

@ -467,3 +467,12 @@ ul.post-tags li + li {
font-size: 7px;
}
}
/*
* Helpers
*/
/* For <span>s that shouldn't break. */
.nobreak {
white-space: nowrap;
}