Tag Archives: pmg originals

CMF 6: The Process

This post is part of a series for game developers applying to the Canada Media Fund.

So far this series has mostly talked about different aspects of applying to the CMF for project funding. Today I want to talk about what happens after you’ve gotten a project accepted.

The (Not So Secret) Agent

When you submit an application to CMF, you are assigned an agent. That person is your go-between for the application, and my experience has been that they’re delightfully helpful. Every time I wasn’t sure about something, I could send a question to the CMF agent and they’d get back to me in a couple of days with helpful information.

Here’s an example: I didn’t have payroll set up for Perfect Minute when I was getting ready to start work for Conceptualization. Getting an employee agreement was going to cost me several hundred dollars and possibly a couple of weeks waiting on my lawyer for the agreement. I’d committed to a start date that came earlier than I could possibly get those details sorted out, and so I asked the agent if I could act as a contractor until I had my employment agreement figured out. They indicated that this was highly irregular and not recommended, but in the end they helped me figure out how to bridge that gap.

Maybe that doesn’t sound like much from the outside. But the contract you sign with CMF has a bunch of clauses that basically say if you do anything shady they’re going to pull your funding. That’s not unusual on its own – any business contract is likely to include language that allows either party to exit in certain circumstances – but if you’re not familiar with the other party, or if you’re relatively new to contracts at this level, it can add a lot of stress. Having someone to help you navigate is a big deal.

Program Phases

It’s also important to note that each CMF program is divided into two or more phases. For Conceptualization, the program has just the two phases – Phase I covers your initial estimated costs and plan, and Phase II is your final, actual costs and plan. There’s money riding on getting the documentation for each phase correct.

This gets more complicated when you’re doing one of the production programs; those use three or more phases, with a “beta” delivery in the late-middle part of the development schedule. It’s not so different from how publishers use milestones, but having dealt with a few milestones from both the dev trenches and the managerial towers, they’re tricky.

Things can change really fast in game development, and if what you deliver to someone for a milestone is not what they expected, you might forfeit an expected milestone payment. I haven’t had that experience with CMF, but I’ve had it in other circumstances, and it can be absolutely crushing. Project-killing, even.

It’s important, then, to communicate when changes happen. I asked for several schedule extensions during the course of our Conceptualization work, as it became obvious that certain assets just wouldn’t be ready, and as we realized that some of the early decisions we’d made weren’t working as well as we’d hoped, requiring significant rework and direction shifts. And to their credit, CMF accommodated. The agent eventually came back and said listen, you’ve committed to all documentation by July, so just make sure you’ve got it all in by then.

For me, July wasn’t really an option – I have a day job, after all, and I can’t indefinitely dedicate the 20+ hours a week I was spending over the last four months to a second job – but that took some pressure off all the same. We delivered our final docs a couple of weeks ago, and there’s been a little back and forth since then, but ultimately we were approved on Phase II.

About That Back and Forth

One of the things I personally was paranoid about when I was getting into the CMF’s orbit was my own lack of expertise in business. I was convinced that messing up documents and information would turn into an endless problem full of legal nightmares.

Nothing could have been further from the truth, however. Both during my applications and afterwards, I’ve been able to get detailed feedback on problems with my documents and information, submit amended versions, and see positive results.

I’m sure there’s a threshold below which the agent just can’t help, but thankfully ours was very ready to assist, and our documentation only needed a few changes to meet the requirements. It was encouraging to realize that this was how they do things.

Graduation

The other thing that I appreciated during all of this was that the CMF’s Experimental program portfolio is designed to feed forward. When you submit your final documentation for Conceptualization, for example, they ask if you’re applying for any other programs.

We are, of course. I’ve already talked about the application we submitted to the Innovation & Experimentation program, but it was nice to know that there’s a built-in way to tie the two together. I feel confident that what we submitted shows us in a good light. If we can put together what we did with $20,000, it’s natural to believe we could do a lot more with a larger investment.

I’m excited at the idea, though truth be told I have no idea where I’d come up with our 25% right now. I’d hoped to avail of traditional (debt) financing, but so far that’s coming up empty. There’s the possibility of a Kickstarter, but these days those require a level of readiness and polish that exceeds the grasp of the average unfunded developer who nonetheless has to pay mortgages and keep life and limb together.

Maybe we’ll figure it out. Given we don’t yet have a demo or an approved application, it’s somewhat moot at the moment. But it’s important to be prepared.

On that note…watch this space for news in the days and weeks to come. Our little Action-Painting-Strategy RPG still has some legs yet.


Featured Image

Contracts” by NobMouse is licensed under CC BY 2.0.

CMF 5: Putting Together an Application for the Big Dogs

This post is part of a series aimed at game developers applying to the Canada Media Fund.

To date, I’ve talked mostly about the process involved with the CMF’s Conceptualization program. Conceptualization is the definition of seed money – low barrier to entry (though 2023-24’s changes make it a bit higher for us old white dudes, but I’m ok with that), low dollar value available, highly contingent on being the right person in the right place at the right time.

Conceptualization, however, is mostly designed to feed into the Big Hairy Audacious project programs. These are, in no particular order, Prototyping, Commercial Projects (CPP), and Innovation & Experimentation (I&E).

Prototyping I’ll leave for today; I haven’t actually gone through the application process for it, and so I can’t speak directly to either the work or the experience.

Instead, let’s at the other two, which I’ll collectively refer to as the “production” programs. First, let’s compare and contrast:

CPP

  1. Caps out at $1.5M
  2. Provides 75% of funding
  3. Includes production, marketing, and promotion
  4. Requires completed concept and prototype stages
  5. Newly in 2023-24, requires a Narrative Positioning Statement
  6. Uses a selective evaluation matrix
  7. Funds projects with “a greater probability of commercial success”

I&E

  1. Caps out at $1.5M
  2. Provides 75% of funding
  3. Includes production, marketing, and promotion
  4. Requires completed concept and prototype stages
  5. Newly in 2023-24, requires a Narrative Positioning Statement
  6. Uses a selective evaluation matrix
  7. Funds projects that are “innovative and leading-edge”

Not a lot of daylight between these two, huh? Point #7 differentiates between the two programs, and even there, at first glance, it feels like a distinction without a difference. But it becomes clearer once we consider the evaluation criteria from #6’s matrix:

CPP

  1. Team (15%)
    1. Experience individually & together (11%)
    2. Diversity (2%)
    3. Parity (2%)
  2. Narrative Positioning Statement (5%)
  3. Potential for Commercial Success (45%)
    1. Content and Form (20%)
    2. Financial Viability (25%)
  4. Strategic Positioning & Marketing (35%)

I&E

  1. Team (15%)
    1. Experience individually & together (11%)
    2. Diversity (2%)
    3. Parity (2%)
  2. Narrative Positioning Statement (5%)
  3. Innovation, Creativity, and Advancement (60%)
  4. Financial Viability (15%)
  5. Strategic Positioning & Marketing (10%)

I actually find this to be a great breakdown, and I wish I’d realized much earlier just how different the percentages are between the two. I might have focused even more energy on which program to apply to and why.

So Which One Should I Apply To?

It depends on your project, obviously. For Paint By Monsters, despite channelling elements of half a dozen all-time banger hits, we’re taking a LOT of creative and commercial risks all at once, so we went for the Innovation & Experimentation program. If you’re doing something a bit safer but you have all your ducks in a row as to how you’re going to make money with it, Commercial Projects is likely your better bet.

The Paperwork, Dear God the Bloody Paperwork

The thing that I found most intimidating about CMF programs before I applied the first time was just how heavy the documentation requirements were. Even Conceptualization’s lightweight bucket of text felt like an overwhelming commitment.

But as it turns out, it’s just paperwork, and you’re going to have to do it at some point, so you may as well take a CMF application as a chance to practice.

Different folks will no doubt find different parts of the application difficult, but for me the most intimidating part was the budget. The CMF kindly provides template spreadsheets that guide you through filling out a complete program budget – and, in the case of CPP and I&E, a monthly cashflow statement – but it’s still a lot to behold.

In point of fact, I didn’t start with the CMF budget. I was in the first half of the Evolution program at Genesis here in St. John’s earlier this year, and they pointed me at the Futurpreneur Business Planner. The idea of writing a budget for a couple of hundred thousand dollars got very real, very quick at that point – I have to make a living, plus pay the Stellar Boar folks and our incredible sound artists, and I’d love to hire a few other folks along the way. Doing all that takes a whole lot of money.

Using the planner’s financials tool, I came up with a first cut at a 3-year financial plan. Some key things I’d like to highlight here:

  1. I’d already decided that part of the plan was to give myself more than one kick at the can, so I have 3 different sources of revenue (Paint By Monsters, Business to Business services aka B2B, and Other Games)
  2. I’ve listed $20,000 a month in wages. That sounds like a lot, maybe, but it’s really not. One senior programmer is half that, and if you want a senior artist to pair with them you could easily spend it all on 2 people. In my case it’s more like 3-5 total positions, but saying that just makes me aware that my budget is Really Tight.
  3. There are a LOT of other fees to consider. Insurance, legal, accounting, of course, but for games you also have market fees and Unity’s cut and royalties and on and on it goes.
  4. I’m cash-negative in year 3. That’s a huge red flag, and suggests that I should have built in a lot more work on games beyond Paint By Monsters.
  5. I’m putting in my own cash. It’s not a lot of money – $5,000 against $345,000 in start-up costs – but it’s not zero. There are lots of games you can play to increase that number – computer equipment donated to the company, service-in-kind, etc – but there’s nothing quite like putting cash on the barrelhead to say “I think this has a good chance of success”.
  6. The plan includes debt-funding a significant percentage of activities. This is dicey, and can easily backfire, particularly now that interest rates are back to something like normal. But in a pinch, it’s better to have 25% of your capital at a high interest rate and 75% at a low one than have 100% at a high interest rate. And frankly, it’s still better than most equity deals, at least as far as the long-term costs go.

In the worst case, all of the above sounds like every CFO you ever tuned out halfway through, but this is the exercise, folks. We have to be serious about the money, because the main thing we’re asking for is money.

The full list of paperwork that you need for the programs can be found in the relevant document package, but they all go roughly as follows:

  1. Application In Dialogue
    1. Brief description of the project
    2. List of key people involved and their PERSONA-ID account numbers
  2. Signed and Dated Budget and Cashflow
  3. Financing Commitment Letters
  4. Declaration of the Corporations Canadian Status and its Shareholders and Directors
  5. Other corporate documents
  6. Narrative Positioning statement & attestations
  7. Team Description
  8. CVs for all team members
  9. IP history and ownership for the project
  10. Market research and marketing plan
  11. Project summary (short) and description (long). The short one is almost as hard to create as the long one.
  12. A demo
    1. Technically, video of your demo, but just as a professional courtesy: don’t fake it. If you don’t have a demo, apply for Conceptualization or Prototyping. It’ll have a lower barrier of entry, and will probably help you when the time comes to try for a production program
    2. NB: Do NOT show a demo for conceptualization or prototyping. They won’t even accept you if you have something you’re calling a demo. Paint By Monsters had “Feature Demos”, which is luckily just far enough outside of that to qualify, but I feel like it was a near thing.

Partnering Up

As mentioned, I’m working with Stellar Boar Productions, and that means I’m lucky enough to have a mature, financially stable company alongside my fledgeling studio as well as a very involved and invested partner in this project, Curtis Rioux.

Curtis took on a bunch of the work for this application, and he’s my hero forever because of it. He’s the artist of the partnership, and he made the whole package look 10,000% better, plus he wrote essentially the entire marketing end of it. Highly recommend finding yourself a Curtis. Not my Curtis, obviously. He’s mine. But A Curtis.

All of this was complicated by the fact that over the course of the project our little team of two has expanded. At first it was just me, and then Curtis came onboard, and then his in-house artists. Midway through Conceptualization, we added our sound guys Chris and Adam. And as we head towards full production, we’ve realized we should commit to a few others – a couple of art specialists, a marketing & community resource, a junior programmer, maybe a couple of interns.

This means we have to employ or at least compensate a total of 11 or more people over the course of the project. Our individual studios are still quite small – I’m still one person, looking to add two more, and Curtis only has three plus an intern – but it’s obvious that we can move a lot faster by spreading work out more, and that feels like the right move.

It’s So Much Money

Yeah, it is. And then again, it’s really not.

When I rebooted Perfect Minute Games to focus on original projects, I had Megan Fox‘s words from while back on my mind – you should spend less than $50,000 making your game, because there’s a very high probability you’ll never make back more than that.

That vision is still appealing to me, but I have to recognize that it only goes so far. At some point, you decide whether to work fast or to work cheap, and if you believe – as I have come to believe – that the key to success is largely repeated execution of a good core concept, then you shouldn’t squeeze too hard.

The thing that keeps coming back to me about all that, though, is we really do need IDM funding that fits into the sub-$100k bucket. Teams should be able to build a demo of a good idea with support. Maybe not every team can have that, but it should at least exist.

Go Forth and Gamify

So. What else can I tell you? The paperwork is a stack, but you can do the easy version first. The scope is intimidating, but if you look around, it’s not far from what you’ll have to do for a publisher. None of it is game development, and that’s probably the really hard part – most of us just want to add features and do cool stuff and work with good teams.

That should be enough. It should. But it’s not, and I hope sharing my experiences with the process at least helps you get through the vegetables part of the business a bit quicker.

Paint By Monsters DevLog 7 – Design Process Part 1 – High Level Design (So Far)

Paint By Monsters started life, as with many of my original designs, as an attempt to subvert aspects of an existing popular design. In this case, it was the Horde Survival/Bullet Heaven microgenre, which has exploded in popularity since Vampire Survivors appeared on the scene.

This type of game is an attractive prospect for a dev – mechanically simple, technically and artistically feasible for a reasonably skilled development team, and with a reasonably short development cycle. If I had any sense, probably, I might have been content to simply create a much more direct version of the experience myself. But.

Originality in Replication?

I often take a contrarian stance in some aspect of a new design (witness the small squad sizes in Contension or the worst-of-both-worlds combination of cards and tiles in Mechanisms). I often end up thinking about how to “reverse” a particular a genre. In this case, I was thinking about “reverse horde survival”.

The obvious first step, for me, was inverting the relationship of player and entities onscreen. In Horde Survival, you are one against many, so obviously in the reversal you play many against one. This eventually became many against few rather than one, since there’s still action economy to consider, but the core idea remains the same – the player uses a horde of relatively weak minions to fend off a small band of powerful invaders.

This idea, on its own, is the same basic formula as Dungeon Keeper and its ilk. That’s not a bad thing – Dungeon Keeper was a lot of fun, after all – but one thing dungeon defense games don’t do all that well is the kind of continuous action that horde survival has perfected.

So how could we channel that feeling of “action” if mostly you’re just spawning hordes of autonomous creatures? Feature Demo 0.0.1 took a look at the simplest version: spawning minions in realtime. Nothing fancy, just skeletons appearing whenever and wherever you hold the mouse button down.

The next few feature demos built on top of this foundation – 0.0.2 added a little agency to the enemy, 0.0.4 added a win condition, 0.0.3, 0.05, and 0.0.6 added new enemy and minion types. The “minimum viable loop”, such as it was, seemed complete. And it felt…not great.

Player Experience

I knew why it didn’t feel great. Even with a bunch of minion types to switch between, even with limited numbers of each minion type, even with adventurers carefully tuned so you could just barely beat them if you did a good job with the resources available…you were just moving the mouse around with the button down. It didn’t feel intentional.

That’s when I starting thinking ahead, thinking about what the Player Experience should be. Player Experience is something that gets talked about a lot more in board game design than in video game design, in my (limited) experience, but it’s important in both.

It’s not really about the core loop, though that loop will inform it. It’s not really about the theme, though the player will form impressions based on the theme that will affect their experience. It’s not even really about the action economy itself.

Player Experience, at its very core, is the answer to “What do I want the player to feel while playing this game?” For Paint By Monsters, as it turns out, the answer to that question is: I want them to feel like an artist who uses their art to stand up against tyranny, the same way many artists I admire around the world have done throughout the ages.

Until this point, mind, I had no idea that was any part of what the game was about. I thought I was trying a new take on something that’s kept me creatively engaged for years. I wrote a book a while back set in a world where music and magic were the same thing. I was spending hours in that world nearly every day for 2 years, and at some point, I realized that in that world any art form should invoke magic.

Paint By Monsters was playing some of those same notes, and I kind of thought it was going in the same direction. But reading a story where some folks use art as magic, and actually playing the role of one of those folks, as it turns out, feels different. There’s a lot that comes out of that, but the big thing was clarity on a few different pieces of design:

  1. The Adventurers (who til now I’d sometimes been calling Heroes) were antagonists. There’s an easy perspective switch to make here – anyone with a little history in their head can appreciate how the crown and its servants might sometimes have dealt unkindly with common folk and upstarts in centuries gone by.
  2. The player should really feel like an artist while they play. Thus was born the notion of The Artist, the character represented by the player themself, and the Studio, the room in which they make their final stand in each life.
  3. Along with the Artist came Brush Strokes, which eventually became the basis of Feature Demo 0.0.10. It feels very different to just continuously spray minions into the arena, trying to surround and confound the enemy, versus using quick, precise strokes. It feels intentional.

These, then, are the cornerstones of the game’s core gameplay loop. We call it Room Painting.

Each new room is a new chance to try to stop the Adventurers from getting closer to the Studio. In each room, you channel creative energy to paint minions into the scene, and somewhere in the ensuing chaos one side or the other emerges victorious.

There are a lot of fun bits and pieces that have emerged from this core concept, and I’m looking forward to talking about those in future articles, but the emergence of these three key ideas, and particularly the Brush Strokes mechanic, was the first time I felt like I was headed for a good understanding of the Player Experience.

Art, Artists, Art Directors, and Beast-Headed Men

Somewhere around this time, I started talking to artists. I eventually landed on the incomparable Curtis Rioux and his merry band at Stellar Boar Studios. At first we talked solely about the studio doing art for the game, but as I went through the application process for CMF, I realized that games have many kinds of design intermingling, and art was an area where I really didn’t have the right skills or sensibility.

Happily, Curtis does have such a sensibility, and furthermore, when I sat down with him to talk about his ideas as Art Director for the game, he was already moving at the speed of thought. He brought a bunch of medieval mythical creatures to my attention, the best of which we chose for our starting lineup. I can’t wait for him to tell you all about the process of bringing those to life.

This new input set fire to my brain. I’d had a vague notion of what the world map might look like before, but adding these unusual creatures to the mix, along with a bunch of HEMA nerdery (check out Tod’s Workshop and Shadiversity in particular), gave me a strong sense of the tone of the game. There’s a playfulness here that wasn’t immediately apparent with the generic royalty-free assets I’d been using initially.

How can you not laugh at this guy?
Why is he wearing a padlock as a jaw strap?

I recognized, looking at these strange artifacts of ancient imaginations, that we’d do well to hold our tongues in our cheeks now and then.

Take Me to Your Action Heroes Murder Hobos

Maybe because of that new sense of levity, I also recognized that the game feels a bit like an Action RPG, and also that dudes who just run around with swords are Bo Ring. We needed a little flavour. A little flare. A little Michael Bay, if you will.

At this point I’d already worked on 0.0.7 & 0.0.8 (heavily informed by the excellent upgrade system in Brotato) and 0.0.9 (Dungeon Keeper, obv), and those informed my ideas about where we might inject some Action Hero notes. I also drew these:

This isn’t actually how it will go, but it inspired something all the same.
An early concept showing the Dandy swinging on a chandelier like Errol Flynn. Somehow, despite the diagonal lines, I thought I was making “pixel art” with this.

Just messing around with these sketches let me think in more concrete terms about what kinds of action might matter – interacting with the environment (particularly the addons from 0.0.9), the room, and the Minion horde. And that set me down the path to thinking about archetypes and Murder Hobos.

Murder Hobos is an idea in tabletop RPG circles that the group of characters in a typical D&D game is sometimes indistinguishable from a band of drifter serial killers whose sole purpose in life is to destroy life and steal property.

These days a lot of RPG players recognize that maybe this isn’t the healthiest model within which to run a roleplaying game, but for Paint By Monsters it fits perfectly.

The Adventurers are, after all the antagonists. It’s fine if they’re despicable. Better than fine – it drives home that whole thing about opposing tyranny.

And if the Adventurers are the expression of tyranny, then the ultimate realization of that is the crown itself. I’d already been thinking about including a traditional roguelike world map (sometimes called an FTL map), and putting Studio and Castle in opposition to one another fit very neatly into that setup.

This became the second loop of the game, which we’re calling Gauntlet Building. The player adds rooms to their magical gauntlet, trying to head off incoming Adventurers, and each time an adventuring party finds a room, they invade the gauntlet in search of treasure and glory, kicking off another iteration of the inner (Room) Loop (the one with the painterly gameplay).

There are, as with everything else, lots of fine details that have spun off from these seeds, and we’ll tell you more about those as development proceeds.

Roguelike? More Like Roguetolerate

The final piece of our puzzle is meta-progression. Folks often say this was the real secret to Vampire Survivors’ success, and it’s hard to disagree. The game makes you feel like you’re adding stacks on stacks on stacks on NUCULAR WEPPONS.

This is the second place in the design where my inner contrarian raised his head. Most roguelike games keep the the meta-progression elements behind very simple interfaces. A few have played with expectations a bit, or used more traditional unlock systems where completing specific in-game goals will open up new and exciting possibilities. But we already had such an interesting, unique world taking shape that tacking on the merest mechanical necessities felt really unsatisfying.

I started thinking about Evil Overlords and the tropes around them. Think about the villains in Lord of the Rings or Wheel of Time, for example – a dark lord is defeated, an epoch passes, a dark lord rises once again, ad infinitum.

Epochs

As a word nerd, any chance to use the word “epoch” is a chance worth taking, and so we came up with the Epochal Loop. The Artist may not be a dark lord, but they do rise and fall in the same age-old cycle.

Curtis (remember Curtis?) suggested that maybe in these sections of the game, the player is travelling between worlds, exploring an infinite universe of possibilities, and I thought that was just the best thing, for lots of different reasons.

Among those reasons is how it explains why the world we’re on is always in roughly the same technological period. Sure, civilizations rise and fall, but these days folks like to say History doesn’t repeat, but it rhymes.

We could say the roguelike elements of a game like ours – procedural worlds and progression, unlocked pools of randomly awarded abilities, cycles within cycles – fit this idea, but on some level it just feels better to say that maybe The Artist’s very soul is attuned to the medieval, and so when, in their travels, they happen across worlds upon which the people are just getting around to forging steel and fight senseless battles that will nonetheless inspire great art, they feel drawn to those worlds.

At least, that’s the backstory.

In Paint By Monsters, we call the place where the soul goes seeking its next home the Spirit World, and we’re building some unique gameplay around it. It will be a dark, mysterious place that lets you move at a slower pace – a good place to reset your mind and stretch your legs – and we’re still working out some of the details, but we’re aiming for a distinct identity that feels rewarding on its own rather than feeling like the player is wasting time away from the “good parts” of the game.

And not for nothing, it fits nicely with the Perfect Minute Games ethos – we make short, beautiful games for smart, busy people.

If You’ve Read This Far, Thank You!

So that’s where we’re at as far as the high notes go. I’d like to talk sometime soon about the other end of the design process – the nitty-gritty details of planning each thing in a way that will lead to a reasonably well-defined end goal – but for now I’ll leave you with this teaser for our forthcoming art devlog.

Meet the Paint By Monsters Demo Full Cast!

Left to Right: Barber Surgeon, Dandy, JuggerKnight, Giovannia aka The Artist, Blemmyae, Nucklavee, and Monopod

Featured Image

19th century engraving of The Trusty Servant, from the 1579 painting by John Hoskins (public domain).

Paint By Monsters DevLog 5 – Shader Experimentation

It’s been entirely too long since I was last able to talk about the development on Paint By Monsters, but with the Conceptualization Funding sorted and a partnership forged with the incomparable Stellar Boar Productions, I’m finally able to put a little of the old grey goo to work on matters technical and creative.

So: Shaders. This goes back to the thread that was originally pulled when I started with the Brush Stroke feature demo. There are lots of ways to paint stuff in Unity, but I’ve been meaning to take a deep dive (ok, a shallow dive) into shaders for a while now, and this seemed like a good opportunity.

If you want to jump directly to the shader itself, it’s here:
https://www.shadertoy.com/view/Dt2XWG

Otherwise, please, read on.

The Joys of Shadertoy

If you’re not already familiar with Shadertoy, it’s a website that allows you to create complex shaders within your browser, which is just the kind of nonsense that leads to a Destroy All Software talk. But it’s also just kind of awesome, since it lets you mess with shaders on a tight loop of try-fail-swear-fix-enjoy.

I looked at a bunch of different shaders, mostly having to do with mouse trails and such, but when I started iterating I took opexu’s Mouse Trails Soft shader as my jumping-off point. Obviously it doesn’t really look quite like a paint effect, but it leaves a persistent trail of colour based on mouse input, which is about as good as it gets.

I’ll admit I’ve forgotten a lot of what I learned back when I was experimenting with the Kinect. I’d half-forgotten I even wrote a post about a shader with inputs. As a result, I had to relearn some things.

Shadertoy uses a different representation for shaders than Unity, because nobody who implements a shader architecture can seem to leave well enough alone. If you’re not familiar with one or the other, I’d encourage you to read the Shadertoy and Unity documentation, but the short version is that in addition to the Image code (which determines the onscreen color of each fragment), Shadertoy allows you to use up to 4 buffers, and each buffer (plus Image) can accept up to 4 inputs (iChannel0-3).

Mouse Trails Soft uses one buffer, which is where it holds both the image so far and the last known mouse pointer position. The latter is by turns both clever and wasteful, but in this specific case it makes sense.

BufferA takes BufferA (ie itself) as input on iChannel0. It took me a while to suss out enough details to grok the relevant details here, so don’t worry if the following looks like gibberish right now.

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{   
    vec2 uv = fragCoord/iResolution.xy;
    vec2 aspect = vec2(iResolution.x/iResolution.y, 1.);
    vec2 uvQuad = uv*aspect;
    
    vec2 mP = uvQuad - iMouse.xy/iResolution.xy*aspect;
    float d = 1.-length(mP);    
    
    vec4 bufA = texture(iChannel0, uv);
    vec2 mPN = bufA.zw;
    vec2 vel = min(max(abs(mPN - mP), vec2(0.001)), vec2(0.05));
    
    d = smoothstep(0.85,1.3,d+length(vel))/0.4;
    vec2 dot = vec2(d);

    dot = max(dot, bufA.xy);    
    vec4 col = vec4(dot.x, dot.y, mP.x, mP.y);
    
    if(iFrame == 0) {
        col = vec4(.0,.0, mP.x, mP.y);
    }
    
    fragColor = vec4(col);
}

I went through this code slowly, teasing out the meaning of each line.

  1. OK, so uv is the texture coordinate normalized by resolution
  2. Aspect is the aspect ratio
  3. uvQuad is the aspect ratio-normalized coordinate
  4. Wait, but we’re adjusting by the mouse coordinate
  5. Ok, uv is the coordinate of the current fragment.
  6. So mP is a resolution+aspect-normalized vector from the mouse to the current fragment
  7. And d is initialized to…the one’s complement of that?
  8. bufA is the existing 4-component color at coordinate uv
  9. mPN is the…zw value of that value? Which is actually the x and y value from last frame?

For full clarity, the Image code is below, but it’s mostly just repeated setup. This is the point where I realized that I don’t need to understand every detail. Maybe you can tell me why that col *= uv + 1-uv is there.

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
   vec2 uv = fragCoord/iResolution.xy;
   vec2 aspect = vec2(iResolution.x/iResolution.y, 1.);
  vec2 uvQuad = uv * aspect;
  vec4 bufA = texture(iChannel0, uv);

  vec4 col = bufA;
  col.xy *= (uv.xy+(1.-uv.xy));

  if(iFrame == 0) {
    col = vec4(.0,.0,.0,1.);
  }

  fragColor = vec4(col.xy, .0, 1.);
}

With my newfound (albeit limited) understanding in hand, it was time to start working on my own shader. I figured I’d learned enough to start from scratch, since the soft-circle shape was pretty far from where I wanted my code to end up.

First things first: 3 dimensional math!

I want to draw a box that is axis-aligned with the direction my mouse is moving in. The parallel portion of that is just the width of the box multiplied by the mouse’s velocity unit vector, which I can get by normalizing the velocity vector. Assuming, that is, that I can get the velocity vector. Which means I need not just the current mouse position – available as iMouse – but the previous position as well.

Luckily, that’s exactly what opexu’s trick is for. Since opexu stores one of the components in the third color component, however, it limits which colors are available. Not having a blue component seemed like a pretty big issue when Paint By Monsters is so heavily based on painting, so I decided to dedicate a buffer to tracking current and previous mouse coordinates.

And so, Buffer A was added. Buffer A takes itself as input and for each execution it puts the last mouse position into the R & G components, and the new position into the B & A components. On the first frame, it loads everything with position 0, which, as it turns out, can be a bad choice. More on that in a minute.

Buffer A uses the code below to update itself, reading its own previous contents from iChannel0.

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    if(iFrame == 0) {
        fragColor = vec4(0.0);
    } else {
        vec2 uv = fragCoord / iResolution.xy;
        vec2 m1 = texture(iChannel0, uv).zw;
        fragColor = vec4(m1,iMouse.xy);
    }
}

The next thing I needed was my persistent graphic. Again, opexu’s approach seems fine here – I can use a self-referencing buffer that just holds all of the fragments painted so far.

Thus Buffer B was added. Buffer B, as it turns out, is where the key goodness happens. Since I’m reading color from it, it needs to know about newly-painted fragments. Which means I need to paint into it, rather than in Image.

I’ll still need the mouse’s velocity vector, so I feed Buffer A into Buffer B’s iChannel0 input.

vec4 bufM = texture(iChannel0, uv);

I can then calculate my velocity vector.

vec2 mouse_move_vec = bufM.zw - bufM.xy;

As mentioned previously, I wanted a simple box-shaped brush for this iteration on the shader. The vector “width” of the box can be represented as w * vb, where w is a scalar equal to half the full width of the box. This, by itself, defines a narrow, infinitely tall box. We can calculate whether a particular fragment falls within the width box by projecting it onto the velocity vector.

The vector of interest, in this case, is the absolute distance – along a vector parallel to the long axis of the box – from the fragment coordinate to the centre of the box. We first need to calculate the vector between our fragment and any point already known to lie within the box – v_mouse1, for example.

v_frag = fragCoord - v_mouse1;

If we take the dot product of this vector with a unit vector that’s parallel to the short axis of the box (aka velocity_normalized) – we can determine the parallel distance from the original point to the fragment coordinate.

d_parallel = dot(v_frag, velocity_normalized);

If this distance is less than w, the fragment lies within our infinitely tall box.

We can multiply this length by velocity_normalized to get the vector representation of the parallel displacement, which will come in handy later.

v_parallel = d_parallel * velocity_normalized;

The next step is to constrain our box’s height as well. For this we need the perpendicular distance from one end of the velocity vector to our fragment. If we can get a vector that is perpendicular to velocity but still in the plane of our canvas, we’re good.

The simple way to get a vector that is perpendicular to another vector is to use the cross product, represented in GLSL as the cross() function. If you’re just getting started with vector math, this can be a stumbling block – we only have the velocity vector, right?

But the thing is, we also have a 2d plane – the canvas – and a plane can be represented by a 3-dimensional vector that is perpendicular to its surface. Fragment coordinates use x and y, which means (by convention) our 3rd dimension is z.

We can take the cross product of a unit z vector with our velocity.

vec4 v_perp = cross(velocity_normalized, vec4(0., 0., 1., 0.));

However, because we calculated v_frag and its parallel component, v_parallel, there’s another, less computationally demanding way to do this.

Frame of reference transformations are beyond the scope of this article, but in essence they tell us that for any vector v_original and any perpendicular components of that vector v_parallel and v_perpendicular, by definition those components sum to the original vector.

v_parallel + v_perpedicular = v_original

This equation, however, can be rearranged to yield the perpendicular component.

v_perpendicular = v_original - v_parallel;

In our case, we already have v_frag and v_parallel.

v_perp = v_frag - v_parallel;

With both the parallel and perpendicular components in hand, we can fully constrain our fragment with respect to our box.

//Initialize with previously painted fragment color
fragColor = texture(iChannel1, uv).xyz;

// Box is 2*20 high, 2*10 wide
if(length(v_perp) < 20 && length(v_parallel) < 10) {
  // paint it red
  fragColor = vec4(1.0, 0.0, 0.0, 0.0);
}

This shader will set fragColor to red if and only if the current fragment lies within the bounds of a box of height 40 and width 20 with its shorter axis aligned with the mouse’s direction of movement. Since we’re feeding BufferB back into itself, we initialize our fragment from the previous value of fragColor, so even after the “brush” moves on, painted fragments remain painted.


Further Reading

I looked up some stuff about simulating oil paint for real, and maybe at some point I’ll put it to use, but given it will eventually get rendered down to pixel art, maybe not.

Either way, the paper is pretty interesting. Finite Element Analysis with hybrid physical models is not something I’ve seen all that often.

I also started looking up Unity videos to try and get my head back in the shaders + Unity headspace, and I ran across this video by Code Monkey, where he does something very similar to what I’ve done above, but uses C# code and MonoBehaviours instead of shaders and trickses.


Featured Image

Kaleidoscope VI” by fdecomite is licensed under CC BY 2.0.

Paint By Monsters: DevLog 4 + Feature Video 0.0.10 – Brush Strokes!

I’m gonna talk about all the faffery in a minute, but if you want the TL;DR, I invite you to take a look at feature video 0.0.10 – Brush Strokes;

Why “Brush Strokes”, Cousin?

One of the folks in my local gamedev community, the incredible artist rsvpasap, asked me a while back what kind of “painting” there was in Paint By Monsters, and at the time I didn’t have any kind of sensible answer for them.

Well, now I do, at least in the first-proof-of-concept sense. The Brush Strokes feature was directly inspired by that conversation, and I hope Angie would be proud to have sent me down this road.

On Assets, Asset Markets, and General Faffery

I’ve been mostly buying assets for PBM from itch.io artists, but there’s only so much content you can find there. I’ve looked at a bunch of new spots, particularly ArtStation and the Unity Asset Store, and in the latter I happened across the Gesture Recognizer asset.

This asset, on its face, is exactly what I wanted for Brush Strokes – a clean, simple asset focused specifically on recognizing a range of gestures, with good editor integration and the ability to create new gestures without a lot of faffing about. So, you know. Good job Raphael Marques on that front.

Unfortunately, Gesture Recognizer has a few problems out of the box that make it less than ideal to work with as of this writing. Maybe the creator will update it sometime, but in the meantime let’s talk about how I approached the issues that I encountered.

Fixing Gesture Recognizer

The first problem – and really, this is as much an indictment of Unity as a vetting agent as it is of the asset creator – is that unless you’re starting with the example level included with Gesture Recognizer, creating a new Gesture and trying to fill in the ID field causes a whole boatload of exceptions to show up in the Console Log. These will lead you back to the GesturePatternEditor.OnInspectorGUI method, and in particular to this line of code:

var closedLineProp = gestures.GetArrayElementAtIndex(currentGestureIndex).FindPropertyRelative("closedLine");

There are two exceptionally unfortunate things about this line of code. The first is that nowhere does the editor code check to see whether currentGestureIndex is a valid index for the gestures array. The second is that it is only really required in a small subset of gestures, because closedLine is only a concern when you’re closing a gesture that contains a closed loop of some kind.

My solution to this issue was relatively simple. I put an if statement around the entire editor block containing this piece of code:

if (gestures.arraySize > 0)
{
    //do stuff, including the array access
}

This fixed the editor errors, at least for the cases I care about.

I ran into some issues with the OnRecognize event that the asset uses, but I can’t 100% rule out PEBKAC for those, so I’ll just state for the record that Dynamic Events are tricksy, and you should look for them at the very top of the event list for the handler object.

I don’t really want to admit how long it took me to find that entry, but…it was a long time.

The Other Problem With OnRecognize

The really tricky bit with this event, however, is that the parameter for the event, RecognitionResult, only includes the points from the recognized gesture. The asset seems to be focused on some kind of cleaned-up vector drawing use case, so I’m sure that works great in that circumstance where you’re doing the scaling and whatnot in another component (for the record, you probably need to inherit from DrawDetector to do that properly).

But if you’re more interested in the gestures themselves – place, size, all that kind of stuff, and if you want to keep things nice and centralized to boot – you’re going to want the points as measured at the time of input.

Now, I’m not proud of my solution to this one, but I will say that it serves the purpose, and that’s enough for the kind of rapid feature iteration I’m doing on PBM. What I did was this: I changed the array of points that define the input being examined – which is a member variable in the object that invokes OnRecognize (that is to say, DrawDetector) – from private to internal.

internal List<UILineRenderer> lines;

This lets me do the following in my event handler:

var cam = FindObjectOfType<Camera>();
var dd = transform.GetComponentInParent<DrawDetector>();
var lines = dd.data.lines;
var line = lines[lines.Count - 1];
var point1 = cam.ScreenToWorldPoint(line.points[0]);
var point2 = cam.ScreenToWorldPoint(line.points[line.points.Count - 1]);
Vector3 gestureVec = point2 - point1;
Vector3 gesturePos = ((point1 + point2) / 2.0f);

This works for basically any straight-ish line, and gives me the two primary things I care about:

  1. The position of the gesture in world space
  2. The orientation of the gesture in world space

I expect to have to do more complex analysis for future specializations, but these two vectors allowed me to specify

  1. Where my brush stroke effects appear
  2. How big they are
  3. What their orientation is.

Of course, then I had to figure out how particle system shapes work and how they interact with the Position, Rotation, and Scale of their host GameObject…but more on that next time.

Paint By Monsters: Devlog 2 – Work To Date

I promised some local tech folks I’d do a weekly summary of my progress on Paint By Monsters, and I figured since I was doing that anyway, I’d expand on it over here for anyone who’s not in that very specific community.

First of all, I’m happy to report that PBM feels kind of like a game now
https://www.youtube.com/watch?v=_LGMChMhVFk

Things of note in that video include:

  1. Programmer art new logo!
  2. FTL-style “Progression” screen – as I understand it, these are required by law for roguelike and roguelite games
  3. Upgrades – each time you defeat a hero, you get an upgrade for your monsters. I’ll be expanding on these over time, and probably playing with other possibilities.

There are lots of smaller details, too, but I’m mostly just happy to be well on the way to something that’s game-ish in form.

I’ve got lots of plans and ambitions in mind for the game in the weeks and months to come, so I hope you’ll stay tuned for those. Some of the high notes include:

  1. Lair Building v1 – add balconies, traps, chandeliers, and more
  2. More progression stuff
  3. More monsters
  4. Acrobatic maneuvers

I mentioned some of those in my first Devlog over on Itch.io. Which reminds me – if you’re wondering how I’ll be working Devlogs going forward, I’m planning to alternate between itch and this site, with links going both ways. I’m hoping you’ll stick with me on that. I tend to prefer to keep things on this site, but it’s nice to have a more well-known presence as well, especially since between the game page on itch.io and the ko-fi page for Perfect Minute Games I’ve moved from “fun pastime” to “thing I’m both spending and soliciting money for”.

That’s always a bit of a hard rubicon to cross, from hobby to serious, but I’m trying to take the lowest, informal-est approach possible right now so I can keep my focus squarely on making the game itself as fun as I can. At some point I’d like to expand my ambitions to include custom art, animation, and music, but I’m not in a rush for now.

Having said that, if you’re an artist or composer who might be interested in partnering up, my email is always open:

mgb (at) perfectminutegames (dot) com

I can’t tell you how much I appreciate the interest folks have expressed in Paint By Monsters thus far. I’m excited to work on my own game design again, of course, but you never know how well it translates to anyone else. So getting feedback and even financial support has been incredibly encouraging.

Hope yer well.