2017-09-04 12:38 am

Fanfic status update

About seven or eight years ago I had an idea for a fanfic: "What if Samus and Iji had a fight?" That's not very original, I'll admit, but I banged out more text for it than any other fic I've worked on before it sank into a morass of headcanon and fanwankery that didn't look good in foresight or hindsight. To sum it up in one line, it was supposed to be a combat fic and they spent most of their time on a shopping trip.

I revived the story last year with a few mental guidelines. Cut back the fanwankery and build the characters around the headcanon. Rename the characters so they are not the exact same characters but expys, obvious analogues or parodies that the reader can recognize if I write them well (spoiler: I don't) and who also are appealing and interesting characters on their own merits. Add more action and adventure (and fewer shopping trips) and make it meaningful.

For a time the fic's going name was Let's You And Her Fight which was a great name except that the team will change in the second season and include a male fighter. I changed the name to Crash Champions because it kinda-sorta invokes Smash Brothers, which the universe is based around to explain why Samus/Alex Smith and Iji/Jill would be having a fight. I will probably change the name again to Clash Champions which invokes combat and has an actual meaning in English.

Then the fic expanded to include other teams of fighters, a scheduled tournament, team managers, referees, corporate politics, and offworld adventures in every episode. The first fic didn't have any of that. It had ended with Celes stealing Mick's ship and going around the multiverse knocking off the big bads of other video games. That sort of thing is going to be a part of the new story and will turn out differently.

I now have a finished draft of the first of 13 planned episodes. Most of it is still that shopping trip.

My other fics are going nowhere fast. The most promising of them was Odyssia Papadopoulos and the Princess of the Skies which got bogged down in the need to explain all of the Holy Shit that just happened (tldr: an ancient god of war attacks a Russian base during the Cold War) and I don't have anything for the main characters to do, which is really bad for a story that is supposed to be about these same characters. I haven't touched any of the other fics in close to a year.
2017-08-25 01:37 am
Entry tags:

Hong / Starman's story

I ficced up some background on the referee Starman, a minor character. I had wanted to tell his story in Season 1 but decided it wasn't a good fit, so this will probably all get cut. I could work it into Season 2. Read more... )

2017-08-06 02:21 am

The MacLeod House

I had a parody idea this morning that would fit into my Smash fanfic so I pounded it out. This would fit into Season 2, recruitment phase, episode 3 or 4.

Scene: A suburban household

An average modern suburban house is full of rowdy girls playing around and one woman trying to control them all, with a baby in one arm and a phone in her other hand, as she is on the phone to somebody about placing orphans in foster care or public school.

She is repeatedly interrupted. To the girl cooking in the kitchen, "careful with the eggs!" as they roll toward the edge of the counter. To the girls chasing each other in the hallway, "Slow down in the hallway!" The doorbell rings. "Could somebody get that?"

One of the girls opens the door. Outside stands a 12-year-old boy with a serious expression on his face, slicked blond hair tied back in a ponytail, wearing sunglasses and an oversized trench coat that spills onto the ground around his feet.

The boy speaks in an odd accent that is like French and Scottish smashed together. "Hello. I am looking for the orphanage."

The girl calls over one of the teenagers, "Hey {$NAME}, I think your new boyfriend is here."

The teenager rushes over. "He's here?" She looks. "That's not him."

The boy questions her. "Would you be the lady of the house?"

"Umm..." both girls hesitate before calling over their foster mother. "Mom!"

She walks over. "Hello, may I help you?"

The boy: "I seek room and board for a fortnight."

Mom: "Ah, we are an orphanage-"

The boy: "I am an orphan. My parents died" - (dramatic pause) - "a long time ago."

Mom: "I am so sorry. The orphanage is all girls right now, but we _could_ make room for you."

The boy: "That is acceptable."

Mom: "What is your name?"

The boy: "I am Abraham MacLeod, of the clan MacLeod."

Mom: "It's nice to meet you, Abraham. Come on in and introduce yourself."

As the boy steps up to the doorway, we see the tip of a scabbard hidden under his coat. Read more... )

2017-07-04 08:01 am
Entry tags:

Elvish, a new Unix shell

Via lobste.rs, the Elvish shell:

Pipelines in Elvish can carry structured data, not just text. You can stream lists, maps and even functions through the pipeline.

Not too long ago I was thinking that shells should bring in high level language features and pipes should be matched with data types. It sounds promising.

2017-06-09 02:06 am

Webcomics list 2017

It's time to update my webcomics list. Read more... )

2017-06-08 10:28 pm
Entry tags:

Optimizable Malleability, and other thoughts

Optimizable Malleability

The life of a productive environment may look like:

  1. High malleability - you can do almost anything, with few restrictions.
  2. Exploration - certain workflows are found to be better than others.
  3. Optimization - simplified interfaces increase productivity while leaving out lesser-used features.
  4. Stagnation - The existence of a standard way of doing things discourages the development of alternative ideas.
  5. Replacement - Somebody invests a new system that replaces the entire old system.

Examples of malleable systems and optimized systems:

  • Assembly language lets you do anything, leading to goto spaghetti. C gives you formal looping and function call patterns along with a subset of assembly's features. Higher level languages have additional formal implementations of common programming patterns and lack some of C's features to prevent entire categories of bugs. Driver writers and OS programmers still need the lower-level features, but 90% of programming can be done without them.
  • Text files allow you to store data in any format. Every Unix tool invented its own text file format. INI, CSV, JSON, and XML are types of text files that are optimized toward storing certain types of information.
  • Tail call recursion is an optimizable subset of recursion.
  • Excel lets you freely place data without structure. Access requires you to define the structure first.
  • Static typing versus dynamic typing. A language could be dynamic by default with optional static typing and optional type constraints. In this case the optimized system (static typing) came first and the malleable system came later.

Stagnated systems and their replacements:

  • Why aren't webforums based on Usenet/NNTP? The environment of HTML+SQL allowed for the development of alternatives at a lower cost.
  • Why don't new languages use object files? The burden of compatibility is not worth it.
  • Why aren't most programs made of shell scripts? Fewer features, security concerns, etc.

Reconsidering the notion of a "program"

Let us view the entire operating environment as a set of mechanisms for directing input to a function.

Consider the command line shell.

  • The user provides the program with representations of the function's arguments. The arguments are not passed directly, but you provide a string that represents the argument. Code inside the program converts the string to a filename or URL, parses the data, and provides that as the argument to the function.
  • The program provides standard input and output methods, using pipes
  • The program may allow the user to set the initial state of the program, using switches

We could say that a program is a wrapper that sets state, has the standard input and output, and provides access to the desired function(s). Let us consider a future operating environment that separates these tasks.

  • The future system could automate the generation of wrapper code.
  • The future system may use dynamic type casting, late binding, just-in-time compilation, etc to rewrite part of the program based on the user's input.
  • The future system might allow the caller to directly set global variables / class members by name, doing away with the need to parse switches.
  • Inputs and outputs may be something other than raw byte streams. The pipes may have a class type. The system may provide a standard iterator for a given type and handle casting automatically. The standard Unix tools may be rewritten to work on interfaces.

Incomplete classes and comprehensive dynamic typing

Consider the evolution of classes.

  • 1970s - C - A struct is, basically, a way to arrange data
  • 1980s - C++ - A class is, basically, a way to arrange functions around the data they operate on
  • 1990s - C#/Java - An interface is, basically, a definition for a set of functions that we will expect any given type to implement.

The struct, class, and interface are all key/value pairs.

Consider the function:

sub doStuff(x){ return x + 1 }

In the "message passing" concept we might consider x:Dynamic and expect the runtime to check whether the given x has a ._plus() method at call time. (A more complex system could check for this when the object to be passed as x is known.) In the "interface" concept we might check that x implements the INumeric interface which includes a ._plus() function. "INumeric" is a way of saying that a dynamic type will implement a standard set of methods, what C# calls a contract.

An interface might be seen as an incomplete data type. An incomplete data type might be seen as a type of filter. A data type filter could describe the partially resolved value of a dynamic type, or could be used to implement very strict typing.

interface IPercent:UInt8 {
  _value = 0..100 // Value is between 0 and 100 inclusive 

interface asdf {
  foo:String and len = 0..8 // .foo will be a string whose length is > 8
  // let's propose something outrageous... 
  baz: fnord(_) between &("camel"), dronf("llama") and & > 3 
  // * we will have a .baz member
  // * the namespace will also include functions fnord() and dronf()
  // * the result of fnord(baz) has a comparator that puts its result
  // between the results of fnord("camel") and dronf("llama"),
  // * and the value of fnord(baz) will be greater than 3
  // * or else the program throws a type mismatch exception,
  // preferably at compile time 

This would be of little use to a programmer, but might be useful to a compiler, runtime, or IDE.

// as written by the programmer
function doSomething(futz): 

// as interpreted internally 
function doSomething(futz:{
  foo:String = "foo" // string with a known value 
  bar():Int // an undefined function that returns int

The same sort of filter or incomplete class can also be used as a search object.

interface SalariesOver30000:Employee { 
  salary:Numeric >30000   

select SalariesOver30000 from Employees // pseudo-sql

Function constraints

A compiler could theoretically determine that it is impossible for a function to do certain things:

  • a given function may not modify its inputs
  • the function may not make any asynchronous calls
  • the function may not open any additional inputs or outputs
  • the function's inputs may have values known at compile time or runtime

A compiler could potentially use this information to optimize the function, possibly running it at compile time if enough information is known.

My TODO list for language design is to look into:

2017-02-06 03:41 pm
Entry tags:

A lesson in meaningful variable naming

A variable representing a link to a website might be called $url or $link or $site. Take this project I'm working on. At one point in the code the variable might be called $url. At another point it is $link. Further on, it is $site. I want to reach back across time to my younger self and slap him the face and scream at him and impart a lesson on the value of maintaining a consistent naming convention.

So let's say $site represents a link to a website except when it doesn't because I am also using $site as a unique key to represent a website in the general sense that "this website contains web pages". For this purpose I send $site through a filter that strips out the protocol and leading www. and the ending index.html if it exists. This means that $site is not the same thing that it used to be. So $site and $link actually are two different things with two different meanings. They should be two different variables.

I fixed a few bugs just by noticing that the meaning of these variables was not consistent.

In the same program I have two variables $sites_visited and $destination_count that seem to have a similar purpose.

$sites_visited is:

  • set to 1 when process_site() is run
  • checked when recursing into new sites
  • was sent to process_site_results() in an earlier version, but this is commented out

$destination_count is:

  • increased by 1 when process_site() is run (this is a bug)
  • increased by 1 when a site's list of links is finalized
  • used by process_site_results() to determine whether the site should be included in output.

So both of them are set to true when a site is processed and were intended to be used to tell if a site is worth processing. However, they mean different things.

  • $sites_visited is true when a site has been fetched and processed.
  • $destination_count counts the number of times a site has been linked from another site. It is nonzero (true) before the site is fetched or processed.

So they remain two different variables because they account for different concepts.

2017-02-05 07:23 pm
Entry tags:

Quick thoughts on multiple inheritance

Has-A pattern:

class MyClass { 
 FooType foo;
 BarType bar;
  • each MyClass allocates space for a FooType and a BarType.
  • foo and bar establish their own namespaces.


class MyClass extends FooType, BarType { }
  • each MyClass allocates space for a FooType and a BarType.
  • The namespaces for FooType and BarType are incorporated into the MyClass namespace.

So what's the problem? Something in FooType or BarType might overlap.

General outline of a solution:

  • All namespace conflicts must be resolved by the programmer.

Considering specific examples:

1. Both FooType and BarType have a .x property?

  • Solution 1: Forced upcasting. All attempts to access MyClass.x must be upcasted to the parent. All parent methods work on their own .x property.

2. Both FooType and BarType have a .fooMethod()?

  • Solution 1: Forced upcasting. The compiler should warn if the programmer fails to resolve the conflict, and throw an error if the programmer tries to run MyClass.fooMethod() without overriding it. This can cause problems (see case 4).

3. MyClass has its own .x property?

  • Solution 1: Override parent access methods. If the property is interface-compatible with the parent's .x property, the FooType/BarType methods will run on MyClass.x instead of their own .x properties. If the property is not interface-compatible with the parent's .x, the compiler should throw an error and refuse to compile. PROBLEM: FooType and BarType may intend for their .x property to mean different incompatible things or to hold separate pieces of information. Sharing the same piece of data will introduce bugs.
  • Solution 2: Do not override parent access methods. Parents continue to operate on their own .x properties.

4. MyClass has its own .fooMethod()? Theoretically, this should override the FooType/BarType methods. However, it introduces a double-call problem.

  • Solution 1: Override parent methods. This introduces a double-call problem. If both parents have a method called every second that calls their own fooMethod(), this causes the overridden fooMethod() to be called twice per second instead of once per second.
  • Solution 2: Do not override parent methods. Parent calls to fooMethod() will call the parent version of fooMethod().


More thought needs to go into this.

  • Multiple inheritance is fine until you have a namespace collision, and then you're in trouble.
  • If you have the parent classes share data when both have a .x property, then you have the problems that each might treat .x as a different conceptual thing and that conflicting actions on the same .x may introduce race conditions that do not exist when each class uses its own data.
  • If you do not have the parent classes share data, then you have multiple copies of what might be the same conceptual thing, updates to one do not affect the other, and the state of ".x" is unclear.
  • If the child class .x overrides the property for both parent classes, then you risk the parent methods modifying the data in ways you did not intend.
  • If the child's .foo() overrides the method for both parent classes, then you might get a double-call problem when methods in both parent classes call their overridden .foo() method.
  • If the child's .foo() does not override the parent method, then you lose the ability to extend the parent class by having its .foo() method do something different.
  • The programmer may want to resolve namespace collisions in a different way for different properties and methods in the same class.

2017-01-31 01:58 am
Entry tags:

Revisiting a pet project

Gee, I think this software of mine is close to ready for release. I just need to brush it up a little.

... (create a todo list ... it's half a dozen things)

... (open the file, and there's a list of another half dozen things to do)

... (there are several known bugs that have no discernable cause)

... (none of the functions are documented and I cannot tell what one of them is supposed to return)

... (making it run well will require repeatedly rerunning it and massaging input data files)

... (it produces no output when given the same input that had produced good results the last time I had worked on it)

... (the file is still named test.pl)

This might take more time than I had thought.

2017-01-27 05:18 am

The best spam that I have received in a while

This appeal ended up in my inbox:

(If you are not the person who is in charge of this, please forward this to your CEO, because this is urgent. If this email affects you, we are very sorry, please ignore this email. Thanks)

We are a Network Service Company which is the domain name registration center in China.

We received an application from Huayi Ltd on January 16, 2017. They want to register " hfb " as their Internet Keyword and " hfb .cn ", " hfb .com.cn ", hfb .net.cn ", " hfb .org.cn ", " hfb .asia " domain names, they are in China and Asia domain names. But after checking it, we find " hfb " conflicts with your company. In order to deal with this matter better, so we send you email and confirm whether this company is your distributor or business partner in China or not?

Here is a link to my "company" that distributes HFB. In fact, you can look at all of the HFB that I am distributing.

2017-01-25 07:06 pm
Entry tags:

Unfinished parody: Marksman Blunt

Here is an unfinished parody that was found while cleaning up old files on my hard drive.

Read more... )

2017-01-10 05:51 am
Entry tags:

Some retrievals must be attempted more than once.

Here's another rough draft from my Smash fanfic. Read more... )

2017-01-03 12:28 am

Tang is OG (oldschool gamedev)

I went through some old boxes today. Mixed in between my Cub Scout stuff and stuff from my first year of SRJC was a notebook that had four pages totally filled with a chart of weapons and armor for some D&D-alike that I had forgotten I had ever worked on.
2016-12-31 04:58 pm
Entry tags:

The Harambe Song

(sung to the tune of Fleetwood Mac - Rhiannon)

Harambe lived like an ape in the zoo
Would you like a banana?
The TV showed the end of his life
And he became a legend.

Have you ever seen a gorilla
As handsome as Harambe?
Would you cry if the zookeeper shot him?
Would you give a damn?

He sat around on his gorilla butt
And now he is in heaven.
They took his life with a shot in the heart
And some say that was heartless.

Have you ever seen a 3-year-old boy
Dropped inside your pen?
Would you try to wash him in the water?
Would you try to eat him?
Would you try to eat him?

2016-12-30 06:15 pm
Entry tags:

Scheduling fictional fights

My Smash fanfic-in-progress has a schedule.

I have given myself some guidelines in designing this:

  • Some fights will happen at certain weeks in the story, and this is unavoidable. The others can be shuffled.
  • Four fighters are going to end the season at 4-2, 5-1, or 6-0 and make the finals.
  • Everyone else will end the season at 3-3 or worse.
  • Certain fighters are going to be 0-2 at week 3 so there can be side stories about their struggles.
  • Fighters on the same team do not fight each other.
  • Nobody should fight more than two fighters from any other team. This can be fudged in the offscreen fights.
  • The tournament is larger than the named characters, so fighters can fight "someone else".

I have created a logic puzzle. It's like Sudoku.

So, after a short time I now have a full schedule for all characters. One of them ends up at 4-2 instead of 5-1, and I cheated by having Alex fight "Other" offstage on two different weeks, but it will work. It does not have to be logically perfect, it only needs to carry the story. I was only trying to fit some of the fights to the formal schedule, but I had to schedule more and more of them to make it work.

2016-12-29 04:41 pm
Entry tags:

Game dev thoughts - valuing an object based on its components

Crafting with multiple inputs

Consider a game with a crafting system. Imagine that crafting an object requires several inputs.

  1. Crafter skill level
  2. Input A
  3. Input B
  4. Input C

The qualities of these inputs may be variable.

  • The crafter's skill level varies as the crafter gains experience.
  • Metals: how well refined it is
  • Food product: age and suitability
  • ... etc ...

Imagine that any input can have a quality rating from 0 to 100%. The quality of the inputs can affect the quality of the resulting product. To implement this, we must create a function to determine the output quality. Let us call our inputs [A,B,C,D], each ranging from 0-1, and create some example functions.

  • Multiplication: q = A * B * C * D
  • Summation: q = (A + B + C + D)/n where n is the number of inputs
  • Sum of squares: q = (A^2 + B^2 + C^2 + D^2)/n
  • sqrt(Sum of squares)

The multiplication function emphasizes differences from 1.0, the netural position. The addition of flawed components will create greater flaws in the result.

The summation function minimizes the effect of flawed components on the end result. The addition of perfect components will even out the result toward 1.

The sum-of-squares function will produce results somewhere in the middle of these two extremes. Taking its square root will push the quality value toward 1.

The choice of function is up to the game designer. It will help to throw several functions and examples into a spreadsheet and see what ranges of results you feel are appropriate for your game.

Crafting with weighted inputs

How about weighting the inputs so that some will matter more than the others? You will need to rewrite your algorithm.

Rules for weighting:

  • Inputs with a larger weight will have more influence on the result than inputs with a smaller weight.
  • If all weights are equal, the result should be the same as the unweighted algorithm.
  • If one weight approaches infinity while the others hold still, the result should be as if all other weights are zero.

Let us call the inputs [A,B,C,D] and their weights [Z,X,Y,W].

Helper functions

It may help to calculate how much any weight differs from the mean average weight of all objects in the set. For input weights of [5, 1, 4, 2.8], this produces [1.5625, 0.3125, 1.25, 0.875].

  • f(Z) = Z/(Z+Y+X+W) * n where n is the number of weights

It may also help to adjust the values of the weights relative to the largest weight. For the same inputs, this produces [1, 0.2, 0.8, 0.56].

  • g(Z) = Z / max(Z, Y, X, W)

Function redesign

The multiplication function (q = A * B * C * D) emphasizes the input's difference from 1.0 and compounds these differences as more inputs are added. We can create a helper function m(input, weight) to adjust this difference relative to the weight. For weights [5, 1, 4, 2.8] and all inputs 0.9, this produces [0.9, 0.98, 0.92, 0.944].

  • m(A,Z) = 1 - (1-A)*g(Z)

An analogue to the multiplication function becomes:

  • q = m(A,Z) * m(B,Y) * m(C,X) * m(D,W)

The summation function is easily modified by multiplying each input by its weight, then dividing by the sum of weights.

  • q = AZ + BY + CX + DZ / (Z+Y+X+W)

The sum of squares function can be modified similarly to the summation function.

  • q = (A^2*Z + B^2*Y + C^2*X + D^2*W) / (Z + Y + X + W)

Here is some bonus math that I was working on the other day. Imagine that you have three different crafting functions Z,X,Y that take inputs A, B, and C.

  • Z = A + 2B
  • Y = 0.5A + 2B + C
  • X = B + 3C

Now imagine that you have volumes of A, B, and C in storage; let's say 40A, 80B, 20C. How does one maximize production? This is a solved linear algebra problem so you should go looking for the appropriate method in your language's math libraries.

In Python, you lay out the functions like this:

a = [
        [1.0, 0.5, 0.0],
        [2.0, 2.0, 0.0],
        [0.0, 1.0, 3.0]
r = [40,80,20]

print scipy.optimize.linprog(c=(-1,-1,-1), A_ub=a, b_ub=r )

optimize.linprog() is used because linalg.solve() will give you negative numbers.

What if you want to weight the functions so that one is more valuable than another? I'm still working on it.

2016-12-23 10:49 pm
Entry tags:

The recruitment arc (very rough draft)

Some more of my Smash fanfic. Before the heroes get into the tournament, they have to recruit the fighters. Not everyone is cut out to join the team. Read more... )

2016-12-17 10:20 pm

Crash Champions: Thunder and Silence (rough draft)

Here's an idea that I got one morning and spent the whole rest of the day writing down. Might as well publish.


The Boddy Estate

It is a dark and stormy night outside the Boddy Estate, a Victorian mansion.

A group of detectives enter the mansion. They resemble Sam Spade, Sherlock Holmes, Jessica Fletcher, Charlie Chan, and other familiar faces. They badmouth and berate each other like the parodies in Murder By Death but are even more abrasive because they are only going to be on screen for a minute.

Lightning flashes and the power goes out, leaving them in darkness. The detectives insult each other again, their voices rising as they nearly come to blows.

Lightning flashes and thunder booms, and there is silence and darkness.

The Boddy Estate at morning

Morning breaks through the mansion's windows. Every one of the detectives is dead, sprawled all over the room. One of the bodies is hanging by a noose from a slowly spinning ceiling fan. Another has knives in his body. In the foreground, an open bottle of poison sits next to someone's drink. Spread across the ground are at least two pistols, an axe, a lead pipe, a broken candlestick, and other murder implements. There is no blood. This is PG.

At the open front door stands a group of teenagers with a Great Dane dog. One of the teenagers says: "Gee golly! It's a mystery!"

Cut to opening credits. Read more... )

2016-12-09 01:50 pm
Entry tags:

Building high level code from low level code

Consider that a class in c++ or java defines both an implementation and an interface.

Consider the similarities in these three examples:

// Example 1 
interface IFoo {
 // interface

 // implementation not defined
// Example 2
class Foo {

 // implementation
 int x;
 string y;

// Example 3
// implementation 
struct foo {
 int x;
 string y;

void foo_doStuff(); // interface

An ordinary compiler might be expected to convert lower-level code to a low-level implementation immediately upon reading it. The programmer has defined exactly how the code is to be implemented, and there is no apparent need for higher level considerations.

A hypothetical high-level compiler might first convert as much low level code as possible into a higher-level intermediary language.

  • class Foo is automatically built from struct foo and is automatically populated by the foo_() functions that operate on a struct foo.
  • interface IFoo is automatically built from the internal representation of class Foo
  • This high level representation is saved to an object file and can be accessed by any programming language that can load libraries.

Additional thoughts:

  • An autodoc tool can produce documentation from the resulting high-level objects, especially if the high level object includes comments or links back to the original source code.
  • An IPC mechanism can send the object definition to the receiving side if the receiving side does not have the structure defined.
  • The compiler can detect classes that are binary-compatible with one another and allow them to be casted without harm.

Also, it should be possible for a sufficiently smart compiler to recognize that some for-loops are examples of an iteration. These can be interpreted upwards to a high-level description of an iteration like foreach x in myArray{...} for which the developer has provided a low-level implementation for (i=0; i<length; i++){...}

I cannot think of any benefit to doing this, but it could potentially be done.

2016-11-28 01:26 pm
Entry tags:

DoJ wants to consider anonymity evidence of a crime

Techdirt has been following a Department of Justice request for expansion of powers.

In addition, the DOJ wants permission to break into "compromised" computers and poke around inside them without the permission or knowledge of the owners of these computers. It also wants to treat anything that anonymizes internet users or hides their locations to be presumed acts of a guilty mind. The stripping of jurisdictional limits not only grants the FBI worldwide access for digital seizures and searches, but also encourages it to go venue shopping for judicial rubber stamps.

Like many expansions of power during the Obama administration, no law is changing. They are simply declaring that they will do this from now on.