Sunday, 19 March 2017

My problem with most F2P games

I've been meaning to write this article for some time and I'm never happy with how it flows. I think it's time I just poured it out and maybe do some adjustments later.

I've seen a few people throw around that if you want a successful game (especially if it's online or for mobile) it should be Free to Play (or Freemium if you want). I think this is inherently true, but most people I've asked don't seem to understand what's going on to make this business model so prevalent for those two cases.

Lets define the success of a game. For most this could be some sort of formula that could relate profit with (for those of us that actually care) some amount of critical praise, player count and the desired impact on the target audience.

All of these goals more or less depend on making people want to play your game. So what's the easiest way to get people to play you game? Just make it free, now all you have to do is convince people to try it rather than the much harder process of getting them to actually put money into something. But wait, you say. I'm no longer making any money from people trying out my product. How am I supposed to make money out of it? There's thing thing called monetization and it's an entire discipline which could be (very horribly) summed up as finding a solution to the problem of having lots of players yet no money coming in.

For most companies this has an inherent tendency to become a really shady practice rather easily. You're luring people in with a premise (free game) and trying to make the game fun so they keep playing, yet not so fun so they actually feel comfortable not purchasing anything. So you're compromising the most important part of your game (the fun part) because you followed the F2P model. I'm not even going into the balance issues you'll have if your game is competitive. Soon you'll be designing your game in a way that will lure players into associating microtransactions with dopamine drips: the waiting games with instant gratification if you pay, the powerup slot machines that get you another roll for a few extra cents, the instant energy refill that lets you play for 20 more minutes today.

Note that I'm lumping convenience purchases like Path of Exile's extra slots as a compromise due to the fact that you will also have to consider convenience as a factor that affects the gameplay. Lumping content behind paywalls also falls into this category. The only alternative to this (that I'm aware of) is to sell purely aesthetics items.

In short, picking a F2P model for your game should be a carefully considered decision. Its main advantage is that it will net you a ton of players (very useful if you're going for a multiplayer title where player count is extremely important) but then you will have to shift your gameplay efforts into making sure some percentage of your player base is spending money.

And this is the part that scares me. You're shifting your design efforts to extracting as much money as possible from your fans. Usually some extremely low percentage of players that spend thousands of dollars on things like hats and slightly faster movement speeds. I could never get behind this practice as it feels intellectually dishonest and the best results seem to be appealing to basic human emotions like gambling and immediate gratification.You're making your product successful not by making a good game that people will purchase, but by luring as many people as possible into downloading it and then convincing some small percentage of players to spend as much money as possible.

Can you do F2P in a way that doesn't make me want to take several showers? Kind of (my moral compass is extremely sensitive). Both Path of Exile and Warframe seem to have found a balance where the F2P model helps keep player counts high, and the benefits for paying are designed for the most dedicated fans in such a way that it doesn't give them competitive advantages or make the game simply more enjoyable for them (in my opinion at least, game design is hard to quantify).

And let's not get me started with AAA companies nowadays trying to monetize their Premium games.

Wednesday, 18 November 2015

Low-poly water on UE4

Note: For some reason the original videos disappeared from blogger and I've had to create new ones.

Here's how to achieve a cool retro-style water effect using UE4

First of all, we need a suitable plane. While Unreal comes with one we can use straight out of the box, I prefer having one that's just right for my purposes. Here's one I made using Blender.

The UV map (to the left) is rather important to get right, or you'll just get wonky results. Make sure it maps the corners to 0,0 and 1,1.

And because I know you're in a hurry, here's the final shader (you can copy and paste this into an empty material to save you a lot of work):

How it works:

Firstly we take the current time and use it as UV coordinate modifiers to sample a nice, smooth and tiled noise texture. I found "LowResBlurredNoise" (make sure you're allowed to view engine assets in order to select it) perfect.

To avoid most issues with occlusion culling I then "normalize" the values between -0,5 and 0,5. Why is this important? It allows us to increase and decrease the vertices' height relative to their original position rather than just adding to it (and thus always skewing them upwards). You could multiply this by 2 to make the values range from -1 to 1 but you can achieve the same thing by tweaking the wave scale value.

Finally, with a suitable noise map, all we have to do it modify the original vertex position. We take the normal (which would point up in the case of your plane), multiply it by the noise values and as time pans the noise texture forward through all the vertices in our plane, we get a wave.

Why use the normal instead of just just an up vector (like 0,0,1)? It allows us to place water sideways and so some weird stuff with other shapes, like this:

The bits connected to the "normal" part of the material are a bit of "dark math magic" which recalculates the vertex normals after we modify their position. If it wasn't there, the lighting on our water would be constant and look completely hideous. I may go into more detail on this one day.

Usage Notes:

  • You CAN put several of these planes beside each other. They will cleanly fit and should have no seams if you've done the uv mapping properly.
  • As with all vertex-deforming materials, this one will become a bit iffy with occlusion culling, especially with huge "Wave Height Scale" values.
  • Make sure the water plane isn't casting shadows on itself or is otherwise baked by Lightmass
  • Keep in mind that due to oscillating height, it may clip through the ground if you're not careful.
  • Unfortunately, due to the way Unreal handles flat shading, this leaves us with a rather high poly count for a simple flat shaded plane. But this has nothing to do with the Water Material itself.

Addendum: If you're into Unity3D, /u/Ro9AM has posted a neat little tutorial (with source code) that does pretty much the same thing :)

Wednesday, 14 October 2015

There is such a thing as too much compiler optimization

I spent my University years using antiquated subsets of C and C++, so I decided to try my hand at the latest Standards and Proposals.

After some time I found this weird... Bug? I had a GetNeighbours function that would fill out an array which was passed by reference. It spent a few days as an empty placeholder. Once I filled out the function so it would actually return the neighbours, I started getting compiler errors because std:array was undefined. How could this be? The function had been there for ages, and had always received an std:array parameter. Why was it only throwing out errors now?

The answer was simple but it took a bit of lateral thinking: The compiler had figured out GetNeighbours was performing no useful work and simply ignored it, not even caring that the type of argument was undefined. The function call had been removed and the code had never been compiled.

I'm ashamed to say this took me a few minutes to figure out. Here's a simplified version of what happened:

This works
This doesn't (std::array is not a defined type)
This works. Wat?

Thursday, 10 September 2015

On moving from Unity to Unreal

The team at Titan is working on a soon-to-be-announced Top Secret Project. We've recently changed from Unity to Unreal and here are some things we've thought about sharing with other Devs that are thinking of making the jump.

The good stuff: 

  • Unreal let's you easily alter the aesthetics of your project. The drag and drop material editor, the huge amounts of built-in high quality content let you easily reach AAA levels of quality, even for small prototypes.
  • Blueprints are amazing for quickly prototyping concepts! Beware: any non-trivial math expressions will be a mess of wires, but thankfully there's a handy math expression node to help you avoid turning your code into a spaghetti mess.
  • The community has a lot of experienced developers, which makes useful content and non-trivial tutorials easier to find.
  • The architecture and the way everything is structured encourages newbie developers to write more robust code. Contrary to Unity, there's already a game state, game modes, an Actor-Controller model...
  • Epic's experience has led to so much high quality content that you can easily pick up something like the FPS Tutorial and merely have to tweak a few values to suit your needs - We recreated the movement style of our first Unity game (Slinki) in a matter of minutes.

The bad stuff:

  • The render pipeline is setup for realistic lighting, if you want something really stylistic illumination you can either "hack" your way around this with more complex materials or get down and dirty with the rendering pipeline.
  • Don't get me wrong, Unity can be a bit of a resource hog sometimes. But Unreal seems to be an expert at making even our reasonable Gaming PCs suffer. Compile times will be measured in minutes for anything but the smallest projects.
  • The way Unreal handles project files is simply not as robust as Unity's. Every time you move something, a file a redirector is created. 
  • You can't just drop a png file and use it as an asset, there's always going to be some sort of pipeline to get assets into your game. 
  • As a sidenote to the previous point, you will have to export your blender models as an fbx. Many things can and will go wrong with this process. I would write a tutorial but I found it changes a lot between versions of both programs and none of our solutions have been ideal so far.
  • C# is gone. You will be using C++. This can be a curse or a blessing but overall C++ is not as great for quickly prototyping.
  • It's not very stable. Seriously, it's not. The update to 4.9 broke transparent sprites on the UI. This is not a trivial and easily-ignored bug.
  • The huge ingress of novice game developers has made communication with the Epic team and experienced members slightly harder due to a sea of (mostly) trivial questions.

Wednesday, 29 July 2015

Chocolatey is awesome and you should use it

I've recently started using Chocolatey. While the thought of a package manager for Windows has crossed my mind (oh, my long gone Linux fanboy days), I always relegated it to something that would be too hard to maintain and work with.

For anyone who hasn't used a package manager, here's what makes it better than the classic install/uninstall babble.
  • The endless cycle of "Go to website, navigate to download link, wait, double click, click next, uncheck the 'install malware option', press next 2 more times, wait again, press finish" is gone.
  • Update ALL your software with no user input
  • Got a new machine? Run a single-line command and all your favourite programs are now installed.
  • A lot less annoying popups saying an update is available
  • I think avoiding Adobe Flash updates deserves an entire bullet point. 
So how does it work? Suppose you want to install git and Flash. Easy, launch the command line as an administrator and run this command.
 choco install Git flashplayerplugin -y 
After some time both Git and flash will be installed.

Firefox's giving you warnings that your version of Flash is unsafe?

 choco upgrade all -y 
Now both flash and Git are up to date with (nearly) no user input.

Wednesday, 27 May 2015

Unity's new event system

Despite being very poorly documented, Unity's new event system can be incredibly useful. Here's a really simple script that I keep using over and over.