Saturday, December 15, 2018

i'm ping pong king, an analysis

Daring Fireball uncharacteristically recommended a game for mobile called "I'm Ping Pong King" and it is indeed pretty great - incredibly minimalist in both game play and presentation - yet compelling, and very easy to pay in small but satisfying doses. I've been thinking about what it does right, and how it compares to some previous similar games --

It's Ping Pong stripped to an almost absurdist minimum - if the ball lands on the left side of the table hit left, if it lands on the right side, hit right. (There's a visual telltale, a little "X" that emerges from the where the ball strikes) Despite the seeming triviality of that, game play is still compelling - I haven't quite worked out if it's the "body language" of the opponent and the motion of the ball before it hits the table that sometimes fools me or what, but this game finds a great place on the fine line between too easy and too reflex-demandingly hard.

(Of course in my history, I'm a big fan of games with a Ping Pong / Pong mechanic and a minimalistic control scheme - my own Joust Pong for the Atari 2600 (later renamed FlapPing to avoid Atari lawyers who claim to exclusive naming rights involving "Pong") is similar in that regard, using a single button to let the player maneuver into ball-returning position.)

Swinging back to what makes a popular mobile game - the "single button the flap against gravity" mechanic of JoustPong was later reinvented for the infamously difficult Flappy Bird. There the single button lets the player push the bird up through gaps between (or more often, directly into) big pipes. This game was difficult enough to be considered "masocore" (masochist + hardcore) but was still ragingly popular for a time.

The simplified control scheme suits mobile well. The other thing Flappy Bird and I'm Ping Pong King have in common is a demand for focus - if you are not concentrating, you will lose quickly. IPPK is a bit more forgiving, though, since a match is "first to five points", thus offering a chance for redemption.

I'm Ping Pong King has a meta-match structure that Flappy Bird lacked - you work your way through a series of 50 opponents. In theory each one might be a bit harder, but maybe that only matters in the last ten, and even then the game never gets crushingly difficult. (At least for a guy who has spent too much of his life playing games, but might be getting slower in his middleage) That sense of progression adds a lot to the package, along with great aesthetics of the motion of the ball and the character.

Wednesday, December 12, 2018

yearswerve

Lately I've been working on a personal timelines project, experimenting with visualizing the course of my life so far: where I've lived, jobs I've had, people I've been with romantically, etc.

Time for humans is such an odd beast - it marches inexorably forward, yet loops back on itself in the form of days of weeks and seasons in years. In experimenting with visual representations of it, I thought back to my old hooptime illustration, showing the idiosyncratic way I place a week in physical space (like when making simple day-of-week calculations)

Back then I mentioned and illustrated my even stronger sense of the course of a year - again counter-clockwise, with January at the top, and looping back:


Of course a simple loop doesn't display a forward progression of time, so for grins today I stretched out the loop into something that also expresses the movement into the future:


(It's not entirely dissimilar from repeat until death, my attempt to animate Christa Terry's ingrained visualization of an upward spiral of years.)
You can see the full p5 version here.
I'm still very interested in the topic of how different people visualize time, and speculation on what influenced that (clockfaces, calendar pages, whatever) If anyone has an idiosyncratic time-space mapping I'd be delighted to try and make an illustration of it.

Sunday, December 9, 2018

repeatable random colors in javascript

Indiegamer olsn provides a nice function making a repeatable series of "random" numbers:

// the initial seed
Math.seed = 6;

// in order to work 'Math.seed' must NOT be undefined,
// so in any case, you HAVE to provide a Math.seed
Math.seededRandom = function(max, min) {
    max = max || 1;
    min = min || 0;

    Math.seed = (Math.seed * 9301 + 49297) % 233280;
    var rnd = Math.seed / 233280;

    return min + rnd * (max - min);
}

(Of course to quote John von Neumann: "Anyone who attempts to generate random numbers by deterministic means is, of course, living in a state of sin.")

olsn goes on to say
You may ask: Why ‘(seed * 9301 + 49297) % 233280‘ ?!The answer is both simple&complicated: The combination of 9301, 49297 and 233280 provide a very even distributed set of “random” numbers. Please don’t ask WHY – that’s the complicated part, some very smart people figured out those numbers quite some time ago, and I also cannot tell you how they did it. But as allways: Google is your friend ;-)

That bit reminds me John Carmack's Fast inverse square root where a little bit shifting and then subtracting from the magic number 0x5F3759DF gives surprisingly good results for an otherwise very expensive math calculation. 

My favorite use of finding a great random seed is in classic video games - both Pitfall! and River Raid on the Atari 2600 use it to generate huge amounts of content (for River Raid, see this page on an amazing 'bot that was taught to play it amazing well and explore The River of No Return) but I thought I might use something similar to generate a series of colors for a project I'm on - I wanted to make a series of colors that kind of harmonized but were still distinct - one trick I learned is to constrain each r g and b value to a medium-size range (or if you alternate between #ff and #cc you get some nice pastels, which is how my loveblender site got its look in the 90s which given the era, wasn't half bad)

For each part of the rgb I generate a number from 100-200:
Math.round(Math.seededRandom(100,200)).toString(16);
and that makes a series like this:




(If the inline version doesn't work you can see it in action here.)

(Note to self, Indiegamer's book From Zero to the App Store looks interesting)

Tuesday, December 4, 2018

shape detection

Daring Fireball on The Iconfactory's Linea app update - you can scroll down to the ZipShades video there - as DF quotes:
Simply draw a rough circle, square, rectangle, oval, or polygon and hold at the end. After a configurable delay, ZipShape will activate and transform your rough version into a clean, precise shape. It works with all of Linea’s drawing tools — including the new fill tool.
You don’t have to be perfect — after the shape is generated, there are transform handles you can use to tweak its final position and appearance. No rulers or stencils required!
Gruber calls that "a real standout". Which is fair enough - not many programs support that kind of interaction. But it's not a new idea -
 
that video shows a mid-90s Newton running with the concept.

But you know, it's a lot older than that - here's Ivan Sutherland and Alan Kay showing the way:

That's Sketchpad (a.k.a. Robot Draftsman) all the way back from 1963!

While Steve Jobs was right that HAVING to use a stylus on a phone-sized device was terrible, it's probably not great that it took 5 years into the life of the iPad to introduce a precision stylus, the Apple Pencil.

I'm sure CAD-software has been doing this all along, so I'm not being snarky about this being touted as revolutionary, because it's not, just conceptually cool.

Wednesday, November 28, 2018

&& short-circuiting considered harmful... or at least, a little weird

I've never adored the && short-circuit operator, where if you write
A && B
and then A is false, B is never evaluated (or if a function, never called)

To me the short circut always felt like a weird, overloading side effect of "parsing this in left to right order", even though it's just such a cute and concise thing to do its become a standard. But when I think about parallelization, it seems like && reduces parallelization, like you can't run the second part in parallel (at least if there are any side effects) since you might end up not having to do so if the left part succeeds. (Of course if you are in a heavenly pure functional program wonderland, you have nothing to fear!)

My discomfort might come from how it breaks with other forms of boolean logic - like in logic, there's kind of a commutative property -
A AND B
is the same as
B AND A
but that is absolutely not the case in this style of programming.

Thinking about it more, I wish there was something that looked more like the ternary operator, like
shouldDoSomething && doSomething()
is less clear in its intent than
shoudDoSomething ? doSomething() : null;

Still, I'm kicking against the sticks. The hip kids really dig things that are that cute and concise and it's a pretty well-established pattern.

Tuesday, November 27, 2018

quick and dirty javascript stacktrace

As I've bemoaned, debugging declarative javascript code, fixing things when you don't get the results you expect, is tough. Sometimes it's handy to take a peek at the stacktrace and try to guess at what's calling what and why, and to get a stacktrace:

var e = new Error("at some function"); 
console.log(e.stack);

seems to work ok.

Wednesday, November 21, 2018

the tag

This tweet mentions the <meter> element and shows how it can easily be used for a Amazon-like star display - hadn't seen it before. (And like all good things it might not work on IE)

Here's the meter tag with defaults:


<meter high="66" id="fuel" low="33" max="100" min="0" name="fuel" optimum="80" value="60"></meter>


 Interesting that it has concepts of "low" and "high" for like warning values...