tag:blogger.com,1999:blog-83367890548644958472024-02-06T21:11:41.730-08:00"but all I got was this lousy T-shirt"Unknownnoreply@blogger.comBlogger22125tag:blogger.com,1999:blog-8336789054864495847.post-29362824735079847922018-05-01T12:26:00.002-07:002018-05-01T12:26:09.130-07:00goto considered awesomeSome people consider goto harmful. I don't.<br />
<br />
Most arguments I hear for why goto is bad have to do with code readability or that goto is inherently hack-ish. My response would be that those issues are due to the programmer, not the goto. I can write difficult to read hacks without using goto. If there are other reasons to not use goto, please feel free to comment on this post. <br />
<br />
<br />
First, I will start with a statement. If you think goto's should not be used, then get rid of your continue, break, and return statements too. Also get rid of switch, though the 1989 C standard oddly leaves that out (while also noting that "A switch statement casues control to jump...")<br />
<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">3.6.6 Jump statements</span><br />
<span style="font-family: "Courier New", Courier, monospace;"><br /></span>
<span style="font-family: "Courier New", Courier, monospace;">Syntax</span><br />
<span style="font-family: "Courier New", Courier, monospace;"><br /></span>
<span style="font-family: "Courier New", Courier, monospace;"> jump-statement:</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> goto identifier ;</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> continue ;</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> break ;</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> return expression<opt> ;</span><br />
<br />
<br />
I'm not sure if there's a term for using goto for error handling in C. Maybe "error unraveling", "error unrolling", "function unwinding"?<br />
<br />
From the Linux kernel coding style documentation (Documentation/process/coding-style.rst):<br />
Albeit deprecated by some people, the equivalent of the goto statement is<br />
used frequently by compilers in form of the unconditional jump instruction.<br />
<br />
<br />
<span style="font-family: "Courier New", Courier, monospace;">The goto statement comes in handy when a function exits from multiple</span><br />
<span style="font-family: "Courier New", Courier, monospace;">locations and some common work such as cleanup has to be done. If there is no</span><br />
<span style="font-family: "Courier New", Courier, monospace;">cleanup needed then just return directly.</span><br />
<span style="font-family: "Courier New", Courier, monospace;"><br /></span>
<span style="font-family: "Courier New", Courier, monospace;">The rationale for using gotos is:</span><br />
<span style="font-family: "Courier New", Courier, monospace;"><br /></span>
<span style="font-family: "Courier New", Courier, monospace;">- unconditional statements are easier to understand and follow</span><br />
<span style="font-family: "Courier New", Courier, monospace;">- nesting is reduced</span><br />
<span style="font-family: "Courier New", Courier, monospace;">- errors by not updating individual exit points when making</span><br />
<span style="font-family: "Courier New", Courier, monospace;"> modifications are prevented</span><br />
<span style="font-family: "Courier New", Courier, monospace;">- saves the compiler work to optimize redundant code away ;)</span><br />
<br />
<br />
Okay, so the first three rationales are good and the last is bonus for compiler writers I guess. (The nice thing about compiler writers, though, is that deep down inside, they know that regular programmers know more than they do). Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-26531830723345079272016-09-22T06:08:00.001-07:002018-04-04T05:16:09.766-07:00WoundingSo, 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.<br />
<br />
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 <span style="font-family: "courier new" , "courier" , monospace;">#define WOUNDING</span> to includ/config.h and you should be good to go.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">greg@viper:~/src/SlashTHEM$ git diff<span style="font-family: "courier new" , "courier" , monospace;"> </span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="font-family: "courier new" , "courier" , monospace;">diff --git a/include/artilist.h b/include/artilist.h<br />index 172a20f..522a74b 100644<br />--- a/include/artilist.h<br />+++ b/include/artilist.h<br />@@ -28,6 +28,9 @@ static const char *artifact_names[] = {<br /> #define ELEC(a,b) {0,AD_ELEC,a,b} /* electrical shock */<br /> #define STUN(a,b) {0,AD_STUN,a,b} /* magical attack */<br /> #define ACID(a,b) {0,AD_ACID,a,b}<br />+#ifdef WOUNDING<br />+#define WOUN(a,b) {0,AD_WOUN,a,b}<br />+#endif<br /><br /> STATIC_OVL NEARDATA struct artifact artilist[] = {<br /> #endif /* MAKEDEFS_C */<br />@@ -355,7 +358,11 @@ A("Cat's Claw", DAGGER,<br /> (SPFX_RESTR|SPFX_DCLAS), 0, S_RODENT,<br /> PHYS(5,7), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 1000L ),<br /> #endif /* NEWHON_ARTIFACTS */<br />-<br />+#ifdef WOUNDING<br />+A("Nightblood", LONG_SWORD,<br />+ (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), 0, 0,<br />+ WOUN(5, 10), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, NON_PM, 4000L),<br />+#endif<br /> #ifdef TOURIST<br /> A("Whisperfeet", SPEED_BOOTS,<br /> (SPFX_RESTR|SPFX_STLTH|SPFX_LUCK), 0, 0,<br />@@ -898,6 +905,9 @@ A(0, 0, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L )<br /> #undef FIRE<br /> #undef ELEC<br /> #undef STUN<br />+#ifdef WOUNDING<br />+#undef WOUN<br />+#endif /* WOUNDING */<br /> #endif<br /><br /> /*artilist.h*/<br />diff --git a/include/attk.h b/include/attk.h<br />index a52a9ce..9f11570 100644<br />--- a/include/attk.h<br />+++ b/include/attk.h<br />@@ -141,7 +141,12 @@ extern char *attk_dname(Attk);<br /> #define AD_POLY 43 /* RJ -- polymorphs (genetic engineer) */<br /> #define AD_CORR 44 /* corrode armor (black pudding) */<br /> #define AD_TCKL 45 /* Tickle (Nightgaunts) */<br />-#define AD_ENDS 46 /* placeholder */<br />+#ifdef WOUNDING<br />+ #define AD_WOUN 46 /* Wounding attack */<br />+ #define AD_ENDS 47 /* placeholder */<br />+#else<br />+ #define AD_ENDS 46 /* placeholder */<br />+#endif<br /><br /> #define AD_CLRC 240 /* random clerical spell */<br /> #define AD_SPEL 241 /* random magic spell */<br />diff --git a/include/config.h b/include/config.h<br />index 1655897..1febcf7 100644<br />--- a/include/config.h<br />+++ b/include/config.h<br />@@ -435,6 +435,10 @@ typedef unsigned char uchar;<br /> #define WALLET_O_P /* Perseus' Wallet, and all related code (tsanth@iname.com)*/<br /> #define LIGHTSABERS<br /> #define JEDI<br />+<br />+/* Wounding and Nightblood features */<br />+#define WOUNDING<br />+<br /> #define NWAR<br /> #define CONVICT /* Convict player with heavy iron ball */<br /> #ifdef LIGHTSABERS<br />diff --git a/include/monattk.h b/include/monattk.h<br />index fd440cd..5ca8414 100644<br />--- a/include/monattk.h<br />+++ b/include/monattk.h<br />@@ -90,7 +90,12 @@<br /> #define AD_DARK 48 /* acts similar to cursed scroll of light, making an area unlit */<br /> #define AD_WTHR 49 /* withers items */<br /> #define AD_LUCK 50 /* reduces luck */<br />-#define AD_ENDS 51 /* placeholder */<br />+#ifdef WOUNDING<br />+ #define AD_WOUN 51<br />+ #define AD_ENDS 52<br />+#else<br />+ #define AD_ENDS 51 /* placeholder */<br />+#endif<br /><br /> #define AD_CLRC 240 /* random clerical spell */<br /> #define AD_SPEL 241 /* random magic spell */<br />diff --git a/include/monst.h b/include/monst.h<br />index 86ac201..68fb06c 100644<br />--- a/include/monst.h<br />+++ b/include/monst.h<br />@@ -139,6 +139,9 @@ struct monst {<br /> long mlstmv; /* for catching up with lost time */<br /> #ifndef GOLDOBJ<br /> long mgold;<br />+#endif<br />+#ifdef WOUNDING<br />+ long wounding;<br /> #endif<br /> struct obj *minvent;<br /><br />diff --git a/src/artifact.c b/src/artifact.c<br />index 69b0add..d37b396 100644<br />--- a/src/artifact.c<br />+++ b/src/artifact.c<br />@@ -1281,6 +1281,18 @@ int dieroll; /* needed for Magicbane and vorpal blades */<br /> return Mb_hit(magr, mdef, otmp, dmgptr, dieroll, vis, hittee);<br /> }<br /><br />+#ifdef WOUNDING<br />+ if (attacks(AD_WOUN, otmp)) {<br />+ if (realizes_damage) {<br />+ if (rnd(5)==1) {<br />+ mdef->wounding += rnd(10);<br />+ pline_The("sharp blade wounds %s.", hittee);<br />+ }<br />+ }<br />+ return realizes_damage;<br />+ }<br />+#endif<br />+<br /> if (!spec_dbon_applies && !spec_ability(otmp, SPFX_BEHEAD) ||<br /> !special_applies) {<br /> /* since damage bonus didn't apply, nothing more to do; <br />diff --git a/src/mon.c b/src/mon.c<br />index 1bb6a87..36c2fa2 100644<br />--- a/src/mon.c<br />+++ b/src/mon.c<br />@@ -808,6 +808,18 @@ mcalcdistress()<br /> struct monst *mtmp;<br /><br /> for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {<br />+<br />+#ifdef WOUNDING<br />+ if (mtmp->wounding) {<br />+ mtmp->mhp -= rnd(mtmp->wounding);<br />+ if (mtmp->mhp < 1) {<br />+ pline_The("%s dies from its wounds.", Monnam(mtmp));<br />+ mon_xkilled(mtmp, NULL, AD_WOUN);<br />+ } else {<br />+ pline_The("%s suffers from its wounds.", Monnam(mtmp));<br />+ }<br />+ }<br />+#endif<br /> if (DEADMONSTER(mtmp)) continue;<br /><br /> /* must check non-moving monsters once/turn in case<br />diff --git a/src/monmove.c b/src/monmove.c<br />index a6d1d32..ec22bf8 100644<br />--- a/src/monmove.c<br />+++ b/src/monmove.c<br />@@ -858,6 +858,19 @@ register int after;<br /> if(i == 1) return(0); /* still in trap, so didn't move */<br /> }<br /><br />+#ifdef WOUNDING<br />+ if (mtmp->wounding) {<br />+ mtmp->mhp -= rnd(mtmp->wounding);<br />+ if (mtmp->mhp < 1) {<br />+ pline_The("%s dies from its wounds.", Monnam(mtmp));<br />+ return 2;<br />+ } else {<br />+ pline_The("%s suffers from its wounds.", Monnam(mtmp));<br />+ return 1;<br />+ }<br />+ }<br />+#endif<br />+<br /> ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */<br /><br /> if (mtmp->meating) {</span></span>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-8336789054864495847.post-31249451730189076922016-09-20T06:48:00.004-07:002016-09-20T07:02:00.860-07:00"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.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaHPbDmJ9qF_PEoOHO9I-nmWkReP3H3JKj61UXsi-x6pBZibzLdcriJ11gzrGFVSleZrK2HmNIYQUzSDbolMYhwB8fTnWqc6VVspws60vXjlKOgC6YOxTZ-3EVFiwa88nnAofe6gDGNlfV/s1600/slashem-wounding1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="435" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaHPbDmJ9qF_PEoOHO9I-nmWkReP3H3JKj61UXsi-x6pBZibzLdcriJ11gzrGFVSleZrK2HmNIYQUzSDbolMYhwB8fTnWqc6VVspws60vXjlKOgC6YOxTZ-3EVFiwa88nnAofe6gDGNlfV/s640/slashem-wounding1.png" width="640" /></a></div>
<br />
<br />
What good is wounding without a nice artifact to carry out the message? I've added Nightblood, a chaotic long sword that can wound.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhotVBoRGS6K1j45xb3WFl4FqhTRRjrfGPppe3DTE_IwUpUUZQ6UwQhZELGbUt3SlfrPIytMTBmcZLFE7_tCcdkr8y9fZIdFso_oqWVA38pmuMwuTSRszfqG2r2VgTTxBC72wsgg4AlvQNy/s1600/slashem_wounding2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="436" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhotVBoRGS6K1j45xb3WFl4FqhTRRjrfGPppe3DTE_IwUpUUZQ6UwQhZELGbUt3SlfrPIytMTBmcZLFE7_tCcdkr8y9fZIdFso_oqWVA38pmuMwuTSRszfqG2r2VgTTxBC72wsgg4AlvQNy/s640/slashem_wounding2.png" width="640" /></a></div>
<br />
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.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-12638031721236977912016-09-15T08:14:00.000-07:002016-09-15T08:14:01.587-07:00Starting to get back into itI 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.<br />
<br />
Fortunately, this who process was as simple as running <span style="font-family: "Courier New",Courier,monospace;">indent -nut -kr</span> 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!).<br />
<br />
You can clone the SlashTHEM git repository here: <a href="https://github.com/Soviet5lo/SlashTHEM">https://github.com/Soviet5lo/SlashTHEM</a><br />
<br />
Then just download and apply my patch to fix all the indentation to use indentation of four spaces per indentation level: <a href="https://drive.google.com/open?id=0B7oiSGh7Lg0lWEJKVmRwQzlHN0E">https://drive.google.com/open?id=0B7oiSGh7Lg0lWEJKVmRwQzlHN0E</a><br />
<br />
Enjoy.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-17850304945547210762014-09-20T12:35:00.001-07:002014-09-20T12:35:37.267-07:00jediSince 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.<br />
<br />
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:<br />
<br />
Monk in Nethack:<br />
XP Lvl 1: speed, sleep resistance, see invisible<br />
XP Lvl 3: poison resistance<br />
XP Lvl 5: stealth<br />
XP Lvl 7: warning<br />
XP Lvl 9: searching<br />
XP Lvl 11: fire resistance<br />
XP Lvl 13: cold resistance<br />
XP Lvl 15: shock resistance<br />
XP Lvl 17: teleport control.<br />
<br />
Note that, in slashem, fire, cold, and shock resistances are now techniques, not intrinsics.<br />
<br />
Psion in greghack:<br />
XP Lvl 1: intrinsic telepathy (like you get from eating a floating eye corpse)<br />
XP Lvl 3: see invisible<br />
XP Lvl 5: extrinsic telepathy (like you get from wearing an amulet or helm of ESP)<br />
XP Lvl 10: flying<br />
XP Lvl 15: detect monsters (like the blessed potion, but always on)<br />
<br />
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.<br />
<br />
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.<br />
<br />
Monk's techs:<br />
<br />
XP Lvl 1: pummel, dash, chained blitz<br />
XP Lvl 2: chi strike<br />
XP Lvl 4: chi healing<br />
XP Lvl 6: elemental fist<br />
XP Lvl 8: draw energy, telekinesis<br />
XP Lvl 10: ground slam<br />
XP Lvl 11: ward fire<br />
XP Lvl 13: ward cold<br />
XP Lvl 15: ward electricity<br />
XP Lvl 17: spirit bomb<br />
XP Lvl 20: power surge<br />
<div>
<br /></div>
<br />
<br />
Psion's techs:<br />
XP Lvl 1: pummel, dash<br />
XP Lvl 2: psi strike<br />
XP Lvl 4: psi healing<br />
XP Lvl 6: elemental fist<br />
XP Lvl 8: draw energy, telekinesis<br />
XP Lvl 10: ground slam<br />
XP Lvl 15: psychokinesis<br />
XP Lvl 17: spirit bomb<br />
XP Lvl 20: power surge<br />
<br />
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, <span style="font-family: Courier New, Courier, monospace;">hurtle</span> and <span style="font-family: Courier New, Courier, monospace;">mhurtle</span>, and I'd have to code a third to manage the hurtling of items through the air (<span style="font-family: Courier New, Courier, monospace;">ihurtle</span>?). 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.<br />
<br />
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.<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-11562529709081124792014-06-14T18:18:00.001-07:002014-06-14T19:11:20.484-07:00Out 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.<br />
<br />
But, I'm out of retirement!<br />
<br />
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. <br />
<br />
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 <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">#pray</span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">ed</span> (I was fainting at this point), killed the puma, then saved the game.<br />
<br />
<br />
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.<br />
<div>
<br /></div>
<div>
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.</div>
<div>
<br /></div>
<div>
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 <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">apt-get source nethack</span>, 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).<br />
<br />
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.<br />
<br />
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.<br />
<br />
--------------------------<br />
<br />
Update: I figured out how to build nethack in Debian. </div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-21696421423875145872013-07-21T10:31:00.000-07:002013-07-21T10:31:02.703-07:00GAHHH_NEW_POST!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.<br />
<br />
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.<br />
<br />
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).<br />
<br />
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.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
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."<br />
<br />
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:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqdg7N7waJQfaILc9jhum4SrhqqASzWayqv3CWMONhGe8jbeyEigL5npwBpG0BOnRwKAjMaSgpRKhIj0rzMHncS3K0Vyllmx_cEVFkEJqTctN8yGCpODrhyphenhyphenpKhTGBtL_436ETLqGEwL4xB/s1600/nethack_tourist_death.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqdg7N7waJQfaILc9jhum4SrhqqASzWayqv3CWMONhGe8jbeyEigL5npwBpG0BOnRwKAjMaSgpRKhIj0rzMHncS3K0Vyllmx_cEVFkEJqTctN8yGCpODrhyphenhyphenpKhTGBtL_436ETLqGEwL4xB/s640/nethack_tourist_death.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
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.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZPNH1SD_QOGeEkqDGcWXggNhzwYQ4KvRykywCPYmgKc2IuzFPYq-1KMcvd5RsMXHh1emCo9by9ZOvdG2SWQE_tdfXLzPGwaFG2aiF6zxY7eIMXGAwg7f5deTUim90bTrci3DfMSAJtdwB/s1600/nethack_tourist_offer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZPNH1SD_QOGeEkqDGcWXggNhzwYQ4KvRykywCPYmgKc2IuzFPYq-1KMcvd5RsMXHh1emCo9by9ZOvdG2SWQE_tdfXLzPGwaFG2aiF6zxY7eIMXGAwg7f5deTUim90bTrci3DfMSAJtdwB/s640/nethack_tourist_offer.png" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGJ4G3AmYHwzke2gfVU783DnQ36vUUmat_FgjupH4TC3pqg9H_RocxDIiue034O8Nk7uQ0u2_Bn987e4Dn3c2qMP4bIDWZoN9A4HHrV8Y272YbE2up8k8bTzZj2zXMeB7prDln5_JpbuD1/s1600/nethack_tourist_bathed.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGJ4G3AmYHwzke2gfVU783DnQ36vUUmat_FgjupH4TC3pqg9H_RocxDIiue034O8Nk7uQ0u2_Bn987e4Dn3c2qMP4bIDWZoN9A4HHrV8Y272YbE2up8k8bTzZj2zXMeB7prDln5_JpbuD1/s640/nethack_tourist_bathed.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiem_UNRrCfiDH4hFpdl6qsUzM7uEwZ3BEK4K3cQZamNRgBSOTVbGwI-UbjBVlFYd1XrfE7RQHZN2KyUUUS-ueXgLeBdNPmXQT_SZp8il1ZFL9T-ylbi4ca5Q_vaguSzOAUMt93irgC4vgW/s1600/nethack_tourist_congrats.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiem_UNRrCfiDH4hFpdl6qsUzM7uEwZ3BEK4K3cQZamNRgBSOTVbGwI-UbjBVlFYd1XrfE7RQHZN2KyUUUS-ueXgLeBdNPmXQT_SZp8il1ZFL9T-ylbi4ca5Q_vaguSzOAUMt93irgC4vgW/s640/nethack_tourist_congrats.png" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuC9QVBi9V2VZf5wJtUkAFKG4y15X77RNgofa4VRAyKih9OkQw8qZU-pyT78BXWsgQMuHC9-8FrSUtcaiMmQ_sskJA12lXA-k0-7d0ibZGCfaKc44XoKAh0ylpHEvKcrmzNaF5Rd5MJeXx/s1600/nethack_tourist_grant.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuC9QVBi9V2VZf5wJtUkAFKG4y15X77RNgofa4VRAyKih9OkQw8qZU-pyT78BXWsgQMuHC9-8FrSUtcaiMmQ_sskJA12lXA-k0-7d0ibZGCfaKc44XoKAh0ylpHEvKcrmzNaF5Rd5MJeXx/s640/nethack_tourist_grant.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJTxN3l_Ni_QMZhX_Kfuo7V3OQNK94V4vcE9685-K8m-Wb8UVrca6Ul2DwC0eomTWZVvPY0qMwgZLttHG-d5hJ8Ah6pICEBKczedT5ikKoz3RXCcda0I_xKrhX_b6EoB9-K_edTFQLq9SJ/s1600/nethack_tourist_ascend.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="430" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJTxN3l_Ni_QMZhX_Kfuo7V3OQNK94V4vcE9685-K8m-Wb8UVrca6Ul2DwC0eomTWZVvPY0qMwgZLttHG-d5hJ8Ah6pICEBKczedT5ikKoz3RXCcda0I_xKrhX_b6EoB9-K_edTFQLq9SJ/s640/nethack_tourist_ascend.png" width="640" /></a></div>
<br />Unknownnoreply@blogger.com14tag:blogger.com,1999:blog-8336789054864495847.post-26277140285158740902013-04-10T11:47:00.002-07:002013-04-10T11:47:19.053-07:00busy busy busySorry, updates are going to be slow for a little while. My company is in crunch mode for our next release, so I'm just writing to let y'all know, I haven't abandoned the blog, or my variant. I haven't abandoned nethack either, even though I haven't played my awesome tourist game in ages. The PYEC is such a good artifact.<br />
<br />
In the meantime, my mouse's wheel click has started pasting text when it opens links in new windows, as opposed to before when it would open links in new tabs without pasting. All my searching so far has told me that is default functionality in X, and unless I want to hack X (a possibility...), I'm going to have to deal with it.<br />
<br />
I wonder why it didn't paste before? It doesn't on my Arch Linux system, which is running X, just on my Linux Mint system. Maybe some update got me. The nice thing about minimalist distributions is that they don't get cluttered with unwanted stuff.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-76666209128931659562013-03-27T09:27:00.004-07:002013-03-27T09:27:51.962-07:00Next StepsI've been slow to update recently, since my company is releasing a new version of its software at the end of the week...<br />
<br />
But! My next step is to merge <span style="font-family: Courier New, Courier, monospace;">struct you</span> with <span style="font-family: Courier New, Courier, monospace;">struct monst</span>, or rather, take out redundant data, like location, alignment, intrinsics, etc, etc, etc, etc, etc. I want to treat monsters and the player more equally, though I realize there will be some things that are specific to <span style="font-family: Courier New, Courier, monospace;">struct you</span>. the game has a global <span style="font-family: Courier New, Courier, monospace;">struct you u</span>, and a global <span style="font-family: Courier New, Courier, monospace;">struct monst youmonst</span><span style="font-family: inherit;">,</span> and in some cases, it seems arbitrary which one is used.<br />
<br />
<br />
On an completely unrelated note, I stumbled across this gem the other day on one of those 'horrors of coding' sites:<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> static boolean isTrue(boolean b) { </span><br />
<span style="font-family: Courier New, Courier, monospace;"> HashMap map = new HashMap();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> b = ! !b;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (!(!(b == !b)) == false) {</span><br />
<span style="font-family: Courier New, Courier, monospace;"> map.put(false, !(!(b != !b)));</span><br />
<span style="font-family: Courier New, Courier, monospace;"> } </span><br />
<span style="font-family: Courier New, Courier, monospace;"> return !map.containsKey(b) & (!true | !false);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: inherit;">I believe this is Java code. It may also work in JavaScript but, fortunately, I'm not familiar with JS. It may be the most amazing piece of code I've ever seen, maybe even better than </span><span style="font-family: Courier New, Courier, monospace;">x[strlen(x)] = '\0';</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-8336789054864495847.post-6293658222102054252013-03-22T14:54:00.003-07:002013-03-22T15:06:52.717-07:00sporkhackI was inspired by the subject line of a co-worker's email: "+1 Gauntlets of Coding". It was just an email with a link to wrist braces for carpal tunnel syndrome, but I really like the sound of Gauntlets of Coding. I_have a couple ideas: when wearing Gauntlets of Coding, you movement speed will increase only when using the travel command. Or, it gives you jumping. Both are pretty big stretches at puns about using goto statements to either travel faster, or jump through code... yeah... I'll probably make Gauntlets of Coding a compile-time option, defaulting to not include them.<br />
<br />
Moving on...<br />
<br />
Sporkhack! I've been spending more time playing sporkhack, and I have to say, what a fucking brilliant game. So many changes. From partial resistances, to sacrifice gifts based on XP level, to chaotic Knights, to variable telepathy range, to new items like gold dragon armor, shield of light, Dirge, etc... fucking brilliant. <br />
<br />
Where some variants put a lot of effort into nice ncurses interfaces, sporkhack is all about gameplay. I'm seriously considering ditching the slashem source as my code base for my variant and starting with sporkhack instead, since there are just too many features from sporkhack that I like, and most of them are the bag of poo:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnnZLxUFXwJMimVtynTklII7V3hnlx_5HaeVrnmMjC9goqI6rrzdpyiZWWcihdf-_H1vM0dUkGMZRPDBQlhmLdstAr6SPdvODoJSFlDAWeKtwYxvfTjMFBKo0o3d6D_cjVxVXeE6QSCd_9/s1600/sporkhack_poo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="412" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnnZLxUFXwJMimVtynTklII7V3hnlx_5HaeVrnmMjC9goqI6rrzdpyiZWWcihdf-_H1vM0dUkGMZRPDBQlhmLdstAr6SPdvODoJSFlDAWeKtwYxvfTjMFBKo0o3d6D_cjVxVXeE6QSCd_9/s640/sporkhack_poo.png" width="640" /></a></div>
<br />
<br />
I do have two gripes about sporkhack, and they are very, very minor. One, I don't like the new character creation screen. When I start a new nethack game, I know what I want to play as, so I just run: <span style="font-family: Courier New, Courier, monospace;">$ nethack -u greg-rog-hum-fem</span> for example, and the game starts. Even if you do that in sporkhack, you still get taken to this screen:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSalXd1BsMmPFHgeJn-A0ft2HSLLfsVGDz7GDEg8SRJmANMnZZJMtcKHnbdSJImIPnCinkCOJbKdr6IgvWj7q5vbPEZJxZ6Nr_9hhSV_7dO0t6UsQX4HgOCfcbtHWInl1_Gap0-wpBAp_y/s1600/sporkhack_char.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSalXd1BsMmPFHgeJn-A0ft2HSLLfsVGDz7GDEg8SRJmANMnZZJMtcKHnbdSJImIPnCinkCOJbKdr6IgvWj7q5vbPEZJxZ6Nr_9hhSV_7dO0t6UsQX4HgOCfcbtHWInl1_Gap0-wpBAp_y/s640/sporkhack_char.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
So you have to press "." to start playing. I realize how this starting screen can be helpful to new players, since it lets you know what combinations of role, race, and alignment are allowed, but I guess I'm just old and stubborn and like the vanilla nethack character creation system better. Also, I sometimes run into a bug where, when starting a new game, I get stuck in a corner with no map. I even tried starting as an archaeologist to see if I could dig my way out, but no dice:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0IZtSeKuOx_rwy7wF35TydQiyZeDqk5REHAqtLy783k19pSQ8fpLqKigRH-H6SzrK4mbhBqaz_UI1VB3LWjdN0gMNYj21rEgvB_sp2Fb7HDS85CsexUOkiybCeourvaZiMDwzWDLmLz0n/s1600/sporkhack_bug2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0IZtSeKuOx_rwy7wF35TydQiyZeDqk5REHAqtLy783k19pSQ8fpLqKigRH-H6SzrK4mbhBqaz_UI1VB3LWjdN0gMNYj21rEgvB_sp2Fb7HDS85CsexUOkiybCeourvaZiMDwzWDLmLz0n/s640/sporkhack_bug2.png" width="640" /></a></div>
<br />
<br />
<br />
Has anyone else run into this? I'm using the sporkhack-svn package from the Arch User Repository, so it's possible that this bug is specific to that code.<br />
<br />
...<br />
<br />
When it comes to debugging, my strategy revolves entirely around <span style="font-family: Courier New, Courier, monospace;">printk </span><span style="font-family: inherit;">(</span><span style="font-family: Courier New, Courier, monospace;">printf</span><span style="font-family: inherit;"> if I'm in userland)</span>. I don't use gdb because I don't know how. I've always wanted to learn... but it just seems too daunting of an exercise. Sometimes I'll resort to objdump or readelf in a bind, but mostly, I just print out whatever things I'm curious about. <br />
<br />
Is there a good way to dump debugging messages in nethack, other than using the <span style="font-family: Courier New, Courier, monospace;">pline</span> function? If not, I'll write a patch that will log debug messages to a log file. Then anyone could just call something like <span style="font-family: Courier New, Courier, monospace;">nh_trace( LOG_WARNING, "blah blah blah %s, blah %d", ... )</span> instead of using <span style="font-family: Courier New, Courier, monospace;">pline</span>, which interferes with gameplay.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-31070589568084827542013-03-19T12:29:00.003-07:002013-03-20T11:34:23.609-07:00Girl Power!Who doesn't love numbers? Well, sadly most people, and yet they still remain the best way of measuring things. Go figure.<br />
<br />
Special thanks to NetHack 4's maintainer, ais523, for the data.<br />
<br />
These numbers do not include games that were started but never finished. The player either had to die, ascend, die, quit, die, escape, die, or be killed. There were 2788 games in total.<br />
<br />
First, let's look at starting role vs. max xp level:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKrEBix7jdYUxbKalK77_n5handMP8lXwpzvS56rgE777dRH1dCo9GsDyYcKiwmM4wTS-ZE45M5-51iwNZaqhDRoTgBNogyyRDQ8xP_pntp5C2CaaRMjTZBgfruI1Aky7DZyCFYhT9s1cp/s1600/nethack4_rolexp.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="446" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKrEBix7jdYUxbKalK77_n5handMP8lXwpzvS56rgE777dRH1dCo9GsDyYcKiwmM4wTS-ZE45M5-51iwNZaqhDRoTgBNogyyRDQ8xP_pntp5C2CaaRMjTZBgfruI1Aky7DZyCFYhT9s1cp/s640/nethack4_rolexp.png" width="640" /></a></div>
<br />
Okay, nothing too surprising here. Valkyrie remains a solid choice. Wizard has a tough early game but can become very powerful in the mid and endgame. Tourist did remarkably well, meaning there are quite a few badass NH4 players out there.<br />
<br />
One thing I'd really like to point out is that the Monk dominates the early game. Lots of people dump on the monk, I don't know why, because they're not bad. Only drawback, of course, is that they can't wear Gray or Silver Dragon Scale Mail unless at a high enough level to get over the big to-hit penalty.<br />
<br />
Role vs. points is pretty similar, no surprise there, so I won't bother with the graph. How about ascensions by role?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid-WIned2HuFOo7zYYwr904SSTyu2u-4uxMk2X3P3f2SYXRFGMiWxtDF10480DZtiObxGosRliUlgqX1eHOyXs5zXQ74jpbQrobHhMaJ6EF1bh6ChAW7-X4BSnKYyVPiqPbrD9JhGAkxLd/s1600/nethack4_winsrole.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="468" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid-WIned2HuFOo7zYYwr904SSTyu2u-4uxMk2X3P3f2SYXRFGMiWxtDF10480DZtiObxGosRliUlgqX1eHOyXs5zXQ74jpbQrobHhMaJ6EF1bh6ChAW7-X4BSnKYyVPiqPbrD9JhGAkxLd/s640/nethack4_winsrole.png" width="640" /></a></div>
<br />
Once again Valkyrie, Wizard, and Tourist take the lead! More importantly, I'd like to see role popularity, because that will clearly affect the number of per-role ascensions. (Thanks to the HockeyblogAdventure for pointing out the typo in the below graph title. I'll maybe fix it when I get home from work).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRWluOHW35uqdSL5QlGjN9UNyA1hHZsPWUgjsZEZz5WJ0DrDhOr5FovpI9olNPQSJX5iXZRF_jz3g12atGajk4TU2ZJ8v8O57jbWWBbj17RZjZyDiSCW0PMy1VXYBTQ6t7VAZ5WYq55mol/s1600/nethack4_rolepop.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRWluOHW35uqdSL5QlGjN9UNyA1hHZsPWUgjsZEZz5WJ0DrDhOr5FovpI9olNPQSJX5iXZRF_jz3g12atGajk4TU2ZJ8v8O57jbWWBbj17RZjZyDiSCW0PMy1VXYBTQ6t7VAZ5WYq55mol/s640/nethack4_rolepop.png" width="640" /></a></div>
This confirms one of my theories about Barbarians: they're boring to play. Wizards are always interesting, though it's sad to see a lack of love for my favorite role, the Rogue. It also confirms that Valkyries are strong role. They are relatively unpopular (perhaps because they are so strong) yet have the most ascensions.<br />
<br />
Also interestingly, people prefer to play Male characters, but Females have more wins. Only ~24% of the players used female characters, but they accounted for ~64% of the ascensions:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6XIKj4jP85QLTi_buJjQIWwQ1wzaP8i9VamjRIQEFuW_92xkC2qDfya_SMOLcdfdpGeLaeDbXztKQIrdJamHtpu9wFtJgUZHAa3a36ov6n76GXdoi-mHhDHRlHWPn3bmfuZ-e-NNoCaf3/s1600/nethack4_gender.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="433" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6XIKj4jP85QLTi_buJjQIWwQ1wzaP8i9VamjRIQEFuW_92xkC2qDfya_SMOLcdfdpGeLaeDbXztKQIrdJamHtpu9wFtJgUZHAa3a36ov6n76GXdoi-mHhDHRlHWPn3bmfuZ-e-NNoCaf3/s640/nethack4_gender.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
I usually play female characters because I figure that if I polymorph into an egg-laying monster, like a dragon or cockatrice, I can make myself lots of awesome pets. On the other hand, if an egg hatches in a male character's inventory, there's a 50% chance of it being tame. On one hand, I don't use the egg-laying trick in most games, but on the other hand, when I do use the trick, I get lots and lots of pets out of it. I'm curious what other peoples' preferences are. <br />
<br />
Anyway, this post was just about some fun with numbers. Let me know if there are any other interesting or more complicated stats you want to see. I use the R project for a stats program, and it is superb. Here are the fields with which I have to work:<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">"points" "deathdnum" "deathlev" "maxlev" "hp"</span><br />
<span style="font-family: Courier New, Courier, monospace;">"maxhp" </span><span style="font-family: 'Courier New', Courier, monospace;">"deaths" "deathdate" "birthdate" "uid"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">"role" "race" </span><span style="font-family: 'Courier New', Courier, monospace;">"gender" "align" "name"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">"charname" "death" "conduct" </span><span style="font-family: 'Courier New', Courier, monospace;">"turns" "event"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">"carried" "starttime" "endtime" "gender0" </span><span style="font-family: 'Courier New', Courier, monospace;">"align0"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">"xplevel" "exp" "mode"</span><br />
<br />
<br />
Also let me know if there are questions about what the fields mean. I think the most confusing one might be <span style="font-family: Courier New, Courier, monospace;">align0</span> and <span style="font-family: Courier New, Courier, monospace;">gender0</span> which refer to starting alignment and gender, where as <span style="font-family: Courier New, Courier, monospace;">align</span> and <span style="font-family: Courier New, Courier, monospace;">gender</span> refer to alignment and gender at the game's end. I don't know what the <span style="font-family: Courier New, Courier, monospace;">event</span> field is.Unknownnoreply@blogger.com7tag:blogger.com,1999:blog-8336789054864495847.post-57818043529883596422013-03-14T15:02:00.001-07:002013-03-14T16:09:06.352-07:00code restructuring, againI applied the CK patch my kernel last night to give the Brain Fuck Scheduler and Budget Sector Queue I/O scheduler a try. I'm more interested in the I/O scheduler since disk access is much slower than context switching, though in <i>theory</i>, BFS should give me ~2% better performance... 2%... yay! Also, I know more about storage than CPU architecture, so I have a better idea about what's going on. I gotta say though, I'm impressed with how quickly BFQ hits my external drive.<br />
<br />
Moving on...<br />
<br />
It's a sad day in Boston. The Pats traded Wes Welker. Everyone's pissed.<br />
<br />
Moving on...<br />
<br />
I came up with a better way to do code restructuring. First, techniques can stay in their crazy switch block. You can only do one technique at a time anyway, so there's no point in using function pointer madness. However, none should return inside their case, rather, they should just break out instead and a single return will be placed at the end of the function. Each should also specify their own timeouts. Some do, some use the timeout at the end, some don't even have timeouts:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnp-yhsrqM6tc3etfptED_Tv8Rx7SWbRlEkTDNZXJI_m9_GVQDcnmfmUjWwWc6gPGfEzMyDH55TO8uFql2IGDjnc16C1oTwEQ7Jd8HcmAmoSOrbGj0lRn3eL69rySdu3cVoEN8SkVPmmHl/s1600/sigil_tempest.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnp-yhsrqM6tc3etfptED_Tv8Rx7SWbRlEkTDNZXJI_m9_GVQDcnmfmUjWwWc6gPGfEzMyDH55TO8uFql2IGDjnc16C1oTwEQ7Jd8HcmAmoSOrbGj0lRn3eL69rySdu3cVoEN8SkVPmmHl/s640/sigil_tempest.png" width="640" /></a></div>
<br />
<br />
This is true of techniques and magical effects in general. Being effects, all they do is modify data, so they can return void. If it matters whether you succeeded or not, you can always check the condition after it returns. Instead of linked lists for weapon effects, it will just be a dynamically sized array of effects, and I can loop over the switch blocks and apply each effect in turn.Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-8336789054864495847.post-33114088316026881952013-03-12T12:17:00.002-07:002013-03-12T12:17:43.282-07:00random thoughtsI haven't had much time lately between a Bruins double header that started last night and heading up to VT to ski last weekend. By the way, don't get stuck in chest deep powder, it fucking sucks.<br />
<br />
Anyway, some ideas:<br />
- Weapons dipped in potions of sleep have a chance of putting a non-sleep resistant monster to sleep on a hit.<br />
- Weapons dipped in potions of acid do some acid damage on a hit.<br />
- Weapons dipped in potions of paralyze have a chance of paralyzing a monster for a random, short duration on a hit.<br />
- I'm sure there are some other cases.<br />
<br />
- Lenses of Infravision<br />
- Sunglasses (Lenses of Shade?) that would protect against blinding light-based attacks, and maybe give you +1 charisma when worn because they are so cool.<br />
- Artifact lenses that give you some sort of gaze attack when invoked at the cost of some magic power.<br />
<br />
- Shields of fire, ice, acid, whatever, from sporkhack, have a chance of doing passive damage to a monster if the monster does not hit you and you get the message that you deflected the attack with your shield.<br />
<br />
Soldier role:<br />
<br />
Soldiers can reach expert in firearms, saber, and maybe skilled in long sword and a few other weapons. They would start with a pistol, as well as typical soldier gear: low boots, leather gloves, saber, dented pot, leather armor, tin whistle, and a few K or C rations. <br />
<br />
I can't think of a good first sacrifice gift. I don't just want to make it a gun because you'll have plenty of opportunities to pick up a gun later. Maybe a magic magazine, base item bag, that generates a random number of bullets when invoked... but then again, you also have plenty of opportunities to pick up bullets throughout the game. Maybe a special gun, a Magnum, base item pistol, that does more damage than a pistol and has a chance of stunning and/or knocking back an opponent like a monk's stunning strike.<br />
<br />
The quest artifact would be The Holy Hand Grenade, generated blessed (since it's Holy), and the base item is a stick of dynamite (it's already in the code, not randomly generated though, so you'd need to wish for one). Instead of the long fuse sticks of dynamite have, an armed Holy Hand Grenade would detonate in 3 turns, "One... Two... Three..." or sometimes 5 turns, "One...Two... Five! I mean Three!" Detonation would not destroy the Holy Hand Grenade, i.e., it can be reused, however, monsters can throw it back at you, of course.<br />
<br />
The Holy Hand Grenade would grant some intrinsics when carried, but I've yet to figure them out. I thought maybe fire resistance, but then you could just arm it in your inventory and become a suicide bomber...so you'll have to find another source of fire resistance if you want to do that. Maybe extrinsic telepathy and half physical damage, or drain resistance (since it's Holy?), or something along those lines. I'm open to suggestions.<br />
<br />
The quest nemesis would be The Killer Rabbit of Caerbanno, base monster would be a rabbit. It would be fast, or maybe very fast. Would have stoning resistance and maybe some other resistances, but not fire. Maybe I'll give him an extra bite attack or two, or a slim chance (5%) of his attack causing instadeath.<br />
<br />Unknownnoreply@blogger.com9tag:blogger.com,1999:blog-8336789054864495847.post-38479078991696356142013-03-07T07:52:00.005-08:002013-03-07T08:06:54.066-08:00code restructuring: techniqueBefore I talk about the restructuring of the technique code, I want to extend a big thank you to Finland, which is the source of the majority of my blog views, per capita (USA wins out in overall quantity). In honor of your Finnish dedication, I will add a new comestible to my variant: lutefisk (please let me know if this is the wrong term in Finland). <br />
<br />
My current thought is that it will behave similarly to royal jelly, but when eaten, will give the message: "This tastes like the worst thing you've ever tasted!" I may change the message for the case when confused by a potion of booze, as I once read a guide to eating lutefisk online, and the first step was "get so drunk that you can't taste it."<br />
<br />
...<br />
<br />
Moving on, I'm almost done with restructuring the technique code. Instead of a long switch statement, I'm using a function pointer for each technique. This will allow for the potential of techniques having more than one effect, as the new tech struct can have a linked list of function pointers, where each function is called in serial.<br />
<br />
For example, say we want a technique that deals cold damage and stuns the target monster, and a technique that deals fire damage and stuns the target monster. The two techniques can share the stun code, so the first would have a linked list containing two function pointers, one to fire damage technique code, and one to stun technique code, whereas the second would have a pointer to cold damage technique code and a function pointer to the same stun code as 'fire-stun'. <br />
<br />
Why restructure? Part of the reason is because of shit like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8QbChcAGnaO4QtyRIhYTQcS_UN56-z2bDd8F463YgjT0AYldvtb8DyvvYOFW8NcvilyB4Jft398aG-ff5VO2WbvNoI8nVHZGYoQWIoX_Dgc2gjBaRd4EPkVNy7pfwC04GyTWFOaIAhEfr/s1600/shoddy_code.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="436" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8QbChcAGnaO4QtyRIhYTQcS_UN56-z2bDd8F463YgjT0AYldvtb8DyvvYOFW8NcvilyB4Jft398aG-ff5VO2WbvNoI8nVHZGYoQWIoX_Dgc2gjBaRd4EPkVNy7pfwC04GyTWFOaIAhEfr/s640/shoddy_code.png" width="640" /></a></div>
<br />
A closer look:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilwBwF2Pm4DGGNOkdQXn3zqunWWmm20XhgF6ldscp7TEdvMWRrhSO_69_xk_wAd8b9UZJo2SdsoQCXfIW8PmdRIax7_2RAs0EbDd1vavMsDLynWLam4G1K_o-2JgZdhfUjhlHXOJGP8SsZ/s1600/slsahem_shoddy2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilwBwF2Pm4DGGNOkdQXn3zqunWWmm20XhgF6ldscp7TEdvMWRrhSO_69_xk_wAd8b9UZJo2SdsoQCXfIW8PmdRIax7_2RAs0EbDd1vavMsDLynWLam4G1K_o-2JgZdhfUjhlHXOJGP8SsZ/s640/slsahem_shoddy2.png" width="640" /></a></div>
<br />
<br />
This unreachable break statement appears all over tech.c. My guess is that someone made the mistake early, when writing tech.c, then copy and pasted the mistake in several more places. It doesn't make the game not function, but it's ugly.<br />
<br />
With the new system I'm implementing, there could also be hybrid/random techniques that randomly select from a couple of the technique function pointers (they'd have to be compatible... combining bless and raise zombies doesn't make any sense). These random/hybrid techniques could potentially be granted as sacrifice gifts, which would add an interesting dynamic to sacrificing.<br />
<br />
As a next step, I'm going to take on the scroll/potions/spell effects... i.e., the type of stuff that can be broken up pretty easily. Once again, the new structuring will allow for craziness like scrolls/potions/spells with multiple effects, etc, if I, or someone else, decides to add that in the future. <br />
<br />
The point of all this is to make the code much more loosely coupled to make expanding and modifying the game easier.Unknownnoreply@blogger.com9tag:blogger.com,1999:blog-8336789054864495847.post-30494382547071512992013-03-04T18:09:00.001-08:002013-03-06T08:08:31.747-08:00"oh the beauties of C type declarations"If you can figure out what I'm referencing in the title, you win a FREE download of the original nethack-3.4.3 source code from www.nethack.org!<br />
<br />
...<br />
<br />
As I mentioned in a previous post, the psion role is one of the motivations for making a nethack/slashem variant in the first place; the other being, why not? Basically, the dominate ability will allow a player (or a psion) to willfully control another monster.<br />
<br />
When you dominate a monster, you get to control it's moves and actions for, say, 25 turns, plus or minus some random amount. I realize this can be too powerful in many ways, like walking a tough monster into lava to get rid of it, causing a nymph to drop your precious magicbane, or potentially, having a dominated monster on the astral plane zap a wand of teleport at pestilence to get him away from you. <br />
<br />
Anyway, I've had some page views since I shamelessly (shamefully really) plugged my blog on the nethackwiki, so I'm hoping you guys can give me some suggestions. For example, I can't decide whether to make it a technique or a HIGH level enchant spell. On one hand, a technique makes sense if I want to restrict it to psions. On the other hand, do I want to restrict it to psions? And on the third hand, in implementing the dominate power, I will allow for the possibility of dominating more than one monster at a time. There is a problem with the third hand though; it will slow down game play... no travel, no run, etc, because you have to control each dominate monster (plus yourself) individually, each step of the way, one step at a time...<br />
<br />
Monsters would have a chance to resist, and there'd probably have to be monsters on the no-dominate list--shopkeepers and temple priests, special quest folk--but you'd definitely get a bonus against foocubi.<br />
<br />
I've been hacking around the already hacked to death slashem code (I'm very guilty of returning early in functions as a shortcut, but does a function really need 30 return statements?). I'm pretty close to a functional dominate within the current slashem code, but after going through monmove.c, I decided I need to re-prioritize.<br />
<br />
The current game engine cannot support the dominate ability (as I envision it) without gross hacks and workarounds. Originally I figured I could steal some of the polyself.c code and use gotos in the <span style="font-family: Courier New, Courier, monospace;">moveloop</span> in allmain.c; in other words, gross, gross, despicable hacks. <br />
<br />
This is about the state it was in when I decided to re-prioritize (the cursor to the northwest is just to show that it's a selection thing. Nothing new there. Eventually I'm going to move the cursor over to the kitten):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsYuTplLFmYbYctjiR1BqSXWzlm9ff7GiV-GIgFWX3wI84tnOAz7pInSfuvPWJxzaB8wzeRotAAkb_Kzx5Px2rJB8Hj430XFq5piBr5VTHcH3ZMR7g5oIEYaT0af1PJ8Fkk0ePesKCLVlT/s1600/greghack_dominate1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsYuTplLFmYbYctjiR1BqSXWzlm9ff7GiV-GIgFWX3wI84tnOAz7pInSfuvPWJxzaB8wzeRotAAkb_Kzx5Px2rJB8Hj430XFq5piBr5VTHcH3ZMR7g5oIEYaT0af1PJ8Fkk0ePesKCLVlT/s640/greghack_dominate1.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbYcy7IOV6TmVJDWu13IkV__0837Tpy88Uqa4-0NQ3iLPDTsrg7f1D8_OVBSI6OuS_fX1uOCcdaSQTH2BlmDVrL8rZ9GnvKvA-rfiNvq5i9TQfdiXwZn3XBKr3Tj9dCGEHLLIuekaNoWiP/s1600/greghack_dominate2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbYcy7IOV6TmVJDWu13IkV__0837Tpy88Uqa4-0NQ3iLPDTsrg7f1D8_OVBSI6OuS_fX1uOCcdaSQTH2BlmDVrL8rZ9GnvKvA-rfiNvq5i9TQfdiXwZn3XBKr3Tj9dCGEHLLIuekaNoWiP/s640/greghack_dominate2.png" width="640" /></a></div>
<br />
And then I moved him to the left... or tried. The kitten is actually one place to the left, but I didn't get the screen drawing/updating working before I temporarily pushed the dominate implementation to the back burner.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJzPy8qxthnHo2xcu-dZjpGzlQV3OlNnc_ZF1Q9b5HVOojBN69-TWkcP8gXR_e2XidXze5mXafU-TrGJ93jpmUe27m41Cvy7MNJtClcgFN5RbkG241qlkA8jZ8fZirZx30kyMnSCIHiiM6/s1600/greghack_dominate3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJzPy8qxthnHo2xcu-dZjpGzlQV3OlNnc_ZF1Q9b5HVOojBN69-TWkcP8gXR_e2XidXze5mXafU-TrGJ93jpmUe27m41Cvy7MNJtClcgFN5RbkG241qlkA8jZ8fZirZx30kyMnSCIHiiM6/s640/greghack_dominate3.png" width="640" /></a></div>
<br />
Since I plan on restructuring parts of the code anyway, I'm going to do restructuring in parallel with hacking around with new ideas because the current code is too rigid at present for what I want to do with it. <br />
<br />
I plan on breaking apart some of the monolithic functions into several more modular functions. The overall goal of the restructuring is to separate the game engine from, well, everything else (items, monsters, roles, races, etc). I want to keep the interfaces to the game engine as uniform as possible for player and monster alike. The hope is to make it easier to add new items, monsters, roles, races, and entire systems (bards, music, anyone?) to the game. <br />
<br />
Also, a robust interface to monster strategy could pave the way for experimenting with alternative strategies, like monster AI-based strategies, or evolving/adapting strategies. I will make this a future blog post, because I also have ideas for in-game evolution of both monster strategy and, well, monster creation. What do you get when you cross a yellow dragon with a silver dragon? A gold dragon egg.<br />
<br />
Anyway, I'm going to start with techniques because that's already a pretty self contained system. Instead of the nearly 1000 line-long switch statement, I'm going to remake the <span style="font-family: Courier New, Courier, monospace;">tech</span> struct to contain a function pointer to a function that handles that particular technique's effects. I figure function-call overhead vs. switch statement efficiency isn't going to make a difference in a turn-based, user-land game. <br />
<br />
Besides, who doesn't like to bask in the beauties of C type declarations.Unknownnoreply@blogger.com11tag:blogger.com,1999:blog-8336789054864495847.post-91263767869524847142013-03-02T10:51:00.001-08:002013-03-02T10:51:36.535-08:00more on #twoweapon<span style="font-family: inherit;"><span style="font-family: inherit;">I've been thinking more about the topic of two-weapon combat in slashem, specifically, trying to figure out the reasoning behind the scheme in which certain starting races are not allowed to</span> </span><span style="font-family: Courier New, Courier, monospace;">#twoweapon</span><span style="font-family: inherit;">. This pulled me into the nethack code, </span><span style="font-family: Arial, Helvetica, sans-serif;">which</span><span style="font-family: inherit;"> also has some quirks regarding two-weaponing. </span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">I use nethackwiki.com all the time (much of it based on the ol' statslab txt spoilers: </span><a href="http://www.statslab.cam.ac.uk/~eva/nethack/spoilerlist.html">http://www.statslab.cam.ac.uk/~eva/nethack/spoilerlist.html</a>)<span style="font-family: inherit;">. Needless to say, it's generally the the best place to go for your spoiler needs. It tells you the 'what', and though it doesn't always tell you the 'why' upfront, it does openly reference the source code for those who want to dig further, which y'all gotta admit, is pretty awesome. This post will go past the level of 'spoiler' down to the inner workings of the code. This post will delve deeply into the 'why'... or rather, try to figure out why the why is why it is.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">To start, I have to explain a little bit about the </span><span style="font-family: Courier New, Courier, monospace;">monst</span><span style="font-family: inherit;"> struct and attacks. monst.c contains stats (number of attacks, special attacks, resistances, intrinsics, etc) for all of the monsters in the game. Say for example, you are playing as an orcish rogue. In monst.c, we can see that orcs only have one "weapon type" attack:</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghJcZuj-ss7__XzN1BKoGaBdwASbuBnkbfHEJJJn1foUjiROTsQWcjnWNgw-dtTTXvOznkuf7VrQp8sMxE3BD9IPLsJCW6Jvyuoh1Wb9sNe-NxhLE_Tt3AZ5HHxCAlUuhQUNcdB8kYZcUo/s1600/nethack_monst_orc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghJcZuj-ss7__XzN1BKoGaBdwASbuBnkbfHEJJJn1foUjiROTsQWcjnWNgw-dtTTXvOznkuf7VrQp8sMxE3BD9IPLsJCW6Jvyuoh1Wb9sNe-NxhLE_Tt3AZ5HHxCAlUuhQUNcdB8kYZcUo/s640/nethack_monst_orc.png" width="640" /></a></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br />To briefly describe the structure, every </span><span style="font-family: Courier New, Courier, monospace;">monst</span><span style="font-family: inherit;"> has 6 possible attacks, so in the above picture, you can see that the remaining 5 attacks are </span><span style="font-family: Courier New, Courier, monospace;">NO_ATTK</span><span style="font-family: inherit;">, meaning they just don't have any extra attacks. A mind flayer, on the other hand, has 4 tentacle attacks. The first attack is of type </span><span style="font-family: Courier New, Courier, monospace;">AT_WEAP</span><span style="font-family: inherit;">, so the mind flayer can wield a weapon, but the remaining 3 attacks are tentacle attacks, i.e., of type </span><span style="font-family: Courier New, Courier, monospace;">AT_TENT</span><span style="font-family: inherit;">, so the struct looks like:</span><br />
<span style="font-family: inherit;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilTFR7hE0xJhFpPvzAdBCGlIkAr959YkqUl9HMvAMLb39inYb8BIO4K1QG4ZFh22_p_lEEpV-sPPp6sD2Jj76X6jFgXCKGy_4ClUwx0gLzpeM075iFMuvxzbD7G6ml74qFKoIhTLz-Kwpf/s1600/nethack_monst_flayer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilTFR7hE0xJhFpPvzAdBCGlIkAr959YkqUl9HMvAMLb39inYb8BIO4K1QG4ZFh22_p_lEEpV-sPPp6sD2Jj76X6jFgXCKGy_4ClUwx0gLzpeM075iFMuvxzbD7G6ml74qFKoIhTLz-Kwpf/s640/nethack_monst_flayer.png" width="640" /></a></div>
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">Nethack has a C pre-processor macro that checks for whether a monster can, or rather, could two-weapon:</span><br />
<span style="font-family: inherit;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEise8af7PxBqh4B0XAgSaSffRpYKdgF_8r2f4zITea5KSoHHGgZCAAlmXzGLNRJK_XMt0KZibyzCGlhKvmGifcZ2NMUdB_9GooWsCU-3H84WXn3EdV-lFi6kuWGnFf3oYrJwgHwLDpwDKvi/s1600/nethack_could_twoweap.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEise8af7PxBqh4B0XAgSaSffRpYKdgF_8r2f4zITea5KSoHHGgZCAAlmXzGLNRJK_XMt0KZibyzCGlhKvmGifcZ2NMUdB_9GooWsCU-3H84WXn3EdV-lFi6kuWGnFf3oYrJwgHwLDpwDKvi/s640/nethack_could_twoweap.png" width="640" /></a></div>
<span style="font-family: inherit;"><br /></span>
In other words, if the <span style="font-family: Courier New, Courier, monospace;">monst</span> has a second "weapon type" attack, it may <span style="font-family: Courier New, Courier, monospace;">#twoweapon</span>, as seen here:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLdlnqqcq1-0rIsJvWN6_rGvj7zfMmnpEAv0YEOvP2d68jfvoySy1i8e6KP4fzJdZoH1w1PS2S5gackR03juKIfkLZCIf4zQ3gVoxA20UtMYUNiQTJNEVpHTUKovdLxlB06K_TK6DAv7dT/s1600/nethack_arntable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLdlnqqcq1-0rIsJvWN6_rGvj7zfMmnpEAv0YEOvP2d68jfvoySy1i8e6KP4fzJdZoH1w1PS2S5gackR03juKIfkLZCIf4zQ3gVoxA20UtMYUNiQTJNEVpHTUKovdLxlB06K_TK6DAv7dT/s640/nethack_arntable.png" width="640" /></a></div>
<br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">So why can your orcish rogue wield two weapons at once? Because the game uses the rogue </span><span style="font-family: Courier New, Courier, monospace;">monst</span><span style="font-family: inherit;"> struct when doing the two weapon check, and the rogue </span><span style="font-family: Courier New, Courier, monospace;">monst</span><span style="font-family: inherit;"> has a second weapon attack, as can be seen on line 3002:</span><br />
<span style="font-family: inherit;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9zC35WkdWtFB8mSsiBmujZ19rKcjVlT3Cs-u5hX1UDNmTYzozS0OUFNEjv4SM5bnfGG4Sz4GHkh5_qXpDjWB3Wfo_6gKnzZ2q5XQ-uI6jbyu1eLzwQ5dZsN4PIjF-Q0Y06KtcG5BuTk68/s1600/nethack_monst_rogue.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9zC35WkdWtFB8mSsiBmujZ19rKcjVlT3Cs-u5hX1UDNmTYzozS0OUFNEjv4SM5bnfGG4Sz4GHkh5_qXpDjWB3Wfo_6gKnzZ2q5XQ-uI6jbyu1eLzwQ5dZsN4PIjF-Q0Y06KtcG5BuTk68/s640/nethack_monst_rogue.png" width="640" /></a></div>
<br />
<br />
Now, we've all had the awesome idea of playing nethack as a monk and fighting with both hands, and we were all deeply saddened when slapped in the face with a message like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Ci1kY5OBDRX2vLEUKnYP_qxCA4LQSssg1mrRi_18uMRz3cVf-3I759CuaD_ICF7gdf3EH9k3cSKcio2kKAatY76F1jvMMlGCFiWeoVUDIxCd4aWWCvHhygcY49kHnW4evBlv5Gl1Q08Y/s1600/nethack_monksarnt.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Ci1kY5OBDRX2vLEUKnYP_qxCA4LQSssg1mrRi_18uMRz3cVf-3I759CuaD_ICF7gdf3EH9k3cSKcio2kKAatY76F1jvMMlGCFiWeoVUDIxCd4aWWCvHhygcY49kHnW4evBlv5Gl1Q08Y/s640/nethack_monksarnt.png" width="640" /></a></div>
<br />
<br />
Yet, I could've sworn that, when watching Ong-bak, Tony Jaa hit someone with his left fist. So why, in Nethack, are monks restricted? Turns out, the monk monst in monst.c has a second attack, but it's of type <span style="font-family: Courier New, Courier, monospace;">AT_KICK</span>:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTwnpHkV3CLbaghmZA_6cculjewdg2qduZl1UfV5ph3r4SmolmtQdySy-xbo1swkJOS-Hk_VL1HE148IM3Qjhl6sPpHpNvWaIUJvulPv6JnRb7qm8XtcL2ptasfQm4Tl15WLtLLW3Iot1p/s1600/nethack_monst_monk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTwnpHkV3CLbaghmZA_6cculjewdg2qduZl1UfV5ph3r4SmolmtQdySy-xbo1swkJOS-Hk_VL1HE148IM3Qjhl6sPpHpNvWaIUJvulPv6JnRb7qm8XtcL2ptasfQm4Tl15WLtLLW3Iot1p/s640/nethack_monst_monk.png" width="640" /></a></div>
<br />
<br />
This will cause two-weapon combat to fail when that <span style="font-family: Courier New, Courier, monospace;">could_twoweapon</span> macro above evaluates to 0 since the second attack is not a weapon attack. Furthermore, the monk does not get the kick attack as an encountered monster monk does, because a monster only gets that extra kick in the <span style="font-family: Courier New, Courier, monospace;">hitmas</span> function (short for, "hit monster as" a different type of monsters), which is only called if you are polymorphed. So, the only way to play as a monk and have two attacks, though the second one would be a kick, would be to play as a non-monk, then polymorph yourself into a monk. (Actually, now I kind of really want to do this).<br />
<br />
I want to make something clear. I do not want this blog to be about bashing the nethack code. I think nethack is the best computer game ever made. Part of the reason I am starting with the slashem code base is because I'd prefer to leave the nethack code as it is, untouched, in it's full glory. I admit, I use the hpmon and menucolors patch, but the game engine itself is untouched. <br />
<br />
I do, however, wonder if this behavior, of disallowing two-weaponing for monks, was intentional or a side-effect of the way the game was coded. Obviously, the dev team would've noticed such behavior in testing, so it's possible that this was intentional, though it's also possible that a developer noticed it, checked the code, and said, "meh, that seems fair, I'll leave it that way."<br />
<br />
Slashem seems to handle the monst struct differently, and it's the reason that elves can't two weapon, yet drow can, but I'll leave slashem's two-weaponing for another post.<br />
<br />
Anyway, to conclude, my proposal is that anything with two arms should be able to <span style="font-family: Courier New, Courier, monospace;">#twoweapon</span>. This will involve fundamentally changing the way attacking is handled and monsters are defined, so that will have to wait for a future post as well.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-71293908542428507412013-02-20T09:31:00.001-08:002013-02-20T09:51:08.420-08:00"You got me blacklisted from Hop Sing's?"<span style="font-family: inherit;">"She named name!"</span><br />
<span style="font-family: inherit;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
</div>
Before I go into naming monsters using the call command, I'd like to see descriptions of items remain in the inventory even after the item is identified. "Snow boots of speed" is more informative than "boots of speed", and "silver ring of teleportation" is more informative than "ring of teleportation". You can get the descriptions of identified items in-game anyway, so why not just stick that info in the inventory so we don't always have to look things up?<br />
<br />
Moving on, I'd like to be able to name minions that your God grants you when you are sacrificing for an artifact. I'm not sure why the decision was made to disallow naming of certain monsters. Try naming that deva of whatziquotal to see what I'm talking about. The inability to name <strike>names</strike> shopkeepers makes sense to some degree. I'm sure there are people out there who thing that even attempting to name Izchak should result in instadeath (now that I think of it, this is not a bad idea).<br />
<br />
As it turns out, you can indeed name minions (and priests for that matter) with the <span style="font-family: Courier New, Courier, monospace;">call</span> command. However, line 632 makes a call to the <span style="font-family: Courier New, Courier, monospace;">priestname</span> function which will generate the minion's name based on alignment, etc, regardless of what you've <span style="font-family: Courier New, Courier, monospace;">call</span>ed it. So the name you <span style="font-family: Courier New, Courier, monospace;">call</span> your minion exists in the computer's memory in the minion's <span style="font-family: Courier New, Courier, monospace;">permonst</span> struct, but is ignored by the game. I think simply replacing line 623 with <span style="font-family: Courier New, Courier, monospace;">if(mtmp->ispriest) {</span> should do the trick, but I haven't yet tried it out.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqxUVIR-FZwO0ar3H8Ws0DetASyrvIWdEt2h6PigIPaOIgGinWx02eRLx7nZJhUwFu6k2VwBrnJO6I_k9qf2g2a9GXPM7365Z_h3tq6qXLr5YwkvlOt5VeeppLuiVnARtgkwkhqY4F0ocy/s1600/slashem_minname.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="436" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqxUVIR-FZwO0ar3H8Ws0DetASyrvIWdEt2h6PigIPaOIgGinWx02eRLx7nZJhUwFu6k2VwBrnJO6I_k9qf2g2a9GXPM7365Z_h3tq6qXLr5YwkvlOt5VeeppLuiVnARtgkwkhqY4F0ocy/s640/slashem_minname.png" width="640" /></a></div>
<br />
Here's my proposal. You can name any monster. If you attempt to name an otherwise unnameable (i.e., unique) monster, it appends your name to their name. Say, for example, you steal a magic lamp from Izchak and anger him. You may end up back in Minetown much later in the game, so you might want to name Izchak "<span style="font-family: Courier New, Courier, monospace;">mad</span>". His name would then show up as <span style="font-family: Courier New, Courier, monospace;">Izchak mad</span><span style="font-family: inherit;"> or something along those lines, so you know to be careful on that level. I suppose one could engrave on the staircases to a level where a shopkeeper is mad at you, so I may just end up restricting this to minions only.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Whatever I decide upon (reader suggestions encouraged!), there would be one exception, however. Under no circumstances will you be able to name </span><span style="font-family: Courier New, Courier, monospace;">One-eyed Sam</span><span style="font-family: inherit;">. The reason is that when a shop is created, the shopkeeper will be given a name chosen randomly from a list of strings depending on the type of shop (lighting, books, general, etc). </span><span style="font-family: inherit;">I haven't quite figured out why, but someone decided that the game should randomly choose one shopkeeper name out of thirty-three for </span><span style="font-family: Courier New, Courier, monospace;">Sam</span><span style="font-family: inherit;">, where all thirty-three names are </span><span style="font-family: Courier New, Courier, monospace;">One-eyed Sam</span><span style="font-family: inherit;">, and in honor of whatever drug(s) that dev was taking at the time, I will keep it that way:</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsd7mnsZDAuPqGqZ14mwqw2p3_hn4p-nhd8kpEMIiWBQFhGgQ14qXDTvmqv2s2fCs5FbQlOFiskOt_dZ84uRGaNXkrW2Uo8RcyodiM9e5ZCJw7B1BP1SnLsYAG3AYXe0fss0N0hUvwiSK5/s1600/slashem_sam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsd7mnsZDAuPqGqZ14mwqw2p3_hn4p-nhd8kpEMIiWBQFhGgQ14qXDTvmqv2s2fCs5FbQlOFiskOt_dZ84uRGaNXkrW2Uo8RcyodiM9e5ZCJw7B1BP1SnLsYAG3AYXe0fss0N0hUvwiSK5/s640/slashem_sam.png" width="640" /></a></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Even better, when the time comes to "randomly" select </span><span style="font-family: Courier New, Courier, monospace;">One-eyed Sam</span><span style="font-family: inherit;">'s name, the list is completely ignored, and his name is hard-coded instead:</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis-Hd5u-6nsY1zcXx_8FiC7xX5GC_hGR3hWKJ2gWJp9V1e4G9IN7tdHUN8fsXikLbsQoM-60_d_O6CVk1j2JwrOoYAtZUVi48ZwkA_cZCuQx8Jn4twbWke_51ONX6PsobJkii2q1GX8y9S/s1600/slashem_shknam.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="436" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis-Hd5u-6nsY1zcXx_8FiC7xX5GC_hGR3hWKJ2gWJp9V1e4G9IN7tdHUN8fsXikLbsQoM-60_d_O6CVk1j2JwrOoYAtZUVi48ZwkA_cZCuQx8Jn4twbWke_51ONX6PsobJkii2q1GX8y9S/s640/slashem_shknam.png" width="640" /></a></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Brilliant!</span>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-8336789054864495847.post-24577767556967487342013-02-18T12:40:00.004-08:002013-02-18T12:40:40.046-08:00PsionicsAs I mentioned in a previous post, the Psion has been a driving force in developing my own nethack variant. Here are some of my thoughts:<br />
<br />
They would somewhat resemble monks, i.e., can't wear armor, martial artists, etc. Instead of getting intrinsic resistances as they progress in experience, psions would gain pychic powers, such as see invisible, telepathy, clairvoyance, and maybe eventually detect monsters (as an intrinsic), and flying.<br />
<br />
They'd also need some psionic powers, like a telekinesis technique. The slashem Jedi patch has a pretty good implementation for a telekinesis technique, bud I'd also like to add my own psychokinesis technique.<br />
<br />
Psychokinesis: the player selects a physically visible target (as opposed to seen by telepathy), then selects a visible location to which to move the object. The object can be a monster, an item, a pet, even the psion himself. Damage would be dealt to monsters that are thrown into other monsters based on the affected monsters' sizes. Damage would be dealt if an object (weapon, item, boulder, etc) was moved to a monster's location (i.e., hurled at a monster), potions would shatter. The psion must not be blind, stunned, or confused. Hallucination is okay, since it really opens up your mind, man. There would have to be a chance of failure if used to hurl a hostile monster. Notes: (1) I need to fix the uppercase <span style="font-family: Courier New, Courier, monospace;">The</span> in the below screenshots and (2) the rock-mole in the lower right shows up because I was toying with detect monsters as an intrinsic.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmqyfAHDXkdPBhbKoyZt1v5qtv78TcUJw4H30-QURlgQthOa6c32OPTWUN9UIlyGDsW6d35PJ5nLL7y8B-DA4gRxQA0kzkevlnKSav7QIney5HGixR2L1V2u-yKIDRz95JA04xUZox5OTx/s1600/greghack_psion.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmqyfAHDXkdPBhbKoyZt1v5qtv78TcUJw4H30-QURlgQthOa6c32OPTWUN9UIlyGDsW6d35PJ5nLL7y8B-DA4gRxQA0kzkevlnKSav7QIney5HGixR2L1V2u-yKIDRz95JA04xUZox5OTx/s640/greghack_psion.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbLj71kaU4Uj2-t1_Y3Bh53aRXWqW4J4UN8Z3FchQ210ieipsT2gflt9nYGqvjmmgCnYSFNXz-MbdCE-pNckJHCMVq4lzJBehQCKQWWd8PffN2NyDGd5SfHkwaTkTIaq_P1n2nGh1ZYWxC/s1600/greghack_psion2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbLj71kaU4Uj2-t1_Y3Bh53aRXWqW4J4UN8Z3FchQ210ieipsT2gflt9nYGqvjmmgCnYSFNXz-MbdCE-pNckJHCMVq4lzJBehQCKQWWd8PffN2NyDGd5SfHkwaTkTIaq_P1n2nGh1ZYWxC/s640/greghack_psion2.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3dwTZaQYlJkJ_sJqtV1D5XoC-v_zs4I3KNA1v_LSM8gbw9r84XRZ8z4NrTt4k-PSrBRzw-QRn-Ah9mNyECFqtmbJUGjviMLaGObniBDKBb0V0kMWis4A0-8_cDKyv8FobTBhdwePvbhuC/s1600/greghack_psion3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3dwTZaQYlJkJ_sJqtV1D5XoC-v_zs4I3KNA1v_LSM8gbw9r84XRZ8z4NrTt4k-PSrBRzw-QRn-Ah9mNyECFqtmbJUGjviMLaGObniBDKBb0V0kMWis4A0-8_cDKyv8FobTBhdwePvbhuC/s640/greghack_psion3.png" width="640" /></a></div>
<br />
<br />
Anyway, this thought led me down the path to adding a new feature to the overall game play: the ability to pick-up and throw monsters. Obviously, the held monster will have to be smaller than the player. The held monster will try to escape each turn it is held. It will also attack each turn it can, and will escape if the attack succeeds. This can be useful for carrying pets across traps, or over water, lava, etc. On the other hand, giants become more dangerous because they might choose to pick the player up and throw him into a trap, water, or lava.<br />
<br />
Finally, the coup de grace of my Psion brainstorming: spellbook of dominate. Here's the gist: when you cast dominate, you select a visible monster (I'm up in the air about whether visibility through telepathy should work in this case). If you succeed in a check against the monster's magic resistance, you gain control of that monster for a short duration (50 turns? 100 turns? I'm leaning shorter rather than longer). <br />
<br />
Implementing this will probably require some major restructuring of the code. Currently, the game assumes that you can only control one character. I would need to change things so that the player could control multiple monsters (himself included as a monster). <br />
<br />
The interface should be such that it is clear to the player when he is moving the dominated monster(s) or moving himself. This should be straight forward, just highlight the player under control, change the bottom line to show the stats of the <span style="font-family: inherit;">dominated monster, and add a message like:</span><br />
<span style="font-family: Courier New, Courier, monospace;">pline( "You control the %s with your mind!", Monnam(mtmp));</span><br />
<br />
I can probably use some of the youpoly code as a hack to fake the game out into thinking you are polymorphed into the dominated monster at the location of that monster, with that monster's inventory, but I think a cleaner solution would be to abstract the movement interface/bottom line interface so that it's not geared towards a game where the player can only control a single monster. (This could help pave the way to multiplayer nethack...but I'm <i>not</i> touching that one right now).<br />
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-47997936663014276482013-02-11T07:51:00.003-08:002013-02-11T07:51:46.594-08:00#two-handing artifactsSlashem, to the joy of many players, allows you to wield two artifact weapons at once. There's a catch, though. You only gain "wield" effects from the primary weapon. This was a simple implementation, since it only requires commenting out a few lines of code:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiRcpN2IRJEWYTUwmZqswvrmVEXmvLcACqFHbEMZGB2kP9DCBBW6bgTvZmi-IQW8XOJ3RpufGIH2vOqIEg47xbftep_6pNZMGGEhnJMB7F3cBnjAVQR9XmvAuCe3vYshq5phhjRUcatCjF/s1600/slashem_twoweap.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiRcpN2IRJEWYTUwmZqswvrmVEXmvLcACqFHbEMZGB2kP9DCBBW6bgTvZmi-IQW8XOJ3RpufGIH2vOqIEg47xbftep_6pNZMGGEhnJMB7F3cBnjAVQR9XmvAuCe3vYshq5phhjRUcatCjF/s640/slashem_twoweap.png" width="640" /></a></div>
<br />
For the non-programmers out there, the "<span style="font-family: Courier New, Courier, monospace;">...</span>" can be used for functions with variable-length argument lists, but in this case, it is instead most likely used as a place holder--a "fill this part in later", if you will (note the <span style="font-family: Courier New, Courier, monospace;">TODO</span>). <br />
<br />
The rest of the code, that deals with effects gained from wielding artifacts, is not changed. Since nethack assumes you can only wield an artifact as a primary weapon, it only checks your primary weapon when it handles dealing out wielding effects. I'd like to fix this to check both weapons when #twoweaponing. In fact, there are other areas I'd like to have code for this, so I'm considering a CPP macro or an inline function. Just to be clear, when I say CPP I am, and always will be, referring to the C pre-processor, not C++. I know C++ in the sense that I can just write regular C code, but otherwise, C++ makes no sense to me (check out the C++ frequently questioned answers to get my gist: <a href="http://yosefk.com/c++fqa/">http://yosefk.com/c++fqa/</a>).<br />
<br />
In other news, for the first time in _ages_, I finally have a decent tourist game going. This one is very much ascendable. I've only ascended a tourist once, so it'll be nice to double up. I found an altar very early, dungeon level 2 or so, and sacrificed like a madman until I got Fire Brand, Frost Brand, Mjollnir, and Cleaver. It was around then that I realized Grayswandir was a lawful, not neutral, weapon. Fortunately, with all those other artifacts in existence, I managed to get Grayswandir out of a wish from a magic lamp found in the tourist quest.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaJZkxWGjM-i5g9Ceb5cwn_BzvZ2R7mSay64dPOPHoeLz4MpbLPgiF5NsWfJIouefct5rkfz1Aw3zFFWOjOIc6pp2D7qrOnHEsEjfjiYEsLEgqmYpi1upI0puezUIQFbkKoTycsF7F0qka/s1600/nethack_tourist2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaJZkxWGjM-i5g9Ceb5cwn_BzvZ2R7mSay64dPOPHoeLz4MpbLPgiF5NsWfJIouefct5rkfz1Aw3zFFWOjOIc6pp2D7qrOnHEsEjfjiYEsLEgqmYpi1upI0puezUIQFbkKoTycsF7F0qka/s640/nethack_tourist2.png" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHIxYWgVBb5GnM0Jvk3bJCNGHdTGNgrtsYmDyy43Y9wpKL7xCTuHqSjxWGtMx2AwGxQVA3YC0C5PRADJdEdCgcnFQRElUImgO4deBM8pEFE5QTXjyUONNG63_A7dlXd4jZiKQInT14vVU1/s1600/nethack_tourist3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHIxYWgVBb5GnM0Jvk3bJCNGHdTGNgrtsYmDyy43Y9wpKL7xCTuHqSjxWGtMx2AwGxQVA3YC0C5PRADJdEdCgcnFQRElUImgO4deBM8pEFE5QTXjyUONNG63_A7dlXd4jZiKQInT14vVU1/s640/nethack_tourist3.png" width="640" /></a></div>
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-91413394999547409912013-02-08T08:38:00.000-08:002013-02-09T20:18:48.392-08:00coding_styleA brief history of my coding style.<br />
<br />
The first language I learned was Java, so my style was, more or less, K&R with camelCase. Overtime, I gotSickOfCamelCase in_favor_ of_underscores. (Pro-tip: check out xmodmap for Linux and BSD machines. I've mapped Shift+Spacebar to underscore, which makes my life, and my carpel tunnels, so much happier).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI-KtsfROtrfr0Rh791F3J6o2ZqCZTSsj7HFbb0vRtd7ycsV7uEJjHPknuAsvmxCcGqqnPKZDo6BXLlhFFHegFnZGpMlBfmvfQwxennCjmdmCtdTerEXkiBssiLxMKAQgsjlXEwdDW8ULY/s1600/knr2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="371" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI-KtsfROtrfr0Rh791F3J6o2ZqCZTSsj7HFbb0vRtd7ycsV7uEJjHPknuAsvmxCcGqqnPKZDo6BXLlhFFHegFnZGpMlBfmvfQwxennCjmdmCtdTerEXkiBssiLxMKAQgsjlXEwdDW8ULY/s400/knr2.jpg" width="400" /></a></div>
<br />
Most people consider this the holy grail of coding styles, and for good reason. The nethack and slashem source is written in the K&R style, though the indentation is poor:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-m2xioNjWBr2hhvUa6TIH9AjbgnHMuqWE_JjFN-GE-USYA4n4YJTSu8El4OzA4sqXKMa61vd0yJNeoBfyMnDAk_tma5IjWybQnhjX0EoP8lNeKNgtRa6XxabaLxZLRE_5heisHtCyTQLl/s1600/nethack_badif.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-m2xioNjWBr2hhvUa6TIH9AjbgnHMuqWE_JjFN-GE-USYA4n4YJTSu8El4OzA4sqXKMa61vd0yJNeoBfyMnDAk_tma5IjWybQnhjX0EoP8lNeKNgtRa6XxabaLxZLRE_5heisHtCyTQLl/s640/nethack_badif.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
I don't have OCD. My room's a mess, I have a few weeks worth of scruff grown on my face, but poor and/or inconsistent indentation and coding style drives me fucking crazy. It's a trait my parents wish I had in every other aspect of my life, but only made it to programming and guitar playing. I NEED it to be perfect, and though it never is (including my own code), I try to get it as close as possible.<br />
<br />
Recently, I've changed my coding style a bit. I've strayed from K&R in favor of an unnamed style. Below is an example of my new coding style, taken from a memory manager I wrote for a kernel driver. On one hand, it wastes vertical space (an aspect K&R handles very well) but it's much easier for me to read. Maybe you younguns out there disagree, but I've found that, as I've gotten older, I prefer a style that's easier on my 27 year-old eyes. Note the extra space within parentheses. Check out line 146 for my favorite pointer trick.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_N-7qiG0ZPnBK2fK6bXFlD-SsMiIp14FTElwKq03ZzCFbA0B8_2J8bfJ8tYd5TUc80N3Wsh7mR5HXGeTBWjRlCCRLDXVkEZcSdZShCnWlrEkgui9jo7oDO3kBpUfqNm73fxpZf756F_Bj/s1600/coding_style.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_N-7qiG0ZPnBK2fK6bXFlD-SsMiIp14FTElwKq03ZzCFbA0B8_2J8bfJ8tYd5TUc80N3Wsh7mR5HXGeTBWjRlCCRLDXVkEZcSdZShCnWlrEkgui9jo7oDO3kBpUfqNm73fxpZf756F_Bj/s640/coding_style.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Complicated conditionals are<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyuOvO_i15xIBvE9flJETGWO5KUvSYgY0qy5wi8v_dI4mbIrDwwO1BA8idu_Tf1OR-5LqVp0N6C_zea4Nfs9amLR8Zhg3kLDZq9_WWKqyJcXsqap1mBHppTNjzMU9kB-wAgHJbZ2ZemIFs/s1600/nethack_goodident.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyuOvO_i15xIBvE9flJETGWO5KUvSYgY0qy5wi8v_dI4mbIrDwwO1BA8idu_Tf1OR-5LqVp0N6C_zea4Nfs9amLR8Zhg3kLDZq9_WWKqyJcXsqap1mBHppTNjzMU9kB-wAgHJbZ2ZemIFs/s640/nethack_goodident.png" width="640" /></a></div>
<br />
Are we having fun yet?Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-8336789054864495847.post-3884407495020897432013-02-07T11:59:00.000-08:002013-02-07T11:59:05.910-08:00Jedi patch v0.5 for slashemI'll start today by looking at the Jedi patch. I'd prefer a Star Fleet Officer role over Jedi, but Jedi fit much better into the slashem environment. Until I can come up with a system for inter-specie diplomacy, the addition of a Star Fleet Officer role will have to wait.<br />
<br />
Ever since slashem (<a href="http://slashem.sourceforge.net/">http://slashem.sourceforge.net/</a>) introduced me to lightsabers, I knew it was only a matter of time before someone made a Jedi starting role (<a href="http://www.crash-override.net/patchesslashem.html">http://www.crash-override.net/patchesslashem.html</a>). I am planning on making a grand variant that will incorporate code from a variety of patches and variants, so I started by checking out the Jedi patch. I recommend following the previous link and reading the description.<br />
<div>
<br /></div>
<div>
Dodgy Code: </div>
<div>
<br /></div>
<div>
There's the old saying about the NetHack Dev Team: "the dev team thinks of everything." Lets run this dodgy code through the gauntlet.<br />
<br />
"Also, a skilled Jedi with an activated lightsaber can dodge missiles fired at him (though not reflect them)." Basically, if wielding a lit lightsaber, </div>
<div>
<br /></div>
<div>
The first thing that popped out to me: what if the Jedi is wielding a lit lightsaber in her off-hand? I soon realized that I was asking the wrong question, because the followup question covered that: why does the Jedi's lightsaber need to be lit in order to dodge rocks thrown at her? Furthermore, there's some inconsistency here. A Jedi wearing armor gets -20 to hit, similar to Monk's wielding weapons. But a Jedi wearing a brand spankin' new bronze plate mail is nimble as a fox.</div>
<div>
<br /></div>
<div>
So here's my proposal:</div>
<div>
A Jedi can dodge missiles with a probability based on her proficiency in the lightsaber skill (must have at least "basic" proficiency). The lightsaber shouldn't have to be lit, or even wielded, in order to dodge, but I figure I can use the lightsaber skill to gauge how "learned" the player is in the Jedi ways. The Jedi should not be able to dodge while wearing armor, and Jedi should not be able to dodge if wielding a non-lightsaber object. Yes, scalpels are indeed a clumsy weapon, as are tin openers and meat sticks. The Jedi must be able to concentrate on the force, so they can't dodge if stunned or confused. A blind Jedi can still dodge, but it's slightly more difficult. This blog believes that hallucination should not restrict dodging. I hear it really opens your mind to the force, man.<br />
<br />
I also thought that an 80% dodge rate was a little high, so here's what I came up with. The probability of a successful dodge is as follows:<br />
$(r/6)$ where $r=Prof_{LS} - (1 * Blind)$. skills.h <span style="font-family: Courier New, Courier, monospace;">#define</span>s expert level as 4, skilled as 3, and basic as 2. If a Jedi is blind, $1$ is subtracted from $r$. Blind is just a macro that evaluates to a boolean, which on most flavors of unix, is 1 if TRUE, and 0 if FALSE. Quiz: why is <span style="font-family: Courier New, Courier, monospace;">TRUE</span> almost always defined as <span style="font-family: Courier New, Courier, monospace;">1</span> instead of <span style="font-family: Courier New, Courier, monospace;">(-1)</span>? A: I have no idea, <span style="font-family: Courier New, Courier, monospace;">(-1)</span> makes more sense to me. Anyway, a blind Jedi with expert proficiency in the lightsaber skill will dodge 50% of the objects thrown at him, so long as he's not wielding a non-lightsaber weapon. not wearing armor, not stunned, and not confused.<br />
<br /></div>
<div>
My favorite part of the Jedi patch description is, without a doubt: "The Jedi must then fight along some of his fellow Jedi against the stormtroopers and Lord Sidious himself to gain possession of this powerful artifact which can even reflect beam attacks!" Holy shit! A weapon that reflects beam attacks! Oh wait, the Longbow of Diana does that too...<br />
<br />
So, for fun, I added a system of lightsaber deflection. First, the Jedi must be wielding at least one lit lightsaber, and no armor. The probability of deflecting a beam is as follows:<br />
$(r/10)$ where $r=(Prof_{LS}) - (1 * Blind) + (bonus_{LS})$. "bonus" does not refer to enchantment bonus, rather, +1 per lit lightsaber wielded (+2 if double lightsaber). If two-weaponing, the Jedi must be at least "basic" in two-weapon combat to get the bonus. If the Jedi succeeds in the deflection check, then there's an additional check, with the same probability. If the additional check succeeds, the Jedi may choose the direction in which to deflect the beam, otherwise, it is reflected in a random direction. So, if somehow two lit double lightsabers (both beams lit) are two-weaponed, that's a +4 bonus. A non-blind Jedi, expert in lightsaber, skilled in two-weapon combat, wielding two lit lightsabers will have a 60% of deflecting the beam, and if she succeeds, another 60% of choosing the direction in which to deflect the beam, otherwise, it is deflected in a random direction.<br />
<br />
There's some balance to this. Yes, it's nice for a starting Jedi to have a 20% chance of deflecting beams, however, due to the nature of random deflection, the Jedi may deflect the beam into a pet, a shopkeeper, watchman, some other peaceful monster, or even herself. The lightsaber deflecting code comes before testing for reflection (from amulet of reflecting, silver dragon scale mail, etc) so even with reflection, a Jedi still runs the risk of randomly deflecting the beam at a peaceful. If the Jedi has reflection and randomly deflects at herself, then it will reflect as normal. The series of screen shots below show an example of lightsaber deflection when the Jedi may choose the deflection direction. I chose down and to the left to show that deflected beams bounce off walls and otherwise behave like ordinary beams.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglOddri-qE09yT3plOB8knlRySht6riJwIDg4-YBZ8Zb2DqMbRLs8ScvNcmxZZuo5xrPELLz2urdfiY6iZ8PYn5AwMtI2hpNkS7a_tk0sthydPluC2LC46CsAWoY8OzvbXqpQp83WCaO5b/s1600/slashem_deflect1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="462" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglOddri-qE09yT3plOB8knlRySht6riJwIDg4-YBZ8Zb2DqMbRLs8ScvNcmxZZuo5xrPELLz2urdfiY6iZ8PYn5AwMtI2hpNkS7a_tk0sthydPluC2LC46CsAWoY8OzvbXqpQp83WCaO5b/s640/slashem_deflect1.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgntuZrAWKJyVp6Fl7TGMf9I6-vyF5MJmM59ybmn8IhYUs4__8wN8snLqzVkB1hcUkwVX44k2eDss27hHGWojuGRhx_0fMNXD3UwXsdmALKGq43z09S-7wsPThbk-TOnJB5l37g5-YYHcjV/s1600/slashem_deflect2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="462" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgntuZrAWKJyVp6Fl7TGMf9I6-vyF5MJmM59ybmn8IhYUs4__8wN8snLqzVkB1hcUkwVX44k2eDss27hHGWojuGRhx_0fMNXD3UwXsdmALKGq43z09S-7wsPThbk-TOnJB5l37g5-YYHcjV/s640/slashem_deflect2.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAS6kRnG88lguNMC2o91Z3CEsxBOkKGQZY0OxDzmUHvYCVlLoQui6BNEzW41JovYHb1fa3bzclNyWb5Kzv4pZTypHzBIHrwO9xWZOA03F8yy9CE2L67bInhHsWkGsF5dD8IThif97kttwy/s1600/slashem_deflect3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="462" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAS6kRnG88lguNMC2o91Z3CEsxBOkKGQZY0OxDzmUHvYCVlLoQui6BNEzW41JovYHb1fa3bzclNyWb5Kzv4pZTypHzBIHrwO9xWZOA03F8yy9CE2L67bInhHsWkGsF5dD8IThif97kttwy/s640/slashem_deflect3.png" width="640" /></a></div>
<br /></div>
<div>
<br />
<br />
Jedi Alignment:<br />
<br />
In the original Jedi patch, Jedi must be lawful, and must follow a strict moral code, similar to a knight. But what about Dark (chaotic) Jedi? I wanted to make chaotic Jedi a valid starting role, but it doesn't make sense for a chaotic Jedi to follow a strict moral code. I couldn't just get rid of the moral code checks for a chaotic Jedi, because that would be unfair to the lawful Jedi. So, here's the deal for chaotic Jedi: any wielded lit lightsaber functions as if bloodthirsty (like Stormbringer), so you will automatically attack pets and peacefuls. I figured this makes sense as the dark side like to kill things. If the lightsaber is not lit, then it is not bloodthirsty. <br />
<br />
Also, I thought that the two different alignments of Jedi should receive different first sacrifice gifts. Regardless of alignment, all artifact lightsabers do not need to be recharged, and all lightsabers emit a light with a radius of 2. <br />
<br />
The first sacrifice gift for lawful Jedi is The Windu Blade, in honor of my man Samuel L. Jackson. It is a violet lightsaber, which which deal slightly more damage than green lightsaber: 9+d5 vs. small, 12 + d7 vs. large. It also has +5 to-hit and +10 damage against cross-aligned monsters. This might be a little too powerful, so I'm considering changing it to +5 to-hit and +10 damage against undead.<br />
<br />
The first sacrifice gift for chaotic Jedi is The Darth Maul Blade. It's basically Stormbringer in the form of a double red lightsaber: +d5 to-hit and +d2 damage to non level-drain resistant monsters, plus an additional d8 of damage is dealt to current and maximum hit points, half of which goes to heal the wielder. This might also be a bit overpowered as weapons go, One thing I am considering is removing the drain resistance it grants to its wielder.<br />
<br />
For both artifact lightsabers, I'm open to suggestions.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8336789054864495847.post-7756481212600454132013-02-06T12:22:00.001-08:002013-02-07T13:14:41.876-08:00time to make a nethack variantAs an avid fan and player of nethack and its variants, I've always been struck with ideas for additions/changes to the game while playing. As a C programmer, it only made sense to make my own nethack variant. <br />
<br />
My posts will contain my thoughts about game play as well as my thoughts about the code. Some posts will be geared more towards general game play concepts and brainstorming, such as thoughts for new roles or races. Some posts will be geared more towards game specifics, such as racial stats, role abilities, probabilities of succeeding at various tasks. Finally, some posts _may_ end up being geared towards coding, such as monster <span style="font-family: Courier New, Courier, monospace;">struct</span> consolidation, the use of function pointer lists for special attacks, and the beauties of C type declarations. Even if you don't care about the code stuff, all posts will be geared towards nethack, so feel free to comment on, question about, or suggest anything.<br />
<br />
I'll be using the slashem source code as a base for my project, however, I plan on adding features from several different variants (such as sporkhack and unnethack), other patches (color alchemy, hpmon) and new features of my own. At the end of all this, and potentially throughout development, I will, of course, make the source code available for y'all to test. In addition, I will also make pkg.tar.gz and .tgz files available for easy installation on Arch Linux and FreeBSD, respectively. Most of my testing will be done on Arch Linux (if you think ascending a Tourist is hard, try building nethack from source on an Ubuntu or Mint box). I will also be compiling with gcc, and _maybe_ LLVM on BSD, so hopefully using the two different compilers will catch any mistakes I make relating to compiler specific extensions, like branch prediction (which is fun but generally not needed for a turn-based, user-land game) or other code that doesn't fit the old C89 standard.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyDpzVY0o3gIM57yH_tgEfAKJHpjuUNwzGL51dkGFEb5-p5eaKR-_exLpyZqh_LYITDhoQ6mSTh3c3EAOcgfJxi4MJzEf76elNHESAX_hanDBtZpqnYuGwiZTrRdfF8uH2wAURk59jzwMq/s1600/nethack_collect.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="414" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyDpzVY0o3gIM57yH_tgEfAKJHpjuUNwzGL51dkGFEb5-p5eaKR-_exLpyZqh_LYITDhoQ6mSTh3c3EAOcgfJxi4MJzEf76elNHESAX_hanDBtZpqnYuGwiZTrRdfF8uH2wAURk59jzwMq/s640/nethack_collect.png" width="640" /></a></div>
<br />
<br />
As this is the first blog entry, I will lay out my big-picture plans and *try* to leave the details for future posts. Keep in mind, a lot of this is still in the brainstorming phase. <br />
<br />
1) Re-write/re-structure large parts of the game engine. <br />
<br />
First, I will split the code into two modules. The first module will handle game play. I will replace all closures with their equivalent trigraphs, then implement the entire game in a single function using only pre-processor macros. All control flow will be handled with goto's. The second module will parse the data files, and will be written entirely in perl keywords.<br />
<br />
All kidding aside, the slashem code is pretty kludgy. Then again, I'm used to kernel programming, where we like to keep things robust and concise instead of adding lots of complicated conditionals for specific situations, of which there are many in slashem. That said, I do not see any reason why the 'hit monster' function has to be 1000 lines of nested <span style="font-family: Courier New, Courier, monospace;">if</span> and <span style="font-family: Courier New, Courier, monospace;">switch</span> blocks. <br />
<br />
Basically, I want to make the code more generic. <br />
<div>
<br /></div>
For example, there are three different source files for hitting things: monsters hitting you (<span style="font-family: Courier New, Courier, monospace;">mhitu.c</span>), you hitting monsters (<span style="font-family: Courier New, Courier, monospace;">uhitm.c</span>), and monsters hitting monsters (<span style="font-family: Courier New, Courier, monospace;">mhitm.c</span>). There is also a file for monsters throwing items at you (<span style="font-family: Courier New, Courier, monospace;">mthrowu.c</span>), and you throwing items at monsters (<span style="font-family: Courier New, Courier, monospace;">dothrow.c</span>). (Can you guess which file contains the code for monsters throwing at monsters?)<br />
<br />
<br />
2) Religion.<br />
<br />
Alignment will play a bigger role in things, from first sacrifice artifacts to different codes of conduct. Similar to sporkhack, sacrifice gifts are not guaranteed to be artifacts, and the probability with which you receive an artifact gift from a sacrifice will be based on xp level.<br />
<br />
<br />
3) Add new stuff (below are just some examples).<br />
<br />
3a) New Races.<br />
<br />
Kobold strikes me as a reasonable starting race. They would have a racial technique at first level, "Poison", that poisons inventory objects such as darts or other projectiles.<br />
<br />
Mindflayer is another race I'm considering. They would probably resemble Vampires in slashem, i.e., start with a penalty (either slow, or negative luck) and they would have a bite attack, but they wouldn't fly and would have better Int and Wis stats.<br />
<br />
3b) New Roles.<br />
<br />
Soldier: the game has guns, why not have a soldier role? They would be able to attain "expert" in firearm proficiency, among other weapons. The quest artifact, of course, would be The Holy Hand Grenade. More details on this in a future post.<br />
<br />
Jedi: slashem has lightsabers, so of course, someone already made a Jedi patch. I had some issues with it, so I improved (according to me, at least) on the Jedi role substantially. I'll have a more detailed post about this in the future, and I'll make the patch available when I'm happy with it.<br />
<br />
Psion: this one is my real brain child. I'm saving the details for a future post(s), but let's just say that brainstorming for the Psion role has been a driving force behind other changes I want to make to the game that will affect all roles (quick teaser: a system for throwing, and being thrown by, monsters).<br />
<br />
<br />
3c) New Monsters.<br />
<br />
Probably some monsters from the biodiversity patch and Gold Dragons from sporkhack, to name a few.<br />
<br />
<br />
3d) New Items.<br />
<br />
Definitely going to include the "bag of poo" from sporkhack. I also like sporkhack's magic staff system. Also, why not add things like Gauntlets of Offense, spellbooks of probing, and wands of wonder? Nethack and its variants make references to various parts of geek culture, but they all left out one of the greatest roguelikes of all time: Toe Jame & Earl. Rocket Skates anyone? I envision them as being generated cursed most of the time, providing a faster movement rate than boots of speed, while forcing you to run (as if holding down the shift key when moving).<br />
<br />
<br />
4) Interface.<br />
<br />
No real changes here. I've seen screenshots of the inventory window patch, and other similar layout patches, but I've never tried them. Honestly, I think they are a great idea, but I'm not going to include them because I feel that the game should be able to fit in a standard 80x24 console.Unknownnoreply@blogger.com4