What is Luck?

Category : Design, Games, Mathematics, Meta-Thinking, Rationality · No Comments · by Sep 22nd, 2015

Richard Garfield, the designer of Magic the Gathering, defines luck in his ITU Copenhagen talk as “uncertainty in outcome”. I think by modeling human reasoning as Bayesian, we can come up with another fruitful, if not a more fruitful, definition.

Suppose I were to take out a quarter from my pocket and ask you to guess my next twenty flips. You perceive the heads/tails probability to be 50/50 with high confidence, and so your accuracy on my first three flips, which turned out to be all heads, is very heavily luck based.

Now suppose that my next fourteen flips are all heads. At this point, you will be quite certain that the game was rigged, and your heads/tails probability becomes 100/0. Indeed, your next three guesses are correct. Curiously, at this point in the game we no longer perceive luck as being involved.

In Bayesian speak, our 50/50 distribution is our prior belief, and 100/0 distribution posterior belief. Note that we consider the prior (no pun intended) to be highly random, whereas the latter not so much. Wikipedia defines random as “the lack of pattern or predictability in events”, which suits our current purpose. We will roll (pun intended) with it.

Now another example.

Suppose I leave right now to catch the next bus to work. The bus arrives just as I get to the bus stop. How lucky!

Now suppose I tell you that I have memorized the bus table and had been stealing glances from the wall clock while talking to you, cutting our conversation short when it’s time to leave. The bus arrives just as I get to the bus stop. Not very lucky, but pretty calculating.

This example is insightful in two ways. Firstly, to be perceived as lucky I don’t have to intentionally make a choice. As long as the outcome benefits me, I seem lucky. Secondly, we can make things seem less luck-based via additional information. My new prior (which is my posterior after memorizing the timetable) was good enough to reduce randomness. What appears to you as random may be fairly predictable for me. Randomness can be subjective. In fact, it often is. The stock market, weather patterns, and even the search for a good romantic partner can be predictable for one and random for another. Thus, a definition of luck necessarily takes subjectivity into account.

So I think that perhaps a better definition for luck is “when apparently unpredictable outcome offers high utility”. In Bayesian speak, when an outcome of good utility occurred despite a prior that doesn’t favor it. We should note too that utility, which is subjective too, also affects our perception of luckiness. In a bet with 90% chance to win one million and 10% to loss one million, the winner is still declared pretty lucky. Our perception of utility is biased. In the case of loss-aversion, sometimes the bias is advantageous.

Prior and utility are both extremely malleable, and a variety of cool insights arise (a.k.a. this is an insight dump where I stop being good at explaining things):

  1. Extremely complex conditions gives rise to priors of similar quality to everyone. In guessing the 567,890th digit of pi, everyone starts on the same prior.
  2. In fact, if the universe is deterministic, the reason that statistics and probability exists in the first place is because events are too difficult to predict. In that case, there would be no true prior other than “X certainly will happen”. Our predictions will necessarily always be approximations and guesses (a guess that can only be exact if it also states that “X certainly will happen). If the world is deterministic, probability is a summary of what we don’t know.
  3. Depths of gameplay may arise from a sufficiently complex condition that allows continual optimization. A first card drawn from a nicely-shuffled deck is complex because shuffling is complex, but shallow because we don’t hold any information that can visibly optimize our prior. A card drawn during the middle of the game is complex not only due to shuffling but also due to a significant number of cards already in play; however, this draw is less shallow because we can use the cards in play to optimize our prior if we wish. When we are down to the last dozen or so cards, the draws are actually deeper because we now have very concrete information to optimize from.
  4. When you meet people who to you seems perpetually lucky or unlucky, you should strongly suspect your priors.
  5. Knowledge on probability, statistics is very valuable.
  6. Knowledge about how to improve your priors is extremely valuable. It’s a prior on how to change your prior when you see rules. See factors of correctness. A hidden value in Bayesian models is actually a value or a prior on confidence (the resilience your priors are to change). The phenomenon illustrated in factors of correctness might point to variability of the of underlying prior on confidence. It seems like more research should be done in that area.
  7. Disguising depth through luck allows new players an excuse to feel better. It’s a desirable feature of design.
  8. The best estimation for probability is set in stone, so our versatility (once we have a good prior) comes from selecting our situation such that the most likely outcome yields optimal utility. Something like betting on heads on a rigged coin or timing our leave for the bus.
  9. Complexity is a gradient scale but has very different design properties on different logarithmic scales.
  10. To artificially add luck to anything, create a situation where everyone has the same starting prior. (i.e. dice roll, coin flip, atmospheric pressure).
  11. For fun (not for profit), to make yourself more “lucky”, put yourself in situations where unsuspecting high utility situations may occur, without much probability of low utility situations. This might explain why people who are more curious finds more pleasant surprises.

Why is Writing for Games so Difficult?

Category : Design, Games, Writing · No Comments · by Aug 5th, 2015

link-animated

I’ve been watching walkthroughs for The Last Express. Funny that a concept I thought was innovative a year ago has in fact been done close to two decades ago.

As a game designer, I often find myself awkwardly maneuvering game elements in order to fit the story. Why is writing for stories so hard? I think the problem is interactivity.

Consider the traditional written or oral tale. In the story, not every minute gets assigned equal weight. Seconds, days, or years that are not essential gets skimmed over. This is the convention, without which both writing and reading would be unbearable. Movies embrace this convention through cuts.

In order fit a good story to a game, we naturally want to extend the above analogy to games, but interactivity works against this in three important ways:

1. Major gameplay sections usually do not support the “cut to the interesting part” structure.

2. Conventionally, gameplay sections must be engaging, which does not necessarily correlate with interest points within the story.

3. Gameplay affords the opportunity to deviate from a single storyline, often in so many ways that covering all scenarios is prohibitive in terms of cost.

In any given imaginary timeline, in order to seamlessly integrate story and gameplay, we must slice the timeline in a way that satisfies both the conventions for good story “cuts” and the conventions for good gameplay “cuts”. #2 and #3 are both difficult to account for while maintaining a good tempo for story, and #1 seems outright contradictory to the convention of a good story “cut”, unless the story or the game mechanics are somewhat special.  Writing and gameplay are not a true dichotomy, but it’s clear that extremely specific requirements must be met to optimize both simultaneously.

If the player is playing as a character in the game, then the “seamless integration” would also have to carefully avoid ludonarrative dissonance, a complex topic (and navigation) in its own right.

I think designers who write existing stories into their games are in a world of hurt, yet most games now still ship with an existing storyline. I think this is because for a long time, existing storyline is the only way of storytelling we know of.

So what are some potential solutions? The Last Express incorporates a highly interesting setting to sustain engagement throughout a stable timeline, while utilizing vast amounts of writing and technology to work around #3. Forgoing elaborate stories altogether may be a good choice (consider Threes and Angry Birds). Simple but well-crafted stories may be effective (Shadow of the Colossus) too. A sense of determinism can be built into the game to combat #3, which may also suitably evoke a sense of the tragic.

I think that increasingly, building the narrative out of player experiences rather than in-game story has become a popular choice. Games like Pokemon, League of Legends, and Journey have minimum built-in stories and rely on gameplay scenarios unique to each playthrough to generate evocative stories. One can think of this as analogous to “emergent gameplay”, expect instead we are designing for potent story scenarios – “emergent storytelling”.

Unity 2D Tips and Tricks

Category : Coding, Design, Games, Productivity · (1) Comment · by May 28th, 2015

While the 2D features in Unity3D gets a lot less love than the rest of the engine, Unity3D is still a very powerful tool for rapid prototyping in 2D given some customization. Since the 2D features leverage design decision catered toward 3D, there are occasional gotchas in 2D as well to be aware of. Here I detail some of the tricks and gotchas I noticed while working with 2D in Unity.

In general, it is a VERY GOOD IDEA to extend the given MonoBehavior class to create shortcuts for verbose but necessary instructions. The shortcuts can be implemented by way of C# properties. This reduces clutter in code and leads to less bugs. In fact, all but one of the “tricks” uses this to simplify 2D programming.

Tricks:
1. Barring very special cases, most of your objects are going to have the SpriteRenderer component. When extending MonoBehavior, you can implement a shortcut to access spriteRenderer:

private SpriteRenderer _spriteRenderer;
public SpriteRenderer spriteRenderer{
	get{
		if(_spriteRenderer == null){
			_spriteRenderer = GetComponent();
		}
		return _spriteRenderer;
	}
}

The _spriteRenderer in this code caches the spriteRenderer to skip extraneous costly GetComponent calls.
Now, monoExtendedObj.GetComponent() can essentially be replaced with monoExtendedObj.spriteRenderer.

2. Angle manipulation in 2D is usually limited to rotation on the Z axis. However, to specify Z rotation you must go through Quaternions, which are necessary for 3D rotations. We can shove the messy quaternion operations under the rug by defining a custom “angle” property:

public float angle {
	set {
		Quaternion rotation = Quaternion.identity;
		rotation.eulerAngles = new Vector3(0, 0, value);
		transform.rotation = rotation;
	}
	get {
		return transform.rotation.eulerAngles.z;
	}
}

Note that when getting a value from this property, you will always obtain a value between 0f and 360f. If this is undesirable, consider defining a private variable that stores the non-moded angle value.

3. Alpha (opaqueness) values require dealing with colors property of the spriteRenderer – an extremely verbose operation even with the existing spriteRenderer shortcut. This property lets you set transparency of the spriteRenderer easily

public float alpha {
	set {
		if(spriteRenderer != null){
			Color _color = spriteRenderer.color;
			spriteRenderer.color = new Color(_color.r, _color.g, _color.b, value);
		}
	}
	get {
		if(spriteRenderer != null){
			return spriteRenderer.color.a;
		}
		else return 0;
	}
}

An alpha value of 1 or more is fully opaque; 0 or less is fully transparent. The values are not clamped between getting and setting so that the alpha may double as a transparency counter/timer. However you might want to use a Tweener to achieve timing effects more gracefully.

Tips:
1. Most graphic bugs from your 2D game will come from drawing order or faulty z-values. Unity3D’s ordering scheme for 2D sprites is versatile but also confusing. The determining factors for sprite ordering are (from highest to lowest priority):
-Sorting Layers (Bottom ones in the Unity UI are drawn on top)
-Order in Layer (Higher orders are drawn on top, negative values are possible)
-Z value (Closer in camera line-of-sight (LoS) drawn on top)

By default, the camera is at a height of 10 with LoS pointing downward. This implies that without changing the camera, higher Z values are drawn on top. HOWEVER, the camera also has a near-clipping plane of 0.3, meaning that it will not see anything closer than 0.3 units away from the plane perpendicular to the camera LoS (using default values, any Z-value > 9.7).

Finally, note that Order in Layer is a signed short ranging from -32,768 to 32,767. Attempts to utilize numbers outside of this range will likely mess up your drawing order.

There are several takeaways from this. The first is that you should be careful with modifying default camera values unless you are certain about how camera works in 2D. The next is that while working with dynamic Order in Layer and/or Z values are convenient, you will be working with their respective constraints. In general, Z values are better for handling cases where many more layer values than 64,000 are needed (this does occasionally happen), but can cause sprite to disappear if you are not careful. Z value is also a float, so keep rounding errors in mind.

2. Unity3D’s particle and trail renderers do not have their “sorting layer” field exposed, and that’s terrible because suddenly you cannot control the drawing order of your particles and trails.
To fix this, write a custom component that has the below code and attach to your particle or trail renderer:

void Start () {
        //Change Foreground to the layer you want it to display a particle
        //system on, otherwise particles will not show up.
        GetComponent().GetComponent().sortingLayerName = "YOUR_LAYER_NAME";
}

Note that this will set your object’s drawing layer to a static layer called “YOUR_LAYER_NAME”. If this is not your wish, or you prefer to select the drawing layer in the Unity3D UI, check here to obtain a list of drawing layers and work from there.

3. As these reddit users have found, Unity3D’s 2D collision detection system will make your life very tough if you do not use physics. This is problematic for a lot of simple 2d games where physics would either be a overkill or make debugging difficult.

I have found that the 3D collision detection system has much less stringent requirements. You must still have at least one rigidbody per collision detection, but if you tightly control the z values of your objects (usually by clamping it to 0), you can get around a lot of weird issues that arises in 2D collision detection without physics.

Note that doing both this and ordering with Z value can get hairy fast. Avoid one or the other.

4. Often it is useful to know the dimensions of the sprite either at import time or after stretching, the variables below have very similar names, but only some will be correct:

SpriteRenderer.sprite.rect will specify the size of the sprite in pixels.
SpriteRenderer.sprite.bounds.size will provide the rectangle bounding box of your sprite before scaling in game units. The size of this bound is usually SpriteRenderer.sprite.rect divided by it’s “pixel per unit” under the sprite import settings.
SpriteRenderer.bounds.size will provide a rectangle bounding box of your (sprite)render as it appear in the game, which means after stretching SpriteRenderer.sprite.bounds.size through transforms.

All .size can be replaced by .extents to obtain a box with each dimension halved, this is a useful shortcut when only the size of half the bound box is required.

These are all I have regarding 2D, for now! I’m planning on starting a general Unity3D tips and tricks post soon, and most of that post will apply to 2D as well, so stay tuned!

CS425- Virtual OSPF Router Postmortem

Category : Coding, Design, Reflections · No Comments · by May 21st, 2014
CS425- Virtual OSPF Router Postmortem

I have redeemed myself from the disgrace that is Networking homework! Through approaching the program in a systematic manner, I…