Thursday, September 22, 2016


So, I've implemented the new WOUNDING feature for slashem and included a new chaotic artifact long sword named Nightblood (taken from some book).  The patch is for SlashTHEM.

The gist is that if you "wound" a monster, it will continue to take damage until you kill it or until it bleeds out.  Just apply this patch and add #define WOUNDING to includ/config.h and you should be good to go.

greg@viper:~/src/SlashTHEM$ git diffdiff --git a/include/artilist.h b/include/artilist.h
index 172a20f..522a74b 100644
--- a/include/artilist.h
+++ b/include/artilist.h
@@ -28,6 +28,9 @@ static const char *artifact_names[] = {
 #define     ELEC(a,b)    {0,AD_ELEC,a,b}        /* electrical shock */
 #define     STUN(a,b)    {0,AD_STUN,a,b}        /* magical attack */
 #define     ACID(a,b)    {0,AD_ACID,a,b}
+#ifdef WOUNDING
+#define     WOUN(a,b)   {0,AD_WOUN,a,b}

 STATIC_OVL NEARDATA struct artifact artilist[] = {
 #endif    /* MAKEDEFS_C */
@@ -355,7 +358,11 @@ A("Cat's Claw",        DAGGER,
     PHYS(5,7),    NO_DFNS,    NO_CARY,    0, A_NEUTRAL, NON_PM, NON_PM, 1000L ),
 #endif /* NEWHON_ARTIFACTS */
+#ifdef WOUNDING
+A("Nightblood", LONG_SWORD,
+  WOUN(5, 10), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, NON_PM, 4000L),
 #ifdef TOURIST
 A("Whisperfeet",               SPEED_BOOTS,
@@ -898,6 +905,9 @@ A(0, 0, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L )
 #undef    FIRE
 #undef    ELEC
 #undef    STUN
+#ifdef WOUNDING
+#undef  WOUN
+#endif /* WOUNDING */

diff --git a/include/attk.h b/include/attk.h
index a52a9ce..dee4dcc 100644
--- a/include/attk.h
+++ b/include/attk.h
@@ -141,7 +141,12 @@ extern char *attk_dname(Attk);
 #define AD_POLY        43    /* RJ -- polymorphs (genetic engineer) */
 #define AD_CORR        44    /* corrode armor (black pudding) */
 #define AD_TCKL        45    /* Tickle (Nightgaunts) */
-#define AD_ENDS        46    /* placeholder */
+#ifdef WOUNDING
+#define AD_WOUN     46  /* Wounding attack */
+#define AD_ENDS        47    /* placeholder */
+#define AD_ENDS     46  /* placeholder */

 #define AD_CLRC        240        /* random clerical spell */
 #define AD_SPEL        241        /* random magic spell */
diff --git a/src/artifact.c b/src/artifact.c
index 69b0add..d37b396 100644
--- a/src/artifact.c
+++ b/src/artifact.c
@@ -1281,6 +1281,18 @@ int dieroll; /* needed for Magicbane and vorpal blades */
         return Mb_hit(magr, mdef, otmp, dmgptr, dieroll, vis, hittee);

+#ifdef WOUNDING
+    if (attacks(AD_WOUN, otmp)) {
+        if (realizes_damage) {
+            if (rnd(5)==1) {
+                mdef->wounding += rnd(10);
+                pline_The("sharp blade wounds %s.", hittee);
+            }
+        }
+        return realizes_damage;
+    }
     if (!spec_dbon_applies && !spec_ability(otmp, SPFX_BEHEAD) ||
         !special_applies) {
         /* since damage bonus didn't apply, nothing more to do;
diff --git a/src/mon.c b/src/mon.c
index 1bb6a87..36c2fa2 100644
--- a/src/mon.c
+++ b/src/mon.c
@@ -808,6 +808,18 @@ mcalcdistress()
     struct monst *mtmp;

     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
+#ifdef WOUNDING
+    if (mtmp->wounding) {
+        mtmp->mhp -= rnd(mtmp->wounding);
+        if (mtmp->mhp < 1) {
+            pline_The("%s dies from its wounds.", Monnam(mtmp));
+            mon_xkilled(mtmp, NULL, AD_WOUN);
+        } else {
+            pline_The("%s suffers from its wounds.", Monnam(mtmp));
+        }
+    }
     if (DEADMONSTER(mtmp)) continue;

     /* must check non-moving monsters once/turn in case
diff --git a/src/monmove.c b/src/monmove.c
index a6d1d32..ec22bf8 100644
--- a/src/monmove.c
+++ b/src/monmove.c
@@ -858,6 +858,19 @@ register int after;
         if(i == 1) return(0);    /* still in trap, so didn't move */

+#ifdef WOUNDING
+    if (mtmp->wounding) {
+        mtmp->mhp -= rnd(mtmp->wounding);
+        if (mtmp->mhp < 1) {
+            pline_The("%s dies from its wounds.", Monnam(mtmp));
+            return 2;
+        } else {
+            pline_The("%s suffers from its wounds.", Monnam(mtmp));
+            return 1;
+        }
+    }
     ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */

     if (mtmp->meating) {

Tuesday, September 20, 2016

"Just a fleshwound."

I'm working on a patch for slashem (tends to be the version of nethack I tinker with the most) to add a weapon feature called "Wounding".  Basically, when you hit a monster with a weapon that has the "wounding" feature, there's a chance you will create—you guessed it—a wound.  A wounded monster will take a random amount of extra damage every turn regardless of whether its hit.

What good is wounding without a nice artifact to carry out the message?  I've added Nightblood, a chaotic long sword that can wound.

I still need to test this to make sure it all works, at which point, I'll make the patch available.  Also, I think it's important to mention how much I love CPP.  I'm not talking about C++, but the C Pre-Processor.  All languages should have one.

Thursday, September 15, 2016

Starting to get back into it

I was looking through the Slashem, and then SlashTHEM code, pondering adding some new artifacts, when I decided to do something nice and fix all the indentation problems in the code.  A lot of the issues stem from mixing of Tabs and Spaces.  I personally prefer spaces since tab-sizes can be changed depending on the text editor you're using, so I changed all tabs to spaces.  Whatever your preference, tabs or spaces, I think we can all agree they shouldn't be mixed.

Fortunately, this who process was as simple as running indent -nut -kr on all the source files.  I discovered this very old, simple tool when working for a company that used the GNU indentation style, which if you're not familiar with it, is a steaming pile of horse shit that should never have been invented (Thanks Stallman!).

You can clone the SlashTHEM git repository here:

Then just download and apply my patch to fix all the indentation to use indentation of four spaces per indentation level:


Sunday, July 26, 2015

Pluto a planet?

(This post doesn't concern Nethack).

With NASA being a total winner with its New Horizons mission to Pluto, the debate about whether Pluto should be a planet has emerged yet again.

You can look at wikipedia for more details, but the basic story for how Pluto lost its planet status, or rather, how planet gained its definition is as follows: in 2005, astronomers found a dwarf-planet called Eris with a slightly wackier orbit than Pluto's.

Other, similarly-sized objects had been found, but the kicker in this case was that Eris is more massive than Pluto (still, both are less massive than our own pet rock, the Moon).  This prompted the International Astronomical Union (IAU) to actually come up with a formal definition for the word "planet" in 2006.

So, according to the IAU, in order to be a planet, a celestial body must:
  1. is in orbit around the Sun,
  2. has sufficient mass to assume hydrostatic equilibrium (a nearly round shape), and
  3. has "cleared the neighbourhood" around its orbit.
(Incidentally, I assume #1 is why we refer to natural satellites of other stars as "exoplanets" instead of "planets").

Pluto apparently has failed the third test because it shares its orbit with other Kuiper belt objects.  This led to Pluto being deemed a "dwarf-planet", which led to everyone losing their shit because they wanted Pluto to be a full-fledged Planet.

I propose to you a new stance on the topic.  Whether Pluto re-gains its status as a full-fledged planet is irrelevant.  My proposal is that the word "planet" should re-gain its status as not being formally defined by the IAU.

The term "planet" is a cultural term that goes back centuries.  Everyone knows what you mean when you say "planet" and almost no one can recite the formal IAU definition of "planet".  At the same time, if people want to use more technical terms, like "Kuiper belt object", they already exist.  Undefining the word "planet", i.e., making its meaning ambiguous, is a win-win solution.

Tuesday, June 23, 2015

Space Brick

This post has nothing to do with Nethack.  It does, however, have something to with Kerbal Space Program (KSP) 1.0.x.

For those familiar with KSP, you know that prior to the release of version 1.0, there was no atmospheric model.  The amount of atmospheric drag a ship would generate was a function of the mass of its constituent parts.

The folks over at Ferram Aerospace Research (FAR) created a game mod that replaced the stock KSP aerodynamic system with a much more realistic aerodynamic system that took part placement and occlusion into account, along with other things like Mach effects, etc, etc.  It's a brilliant mod.

To give a brief background, the makers of KSP, Squad, released 0.90 Beta a while back, and said their next version would be 1.0 GA (general availability—I assume most are familiar with the term?  At least, that's why my place calls it.  In short, GA is what comes after Beta in the software release life-cycle).

Squad said they would add procedural fairings and an atmospheric model that included aerodynamic heating.  As someone who writes software professionally, I pondered the concept of a single Beta release prior to a GA release and immediately thought, "no fuckin' way."  But, Squad pulled it off and did an amazing job.  It was an extremely impressive feat.

Of course, the folks over at FAR overhauled their aerodynamic model and made it much more hardcore for KSP 1.0.x, taking stuff like cross-sectional area into account when calculating wave-drag at transonic speeds.

Anyway, getting back on topic, one feature that FAR has had for a long time now, and that KSP added as of 1.0.x, is body lift.  In the words of FAR: "All parts lift: a fast enough brick will fly, if not that well."

So, I set out to make a brick.  Rather, a Space Brick.  The rules I gave myself were as follows: no control surfaces of any kind, meaning no wings, winglets, canards, airbrakes, parachutes, flaps, spoilers, etc, etc, etc.  I also opted to not use reaction control systems (RCS), but that wasn't forbidden by my rules.  The Brick had to be able start on the runway at the Kerbal Space Center, achieve orbit, de-orbit, land back on Kerbin, and come to a stop on the runway at the Kerbal Space Center.

(Note the lawyerly wording above.  More on this later.)

Lift is generated entirely by the body, and steering is accomplished entirely by vectored thrusting (and a single reaction wheel that is built into the cockpit by default that I didn't turn off, but it's probably not needed).

The Space Brick is only "capable" in stock KSP 1.0.x.  It does not fly very well with the FAR mod installed.

Also note that I use the MechJeb2 mod so I can plaster a bunch of numbers on the screen that are helpful to me.  The Smart A.S.S. window is open, but it's not needed and I didn't end up using it.

As for the lawyerly wording above, the Brick cannot take off from the runway.  Take-off is accomplished by channelling your inner Jeremy Clarkson, stomping on the throttle, and yelling "POWER!!!"  The Space Brick has to shoot past the end of the runway before it can pull up.

Similarly, since the Brick is only is controllable at around Mach 0.7 or faster, it needs a lot of room to brake after landing, which is why it doesn't have to land on the runway after de-orbiting; it just needs to come to a stop on the runway.

Single Stage to Orbit

This part is actually very easy.  It's a straight shot from the runway to an equatorial orbit.  No commentary needed.

Atmospheric Entry

This was a bit tough.  I had to adjust the center of mass throughout my descent by shifting fuel around.


In short, it's possible:

So, yes, you'll notice that the version in orbit and the version landed are slightly different.  The landed version has many more wheels.  Also, the atmospheric entry and landing (and take off) screenshots were from three different flights.

In short, I have a proof of concept.  In theory, it's possible to take-off, orbit, and land in a single flight, but I'm hoping for someone who's a better pilot than I am to string these feats together into a single flight.

At the moment, I'm trying to figure out how to attach the craft file.


So, I've figured out how to attach the craft file...kind of.

I don't want people following a link to a file that will make people panic (i.e., a flat-text .craft file should be visible as flat text before you decide to download it to your computer).  Since KSP craft files are just flat text files (as all good files are), I copied and pasted the text into a Google word doc.  That's right, I'm copying and pasting the contents of a flat text file into a Google Word Doc (yes, Google, I'm making fun of you for copying Microsoft Word for your docs format).

You can view the Google doc and copy and paste the text into a file and rename it as Space\ Brick.craft, or whatever the hell you want to name it.

In the meantime, I'll just curl up in a corner and cry and pull my hair out for what I had to do to attach the craft file.  Can you spell "KLUDGE"?

Saturday, September 20, 2014


Since the last post was entirely about coding, this one will be entirely about concepts for the game.  The psion was the first idea I had for a new role in the game.  Since that flash of creativity hit me, brainstorming about the psion has brought me in many directions.  I've come up with several ideas that would affect game play for all roles.

I view the psion as being the brother to the monk role.  Penalties would be given for wearing armor and wielding weapons, however, eating corpses wouldn't make you feel guilty.  Instead of gaining intrinsics like poison/fire/cold resistance at increasing experience levels, psions would gain mental abilities.  I'll lay out the monk's abilities first, then my psion's abilities.  Note that the psion abilities are all, very much, subject to change:

Monk in Nethack:
XP Lvl 1: speed, sleep resistance, see invisible
XP Lvl 3: poison resistance
XP Lvl 5: stealth
XP Lvl 7: warning
XP Lvl 9: searching
XP Lvl 11: fire resistance
XP Lvl 13: cold resistance
XP Lvl 15: shock resistance
XP Lvl 17: teleport control.

Note that, in slashem, fire, cold, and shock resistances are now techniques, not intrinsics.

Psion in greghack:
XP Lvl 1: intrinsic telepathy (like you get from eating a floating eye corpse)
XP Lvl 3: see invisible
XP Lvl 5: extrinsic telepathy (like you get from wearing an amulet or helm of ESP)
XP Lvl 10: flying
XP Lvl 15: detect monsters (like the blessed potion, but always on)

Detect monsters is pretty powerful, so I'm up in the air about that.  I used to have phasing at level 20, but that's WAY too powerful.  I'm thinking of maybe making that a limited-time ability from invoking the psionic quest artifact, which I have not implemented nor spent much time thinking about.

Psion Techniques are similar to monk techniques at the moment, with some exceptions.  The main reason behind getting rid of chained blitz is that I still haven't quite figured out how it works.  psi strike and psi healing are the same as the monk's chi strike and chi healing.  See what I did there?  Changing "chi" to "psi"?  Brilliant.

Monk's techs:

XP Lvl 1: pummel, dash, chained blitz
XP Lvl 2: chi strike
XP Lvl 4: chi healing
XP Lvl 6: elemental fist
XP Lvl 8: draw energy, telekinesis
XP Lvl 10: ground slam
XP Lvl 11: ward fire
XP Lvl 13: ward cold
XP Lvl 15: ward electricity
XP Lvl 17: spirit bomb
XP Lvl 20: power surge

Psion's techs:
XP Lvl 1: pummel, dash
XP Lvl 2: psi strike
XP Lvl 4: psi healing
XP Lvl 6: elemental fist
XP Lvl 8: draw energy, telekinesis
XP Lvl 10: ground slam
XP Lvl 15: psychokinesis
XP Lvl 17: spirit bomb
XP Lvl 20: power surge

Telekinesis is taken from the Jedi patch.  I actually like the author's implementation.  With telekinesis, you can pick up objects from a short distance and you can interact with traps (disarm and trigger them).  Psychokinesis is different.  You'd be able to move a monster, item, or yourself from an arbitrary location (within a limited range) to an arbitrary location (within a limited range).  Another option would be, instead of moving the object to an arbitrary location, you would pick a direction in which to move it, though I prefer the former.  There is already code in place to handle "hurtling" monsters and yourself through the air.  Of course, they are in two different functions, hurtle and mhurtle, and I'd have to code a third to manage the hurtling of items through the air (ihurtle?).  I'd like to combine all three functions into one, because that would only make sense.  Anything with coordinates (i.e., a location on the map) should be able to be hurtled by the same function.

Moving on... so I want to be able to hurl monsters through the air.  I followed that thought to its logical conclusion, and decided that I should implement a system of picking up, and throwing, monsters.

Saturday, June 14, 2014

Out of retirement!

I had given up on writing a variant.  The usual excuses prevailed: work, the code is insane, I discovered Kerbal Space Program, etc, etc.  But, I'm taking a break from Kerbal Space Program because of an ATI graphics driver bug that has been driving me crazy.

But, I'm out of retirement!

I was in the middle of a solid game, playing as a female human rogue, and had stumbled across some very good luck: two magic lamps (both resulted in wishes), two bags of holding, etc, etc.

Then I ran into a bug that almost resulted in my character's death (by starvation).  I was very lucky to be saved by a puma's attack, and quickly #prayed (I was fainting at this point), killed the puma, then saved the game.

The main reason I was lucky about surviving is that I was able to save the game and copy the save file so I can reproduce the bug easily.  Whatever your feelings might be when it comes to copying nethack save files, I guarantee I'm more passionate about having solid test cases for bug reproduction and bug fix verification.

Anyway, a while back I blew away my Arch Linux installation because the folks over at Arch started doing crazy things that broke everything for me, so I switched to Debian.

I've never successfully built the nethack-3.4.3 code on any OS other than Arch and FreeBSD.  I'm running Debian now, and I can get the source with a simple apt-get source nethack, but unlike the OS's with ports trees, it doesn't come ready to rock.  I still have to figure out all the crazy config options and, traditionally, I get frustrated and give up before working through all the errors (please leave a comment if you have easy steps for compiling in Debian).

So I dusted off my old piece of junk $110 desktop computer (brilliant buy, I love this thing) that has FreeBSD installed and will work on the fix there.  Yes, I did actually have to dust it off, please don't make fun of me for that.  I'm updating the system now, and then I'll work on the fix.

Once I have a fix, I'll write up and post my root-cause analysis along with the patch and the saved game that triggered the bug so others can verify the fix.


Update: I figured out how to build nethack in Debian.

Sunday, July 21, 2013


Now that I'm sure everyone has stopped visiting this blog, I am back!  I was very busy for a while at work as we had a very important deadline approaching for a couple of months.  But that deadline was reached, and good news abounds!  My tiny little start-up was very recently acquired by the best possible company that could've acquired us.  Everybody's happy.

Now, back to nethack.  I haven't played in so long that I've forgotten a lot of the little nitty-gritty spoilers I used to know.  I once again have to look up specific prices of scrolls, potions, rings, etc.  Of course, I'll never forget that my three favorite rings, slow digestion, free action, and levitation (in that order), are all 200 Zk.  Regardless, I'll probably need a little ramp-up time to refamiliarize myself with the little details of the game, as well as the intricacies of the gameplay, before I can jump back into the code.

What's important to take away though, is that this blog is not dead.  It was just wearing an amulet of live saving (ugh, I know, awful joke.  I'm here all week).

Secondly, what's important to take away is that I finally finished my tourist game.  Tourist is one of the best roles in the game.  The early game is very difficult, but the quest artifact is arguably the best in the game, and the quest itself yields tons of loot.

One fun little stupid thing I like to do is chat with Death.  The background is that there are four Riders of the Apocalypse, explained in great depth in The Book of Revelation.  It's a great read, and if you haven't read it, it's probably one of those things you should read aloud to your children at bedtime.  In the words of my boy TJ (Thomas Jefferson), it is "merely the ravings of a maniac, no more worthy nor capable of explanation than the incoherences of our own nightly dreams."

On the Astral Plane, in nethack, you will find three of these Riders: Famine, Pestilence (also know as Conquest in the BoR), and Death.  If I am able, I always make a point to chat with Death, because he gives some insight into who the fourth Rider is:

This actually makes a lot of sense.  You spend the game going through a dungeon killing thousands of creatures.  I can't really think of a better definition of "war" than that.

Monday, April 22, 2013

Ugh.. more off topic

Oy, time has been short.  Exciting things are going on at the start-up I work for, so most of my efforts have been focused there.  I was able to do some brainstorming today about nethack stuff, so I'm excited to get back into nethack coding.

A quick rant, very off-topic:

I run Arch Linux on my home laptop.  It's an absolutely brilliant distribution.  Forever, I've loved everything about Linux.  When I gave FreeBSD a try, I was introduced to the ports tree, and quite frankly, it's the greatest thing existing in the field of operating systems.  On top of that, the rolling release model just made so much more sense than, for example, Ubuntu's "every six months whether it's broken or not" release model.

Anyway, a few months back, I discovered Arch Linux.  It had everything I could ever ask for in this world.  It ran a Linux kernel, but also had a ports tree, called the Arch Build System (ABS), as well as a rolling release model.  Fucking brilliant.

Gnome.  Underrated race in nethack, and also a perfect desktop environment for Linux/BSD.  I'd go as far as saying that Gnome2 is the Holy Arc of the Covenant of desktop environments.  Unfortunately, Gnome3 is the Treblinka of desktop environments.

No problem, though, because some clever folks forked Gnome2 and made MATE.  I've been running with MATE on Linux for a while now, and am lucky enough that Gnome2 is still supported in FreeBSD.

Things changed recently when I did a full system upgrade on my Arch box and installed MATE 1.6.  They got rid of the weather applet!!!  Granted, this could be Arch Linux specific (please comment and let me know if it is), or maybe I'm doing something wrong, but damn!  I loved that panel applet.

These days, UI innovation seems to revolve around "what can we remove?" rather than "what can we add?"  It's a fucking awful approach, because you lose users each time beloved features are removed, and with Linux, you rarely gain new users because people are somehow afraid of the best operating system currently in existence, thanks to FUD campaigns by various entities that view Linux as a rival... as they should, because technology that existed in the Linux kernel (and BSD kernel) 10 years ago is finally gracing OS's like Windows and OSX today (Hell, OSX took their kernel from BSD and Mach, because Apple realized they could not produce anything better).  10 years is a very long time when it comes to computer technology.

So, I've switched to Xfce 4.10 for the time being.  So far, I'm very happy with it.  The Xfce4 weather applet even has wind speed!  6mph in Allston, MA right now.

In other news, my (as my co-worker puts it) +1 Gauntlets of Coding arrived.  They're just wrist braces to combat carpal tunnel syndrome, but with my ergonomic keyboard and vertical mouse, carpal tunnel doesn't stand a chance.  The wrist braces were supposed to arrive last Friday, but when I saw the tracking info, they were listed as being in Watertown, MA, in the heat of the lockdown... no way in hell they would be delivered to me then.  I'm glad we got the younger brother/bomber alive.

Monday, April 15, 2013

Something else to remember on Patriots' Day

Patriots' Day is a holiday celebrated in Massachusetts to commemorate the anniversary of the Battles of Lexingon and Concord, to which my home town of Sudbury, MA, sent the most militia men out of any other city or town in the colonies.

Earlier today, multiple bombs went off in my city, near the finish line of the Boston Marathon.  I've been in touch with a couple of my friends and am trying to find out if the rest are okay.  

I was lucky enough to not have the day off from work, as most people did, so I was safe at work during the time of the explosions.  My thoughts go out to any and all affected by this horrific tragedy.