A Tale of Poor Exception Handling

Today we have a tale of good intentions and failed implementation. A tale of misleading results and frustrating debugging. A tale that has happened countless times in software systems around the world and will continue to happen countless more times in the years to come.

Our tale begins as our hero starts a new week. The previous week was a big one for our hero, who finished the week with the merge of a major update our hero’s team had been working very hard on. This merge was rather large, so our hero was paying very close attention for strange application behavior that could be attributed to the merge.

During the morning status meeting, the team begins discussing the fact that a team member has not been able to log into the app since they arrived earlier that morning. Our hero becomes concerned, pulls down the latest code, and runs the app. Sure enough, the app is preventing users from logging in.

Our hero’s quest has begun.

The application in question is a mobile application which connects to a back-end API. The code has been developed by a third party, which is no longer involved. The application was originally developed as a proof-of-concept. Alas, the proof-of-concept code became production code, bringing with it all the proof-of-concept “get it done quickly” decisions and technical debt. It is at this point that our hero’s team becomes involved.

There are many points at which a failure could be happening to prevent a user from logging in to the application. Our hero begins by adding breakpoints to the mobile application code in the hopes of finding an obvious cause of the problem.

The first pass through hit one of the expected breakpoints, then skipped the rest and instead hit the breakpoint in the exception handler block. The “exception handler” block does nothing more than log the exception and move on. In other words, it swallows the exception. Since our hero’s team is not responsible for this code, it is not their responsibility to fix it at this time. Our hero notes that the exception being caught is a NullReferenceException. Our hero finds this highly unhelpful and is forced to run the code a second time, this time stepping through each line of code after the first breakpoint. Lo and behold, our hero finds the offending null reference. It is a variable that was returned from a method as null and was subsequently used by the remaining code without a proper null check. Thus, the NullReferenceException.

To learn the true cause of the null reference, our hero must dig deeper.

Our hero runs the app a third time, eventually stepping into the null returning method to find yet another exception swallowing block catching yet another NullReferenceException. This exception swallowing block was slightly different, though: it returns null in the case of an exception. Our hero is looking at a method which catches a NullReferenceException and handles it by itself returning a null reference.

Our hero comes to the cold realization that this is going to be a very long quest.

Undaunted, our hero forges on. Method after method, our hero descends the call stack. Battling missing null checks and swallowed NullReferenceExceptions at every level, our hero is determined to find the source of the problem. Deep down, in the bowels of the application code, our hero scrolls and steps and scrolls and steps until… Finally, our hero sees something different! Through blurry eyes, our hero squints at the code on the screen.

What is this? our hero thinks. It looks like an HttpClient…

It is!

Wait… It’s receiving a 500 error from the server.

At that moment, after tracing the nulls through a labyrinth of unnecessarily complex code with extremely poor exception handling, our hero is staring at the abyss as the sad understanding washes over.

The original error isn’t coming from the mobile code at all. It’s coming from the API code on the server.

Our hero stares incredulously at the code for a moment longer. Then, unwilling to be bested by poorly written code, our hero takes a deep breath and leaps into the abyss.


It’s dark here. And cold. So cold.

Our hero takes a moment to survey the surroundings. This is the server, all right.

Our hero gets right to work looking for the logs. A few clicks later, the logs are on the screen and our hero begins inspecting them.

There’s the authentication request! And there’s the error! Hooray! The API issue is going to be easy to diagnose!

StringFormatException, our hero thinks. I can look at the API endpoint code to find where a string is being formatted incorrectly and claim victory!

Our hero does just that. There’s the API endpoint code. A quick scan of the method and… There! That’s where the code is incorrectly formatting the string! The IDE has even helpfully underlined the offending code with a green squiggly. Problem solved!

Wait a minute…

What is that code trying to format?

It looks like it’s trying to format an exception message…

Our hero quickly looks the code over. Sure enough, the code in question is the exception handling block. The exception handling block is catching an exception, then failing to format a message with it for the logs, and, therefore, causing the API to return a 500 error.

Our hero’s heart sinks.

More poorly written exception handling code. More line by line debugging and traversing the call stack.

Our hero rallies.

It can’t end like this. I must find the source of this exception!

Our hero sets up the server code for local debugging, sets some breakpoints, takes a deep breath, and sends a request.

Line by line, method by method, our hero continues the quest. This time, battling StringFormatExceptions.

Until…

There it is. The cause of all of this. After seeing several exception handlers catch exceptions and then throw their own due to poorly written string formatting code, our hero is staring at the real root cause. A null reference that is a true null reference. Not one caused by poorly written exception code. But an actual null reference caused by a member being used without being properly initialized.

Our hero looks at the commit history. Sure enough, there is code that was inadvertently removed by a team member.

Our hero re-implements the code and runs the server code locally again. This time the server code handles the request flawlessly. Our hero gets excited. The mobile application moves past the login screen.

This is real progress!

The mobile application continues to show the loading spinner. Our hero waits patiently. Seconds tick by. Our hero gets anxious.

Then, a flash. The mobile application changes screens. Success! The user can log into the app now!

Our hero sits back, exhausted, and looks at the page displayed by the mobile app.

Wait. Something is wrong. That’s not the correct page.

Our hero quickly brings up the code that navigates the user after logging in, sets some breakpoints, and runs the application again.

First breakpoint hits. Excellent. Next breakpoint… Wait. Exception handler breakpoint?

Our hero stares at the screen in complete disbelief.

A NullReferenceException.

NOOOOOOOOOOOOOOOOO!!!!!!!!!!!!

Share

Coding with Kids

As a professional software developer with four kids of my own, I’ve played around with different ways to introduce my kids to some of the basics of coding. We’ve tried a few different tools and exercises and my kids always seemed to enjoy it.

However, I never took it beyond just some fun with my own kids. That is, until my oldest daughter suggested I try sharing some of it with her class. That suggestion got the ball rolling and, before I knew it, I had a date lined up with four different classes comprised of over 100 kids at their Montessori school.

The experience was awesome.

We broke it up into three sessions, with the first session being older kids (grades 4-6) and the other two being younger kids (grades 1-3). In the process, I learned a few things about what worked well and what didn’t work as well.

In this post, I’d like to talk about what tools I used, the plan I came up with, the actual execution, and what I learned from it all. It was a lot of fun and I saw that the kids were really interested in learning more about working with computers. Hopefully my experience will inspire other software developer parents to at least sit down with their kids and explore the world of coding. Who knows, maybe that will lead to a day of coding at their school too.

The Tools

Right now is an excellent time to teach kids how to code. There are a lot of great tools out there that take different approaches to learning. And it’s becoming “cool” to learn how to code. That combination opens up the door to a much more broad audience than ever before. Below is a list of technologies my kids and I have played with:

  • code.org – This might be the best place to start (and it’s what I used with the school kids). There are Hour of Code activities, teaching materials and plans, and they now even have a very nice and simplified visual coding environment.
  • Scratch – Developed by MIT, Scratch is a very popular visual coding environment. It was developed long before the code.org environment and it’s a little more advanced. This is the logical next step for kids after they feel comfortable with code.org. My 6 year old even enjoys just playing other kids’ games (you can create a free account and share your games with others). Here’s a good place to start, if they haven’t already tried Scratch: https://scratch.mit.edu/projects/31407152/
  • Scratch Jr – It’s Scratch, but aimed at younger kids. This is another good first step because it is another very simplified visual coding environment. It’s a mobile app that works best on a tablet.
  • Swift Playgrounds – This is an iPad app that teaches kids how to code using Apple’s Swift programming language. Swift is used to write apps for iPhones and iPads. The app has a similar sort of feel as some of the Hour of Code exercises from code.org, but it’s real Swift code that the kids see and work with. My 9 and 12 year olds really enjoy this one.
  • Beginning Game Programming for Teens – This is an article about game programming with Python written by a teen for teens. It’s definitely more advanced than the other options so far. However, it introduces kids to writing actual code, not just a fun and colorful abstraction layer. I followed along with it a while back to see if my kids would like it and was able to make his examples work, with some minor tweaks. Hopefully that was only necessary due to my setup, though. My kids weren’t quite ready for this one yet when they tried it, so it kind of faded away.

Other than the Game Programming article, these tools are aimed at absolute beginners. They abstract core programming concepts such as commands, variables, logic flows, and looping with an easy to understand visual approach to coding. They are very approachable, even for non-technical people, to help kids begin to learn what it means to create a program, see the results, and debug it when something doesn’t work as they expect.

The Plan

For my day of coding with the kids at school, I chose to use materials and the development environment from code.org. I worked out a plan that kept things simple, yet fun. It was comprised of three parts:

  1. Overall introduction to computers and coding. Talk about how important computers are in today’s world. Yes, smart phones and tablets are computers.
  2. Introduce the concept of commands using Graph Paper Programming. This is a physical exercise in which kids write “programs” that their partners will “execute” to fill in cells of a grid to make pixel art.
  3. Make a game from scratch using the Play Lab. The game I chose to do was called “Chase the Zombie”. Add two “actors” to the game, one to control and the other to catch. Simple enough to program in 45-60 mins, yet still fun enough to keep the kids engaged.

For the older kids, we planned to let them use Chromebooks provided by the school. We scheduled 2 hours, with the intention that the kids would have the last 30 mins to start to explore and roam, while I help out when they get stuck or have questions. The group was going to be fairly large (~60 kids) and the school doesn’t have enough Chromebooks for each student to get one. However, I actually saw benefit in having them pair up. After all, Pair Programming is a thing for a reason. I was hoping pairing the kids up would cut down on the number of questions I would have to answer overall.

For the younger kids, I thought it best to project my screen and do more of a guided session. I was hoping that would give the kids the opportunity to see it happen and play around as I keep it interactive and ask for help throughout, but not put the responsibility on them to completely drive the process. We planned for 1.5 hours for the younger kids.

The Execution

On the day of, the older kids were up first. Again, we had them organize into groups of 2 or 3. That really did help cut down on the number of questions because they didn’t need to get me involved until all the kids in the group were stumped. With that many kids, it was still pretty loud and chaotic. However, it seemed as though the kids were excited about the experience and I got a positive vibe overall from the room.

We started out with a brief intro, then started getting into the Graph Paper Programming exercise. I think the best thing to do for this would be to work through one example as a group, before turning them loose. That was my first lesson learned. In the interest of time, I described what needed to happen, then set them loose. Some kids understood how it worked right away and others needed to be walked through it more. Overall, this ended up going fairly well, once everyone understood what they were doing.

Next up, we switched gears to the code.org development environment with the promise that the kids would be making a game from scratch. That got them pretty excited. I projected my screen and walked the kids through the environment, then got to business. I had planned out how to layer the pieces in with a sequential story of sorts. For example, “Add an actor to your game. Now run it. Ok, now should we make your actor move down? Good, now let’s make the actor move all the other directions.” And so on.

Early on, I could tell that some kids already had some experience with coding and it became obvious that making them stick to my plan would hold them back. So I let those kids roam free for the majority of the hands-on computer time and focused on the kids with little to no experience. It was neat to see what the experienced kids came up with along the way. However, that did cause some distraction to the lesser experienced kids because they sometimes saw something different than we were doing and wanted to try it, then get stuck. Overall, it was just short of chaos, but the process still went surprisingly well. 2 hours ended up being the right amount of time for that group.

After wrapping up with the older kids, it was time to move on to the first group of younger kids. Unfortunately, we got started a little late, due to a miscommunication. However, the time we had ended up being just about perfect. The Graph Paper Programming went about as well for them as it did for the older kids, which is to say it went well with some room for improvement. The decision to make the code.org portion a guided exercise proved to be a good one. The kids loved to be able to see the game take form, especially being chosen to test it out at every step. Overall, really good engagement from them. My 12 year old, Grace, was also able to tag along and help answer questions too, which was fun.

Moving on to the final group of the day, the second group of younger kids, everything seemed to go by much more quickly. Probably due to a combination of starting on time and myself having had some more practice leading the experience by that point. This group was also very engaged. They had great questions, threw out some great ideas to try, and were just about jumping out of their seats to be chosen for each of the test runs. It went by so quickly and smoothly that we found ourselves finishing up with my prepared plan about 30 mins early. We used the opportunity to cover some additional topics and even make another game from scratch.

What I Learned

First off, I had a great time doing this. I had done a practice run with my kids and some neighborhood kids in the weeks leading up and was able to make some tweaks to my approach. I think it went very well overall and it sounds like the kids agreed. My kids told me after school the next day that lots of their classmates were working on coding throughout the day, which I was happy to hear.

Here’s the lessons I learned:

  1. The first lesson I learned is actually something I already knew to do from presenting at conferences: practice. Doing a test run with my kids and some neighborhood kids validated that I could do what I needed to do in the time planned. It also showed me some things that could be improved in how I framed the conversation.
  2. The next lesson I learned is in regards to the Graph Paper Programming, as mentioned above. Take the extra time to walk through an example prior to setting the kids loose. We also only spent around 20 mins on this exercise. I don’t feel like it was too rushed, other than some kids needing further explanation. But I do feel like that exercise alone is interesting enough to make stand alone session. That’s how they planned it with the code.org materials as well. However, I wanted to use it to kick things off, then move on to making a real game.
  3. With a younger kids, particularly 1-2 graders, it really helped to keep the coding portion more of a guided group exercise, rather than an individual hands-on exercise. The kids seemed to still really enjoy it without dealing with the confusion of not understanding what to do next.
  4. With the older kids, I learned that there are kids out there doing this stuff already and they can do some neat things with someone there to answer questions along the way.

Conclusion

The biggest take away I had from this experience is that there is a lot of curiosity around coding out there. Not all of these kids are going to grow up to be software developers. However, that didn’t stop them from having fun learning about how computers work and how to program them. I really enjoyed having the opportunity to introduce them to it and being there to experience their excitement as they were able to make a game of their own come to life.

Hopefully this is only the first of many such opportunities!

 

Share

I’m speaking at NDC MN 2018!

Norwegian Developer’s Conference (NDC) is one of those conferences I’ve heard about for years and always wanted to check out someday. Since it was located in Norway, I didn’t think I’d ever get the chance. However, it’s coming to St. Paul Minnesota May 7-10 2018, and I’ve been selected as a presenter! It really is an honor to be selected for a conference with as much global reach as this one and I’ve very excited for the opportunity to present at it.

My session is Go Mobile with Xamarin, which will be an introductory discussion about mobile development with Xamarin for Android and iOS. I’ve been working with Xamarin for several years now and am looking forward to sharing some of my knowledge with NDC MN.

If you’re in the area, come check it out. There’s a lot of great speakers lined up and it will be a great opportunity to learn a ton.

See you there!

Share

Mirror Maze 2.0 Has Been Released!

I’ve been hard at work these last few months on the new version of Mirror Maze. After initially releasing Mirror Maze, I had a number of ideas that I wanted to implement. Today, I’m excited to announce that Mirror Maze 2.0 is live! I’m really happy with how the new ideas turned out!

I completely re-envisioned the game types (with the help of my kids), bringing 7 new game types and 250+ new mazes to 2.0! It was a lot of fun bringing these ideas to life and I hope you enjoy the updates.

You can learn more about Mirror Maze 2.0 over at the marketing site.

Mirror Maze 2.0 is live in the App Store and Google Play. Go check it out!

 

Share

CocosSharp – The Game Loop

This post is part of my Mobile Game Development series. Start at the beginning to catch up. This series was inspired by the things I learned developing a new game for Android and iOS called Mirror Maze.


I’ve talked a lot in this series about the foundation, building blocksvarious different node implementations that come out of the box with CocosSharp, and how to implement your own custom node. That will get you going with a CocosSharp application, but it will be static at this point. A game with nothing but static graphics isn’t all that cool, so you probably want to get things moving around a bit.

In game development, there is the concept of the Game Loop. The game loop is the chunk of code that gets called repeatedly, usually around 60 times per second, which drives the game. It processes things like user input, game state, and collision detection, then handles updating the nodes and rendering the game frame. The game loop is where all the magic happens.

In CocosSharp, each node has the capability of implementing its own game loop. There is a method provided by the root class CCNode, called Schedule, which takes an Action and schedules it to run for every cycle.

I typically implement a method called Process for scheduling. The Process method needs to take a float as a parameter, which represents the number of seconds that have passed since the last time Process was called. Remember that this method will be called somewhere around 60 times per second, so the actual value of the seconds parameter will be somewhere in the neighborhood of 0.016667. Don’t expect a whole second or more to have passed since the last call.

Adding Movement

Having a game loop that doesn’t do anything is no fun. Let’s draw a circle and move it across the screen.

The code above creates a CCDrawNode, draws a blue circle with it, then positions it in the middle on the left of the screen. Once the game loop begins, the circle will move one unit to the right every time through the loop. At this point, the circle will move right off the screen and continue to move to the right for the entire time the application is running. We can add some more processing to have the circle bounce within the visible bounds of the screen.

In the first change above, I added a member variable called Movement. When Movement is positive, the circle will move to the right. When Movement is negative, the circle will move to the left.

In the second change above, I updated the Process method to use the new Movement variable for the circle’s position and added logic to reverse the movement direction when the circle’s bounding box starts to move outside the visible bounds of the layer.

Now, you can run the code above as long as you want and just watch the ball move back and forth across the screen indefinitely.

Pause() and Resume()

The game loop will run continuously until the node is removed from the scene. However, there are times you won’t want the game loop to run. Perhaps you want your player to be able to pause the game and resume it right where they left off, without your game doing processing that would change the game’s state. That is why CCNode also provides Pause() and Resume() methods. Calling Pause() will stop the game loop from being called until the Resume() method is called.

To be clear, however, calling Pause() will only pause the game loop. It will not prevent any touch interactions you may have added from being handled. You’ll want to keep that in mind when you start working with touches, if you leverage the Pause and Resume methods.

With the concept of the game loop, you can now start to do some interesting things with your game. However, most games will need some sort of touch interaction. In the next post, we’ll take a look at how you can add that touch interaction.

Share

CocosSharp – BoundingBox Explained

This post is part of my Mobile Game Development series. Start at the beginning to catch up. This series was inspired by the things I learned developing a new game for Android and iOS called Mirror Maze.


BoundingBox is a property on CCNode that describes the rectangular box at the boundary of the node. BoundingBox is of type CCRect, which has some really useful properties: MinX, MaxX, MinY, MaxY, and Center (a CCPoint).

It’s important to understand exactly what BoundingBox represents and what it doesn’t. Much like Position, BoundingBox is relative to the node’s parent. In fact, Position is a big part in calculating the node’s BoundingBox. Position, AnchorPoint, and ContentSize are all factored in to the node’s final BoundingBox. However, BoundingBox does NOT factor in any rotation or scale that has been applied to the node. It may seem strange that those seemingly key transforms are not factored in because it can be very useful to know what the bounding box of a node is after rotating and scaling it. And that is why there are a couple more flavors of BoundingBox that you can make use of.

BoundingBoxTransformedToParent does pretty much what you would expect based on the name. It returns the bounding box of the node relative to the parent AFTER applying positioning and all transformations (scale and rotation). If you don’t do any transformations on a node, this property will return the exact same result as BoundingBox would.

BoundingBoxTransformedToWorld returns the bounding box of the node relative to the world space, after applying positioning and all transformations. When you want to compare the bounding box of one node versus another node, this is likely the property you want to use. It will give you a more “real” version of the bounding box because the coordinates will be in relation to the coordinates of all the other nodes in the world space, whether they are children of the same parent or not.

It’s very important to understand exactly which bounding box property you want to use when you need to reference the bounding box of a node. I wish I could give you more direction around which one to use in what scenario, but the reality is that it is highly dependent on the specifics of your app and what you are trying to accomplish with it. Based on my experiences so far, I can say that I found myself using BoundingBoxTransformedToWorld in most cases, but not all. I tend to want to know where the node is in the world, rather than relative to the parent, when I grab the bounding box.

Working with the bounding box of a node is something you will likely do a LOT throughout the development of your game. Whether it’s for collision detection, relative positioning of other nodes, or reacting to touch interaction, this is one of the more important properties you will need to understand. The best way to really wrap your head around it is to play around with it or set a breakpoint and inspect the results of the different bounding box properties at different times within your application.

Share

I was on the Gone Mobile Podcast!

Recently, I had the opportunity to chat with the guys over at the Gone Mobile podcast about my experiences with CocosSharp, my Mobile Game Development series, and the game that started it all, Mirror Maze. I rambled on for nearly an hour, but it was a lot of fun. We talked about how I got started with mobile game development, how it’s a fun thing I do on the side (and not my day job), as well as some of the basics of working with CocosSharp. Check it out and let me know what you think!

Gone Mobile 41: Mobile Game Development and CocosSharp with Brent Edwards

Share

CocosSharp – All About Positioning

This post is part of my Mobile Game Development series. Start at the beginning to catch up. This series was inspired by the things I learned developing a new game for Android and iOS called Mirror Maze.


Positioning in CocosSharp can get pretty mind bending at times. This is because CCNode has Position as a property and everything your user will see in your app will derive from CCNode, which means everything has a position. Couple that with the fact that there will likely be varying degrees of nesting with these nodes, each containing their own Position, and things can get quite hairy. So, let’s talk about the main components that are involved with positioning: Position, Anchor Point, Rotation, and ContentSize.

CCNode’s Position property is of type CCPoint. CCPoint is a simple struct with x and y properties, each of type float. Now remember, your game’s dimensions are logical dimensions that don’t necessarily map to pixels. Therefore, the positioning used in CocosSharp uses floats for coordinates so that you can have much more precision than integers would provide.

In CocosSharp, the origin, coordinate (0, 0), starts in the lower-left corner of the screen. Increasing the x coordinate value moves the node to the right and decreasing the x coordinate value moves the node to the left. Increasing the y coordinate value moves the node up and decreasing the y coordinate value moves the node down.

You may have noticed the phrasing that I used for the origin, that it “starts in the lower-left corner”. CocosSharp has the concept of cameras which can be moved around, changing where in the world space the user is able to see. So the origin starts in the lower-left corner, but cameras may move around, making it seem as though the origin moved. I’ll talk about the concept of cameras in a future post in this series.

CCNode’s AnchorPoint defines where on the node the position actually refers to. By default, the anchor point is at the center of the node. The AnchorPoint property is also of type CCPoint, but uses it differently than Position does. The values of the x and y properties are treated as percentage values, rather than explicit values. Therefore, the AnchorPoint default value is (0.5, 0.5), which, again, is the center of the node. Going around the horn we have:
Lower-Left: (0.0, 0.0)
Upper-Left: (0.0, 1.0)
Upper-Right: (1.0, 1.0)
Lower-Right: (1.0, 0.0)

Fortunately, there are predefined static properties for you to use. These static properties are all part of the CCPoint class and are named CCPoint.Anchor*.

CCNode’s Rotation property is pretty straight-forward. The type is float and defines how much the node is rotated in degrees. A positive value rotates the node clockwise and a negative value rotates the node counter-clockwise, all around the AnchorPoint.

CCNode’s ContentSize property is what tells CocosSharp how big your node is. ContentSize is of type CCSize, which has a Width and Height property. When you start getting into custom nodes, making sure this ContentSize property is accurate is key to keeping positioning correct in your game.

When applying changes to any of these properties, it’s important to remember that the changes are always relative to the node’s parent. If the parent is the root node, then all the property values can be taken at face value. However, let’s say the node’s parent is another node, and the parent node has changes applied to any of its properties. The parent’s changes are applied first. Then, the child node’s changes are applied to the child, relative to the newly re-positioned parent. To help make this more clear, let’s look at an example.

NodeA is added to the root layer. NodeB is added as a child to NodeA. The following code sets this up:

Now, let’s say that NodeA has a position of (10, 20) applied. Then NodeB has a position of (25, 35) applied.

Now, as far as NodeB is concerned, it’s position is (25, 35). However, what the user actually sees, due to the parent node’s changes being applied first, the user sees NodeB with a position in the world space of (35, 55). The concept of a node’s world space is conceptually pretty simple: Where in the world space of your game is the node, after all positioning is applied to the node and all parent nodes.

This example is simple on purpose, to ease into the concept of world space. It doesn’t take long for things to get much more difficult to calculate, for instance by adding rotation to NodeA. Thankfully, you don’t have to calculate it on your own. CCNode has the concept of BoundingBox. However, fully understanding BoundingBox requires a more in depth discussion. In my next post, I’ll dive in to all things BoundingBox.

Share

CocosSharp – Implementing a Custom CCNode

This post is part of my Mobile Game Development series. Start at the beginning to catch up. This series was inspired by the things I learned developing a new game for Android and iOS called Mirror Maze.


You can do quite a lot with the node implementations that CocosSharp provides out of the box. However, sometimes you’ll find that you need to do something custom. As a general rule, you’ll want to implement your own custom node any time you start adding several children to a CCNode instance or want a collection of nodes to be considered a logical unit. Implementing your own CCNode is a breeze, since it already provides a ton of functionality that you can leverage right out of the box. As with most things in CocosSharp, though, there are some things you should be aware of to make your life a little easier when you do implement custom nodes.

One reason why you’d want to make your own custom node is that you want to group other nodes together. An example of this from Mirror Maze is each collection of mazes in the level selection menu.

Menu

I developed a simple container UI element, essentially a rectangle with rounded corners, as the background, then added a label toward the top and a bunch of circle buttons below it for choosing which level to jump to. The game contains several of those maze collections, so I wanted to make something that I could re-use.

The custom node I created for that menu is nothing more than a collection of child nodes. However, I can add that menu node to my layout and position it how I like, without having to individually position the background, the header label, and all the buttons. They all move as a unit when I move the menu node.

When I implement a custom node, there are two or three things that I always do. The first two are mandatory and the third is optional, depending on the needs of the node.

Step 1: Constructor

The first thing I do is instantiate any children that will be there for the life of the node. I do this in the constructor of the custom node. If I need to reference any of the children at a later point, for positioning or anything else, I also add a member variable for that child node.

If you have absolute positioning to do for any of these children, meaning positioning that doesn’t depend on anything else, you can set that positioning in the constructor as well. However, at the time that the constructor is ran, the node hasn’t actually been placed into the parent’s scene yet. That is important because that means the node also does not have any size or position associated with it yet.

Step 2: Content Size

The second thing I do, and arguably most important, is to make sure to keep ContentSize updated. ContentSize is the property that tells CocosSharp how big the node actually is. ContentSize factors heavily into positioning and BoundingBox, which I will cover later in this series. It’s important to update ContentSize to reflect the total size of all the children in the node whenever you finish adding children or something that would affect the size changes. ContentSize is of type CCSize, which has Width and Height properties (both floats). This step is one of the things I really wish I knew sooner. You’re welcome.

Step 3: Positioning (Optional)

In a lot of cases, the child nodes I add to a custom nodes need to be placed relative to other child nodes or the parent’s VisibleBounds. VisibleBounds is a property that CCNode provides that returns the bounding box of the visible world. Basically the bounds of what the user can see. In Mirror Maze, I used the VisibleBounds a lot to position children somewhere along the outside of the visible boundary. Since the node hasn’t been placed in the scene yet at the time of that the constructor code is run, this brings us to the third thing I generally do when implementing a custom node: override AddedToScene.

AddedToScene is the method that CCNode will call once the node has actually been added to the scene, which means that it will start to have sizing and positioning available to it. VisibleBounds will always return a default rect before the node is added to the scene, so AddedToScene is the first time you can start to use VisibleBounds.

The above code positions SomeSprite in the bottom-left corner and SomeDrawNode in the bottom-right, then sets the ContentSize to be the full width of the VisibleBounds and the height of SomeSprite (the taller of the two child nodes).

Overriding AddedToScene isn’t always necessary. If you are placing all of your child nodes at specific coordinates that aren’t affected by whether the node has been added to the scene or not, you can skip this step and just stick with the first two steps, putting your positioning in the constructor.

After following the steps that I follow above, you’ll have a usable custom node. If all you want to do is group other nodes together, you’re good to go. If you want to add further functionality, this is where you can go nuts. In my next post, we’ll learn about how positioning works in CocosSharp.

Share

CocosSharp – Using CCLabel

This post is part of my Mobile Game Development series. Start at the beginning to catch up. This series was inspired by the things I learned developing a new game for Android and iOS called Mirror Maze.


There’s already documentation on CCLabel available from the CocosSharp team, so this won’t be a comprehensive post on the topic. However, there are some things I’d like to point out.

When I developed Mirror Maze, I wanted to use a custom font to give the game its own unique look-and-feel. There are a lot of places online to find free fonts which have licenses that allow usage in your projects. Using the font that I chose in CocosSharp was easy and just required making sure everything was set up as the engine expected.

The Setup

As I covered in the Foundation post, your GameView should be configured to look for your assets in the Content folder. One of the folders within the content folder is for your fonts and is aptly named, “Fonts”. Without this setup code, CocosSharp will never know where to find your font files, so make sure you have it configured properly before moving on.

Next, copy the .ttf file for your font to the Content/Fonts folder for both Android and iOS projects. I found that Xamarin Studio properly set the BuildAction for Android to AndroidAsset for me, but I had to manually set the BuildAction for iOS to BundleResource. Double check each of those to make sure yours is set correctly also, or CocosSharp won’t find the font at runtime. You’ll know whether you did this correctly when you run your game. CocosSharp will not error out when it can’t find your font, but it will revert to the default font.

Usage

Once you have your font included in your platform-specific projects, you can put it to use with a label instance.

Let me break this down a bit.

Parameter 1: “Hello World”
This is the initial text displayed by the label. It can be changed at run-time, which we will talk about in a bit. It’s important to note that, for sizing purposes, you have to have a value for this. Starting with an empty string will give you a width and height of 0, which can be problematic when it comes time to properly position the label, particularly if you are doing vertical positioning. If you have to start with dummy text, then change it at run-time, do it.

Parameter 2: “Fonts/myfont.ttf”
This is the location of the font file to use, within the Content folder. The file extension isn’t supposed to be required, but I found in practice that it is.

Parameter 3: 40 * Constants.FontSizeMultiplier
This is the font size. You can have this be a fixed size, but I found that font sizes need to scale just like sprite graphic files do. I covered the reasoning behind this in the Foundation post. Constants.FontSizeMultiplier is a static float that is set during the initial startup code.

Parameter 4: CCLabelFormat.SystemFont
This is the type of font being used. When you use your own font file that is included in the projects, you will use CCLabelFormat.SystemFont.

Making Run-Time Changes

Now that you’ve got an instance of a label, you can position it just like any other node. You may also find the need to update that label with different text, or even colors, at run-time. Either of these are simple to change.

The code above changes the text of the label. As simple as this is, there’s a gotcha that I found in practice with this: Every time I’ve changed the text of a label after it has been initially instantiated, I’ve found that a few bytes of memory are leaked. I haven’t taken the time yet to dive into the CocosSharp code to see why that might be the case, but I found it to be consistently true. A few bytes of memory leaked may not seem like a big deal. Do that enough times, however, and eventually the device can run out of memory, causing your game to crash. Just something to keep in mind.

The code above changes the color of the label to red. What’s important to note there is that the color in this case uses the CCColor3B struct, which is different from CCDrawNode (which uses CCColor4B). CCColor3B and CCColor4B both are very similar. However, in practice, I found that a label with a custom color will render as a slightly different color from the CCDrawNode rendered with the “same” custom color. Again, I haven’t looked into the CocosSharp code to find out why this is the case, but it is noticeable if you place the two next to each other.

That wraps up our discussion of CCLabel as well as the provided implementations of the CCNode class. In my next post, I’ll talk about what it takes to implement your own custom CCNode class.

Share