Respect Yourself

– sung to the tune of Express Yourself.

Look around you. Are you alone? You have two things that nobody else in the entire world, past or future, will ever have. No matter how good or bad things have been, you still have these things.

Your body and your life.

Do you care about your life? Why? Why not? Do you really feel like a waste of space? Do you believe you can change the world?

This world has done a great job of breaking us down. Making it feel like we will never get anywhere in life. Making it seem like nothing matters. There are certainly many acting like nothing matters. Can you really believe that nothing matters? That you could just disappear and nobody would notice?

So you do care!

Then act like it! Why disrespect yourself?

Have fun. Its good to have fun! Party! But you dont have to destroy your body or your future to do it. You can have more parties and more fun that way!

A little alcohol is fine – our bodies can handle it. But only once in a while. Not every day. And not so much you get sick.

Heres a novel idea. You have hope for a future. What about the person next to you? The one down the street? The one on the other side of the world? Do you know their story? Do you know what they have been through? Do you know the story of every person in the world?

Didnt think so.

Then why would you talk about someone else as though you do know everything about them?

Once you respect yourself, you start to realize that every other person around you deserves the same respect. Isnt it because of other people directly or indirectly putting you down the reason that you were unsure you were worth anything? So why do that to someone else?

How do we teach this? How do we spread the idea? Hard to say. Some public schools try, but the kids often think its a joke. Other public schools simply dont have time or money to try.

What about parents? Were all so busy, trying to make enough money just to get through another day. Being ground into the dust it seems like, the very picture of the hopeless.

But you parents do have one hope: your children. Your kids know you are stressed out and hurting. What they dont know is why. They dont know the hope you have that life will be better for them because of the work you do. They may not know that they are literally your hope.

And all it takes is for you to tell them. They dont have to know every detail of how your life ended up here. And you dont have to burden them with everything you want for them. But you can tell them that your life is already better because they exist. Because you give them worth, they are more likely to believe that they are worth something to themselves too.

All it takes is for you to tell them once in a while.

Watch This Space

Watch this space.

Every year my church organizes a “men’s retreat,” one weekend a year where they rent out a place that you can have teaching sessions and a place to sleep. It’s a bit of a misnomer as you don’t really “relax” much, but you do get to have time with several other people from the church that are frequently too busy for thoughtful conversation.

Over the course of the last few years I’ve become increasingly opinionated, and willing to share those opinions in any situtaion that feels related. These opinions are based on my understanding of God’s will and my reading of the Bible.

It occurred to me at this retreat that I cannot pinpoint locations in the Bible that would support or disprove my opinions. This is something I wish to rectify.

First I plan to research each subject, looking for what other opinions and commentaries have to offer and write about what I find. The goal is to make notes about things to be watching for during phase two: re-reading the Bible, looking for and noting all the things I seek.

I have quite the laundry list of ideas to be confirmed or denied. Perhaps you’ll find these interesting too? No idea what order I will work on them.

  • When Godly people talk about themselves, they always say they fall far short of the mark of God’s Law. Why is this? Is it truly so difficult to follow Ten Commandments, and the rest of the Law of the Torah? I expect we will have to dive into the question of “What is sin?”
  • I am a God follower and a “furry,” and I feel no shame nor conflict with it. I like to think that I’m enjoying God’s creatures in a totally unusual way. But the meaning of furry is also wide and varied, and I do think there are ways to be furry that would go against God’s law.
  • As humans, we learn and grow as we go. Therefore we need to leave space in our marriages for the individuals to continue to grow, rather than call it quits because one or both people have grown in their understanding of God, the world, or themselves.
  • Marriage is a sacred vow, one that appears all too often to be broken by people who didn’t understand what it was meant to be in the first place. I believe all couples intending to be married should be trained in “how to argue appropriately,” as well as a requirement that they trust each other. With that, almost all mountains can be climbed.
  • God gave us these bodies, to care for and enjoy. So why does it seem like everyone considers sex and kinks in a healthy husband and wife relationship as a sin? What does God’s Law have to say?
  • Pornography is easily addicting. But I argue that a form of it, used in an appropriate way, is not sinful. Instead I hear God followers putting themselves down about any use of it. I argue this is simply another way God followers are led to believe themselves unworthy.
  • You should not have to change who you are to be able to keep a job. But I will agree that you can improve how you interact with others to make a job better for yourself and those around you.
  • We ask for knowledge in our times of trouble. But isn’t that what got Adam and Eve kicked out of the Garden? Is it appropriate to ask for knowledge and wisdom?

In the coming months I hope to research and pray about these topics and more in the hopes of finding some conclusions in God’s Law. This is more for my benefit, but I hope you come along for the ride.

Watch this space.

Asset Bundle #9

It’s finally time to release – the core of Asset Bundle #9!

As long time readers already know, I’ve been working with asset bundles for years. I finally got around to packaging up the core system that I’ve been solving problems with so that others can benefit from what I’ve learned.

You can learn more about it’s technical abilities from the developer site: http://bundle.dwulf.com/developer.html
And then to convince your boss to let you buy it, there’s a section of the site for them too, to make it easier to explain why you need it. http://bundle.dwulf.com
And then go buy it from the Unity Asset Store! https://assetstore.unity.com

This is the core – the part that actually downloads bundles and unpacks them. It’s currently compiled for current Unity versions, but can absolutely be rebuilt for older versions once purchased.

Over time (or based on interest) I plan to release template projects that demonstrate how I use this core to accomplish the things I talk about in my blog series about asset bundles. Want a refresher?

Hope to hear from you about questions and how you are doing neat things with it!

Coroutines vs. Callbacks: Maintaining Sanity

Why

I’ve seen a lot of Unity3d projects over the years. The first thing I look for in every project is one critical piece: how does it handle asynchronous tasks. In Unity, there is a limitation that you can only talk to the engine on one thread or “train of thought.” Asynchronous tasks are how the project appears to do two things at the same time, even though they are actually only using one set of tracks. There are two very common reasons to need asynchronous tasks.

The first is for networking with a server. The Internet takes time, no matter how fast or strong the connection you have to it. And you can’t just make the entire game halt while you wait to talk to the server. Everything is on that one track – including drawing your game. If you wait for the network response, your game isn’t drawing anything at all. It just freezes.

The second reason to need asynchronous tasks is to load assets. If you’re loading a new level, it takes time to load all those neat objects and textures you spent so much time and effort into creating. Even for simple levels, most of the time it’s pretty fast. But these devices are doing a whole bunch of other things like checking your email. Sometimes it can take minutes!

Fortunately, most games don’t actually need this asynchronous ability. They can get by with freezing the screen for a moment and then moving on. Therefore typical Unity tutorials do nothing to teach about it. This is a real problem! Tutorials don’t offer much for best practices. This leaves many coders casting about for their own solutions, which often end up overcomplicated and wasteful. Worse is the fact that retrofitting the code is often very difficult.

Coroutines

Unity handles asynchronous tasks with a C# idiom called “coroutines”. They are a way to turn a regular function “inside out”, breaking it down into steps that will stop when the coder says so, allow it to do something else, and then come back later to where it was. The technology is part of the C# standard, which turns a method containing “yield return thing;” into an IEnumerable class that the caller uses for its side effects.

What Unity adds is StartCoroutine to most of the common classes to run those IEnumerable classes for you. This works fine in most cases. Until something goes wrong! Unfortunately, error handling isn’t included. If the coroutine method throws an exception, the most you get is an error in the log. It completely breaks anything that’s waiting on the coroutine, just jumping off into nowhere, with hardly any way to recover or even find out what happened!

Another place coroutines fall down is for returning values. Coroutines cannot have “out” or “ref” parameters. This means to get a value out of an asynchronous process, you have to pass in an object that will get the resulting value and then read from that.

Callbacks

Another standard C# idiom is the “callback.” These actually seem easier to use than coroutines, because you can create callback handlers just about anywhere. At the place you start an asynchronous call, you can immediately declare an “inner” method to handle the result of that call. All of it just happens for you, nice and clean.

Until you have to chain a bunch of tasks together, and properly deal with errors at any stage of the tasks. Suddenly you’re facing what I will refer to as “boomerang hell.” This is where there are so many callbacks and inner methods that the intent of the code is unreadable. Let’s start with a real world example. We need the game manager to “load next level.” This makes a server call to find out what the next level is. Back in the game manager, it asks the level manager to load the level. And then the game manager asks the game piece manager to load the player’s pieces based on the server response. Only then it ‘switches’ the game mode to the new level. Here’s what that would look like with callbacks.

public class GameManager
{
	 public Promise LoadNextLevel()
	 {
	 	var result = new Promise();

	 	var getNextLevelToken = _networkManager.GetNextLevelFor(_player);
	 	getNextLevelToken.OnSuccess += (getNextLevelResult) =>
	 	{
	 		// load the level
	 		var loadLevelToken = _levelManager.LoadLevel(getNextLevelResult.levelName);
	 		loadLevelToken.OnSuccess += (loadLevelResult) =>
	 		{
		 		// and start loading the pieces
		 		int numWaiting = 0;
		 		Exception lastError = null;

		 		// call when all pieces are done
		 		var loadPieceDone = ()=>
		 		{
		 			if (lastError == null)
	 				{
	 					// All finished without error.
	 					SetGameMode(getNextLevelResult.levelName);
	 					result.Succeed();
	 				} else {
	 					// error.
				 		// Note how we add information to the exception, creating nested Exceptions as a kind of higher-level stack trace
				 		result.Fail(new Exception("Trying to load next level "+getNextLevelResult.levelName,innerException:lastError));
	 				}
		 		};
		 		foreach (var name in getNextLevelResult.levelName)
		 		{
		 			var loadPieceToken = _pieceManager.LoadPiece(name, _player);
		 			numWaiting ++;
		 			loadPieceToken.OnSuccess += (loadPieceResult) =>
		 			{
		 				numWaiting --;
		 				if (numWaiting == 0)
			 				loadPieceDone();
		 			};
		 			loadPieceToken.OnFail += (error3) =>
		 			{
		 				numWaiting --;
		 				if (numWaiting == 0)
			 				loadPieceDone();		 				
		 			};
		 		}
	 		};

		 	// deal with errors appropriately
		 	loadLevelToken.OnFail += (error2) =>
		 	{
		 		result.Fail(new Exception("Trying to load next level "+getNextLevelResult.levelName,innerException:error2));
		 	};
	 	};

	 	// deal with errors appropriately
	 	getNextLevelToken.OnFail += (error1) =>
	 	{
	 		result.Fail(new Exception("Trying to load next level.",innerException:error1));
	 	};
	 	return result;
	 }
}

Notice how it is almost easy to read, until you add error handling. Then it gets long and difficult to read the flow of the method. And you will need error handling! You can’t just leave your players out in the cold with no indication that something happened.

A common response to this situation is “then make your methods do less.” At that point you’re making it even harder to work out the flow of what should happen.

Coroutines?

Let’s take another look at what that task would look like with coroutines. This time, we are going to use some custom wrappers that get around some of Unity’s limitations.


public class GameManager
{
	// caller will do self.Run(_gameManager.LoadNextLevel());
	public IEnumerator LoadNextLevel()
	{
		// make server call
		// This 'Run()' is a wrapper on StartCoroutine().
	 	var getNextLevelToken = Run(_networkManager.GetNextLevelFor(_player));
	 	yield return getNextLevelToken;
	 	if (getNextLevelToken.Failed)
	 	{
	 		// returning an exception automatically stops this coroutine.
	 		// Note how we add information to the exception, creating nested Exceptions as a kind of higher-level stack trace
	 		yield return new Exception("Trying to load next level.",innerException:getNextLevelToken.Error);	
	 	}

 		// load the level
 		var loadLevelToken = Run(_levelManager.LoadLevel(getNextLevelToken.levelName));
 		yield return loadLevelToken;
	 	if (getNextLevelToken.Failed)
	 		yield return new Exception("Trying to load next level "+getNextLevelToken.levelName,innerException:getNextLevelToken.Error);

	 	// start loading all game pieces.
	 	var pieceTokens = new List<Promise<GamePiece>>();
 		foreach (var name in getNextLevelToken.levelName)
 			pieceTokens.Add(Run(_pieceManager.LoadPiece(name, _player)));

 		// wait for all pieces to finish loading.
 		foreach (var token in pieceTokens)
 			yield return token;

 		// Any of them fail?
 		foreach (var token in pieceTokens)
 		{
 			if (token.Failed)
		 		yield return new Exception("Trying to load next level "+getNextLevelToken.levelName,innerException:token.Error);
 		}

		// All finished without error.
		SetGameMode(getNextLevelToken.levelName);
	 }
}

Isn’t that so much easier to read? You always know what steps are going to happen in what order. And as an added bonus, if something were to interrupt the flow like the game being force closed, or the caller being deleted for some other reason, this will automatically stop and clean up after itself.

What madness is this? How do we get such magic for ourselves? You can get the latest at GitHub.

In another post, we will dive in deep on the design and use of this magical wrapper.

Never Burn Money

Discovery

Your project has been running for years. It’s been through so many hands that nobody understands the whole thing. It is just too big. But it’s also too big to start over, too much has been invested in it. Unfortunately, the code was not well designed and is just getting worse with each new desired feature. We made a coding standard for all new code going forward, so why is it that things seem to be getting worse and not better? How can we fix this mess of spagetti?

The reason nothing is getting better is that nobody knows where to start from when adding a new feature. The code is so large that when you want to add something new, you don’t know what to build it on top of. There are no layers of the original app, because it’s grown over with the vines of so many special cases that were added by the coders before you. So everyone reinvents the wheel each time, making the project even larger.

But all is not lost! There is still a path to redemption!

What is really wrong is an issue of discovery. The project is so big that nobody knows the ‘best practice’ for this project to do any given task. “I want to make a scrolling list of UI items.” There’s a whole lot of ways to do that, and because this project is so big, there’s lots of examples. But none of them do quite what you need, or it could be more efficient. So you make your own version which does it better. And the next person comes along and knows _nothing_ about what you wrote, so they do it all over again.

The solution is actually very simple: an index document that lists generic tasks and points to specific examples of code that solve those tasks. In the Index, you’d search for “scrolling list of UI”, and it points to an exact file that demonstrates that task. Or it could get even more specific, like “for a few elements” and “for many many elements” and “with group headers”, all pointing to different examples in the code. With each entry it lists a one sentence blurb that clarifies what makes that example different from the others in the category.

One of the bonuses of an index document is that it can be searched easily, as there should not be a large amount of content for each kind of task.

Homework

A couple months go by. There are finally some good examples of doing several things in the project. The index document is pretty stable these days. But the project is still getting bigger somehow. What’s going on here?

We’ve started creating these ‘clean’ examples, but nobody is making them re-usable! They’re only doing copypasta!

The failure is that the app is not being designed in layers. When a new feature is requested, the code is being copied from the template instead of refactoring the template to provide shared code for both the template and the new feature. New rule: to add a feature you must add a layer, not modify existing code. You can refactor existing code to make that new layer, as long as you support the original with its own layer on you refactored base.

This sounds like a heavy burden in such a large codebase, but that will only happen when first starting out. It should happen less and less often, once we start doing it in earnest. This is because the more layers we add, the less special cases will be needed.

RAM

So that fixes that. Right? Not quite. This entire process change is a new coding standard. And if we’re doing our job, the coding standard will continue to improve, covering new situations that we haven’t handled before. Now we have an index file that’s pointing at the old examples, which don’t match the new standard. It’s still a better situation than we started with, true. But how can we tell that the examples are all following the latest standard? We can’t.

Yet again, there is a simple solution to this problem too. We ‘version’ the standard. With human understandable numbers, like ‘2.0.’ As we update code to adhere to a new standard, we simply comment the source file with a header mentioning “Code Standard 2.0.” The rule would then be: if you don’t see a coding standard tag, you’re not allowed to use it. If you see a tag but it’s old, verify that it still meets the latest standard and update the tag.

For ‘core’ objects that is used by many things like UIController, one tag for the header isn’t really enough – instead it gets included in specific method definitions. The idea is the same.

We can even extend this to best practices in our prefabs! A simple single MonoBehavior component that stores an enum of a coding standard version. Along with the Note component for commenting, it will clearly identify that the GameObject and children of that hierarchy are correctly following a given standard, and is therefore safe to use as a starting point for a new UI or system.

And there we have it. A way to untangle the mess without losing your hair.