Use:

UGameplayStatics::CreatePlayer(World, Index,bSpawnActor) (Docs).

When creating a custom game mode it wasn’t clear in the documentation how ones goes about:

  1. Spawning a playercontroller
  2. Spawning a pawn
  3. assigning both to each other
  4. and possessing the pawn with the controller

So I basically did it all manually inside InitGame(). This cropped up some unwieldy UI focusing bugs. Once I replaced it with a call to CreatePlayer() things started working as intended. Hope this helps anyone who’s starting out in UE4 with C++.

“If the byline on your article doesn’t enlarge its readership then you don’t have much of a value. All you’re doing is using the distribution network of a company. That makes you expendable. They can find someone else just like you. “

– Clay Davis

Quite an interesting read regarding the business of writing for a living. I don’t 100% agree with all the conclusions he argues for, but when put through the lens of indie games I think a lot can be applicable as well. The above quote struck a chord with me as it described the value of any given article on a major news site. In the 2009-2011 era of iOS indie games market, I think it’s fair to say most indies didn’t bring their own following to the app store. They used Apple’s distribution network, namely, App Store headlining features to move units.It was pretty clear that the ones that got early successes outside of “viral hits” were bringing to bear their already existing fanbase to the platform (licenses, tie-ins, pre-existing userbase). As more indies showed up to the party, it quickly became evident that any one game or studio was pretty much expendable, both to the platform holder and to players because there’d be 10 more with just as high quality (if not higher) games ready to sell or give away.

I think mobile is becoming a place where you have a better chance at trying to expand your following or re-enforce it, not start it. I’m pretty convinced you need more business savvy than game design savvy to be able to get any decent return on iOS indie games. That’s something most indies are horribly underprepared for. I’m starting to  think no amount of impeccable game design/execution will move a game from “financial flop” to “middling success” without a large dose of monetization strategies built into the game. This wasn’t the case from the outset, but times have changed the nature of the game.

Another choice quote from that article that made me think:

Every other site is based on ad revenue. That’s because sports fans have been conditioned not to pay for any content they receive. (This is why consumers complaining about content is so contradictory. Does any other free to consumers business hear this all the time: “Why isn’t the content that we don’t pay for more to my liking?!)

– Clay Davis

Music, literature, and games, seem to be running on similar paths when it comes to how people value them and what people expect out of them.

With each game release I’ve noticed I’ve committed less and less time to writing the ‘fun bits’ and more time spent trying to mitigate complexity and find ways to make as many things as testable as possible. I guess that’s the nature of the beast once you go beyond your average ‘asteroids’ clone. With the recent announcement of SFT getting asynchronous play in the coming months, I’ve been scoping out my dev schedule for what needs to happen to make it reality, and the only issue that I keep circling back to is “how the hell do I make all of this testable/bug free”. Sure, I could write the async frontend and backend and just do some “dry runs” on a few VM clients, but I’d lose sleep knowing full well that wouldn’t cover even half the potential bugs or edge cases. I use to reserve testing for server-side components, core game logic, but our games have grown to a level of complexity that I can’t ignore the UI/animation layer anymore in regards to testability.

The core logic of the game is fairly well unit tested. But the UI/animation layer on top of it has less than ideal integration testing. That layer has tiny bits of interface logic that has grown quite complex despite most of it not really touching the actual game state. It has sufficed for now, but it’s increasingly clear that it needs to get refactored, maybe in some cases re-done for easier integration testing if I want to move the game from “real time only” to “real time, async, and seamlessly transition between the two”. On top of that, I just recently moved SFT to Unity 5.x which has cropped up a lot of bugs on the UI layer, and are increasingly hard to hunt down. Adding in integration testing after the fact is definitely not the best way to go, but I’ve gotta make do. The show must go on!

Early on in the development of SFT I had concerns about how I was going to do text rendering on the cards in such a way that things stay readable regardless of resolution, while keeping fonts looking nice. I ran into aliasing issues as well as pixelation, since all the fonts being rendered were simply bitmap textures on top of cards that are flipping, rotating, and scaling in 3D space. I had read about SDF (signed distance fields) font assets for text rendering and was wanting to get something implemented for SFT’s cards. But alas, I had to temper my eagerness to “learn something new and cool” and focus on getting the game done.

So in the end, I opted to use Unity’s built-in font rendering, along with NGUI’s nice text layout and rendering tools, and  tuned the distance of cards from the camera in the different UI screens to make sure everything stayed “more or less” readable in as many cases as possible on as many resolutions as possible. This worked well for the rest of production and I think we have a very shippable solution for card text in SFT.

A couple of weeks ago I ran across this Unity asset called Text Mesh Pro. It had SDF font rendering! I poked around with it for a bit as it was a very easy library to just drop in and start rendering text in the game:

Screen Shot 2016-02-12 at 7.08.15 PM

 

The top number is rendered with Text Mesh Pro. The bottom with a combination of Unity fonts + NGUI UILabels. The difference is stark. Now in practice, I think most wouldn’t even notice. The UI in SFT was minimized to the best of our ability to make sure the limitations of the fonts didn’t draw attention to themselves. Sure enough, it was hard to tell in SFT unless you were looking and had both builds side by side. It was a definite improvement, but I think in future projects using SDF fonts will make me less weary of using thin or very large typography. Even if the visuals aren’t miles ahead, the big win here is memory savings. Instead of having huge font atlases with 200pt fonts to keep things crisp, a single small SDF atlas is all that’s needed for any point size, and in the case of the TMP asset, any style.

This is one of the things Unity gets right. The font rendering asset that Digital Native Studios put together represents probably hundreds of man hours. I simply couldn’t justify that kind of time for our game on just text rendering, despite it being arguably an important part of a card game. If I wanted to do that for any piece of “core” technology in any given game, we’d be measuring our development time in years, not months. Sadly, we can’t afford that kind of time. Instead, I made use of the tools we had at the time (which were good for the most part), and alter the game’s aesthetic to match with what we were capable of. Being able to go and drop in a new library for font rendering and immediately benefit from it after 20 minutes of work + a few bucks vs hundreds of hours is impressive. Hats off to the developer behind this nice little tool!

Taking the “conflict” out of shared roles:

We opted to do a ‘ranked preference’ for role selection in SFT. Instead of players joining/leaving and selecting anywhere from 1-3 players to control and then having more UI flow when conflicts arise, or a character is left unselected, or a few other scenarios, we simply take everyone’s preference list and the game deals out character roles based on them. If there’s a “tie” (for instance two or more have captain as their first choice) it’ll be random who gets it. This means:

  1. One UI (simpler implementation)
  2. No timing based conflicts or resolutions to manage
  3. More control over how players are distributed.

The core reasoning behind going for this system was also due to the game always has 4 valid characters. You can’t play SFT without one of the roles. If a player drops mid-game, the host takes over that player’s role. The key influence for this system was from Evolve. A fine game I might add that I think deserves way more credit than it has received.

Finally got another card ability animation implemented into SFT:

The method and architecture I’m using for driving game logic I think has served me well for the past few years. I shipped Outwitters on the basics, and expanded the gameplay “engine” for SFT, which allowed for real-time multiplayer (albeit in sometimes hokey ways). The drawback is I haven’t found a good way to untangle it from the animation layer. It’s all 100% unit-testable, but when it comes to driving user input visuals for card play, it’s still a mess of:

  1. Play this animation clip when a user clicks.
  2. At this point in time, run this action to apply changes to the game state
  3. Then run this bunch of code to update UI, send state machine changes to animation FSMs, and send out any other misc events
  4. Then either:
    1. wait some arbitrary amount of time to submit another “action”.
    2. Have some hook in either an FSM or animation clip, to call back to a method to submit another “action”.
  5. And proceed to pull hair out at all the other permutations of that flow should the user wish to back out of the “happy path”.

This makes for a very difficult setting to collaborate on animations. Ideally it’d be nice to just have the artist create some canned animations that I can just use and then time them to game logic when needed on a separate queue/thread. In practice this doesn’t work because a lot of card animations are spline-based. Furthermore, the splines are dynamic since cards could be in any number of states, locations, or orientation at any given time when a user decides to click them. This makes the process of “animating” abilities such as the above really time consuming. The alternatives:

  1. creating a ton of animations for each possibility (lol, no).
  2. Or a less ‘fluid’ look where cards simply don’t move as you’d expect, but do slightly strange arcs since it’s the same canned animation regardless of angle, position in hand or inventory slot.

I think in retrospect I needed to spend some extra time, maybe a week or more, coming up with a better pipeline or workflow to allow for easier iteration on card animations. My first hunch is maybe trying to make some sort of ‘building block’ animation library for cards. So for complex sequences they’d simply just be queued up series of fundamental animations in cards, and then I can easily just interlace calls to PlayAnimation() and SubmitActions() and treat them almost identically in code as opposed to the one-off hacks for each ability that currently exists. But even that process is rife with a lot of edge cases due to the dynamic nature of how players interact with cards, and ultimately would still require some programmer help to get things looking right.

For the moment, card animations in SFT are created by:

  1. The artist creates a fully animated mock up in Unity using the tools they know. Artist now exits stage right.
  2. I then painstakingly try to mimic that entire flow (and very often other user flows not captured in the 1 one-off mock up) using a combination of animation clips, splines, FSMs, and procedural animation via code.
  3. Give up trying to replicate the mock up when enough time has gone by and I realize I have to move on.

I’m able to capture the majority of the mock up’s “essence”, but a lot of the subtleties of the animation that artists are actually good at creating are lost due to lack of time and lack of flexibility. Maybe next go around if we’re doing another card based project I’ll be able to have another go at this.