A Team of 1

Team management is a big complicated process that we have entire dedicated team members for in the game industry. Producers are important. One of the hardest things about really doing a project beginning to the end just with yourself; code, art, design, and don’t forget production – is really that last part.

Most of the tools and techniques out there for product management are built around teams, because generally you have multiple people working together and trying to meet each others needs. When you try to do it all yourself you are your own blocker at all times, and if you try to produce yourself in the normal manner, with conventional tools, sure it will work, but you have created quite the waterfall nightmare.

Again, let me stress, a lot of the point in conventional production pipelines is for communication between people. Yet if the only person you need to communicate with is yourself, inline may be the best way. Right where you are going to look.

As I went to rewrite my combat loop, and after I had blocked out enough of my Models to start working the first thing I did was write my TODO list. Not in Jira, not in a spreadsheet, but right there, before I even started trying to write the code. What winds up happening here (even though new TODOs show up as you work, and concepts Unpack into more complex steps) is these TODOs get replaced and moved as needed into actual code.

As I look at this I start to imagine if I was working with other people, and using some kind of ticket system each of these TODOs should have a ticket associated with it, and suddenly you have an extension of existing best practices if you ever scale your team above 1. No more mystery TODOs in code, there is an external point of contact. Perhaps one extra nice to have on these might be a version number to indicate when they probably should be done by.

For actual assets I probably will fall back to a spreadsheet, but I’ll probably be doing a lot of placeholder work, and so for each of those assets in Unity I’ll set a “Label” (not to be confused with Tags even though it uses a tag icon, lower right.) It might even make sense to put version/release numbers here.

In theory by Labeling assets like this even in a team environment you can help indicate how assets should be treated, and leave less mystery around them down the road.

Any way, back to my combat loop. I’m down to needing to send actual attack events again. Which I’m planning to send directly to the object attacking, then out to the trigger system (pre attack,) then pass to the object defending, and again out to the trigger system (post attack.)

So You Want to Make a CCG

Finding myself between jobs I looked to a recurring problem of portfolio work as a TA. I can point to projects I’ve worked on, and describe what I’ve done but that all gets very ambiguous. So much lives on the backend that I don’t currently have access to so. It’s also been years since I’ve worked on a project where I got to really leverage some of my skills in a demonstrable fashion. I started tooling around with making generic tech that I’ve had in mind for a while and came to the conclusion; let’s make a CCG because that’s not hard (eheheh… sigh)

I didn’t grab any screenshots through the very first stages of ‘capsule wars’, in which I fussed with the general structure of figuring out how I wanted to control units moving back and forth, and smacking each other, but once I got the basic timing sequence down I went in and set up some placeholder characters and rudimentary animations.

So I got that working that way. Click a square it puts down a default 4:10 unit, it picks a target, walks across and smacks the opponent. Then I got mired down in the planning phase, and went in circles.

Ultimately I concluded that for my real goals I needed to back up, and come at this from a wholistic top down approach, and make the whole game state serializable. (Because that’s easy!) The goal here is to create a transferable state model for everything, in part so that an AI can run simulations to pick a move. MVC (Model, View, Controller) is mostly the pattern, but I’m introducing a D as well, which is data. Data objects will actually make up a lot of the functional parts of the game, non-volatile building blocks such as the selection filter:

The concept here is that the code will never need to instance the concept of this “Ranged Allies Around Source,” where as the object name itself will be descriptive where it is referenced in other components such as Triggers. Ranged is likely to be an automated Keyword on Units based on their attack type. I’m using strings since while the compares are less efficient they flexibility is much higher than Enums. This way an entirely new Keyword can be introduced to the game with no code or binary changes, and the code never references the theme of the world. Do you have arcane magic, or nature magic, or don’t? The code doesn’t have to care.

Filters are intended to work in two directions Event sourcing and Action targeting. So for instance lets say a card does damage to all enemies when it enters gameplay. In the trigger there will be a Appears event and a Filter (Main: Self, Area: n/a, Role: Source) then a Damage effect and a Filter (Main: Enemy, Area: All, Role: All). Conversely if that first filter were not set to Self but Enemy, and we re-used the filter both times every time an Enemy appeared it would take damage.

After all that I took a break and grabbed some Free Unity Assets just so I could look at something prettier whenever I switched over to Unity.

Right now I’m trying not to stress over art. There are a lot of options, though I’m leaning to full 3D rather than the 2D puppets common in the genere. The reason for that is the ability to do other nifty things.

Obviously I’ll have to change my UnitHUDs to some kind of billboard, but that was the plan any way. The main trick here for selecting the different views is a simple function that compares the absolute value of Vector2.Angle between two Aspect Ratios and the screen, and picks the closer, then simply applies it’s properties.

public AspectSelection ReturnCloser (Vector2 target, AspectSelection other)
    {
        if (!other)
            return this;

        if (Mathf.Abs(Vector2.Angle(target,other.aspect)) < Mathf.Abs(Vector2.Angle(target,aspect)))
        {
            return other;
        }
        return this;
    }

The deeper trickery is writing a helper singleton that allows scripts to register for screen events. Though I plan to transition this singleton to a simple static class that attaches to an Update singleton that non-monobehaviors can access. The reason for all of this silliness is that Unity never got around to generating a screen event system of their own, and the only way to detect screen changes is to check manually on say Update.

Any way, thats enough for now. Back to re-writing the turn flow to a viewless stored structure, then reading the view out. Wish me luck.