Friday 11 March 2016

Pun Shooter #17 - Summary of recent work

Since my last post was arround the 3rd of March,  I missed out a little. Here's a summary of significant features added:

  • Global leaderboards
  • Mobile controls
  • HP system
  • Loot drops
  • Unique mascot with stats
Overall that's about 15 commits in the past week or so.

Saturday 5 March 2016

Leaderboard integration: GameSparks vs Heroic Labs.

Introduction

In a recent post I give a bird-eye view of Parse alternatives. Last week I integrated leaderboards in Bad Bears using both GameSparks and Heroic Labs. Granted, these guys offer more than just leaderboards - notably, 'cloud' (aka server side) storage, cloud code and analytics.

Other candidates I quickly sidelined:
  • Gamedonia since leaderboards are very much DIY in their case.
  • Not everybody enjoy scrubbing back and forth while squinting at code lines and straining their ears to decode compressed American English audio. Sorry BrainCloud (and no: I don't want your sample project)
Other candidates (see my previous article) may be worth considering. Now that I tried two I might overcome my issues with BrainCloud and give it another try.

GameSparks

GameSparks provide a comprehensive service; I like that logged info includes a player's city and country.

I like the test harness which allows building JSON queries in a sandbox - what this means is that you can 'play your game' against their test server directly, which of course goes way beyond leaderboards.
But then again. This shouldn't be a substitute for a well documented service with clean APIs.

I don't like that I had to use a JSON parser just to get a player's rank. Their APIs feels stuffy at best (You got a namespace named Api? Give me a break...) and I found myself juggling between documentation pages, API docs and admin panels to patch my code together.

Support exists though I'm not liking it yet.

I spent 4~5 hours setting up and integrating.

GameSparks was founded in January 2013.

Heroic Labs

The Unity SDK integration is nice: just drag and drop a dll and you're ready to code.

Docs are shiny, with a comprehensive, top to bottom document explaining (with to-the-point code snippets) how to integrate their features with your game.
Still, the docs sometimes wander off topic, and put business talk in a separate document?

On the down side, you get less 'out of box'; for example I wanted leaderboards ranking players according to their latest score, which requires (yet to be written by me) custom code.

Support is good.

I spent 2~3 hours setting up and integrating.

Heroic Labs were founded in October 2014.

A note

Something that most providers (including these two) seem to go with in their sample code: anonymous functions. Beginners will be confused by this - they won't even know when the code executes.
Also, I'm guessing that these will go away when structuring my code, keystroke saving all on their end not mine.

Session logs

I'm not sure how informative this is. But anyway that's how I used my time testing these APIs.

GameSparks

7:19 - Oh my, I already have an app setup.
7:23 - Don’t understand “Segment Configuration“.
7:29 - They say they have a package but they don’t. Oh wait… bad presentation of their SDK intro.
7:37 - This cockup with the sample proj. versus package (since I enterprised to frankenport the package in my project on my own), now that caused GUID errors.
7:42 - Don’t get it. I mean, they were trying to make me enter the API key and secret or whatever but this part was way too verbose, got lost.
7:54 - Duh, imposing your puny singleton pattern upon me?
8:10 - Can authenticate. Really dislike these implicit functions.
8:21 - One thing that bothers me is that it looks like their SDK needs to asynchronously perform some kind of init before I authenticate. I would expect that waiting for an all-clear event before authenticating would do it but meh. So I hooked my authentication to the start game button (since I used device authentication ). How unsightly.
8:34 - Already created a leaderboard.
8:35 - Off to the test harness I guess we’re testing how to submit scores. So I will create a user John.Doe with display name John and password ******. Works.
8:40 - I go to LogEvent and “submit a score”. They say “since the event is attached to the leaderboard“ but I don’t remember doing that. Seems to work though.
8:50 - When they say "numbers” they mean integers.
9:05 - Looks like I should use “LAST” for my event.
9:14 - Good time to submit scores is when a player win or lose. got hooks for this.
Ah well. One good thing is the test harness. I’ll be able to validate my notions about how to setup the event and leaderboard using that. So, I can post scores. I need to do rankings and leaderboard requests too.
10.38 - Anyways. I don’t have a JSON API handy. Yea yea JSON is easy to parse but what if you did NOT want to parse?
Now, I want to get the player’s rank first thing when entering the game. Means I need to authenticate as fast as possible.
11:03 - Seems like they didn’t want Unity users to get any callback after initialising their API.
11:07 - Displaying their data in my widgets
11:26 - What the heck is preview mode?
11:56 - Setup live environment. 
12:05 - CLEAR
Two days later
2:05 I want to silence their logs. I don’t mind logs as long as I can control them
- Well. I’ll just hack PlatformBase. Oh, and they use a very interesting pattern here. Gistbox!
2:15 - CLEAR

Heroic Labs


6:18 - Creating my account
6:22 - Creating a leaderboard.
6:23 - Heading over to Client SDK docs
6:30 - Installed, copied API key to my sample code.
6:33 - Ran; encountered an error. Mailed Support.
6:40 - Deleting their SDK dll.
6:43 - CLEAR.
6:54 - They seem to be looking into it.
Two days later
1:52 - Logging (note: links are not extremely visible, like here: https://heroiclabs.com/docs/guide/unity/)
2:11 - inserted my API key. 
BREAK
2:23 - So mmh. Apparently NOT receiving a message means we are okay. No news, good new, eh?
2:40 - Not sure why they are caching the session client. Where is the overhead really? Also, did they forget to paste the code showing how to serialise the session client before deserialising it?
2:54 - Nickname cannot contain profanity? Grrr(*)
And I’m guessing that, though it looks there is a callback for it, it's not being called?
3:05 - Adding client code to get leaderboard and submit scores.
3:08 - Leaderboard.Entry should be GameUp.Leaderboard.Entry. Well I got my own Leaderboard class.
3:21 - I wonder if I can submit decimal values to leaderboards?
3:24 - Now, their service won’t log me in. Well, actually there is a weird inspector(?) bug that causes my API key (the public field in my custom class) to get deleted. No wait, *I* keep renaming this. My bad.
3:31 - Unity died on me. RIP. Also, it's not restarting wtf.
3:52 - They don’t allow spaces in nicks either… ?
3:57 - Their API makes it easy to get updated ranks. Just need to wire this up.
4:08 - Another freeze. Not sure if it comes from their API, GameSparks or running the two side by side. Eh.Something else entirely.
4:27 - Just need to sort my board using the latest scores. Can it do that?
5:00 - CLEAR
(*) A common feature of not so clever profanity filters is that they reject actual names, like "Tito" or "Titus". Not allowing spaces is more of a bummer, something that our players won't be jazzed about.

Wednesday 2 March 2016

Browser caching notes

Like with most web content, sooner or later browser caching can become an issue with Unity games.
  • For testing, private windows work well in that they're not supposed to cache data, and it appears they don't.
  • See this page for a small trick that... well... might work if you update your game frequently on live builds.

PUN shooter #16 - Mouselook and Classic FPS controls

Since I started the Bad Bears quiet alpha a common request is the classic mouse-look found in many first person shooting games (apparently made standard by Quake). I decided to implement this today.

I've been trying to get nicely decoupled input:
  • Avatar objects don't contain input code. This avoids PhotonView.isMine bulls**** symptomatic of poorly designed (multiplayer) avatar controllers. 
  • Makes it easier to write non player characters based on same avatar code.
  • Makes it easier to reuse input components for something else.
Here's how it works (follow links for source code):
  • [MouseDelta] produces a smooth output vector while the mouse is moving. The mouse cursor is hidden, locked while this component is enabled. One point of note is that, while the mouse cursor is locked, Input.mousePosition will return the same value at all times; input axes "Mouse X", "Mouse Y" are used instead. Its output is consumed by a [RotationController] which rotates the avatar that the camera is attached to.
  • Likewise [Joystick2] processes "Vertical" and "Horizontal" inputs (by default, maps WASD), sending the result to a [MotionController].
The above uses [Vector2Input] and [Vector3Input] to decouple consumers from their inputs. Oh, and you need my [god class].

One potential limitation with the above is that the avatar needs to be kept upright when using a trivial first person camera setup (camera parented to the avatar). I used [KeepUpright] to avoid this problem.


Tuesday 1 March 2016

Git marmalade

As I recently discovered, one of Git's awesome 'hidden features' is that using several user accounts is more than their system will gracefully handle.

Committing from the same machine I used with another account generates commit messages for that previous account. A Gist explores the issue and this helped me fix the inappropriate commit.

In short, if you're worried about this:

  • Use git config user.name and git config user.email to check your "identity". 
  • Use git config user.name "John Doe" to update your user name (and likewise for e-mail)

Am I supposed to run a script whenever I switch account... ?

Monday 29 February 2016

PUN shooter #15 - Core experience fixes

Even a simple shooter without perks may need fixing.

I temporarily disabled battle mode because it felt broken. I don't want it to stay down for long though, because it can be fixed.

This put the emphasis back on survival mode which at the moment is the most accessible game mode.

Note: When a player enters, they should see a notification if the game is 'empty' at least until we can substitute some kind of fun.

One issue with survival mode is that the progression implicit to battling other players is not obvious enough:
  • A player should see their rank when they enter the game.
  • I think we'll be showing a leaderboard with daily ranks when a player lose (should also be visible from the main menu)
  • A player should see notices, or a short narrative, possibly during or after they battle enemies they encountered before. For example: "This guy is a wimp, he's only ever won x times" or "This is the guy that done you in last time. Time for payback" or "You got busted xx times today".
Also, it looked like the ranking system was broken (but not the number of win/losses) but this is unconfirmed. Maybe data gets deleted when replacing the web player or clearing the history?

Too many players are asking for mouse look and overall more conventional controls.

Sunday 28 February 2016

PUN shooter #14 - Multimap

Now I have 4 maps but not sure how I want to make them available: If all users choose their own map, the probability that two users are in the same room is now 1/N where N is the number of maps.

: D

But then again, I need a simple way to open the maps for showcasing and testing. So, I implemented an option to join a specific room (numbered in the menu). Now I want players who just choose 'Survival' to join a non empty room if possible (otherwise, pick a random room)
It's possible to just try joining rooms (since the names are known in advance) but this isn't gonna play nice with my workflow where loading the target level and joining a room are the same thing.

So, I connect to the network from the game menu and check rooms.

Before starting a game, we need to disconnect from the server, or vary connection logic to avoid a redundant connection attempt.

Since there wouldn't be much benefit to showing these options at this stage, they are only available when SHIFT is pressed.

Try the latest build [here]