Automute Evolution: Microgames

I had an epiphany today on my way to work.  As I was driving I saw a billboard with the words “Click It” printed on the sign (referring to clicking a link in a browser to the company’s webpage) .

My brain, brainwashed as it is by PSAs then responded mentally with “Click it or ticket” (i.e. your seat belt).  In my mind I then made the connection between clicking a link and clicking a seatbelt buckle.  This led to the idea of a little minigame about dragging a seatbelt over a character.  I’m not sure why or how it happened, but as I threw the idea around in my head a little bit for some variations on this theme it hit me:

Automute shouldn’t be a singular project as a full game.  For a long time I’ve had the view that Automute is supposed to fit the mobile game form.  Fast, quick, easy to pick up.  But I’ve pushed so hard on making it a “big” project, a complete game with levels and all that.

I still have to add in some of the same code to do the basics (which is what I’m working towards now), but in terms of level design, I can simplify it.  Automute should not be a monolithic game.  Instead it should be a component of a series of “Microgames” (a la WarioWare: Mega Microgame$).

I started to picture how a buckle-up game could be one mini-game amongst the driving game I have now.

When I shared this idea with a friend they laughed because they realized it’s right up my alley.  First, I have a bad habit of failing to stick to an idea if I work with it too long.  I’m a lot better than I used to be, but it’s still an issue.  Clearly, Killing Horizon was a massively large project that was more than I could chew as a first time game programmer.  And my mind wandered – to Automute, which still seems to be a bit more than I had hoped, even though, in theory, it is probably one of the simplest games possible.

So what I really need to do is realize that I need to create a framework that will enable me as a dev to implement my visions of these microgames quickly and rapidly.  Because I like to think of wacky and interesting concepts, microgames seem a perfect format.  (How can you NOT love a game that has you picking your nose in a second or two).

Now – I’m not saying I would ape the format of WarioWare (It’s been quite a few years since I played one of them – probably a decade, really), but the idea of short quick small games to pick up and play, in succession, rapid fire, ADHD gameplay which is perfect for phone gaming.  My problem, of course, is I don’t really have a cell phone (I KNOW!).  I have a cheap 50 dollar phone I rarely ever use (but it does have Android).  I could test on that and hope that being such a low end system means it should run better on newer/faster systems (but everything has its quirks, right?)  I don’t know how this format would compare on a tablet (do people really just whip out a tablet on a subway ride and play a game while standing at a pole?)

Automute will continue to be the first game in the series, but being that I’m focusing right now on making it work with scoring, I will try to start working on abstraction from an engineering/design perspective.

This means I can create games with this framework as little modular levels that players can load, and I could update them (either free or as packages players could purchase, or something of that nature).  I could theme packages, so, like – in this case, I have my seatbelt game and that could combine with automute, so there’s a “car” theme right there.  Find a set of small concepts for vehicle games that are quick, and use “Natural User Interface” (tap, drag, pinch, etc…) And that can be the first release.

Yes, I think I quite like this idea.

Delegate Notes 2: Delegates and Events

Well I think I pretty much grok delegates alone.  So I moved onto events this weekend.  Being that my day job had me working 19 days in a row, yesterday was my first full day off (even though I took a half day the day before)… So I was tired and out of the loop.  I was frustrated at how utterly stupid I was feeling, lacking any real cohesion of thought processes.  My brain was seriously foggy.  It was annoying as hell.

I ran some errands and tried again, after the errands, to focus on figuring out events and yet again, it didn’t click.  I watched videos.  I read various online tutorials, I looked at some ebooks and nothing clicked until I saw Illustrated C# 2012 by Daniel Solis, which laid everything out step by step in very clear examples.

What was bothering me most was that almost every example I was seeing had some level of indirection or added complexity – whether it being authors trying to throw in more detail about the inner-workings of events, or creating complex examples, or just being bad at explanation, something just wasn’t clicking.  I’m sure that all the background reading was having an effect, I absorbed little by little as I went on.  One thing that did help tremendously, apart from the book, was the Advanced C#: Lesson 4 – Delegates, Events and Lambda Expressions video on Youtube by Jesse Dietrichson.

I sat down now – near the end of my weekend – and proceeded to attempt what I thought would work for my sample “car dies -> add a value to score” (which is my goal for the REAL use in automute)…  I took the aforementioned book and went step by step through his text, modifying the examples as I needed to.  I ran into an issue with the code for subscribing to the event… If you recall in my previous post regarding delegates, I said:

D: Do NOT use the parens after the function name of the function you are pointing to.  The following will NOT work.

d = hello();

Similarly, when you subscribe to an event, you use the += operator, like this:

Here is my “Vehicle” class.

VEHICLE CLASS (PUBLISHER):

So the first things to note:

1) You have a “Publisher” and a “Subscriber”.
A. The publisher is the object that publishes the event. That is the one that says “HEY I GOT SOMETHING HERE!”
B. The subscriber, of course, says “HEY, THAT IS WHAT I HAVE BEEN WAITING FOR, LEMME LOOK AND APPLY MY OWN SHIT TO IT!”

In my case the Publisher is the Vehicle and the Subscriber is the LevelManager.
In my setup, you notice I have the vehicle constructor made to set the basepoints when I instantiate a vehicle object. In the Unity Engine, I’ll simply be using the default serialization and editor capabilities, but for this test I just used the constructor.

So here’s how the rest of the actual shit works…

2) The Publisher creates a delegate. If you recall, when you create a delegate like this you are creating a TYPE. This TYPE informs anything that calls the delegate as to its signature requirements. If I want to use a method with a delegate it must have the same return types and same parameters.
3) The Publisher also creates the event. The event is declared by the “event” keyword (in the same way you use “delegate” to declare a delegate – HOW CLEVER! LOL). When declaring an event, you use the previously declared delegate as the event TYPE.

So in my code below:

I first declare the dieDelegate. Return type of void and parameter of int.
Then I declare my event using the dieDelegate which I had declared above as the TYPE of the event, then I give the even the name (dieEvent).

I then create a method that calls the event. To call an event you always want to check if there are subscribers. That is done by checking whether the eventName is null. This is done in my dies() method.

This guarantees that the event will only trigger if there is someone listening.

The next thing to do is to create your application of the event. In my test case, I just did a little crash() method which does a countdown from 10 to 0, displaying the value then having a user hit a key to display the next value until a particular value is triggered generating the “Death” (in this bit of code it’s 9 — LIVE FAST, DIE YOUNG!)

So you see I do my countdown, display the value, read a key, detect if the value is the “death” threshold and if so, tell the user they died, then trigger the “dies()” method.

But in the dies method all it does is call the “dieEvent” with the basepoints of the vehicle.  Nothing happens in the vehicle class itself beyond this.

And that’s why we have subscribers…

4) For the subscriber – this is where the magic happens. Here’s where we hookup, ladies and gents. In my LevelManager class, I first setup the score which I’m going to be setting when the vehicle dies. I also give it a level number just to do a little more complex math than just set the score to the car’s score.

5) First, I need a vehicle to play with so I instantiate it with the constructor and pass “25” in as the basescore of the vehicle.
The next line is where I subscribe to the event. I am hooking up/pointing the event to the method that will be called when the event happens. I do this with the += operator.

6) You’ll note that I’m not using the name of the delegate (dieDelegate), nor the name of the method that calls the event (dies()). I am using the name of the event itself (dieEvent), along with any required accessor (in my case, since I’m calling it on a vehicle object declared as “v” I must use v.dieEvent…) Then I just set it to trigger my setScore() method. Notice, however, that I’m not using the parens after it (this is what I mentioned earlier in the post)… Don’t use parens when linking – otherwise it will try to invoke the method, and thus instead of attaching the method/delegate TYPE it is invoking the method as a function and attempting to attach the return type (void).

7) The final thing to note is that I’m not actually calling the setScore method anywhere in LevelManager, directly.  Instead, since the setScore has the same signature / type as the event (dieEvent), when the event triggers, all the arguments it takes are then passed along to all the subscribers.  The subscribers are then invoked on their own, being given the parameters of the event.  So you see the “(int s)” parameter being passed to “setScore()” is really just the “(basepoints)” parameter being passed in the “dieEvent(basepoints)” method call.  I have a few ways I can picture this, but am tired of writing now.  Perhaps I shall return to this topic at a later time to try to give a better visual metaphor, maybe even with a drawn diagram.  For now, I think I shall relax for the rest of the night.
TTFN!

LEVELMANAGER CLASS (SUBSCRIBER):

Delegates, Events, Practice/Learning

So – so far, when I’ve been trying to learn something new, I’ve been doing it directly in my code. I think that has had the side-effect that I have been hesitant to try new things because of being afraid of fucking up my code. This is dumb thinking (especially if I properly backup and use source control – which I *have* been doing since my screwup on that little number last time), but it can still be something to think about.

When learning things, sometimes it’s best to strip down the complexity and really focus on the core concept.

I’ve been looking at tutorials and text regarding delegates and events in C#. Conceptually it’s fairly simple. But implementation is a little more complex than I would think, and therefore, that complexity, combined with adding it to my already existing code (which adds yet more complexity) meant that I’ve been afraid to dig in (it doesn’t help when I have been working lots of overtime at my 9-5 job and just want to be braindead after work).

Between realizing that I can test code without having to deal with Unity directly, along with some advice I gave a C programmer on reddit last night about not diving in too deep, and stepping back the complexity of something while you try to learn, made me realize that I should work directly in C# with some sample delegates and events that don’t utilize the Unity framework, and once I fully grok the concept then could even, hopefully, get some template/scaffolding code that I could plop into the larger framework of the game (and just modify as needed)…

Take my own advice. Sometimes, that’s the way forward, it’s easy to sit there and give wise advice to others (well, if you’re being rational and not just being opinionated about stupid shit, which, admittedly, is 90% of the time for most people, including myself)… But it’s good to perhaps step outside your own self, and give yourself the advice you might give to someone else.

When you ask “How should I approach this?” don’t answer for yourself, answer as if someone is asking you that question, and having that separation might make the pressure of finding an answer more clear and give you some insight that you might not really have gotten if you’re stuck nose down in your own ego.