50+ Naruto Authors Who Did Something Well

I’m not really sure why, but this weekend, I ended up not only noticing a FanFiction.net author’s poll for picking the top 5 Naruto authors from a list of 50, but taking the time to examine all 50 choices. Suffice it to say, the poor quality of almost every choice on the list was beyond embarrassing. (I’m assuming the 50 choices were finalists of some sort, proposed by “the average FanFiction.net user”)

Most of them were the kind of authors I wouldn’t read if you paid me (people who, as far as I can tell, spend their time writing tired, cliché, fix-it or shipper plots that were done to death years ago) and, of the 10 who have actually written at least one story I recognize as something I’d consider worth reading in retrospect, almost none of them are the authors I’d really recommend for their skill, talent, wit, cleverness, and/or ability to keep it up over the course of several fics.

Given that I had a little free time and a decent collection of records on what I’ve read and liked, I decided to compose my own list, complete with the fics that earned them their place. I really didn’t want to sort all 50 from best to worst, so it’s in alphabetical order instead.

Not everything they write is good, but each of them wrote something good at least once and all of them demonstrated that skill and/or luck in Naruto fanfic. (I’m not sure I’d have been able to find 30 authors, let alone 50, if I limited myself to people who wrote more good stuff than bad over the course of their interest in fanfiction)

Enjoy and, if you think I missed someone, please leave a comment so I can check them out.

  1. Aleh (Appreciation)
  2. Andoriol (Naruto: Lord of Konoha)
  3. Angel of Snapdragons (A Drop of Poison)
  4. anothvortex (all four stories)
  5. Asha’man of Fire (Kitsune on Campus)
  6. atom-of-ice (Naruto’s Advice)
  7. Average Naruto (Tomato)
  8. Bloodreaver Alpha (Diary of a Madman: Memoirs of a Nukenin)
  9. brown phantom (Students of the Snake, Naruto’s Kit)
  10. Case13 (Reload, The Art of the Deal… and I’m told his other Naruto stuff is amazing too but it’s still on my to-read list)
  11. Chibi-Reaper (Overlord, Uzumaki Naruto, Sorceror for hire, and various clever ideas that haven’t been written far enough yet to list)
  12. Chilord (Bondage Style!)
  13. ChoppedHige (Nicknames and Shadows)
  14. Crimson Skies (This Time Around)
  15. Denim88 (Cracked Mask)
  16. DisobedienceWriter (Naruto’s Compensation)
  17. dogbertcarrol (Glaring Problems, Play it again, Naruto!)
  18. Dragon Man 180 (Feel Like A Woman)
  19. drakensis (The Night The House of Cards Was Built, Cheaters Prosper)
  20. EdStargazer (Naruto: Captured)
  21. froznfox72 (Geniuses of Hard Work)
  22. gsteemso (The Disorderly Princess and the Fiery Steed)
  23. HitokiriOTD (The Book of Naruto)
  24. Innortal (Shinobi OneHalf, The Naruto Omake Files: Innortal Style)
  25. Jade R. Raven (The Rival)
  26. Jonakhensu (Kyuubi no Cabbit)
  27. Jonque (The Missing Hokage)
  28. Kenchi618 (Better Left Unsaid)
  29. Kraken’s Ghost (Foxhound)
  30. leafygirl (Loophole)
  31. Lord Archive (Between Deception and Truth)
  32. Lucillia (Time MixUp, History Exam, Little Uzumaki, The Consequences of Drunken Experiments, Chickenzilla, 5 Hokages, Underwear the Cat, Pet Names, Yukiko, and various others)
  33. Majin Hentai X (Naruto: Game of the Year Edition)
  34. Minnionette (Switched!)
  35. MockV (A Twist of Chance)
  36. MogTheGnome (The Great Romantic, Naruto, the Spanking Nin, The Imprint, The REAL Sound Nin, and less memorable others)
  37. Nes Mikel (Garden of Sanctuary, Medusa Javelin, Empyreal Paradox)
  38. nobody102 (Scorpion’s Disciple)
  39. notgonnasay09 (Guardian’s Wings)
  40. Nugar (Ask Me No Questions, Anything and Everything)
  41. Orrunan (Uprooted)
  42. Ozzallos (Tales of the FoxCat)
  43. Sarah1281 (It’s For a Good Cause, I Swear!)
  44. Shadow Crystal Mage (Death and the Uchiha)
  45. ShaperV (Time Braid)
  46. Smylingsnake (Oops!)
  47. S’TarKan (Out of Darkness: A Jinchuuriki’s Tale, Team 8)
  48. The Red Dragons Order (Flip Flop and Fly)
  49. TwinEnigma (Secretive, Transcendental Idealism, House of Dogs, Replica, Ad Oculos, Side Effects May Occur, Alternate Hosting, and less memorable others)
  50. yasuhei (Ganbatte ne, Oirokechan)

Runners-up:

Entries in this section didn’t make the top 50 list, not necessarily because they weren’t as good, but because I don’t remember them very well, so I have to take my records’ word for it that they’re good… and I don’t trust my younger self’s judgement without nostalgia to back it up. 😛

Some of them are here due to a lack of quality though. They’re still good… just not quite good enough to match one or more similar authors in the list above.

Note: Before I get any flames about Chunin Exam Day being down here, please keep in mind that I’m perfectly willing to admit that Perfect Lionheart does have a knack for writing catchy stories with strong starts… he just draws them out and gradually changes them until they’re not what I wanted anymore. (I’ve often wondered whether he’s a troll or just arrogant and too full of hubris)

Late-Comers:

This is where I put authors who wrote really good stuff… but I only found it after I’d written the first version of this post.

Posted in Fanfiction | 40 Comments

Tuning TiddlyWiki for Polished Prints

This morning, in typical distracted fashion, I got the urge to start experimenting with using CSS to style a website for printing and decided to use the copy of TiddlyWiki I use for personal organization as the test bed.

I was so impressed by how nicely the results printed out that I just had to share them. The particular pages that most impressed me are private stuff, so I can’t share them, but here’s the TiddlyWiki markup reference:

TiddlyWiki: Screen versus Print

Here’s the full PDF. (Note: There is actually a visible difference between reading the PDF on-screen and printing it. DPI makes all the difference. I was also going to experiment with page margins, but I liked the results so much that I didn’t want to change anything.)

The CSS below works perfectly with a completely un-modified default TiddlyWiki theme… though it does also include a couple of tweaks that only really have an effect if you’ve got certain plugins installed. (eg. CheckboxPlugin)

Depending on how you use TiddlyWiki, you may want to skip the “Hide tag-related floats” or “Page break before each tiddler” lines in your copy. I made sure that, before I hid them, the floats didn’t look too horrifying.

To really exercise the stylesheet, print out a stream of several tiddlers with at least one outline list full of checkboxes and at least one span of text similar to an O’Reilly book. (Roughly a page worth of paragraphs with some technical nouns marked up in italic here and preformatted text there)

UPDATE: After sleeping on my results, several improvements occurred to me:

  • Fixed table heading color in Chrome (Not sure how I missed this one)
  • Adjust things to look good when printing of background colors and/or images is enabled.
  • Create a CSS class that can be applied using {{checkList{ ... }}} to hide bullets if your list starts each entry with a checkbox anyway. (Much prettier TODO lists both on-screen and in printouts)
  • Switch to vertical-align: bottom for checkboxes after more eyeball-testing with Firefox and Chrome
Posted in Geek Stuff | 1 Comment

8 PCs In A Bunker: Ownership, Respect, and Principles in the Steam Era

TL;DR: DRM is you paying to be mistrusted and quietly disrespected; Piracy is an implicit endorsement of someone whose behaviour you disagree with.

(UPDATE 2016-01-14: If you pirate, It also makes it easier for them to blame you for their own bad business decisions. If everyone would just play something else instead of pirating, they’d be forced to ask “What are they doing that I’m not?”)

(UPDATE 2016-10-08: If you like this, I suggest watching Rerez’s 3.5 minute talk about why emulation shouldn’t be a dirty word in the video game industry.)

Every now and then, I’ve had someone look at me in surprise because I refuse to buy games that are only available on Steam. “But it’s so convenient,” they’ll say or, if they know me personally, “What’s wrong with taking advantage of the $1 deals like your brothers do?”

My answer to them is that Steam violates what I refer to as my “8 PCs in a Bunker” policy but, more fundamentally, it’s a matter of ownership, respect, and principles.

Until games started to use phone-home systems like Steam for their DRM, you effectively owned any game you bought. Yes, there was that nasty little stub of code which meant that, if you broke the disc and you hadn’t made a copy and grabbed a crack, you were screwed but, aside from attacking people reselling used copies on eBay like AutoDesk does with AutoCAD, your intuitive expectations for buying something were upheld and agreeing to the EULA was, for home users, effectively a meaningless formality.

Then, along comes Steam with its addictive sales, ultra-convenient game manager, and integrated social framework… pay no attention to that man behind the curtain. What they don’t want you to stop and think about is that, by buying games with phone-home DRM, you’re not actually buying them anymore. Steam and similar systems give the publisher the power to enforce that license agreement we’ve all grown so used to ignoring. You didn’t buy anything; you just paid a one-time subscription fee… and legal departments always make sure that subscriptions can be revoked at the service-provider’s discretion.

Suddenly, Valve is in a position where they have all the power and I just have to trust that they won’t abuse it. Suppose Steam loses out to a competitor someday and closes up shop, I have to have faith that Valve or the game’s developer will release an update to remove the game’s dependence on it. If they’re killing off the brand anyway and the games are a decade old, do you really think they’ll see a worthwhile investment in that?

(UPDATE 2016-03-31: Look at what happened with Games for Windows Live if you need a real-world example.)

Suppose Valve goes public. (If a U.S. company grows big enough, staying privately owned becomes more hassle than it’s worth. That’s what happened to Google.) Suddenly, they’ve got a CEO in charge with a fiduciary responsibility to maximize profit. Once again, mandatory auto-update + Steam required + subscription-style licensing easily becomes “We think you’re a pirate/cheater/pedophile/communist and we’re revoking your account.”

(UPDATE 2016-03-31: And my worries appeared to be correct, because I’m now hearing tales of people who got banned without getting refunded for the single-player experiences they lost access to. Even if they were paying me to play games via Steam, I’m not sure how much monetary compensation I’d need to make up for the stress of having that Sword of Damocles hanging over my head.)

We’ve already seen how little the promise of a DRM-locked eStore is worth when certain online music stores closed up shop and, at best, left it up to you to jump through hoops to preserve your collection. They’ve already got your money. Why should they care about tarnishing a brand that’s being end-of-lifed anyway?

Paying to be distrusted and quietly disrespected just isn’t the kind of relationship I want to have and I don’t like the “guilty until proven innocent” culture it fosters. Besides, if you can suppress the instinctive “Ooh! Shiny!” reaction that Steam sales are so finely tuned to trigger, it becomes very easy to find ways to spend your time that don’t force you to choose between pleasure and principles.

My favorite ways to have fun without feeling dirty include:

Aside from the pleasure of not feeling like I’m whoring myself out to the corporations (to put it bluntly), there’s a certain degree of satisfaction in being able to save my money, spend most of my time entertaining myself for free, and often have something to show for it when I’m done.

Now, some people might argue that, if you “pirate” games, It will also satisfy many of those goals and prevent them from revoking your access to the game, but part of having principles is doing it right, so you can feel good about yourself for not giving into the temptation to weasel your way around them.

I’d much rather feel good about entertaining myself than validate a publisher’s sense of entitlement and give implicit approval (and possibly word-of-mouth advertising) to a game developer who is unwilling to have principles of their own. It also helps that, when I do refuse to buy a game, I can harmlessly indulge baser instinct (some might call it a guilty pleasure) by revelling in doing my part to consign them to obscurity.

(UPDATE 2016-06-50: “Not only am I going to withhold my money, I’m also going to deprive them of any legitimate grounds for complaining about it. That’s much more satisfying.”)

So, with all this philosophical posturing, what exactly is an “8 PCs in a Bunker” policy? It’s something I cooked up in the mid-’90s when I was a poor kid with a lot of smarts and a risk-averse personality to match.

In short, suppose a nuclear war were to break out tomorrow and I was left with only 8 PCs in a bunker, blank hard drives, and a bunch of DVD+R backups. Could I still enjoy what I’d bought to a reasonable degree?

Think about that for a moment:

  • Blank hard drives, so you have to be able to install from scratch.
  • No Steam servers, so you have to be able to back up the installer to DVD and “phone home at least once to verify ownership” won’t work.
  • No phones and no call center, so “phone this number for a manual activation code” won’t work
  • No access to a central matchmaking service or an MMORPG server farm, so you’d better hope that, if they’re needed, the server software was available for download too.
  • Burned DVD+Rs, so if you’ve got old-style “lock it to the installation media” DRM, you’d better already have a crack too.

There are probably other things I took into account when I first designed the policy, but I think you get the idea. It’s an imaginative way to ask myself “Do I own this? Do they seem to trust me?” that covers pretty much any eventuality the publisher is likely to consider worthwhile.

I actually go further with non-games (insisting on open-source software so I don’t have to “take it to a manufacturer-owned service center” when it breaks) but that’s another story.

Update: Tor/Forge now also sells DRM-free eBooks and I should probably mention that, if you like to read to learn, O’Reilly and No Starch Press sell DRM-free eBooks too.

Update: Image Comics is apparently working to remove DRM from their offerings now.

Update: Another source for free eBooks is The Open Library.

Posted in Otaku Stuff, Web Wandering & Opinion | 8 Comments

How to perform a one-off migration into Django ORM

While working on a project I haven’t yet made public, I found myself needing to migrate data into a Django project without being able to use the simple, common “Use inspectdb, then migrate to the new form with South” approach some suggest.

Here’s the simplest sequence of commands I’ve found for performing a migration to an existing app with some possibility for reusing the migration later if necessary:

django-admin.py startproject <throwaway project>
cd <throwaway project>
python manage.py startapp <real target app name>
[repeat for all target apps]
[edit settings.py and tell it about your DB and apps]
python manage.py inspectdb > temp_models.py
[look at temp_models.py and make any adjustments necessary]
[edit models.py for each app and move the relevant bits from temp_models.py]
python manage.py syncdb
python manage.py dumpdata > migrated_data.json
[...and then set up South to prevent future pain] 

Nothing fancy. Just something that saved me some hassle and might do the same for someone else. Here are the actual commands I used for clarification:

django-admin.py startproject gbi_temp
cd gbi_temp
python manage.py startapp gbindex
python manage.py startapp icolinks
python manage.py startapp ffcms_core
vim settings.py
python manage.py inspectdb > temp_models.py
vim temp_models.py gbindex/models.py icolinks/models.py \
    ffcms_core/models.py
python manage.py syncdb
python manage.py dumpdata > migrated_data.json
mv migrated_data.json ../ffcms/
cd ../ffcms
python manage.py loaddata migrated_data.json
Posted in Geek Stuff | Leave a comment

Hurricane Electric IPv6, m0n0wall, and Dynamic IPs

After years of wanting it, I finally got around to setting up an IPv6 tunnel. (My brothers’ Flash plugins weren’t too pleased for some reason, but I’ll re-enable IPv6 on their machines later)

I quickly discovered that there was one small problem though. Hurricane Electric’s TunnelBroker.net doesn’t offer a DynDNS-style API for DNS-O-Matic to replicate my m0n0wall DynDNS updates to.

They do provide a more homegrown HTTP API and I tried e-mailing DNS-O-Matic to see if the could add support for it, but got no response and, since m0n0wall doesn’t let you hook on-reconnect events, I needed something ddclient-like.

I checked around to see if anyone else had m0n0wall-based solutions, but found nothing and, being the geek I am, I felt more like whipping up a custom tool in an afternoon than spending an hour trying to puzzle out the search keywords for a more flexible ddclient-alike.

upd_ipv6.py requires Python 2.5 (I think) and LXML (m0n0wall’s interfaces status page isn’t well-formed enough for ElementTree and I didn’t feel like doing any SAX-style parsing by hand). It’ll probably work on Windows and MacOS, but I’ve only tested it on Linux and it’s not a daemon, but that’s what cron and the Windows task scheduler are for.

To configure it, run ./upd_ipv6.py --dump-config and then edit the config file at the path it mentions. You’ll probably want to create a custom m0n0wall user that can only access the Status > Interfaces page.

Once that’s done, just stick it somewhere out-of-the-way, add a cron line like this to run it once every five minutes:

*/5     *       *       *       *       ~/bin/upd_ipv6.py

It’ll only contact TunnelBroker.net if your IP changes.

Posted in Geek Stuff | Leave a comment

A Python programmer’s first impression of CoffeeScript

CoffeeScript is a simple, clean, fast language which compiles to JavaScript, either at build time, with a caching framework plugin on the server, or at runtime in the browser.

The syntax looks like a cross between Python and Haskell1 and, generally speaking, is used similarly enough to Python that you’ll have little trouble picking it up and using it comfortably.

It does have a few of what non-Ruby programmers will consider distasteful warts, but for the most part, it’s an elegant and delightful language.

You’ll probably want to keep the syntax reference open in a background tab at first, but if you’re comfortable with Python and you’ve done any programming with jQuery or some other modern JavaScript library, you’ll feel right at home.

Below, I’ve summarized the points which the documentation doesn’t completely prepare you for as a Python programmer.

Helpful features with no direct Python analogue

A.K.A. Things which you’ll probably forget to use at first, but which you really should work to remember.

Use almost anything as an expression
Not only does CoffeeScript have anonymous functions, you can treat pretty much anything as an expression and it’ll be wrapped in an anonymous function if needed.
Indent-stripping multi-line strings
If you use single-quotes rather than triple-quotes for multi-line strings, it’ll still work and leading indentation common to all lines will be stripped. (like textwrap.dedent(), if you’re familiar with it)
Embedding expressions in strings
Given how much string templating is done in JavaScript, it really helps that you can put any expression directly inside the Ruby-style #{string interpolation operator}
for own key of
To iterate over only the properties which weren’t inherited, use for own key of rather than for key of. (Very useful since JavaScript doesn’t make a distinction between properties and associative array keys)
Fat-arrow function syntax
To bind this to the parent object, even in a callback, simply define it with => rather than ->
Ultra-concise constructors
Rather than filling your class constructors with this.foo = foo, you can simply use the @ shorthand for this. and write constructor: (@foo, @bar) -> with an empty method body.
Checking for the existence of variables and properties is concise.
Use variable ? "default value" and obj.method?().thing?.widget

Similarities and differences with Python not explicitly mentioned

A.K.A. What the documentation won’t directly prepare you for if you have Python instincts.

Ternary syntax will break your muscle memory
For a ternary expression, Python uses result = a if test else b while CoffeeScript  uses result = if test then a else b. (The if statement syntax on a single line)
a = b and c or d works Pythonically but you don’t need backwards-compatibility with pre-ternary Python releases
Boolean operators don’t coerce the return value to a boolean (a will be c or d, not true or false) but 99% of the time, what you really want is the ternary operator.
Comprehensions use when, not if
If you write result = (x for x in list if x % 2 == 0), you won’t get an error… but you will get a loop inside a conditional rather than a conditional inside a loop.
(If item in the parent scope isn’t evenly divisible by 2, the loop will be skipped. If it is, result will be identical to list)
Comprehensions iterating two lists produce a two-dimensional array
In Python, this syntax will produce a one-dimensional list while, in CoffeeScript, it produces a list of lists.

a+b for a in A for b in B
newList = list1 + list2 + list3 is not array concatenation
You could use newList = [].concat list1, list2, list3 instead, but a cleaner and more flexible alternative is to use splats. This example cleanly concatenates three lists and two individual numbers into a single list:

newList = [listA..., numA, numB, listB..., listC...]

In my opinion, this makes CoffeeScript cleaner and more intuitive than Python for this task.

When foo is an array, if foo is always true
[] != false so, to check whether a list is empty, you have to do if foo.length instead.
someFunction(arg3 = 1) is not the syntax for positional arguments
…but because assignment is valid in an expression, it won’t raise an error. What you want is someFunction null, null, 1 or someFunction(null, null, 1)
There is an equivalent to someFunction(x, y, *args)
As in Python, splats aren’t just for function definitions.

 someFunction x, y, args...

Counter-intuitive Perl/PHP/Ruby/etc.-isms

A.K.A. Where most of your subtle, hard-to-find bugs will come from as a Python programmer.

If you don’t use parentheses in a function call, CoffeeScript will guess them for you
…but Haskell programmers and shell scripters will be surprised when a b c d means a(b(c(d))) rather than a(b,c,d). This also means that foo () is sometimes invalid when foo() is OK.
On the plus side, it works very well for ensuring that anonymously defined callbacks aren’t an exception to the “indents, not braces” block syntax.
The rules are simple but it’ll still take some getting used to before I’ll stop occasionally tripping over them. Here’s how jashkenas explained it to me:

The call wraps forwards to the end of the line, or to the end of the indented block, with one specific exception for postfix conditionals.

alert a alert(a) alert inspect a alert(inspect(a)) alert inspect a if b alert(inspect(a)) if b
Colons aren’t part of the block syntax
Habitually typing a colon after a function name or control statement will turn it into an object property (think dict literals)… which can do all manner of crazy things if it’s something like “else:” which is still valid CoffeeScript.
You can’t shadow a higher-level variable
…only refer to it as in Ruby’s “local scope”, so expect to cause subtle bugs if you habitually reuse a handful of temporary variable names. If you want to get out of the habit, PyLint‘s default configuration will complain when you do this in your Python code.
Like Perl and Ruby and unlike JavaScript, CoffeeScript does implicit returns
…so expect subtle bugs until you internalize that CoffeeScript’s function syntax is really a multi-line lambda.
(As the docs say when talking about comprehensions intended only for their side-effects, “Be careful that you’re not accidentally returning the results of the comprehension in these cases, by adding a meaningful return value, like true, or null, to the bottom of your function.”)
As with PHP, single- and double-quoted strings have different meanings
…with interpolation only working in double-quoted strings.
Like in C and many C-inspired syntaxes, and explicitly unlike Python, you can do assignment inside an expression.
So expect to shoot yourself in the foot on occasion by accidentally typing = instead of == and not getting an error message. (You can, however, reduce the risks by habituating yourself to the is and isnt aliases for == and !=)

Caveats to re-mention for JavaScript programmers

A.K.A. Where subtle, hard-to-find bugs may come from if you have a lot of experience working with plain old JavaScript.

Switch statements don’t allow you to fall-through to the next case
CoffeeScript automatically inserts break; into every case. However, when statements will accept comma-separated lists instead. (I seem to have misplaced the response which gave me this tip. Help appreciated in tracking it down so I can link it.)
To avoid namespace pollution, everything is run in an anonymous wrapper
…so you have to explicitly attach things to the window object if that’s what you want.
== and != are converted into === and !==
If you really want the intransitive, coercion-inducing version, wrap the expression in backticks to mark it as raw, untranslated JavaScript.
CoffeeScript’s in is Python’s in
JavaScript’s in is CoffeeScript’s of.

Python features still to find equivalents for

Did I miss something?

I’m new to CoffeeScript, so please let me know if I’m wrong or if I forgot to mention some area where Python instincts will steer you wrong with CoffeeScript.

Also, don’t forget to read the FAQ. It’s not as noticeable as the docs, but it’s almost as useful. 🙂

1. Technically, the syntax is inspired by Ruby and YAML, but I know quite a few Python programmers for whom that wouldn’t mean anything, so I compare to Python and Haskell first instead.

Posted in Geek Stuff | 45 Comments

GQView Collections on the Framebuffer

So there I was, waiting for some nVidia drivers to compile so I could get back into X11, flipping through images in fbi, when I realized I was sick and tired of fragile, irritating, one-liners to pipe lists of images into it.

Enter gqfbi. A little, one-hour creation of mine which makes using fbi so much more comfortable.

GQfbi is a small, Python-based wrapper script for the fbi framebuffer image viewer which will make it just Do What I Mean™.

Features include:

  • Automatically excluding files fbi won’t recognize to prevent it from pausing for a second or two to force you to read the “couldn’t load this image” message.
  • Support for taking any combination of paths to images, directories, and GQview/Geeqie collections.
  • Calls fbi with readahead and auto-scaling enabled. (I’ll make them optional when I get around to actually making optparse do something useful)

Planned features:

  • Support for asking fbi to slideshow, shuffle, and loop.
  • Support for taking Zip/RAR/CBZ/CBR archives as input for framebuffer manga-reading.
  • Its own git repository rather than lurking in my roaming profile’s ~/bin

If you like it, please let me know. I don’t use it often, so you’ll probably be single-handedly responsible for getting a feature implemented.

Posted in Geek Stuff | Leave a comment