Creating simple tools in UE4 – part 1

In this series of articles I’m going to show how to create some high-impact, low-effort tools to help develop your game in UE4.  Tools range from simple batch files or humble debug commands to complex ensembles like the UE4 level editor or Max/Maya; but for now let’s focus on some approaches that don’t require a broad knowledge of Unreal Engine or Slate to pull off. Some of these topics deserve a post of their own, but I’m going to start with more of a survey approach and see what people are most interested in digging into.

Programming is all about strategic laziness: the guiding philosophy developing tools is to spend time now to save someone time later, improving overall developer efficiency. This might play out by allowing the user to finish the same tasks in less time or it might allow them to perform more iterations in the same amount of time, increasing polish level and fun factor. Ideally you also save more time than was involved in making the tool, but that is not a hard requirement due to other factors like user morale, making it possible for a different group of people to do the work, reducing mistakes when the cost of failure is high, etc… This is especially true when it comes to automating key processes where a mistake might cause downtime or otherwise hurt your customers, e.g., releasing a broken update or corrupting a database.

Continue reading “Creating simple tools in UE4 – part 1”

CGA Post-Processing in UE4

I spent some time last weekend prepping for #cgajam by playing around with different materials / effects to constrain a UE4 game to CGA colors, and came up with a drop-in post processing BP.

Small preview, click here for full view

How to use

Download the template (requires Unreal Engine 4.16, licensed as CC0) and unzip it.  You can either open the project directly and migrate the Content/CGAJam folder into your project or drop the whole folder into the templates directory of your 4.16 installation (e.g., C:\Program Files (x86)\Epic Games\UE_4.16\Templates) and then create a new project (info on how to make a project into a template here).

There’s an example map but all of the magic is wrapped up in BP_CGAPostProcess; just drop one into your level and try playing around with the settings to suit your content. You can pick one of the two palettes, adjust how much color-space dithering and screen space dithering there is, and tweak the overall gamma / brightness. For the hand painted environment I found 50% screen dither + 50% LUT dither at level 3 to give me the best results, but for the example scene with solid shapes and color fills, 100% screen dither with no LUT dither looked better.

Implementation details

CGA had a variety of different modes and palettes, but the most memorable for gaming was the 320×200 graphics mode using either palette 0 (black, red, green, yellow) or palette 1 (black, magenta, cyan, white).  Color 0 (black) is actually adjustable to any of the 16 CGA colors, though it doesn’t appear to be allowed for #cgajam. The red and green components of colors 1..3 are the same in both palettes as well, only the blue color differs.

UE4 has a lookup-table texture (LUT) based color grading system, but there’s no way to control the filtering used to sample it, so it can’t produce ‘crisp’ CGA colors.  It’s still useful to get colors to nearly the right place though. I’ve included 4 LUT textures for each palette with varying color-space dithering (0%, 25%, 50%, 75%); you can adjust the strength of the color grading as well to vary the effect.

Color grading LUTs for palette 0

The post-process material (M_ForceCGA_PostProcess) has a screen-space dither pattern which dims based on brightness prior to matching to one of the four colors in the active palette.  The color matching (MF_ForceToCGA) and dithering (MF_DitherBrightness) are split up into separate material functions to make them easier to reuse, e.g., in the UI material.

The actual color matching is done using a cheap lookup texture with red->U and green->V (the 2×2 texture is set to uncompressed, clamped instead of wrapped uvs, nearest filtering, etc… to give us a clean and exact output value).  We can ignore the input blue entirely as mentioned above, and multiply the output blue with the correct value for the current palette (dim it for palette 0 and keep it as-is for palette 1).

MF_ForceToCGA
MF_DitherBrightness

User Interface

For the UI, you’ve got two options:

  • Stick with the CGA colors, which need to be specified differently in the UI than in the world since UI happens in a different color space, e.g., yellow is (1,1,0.092) instead of (1,1,0.333) (the correct final color will show up in the hex sRGB setting of the color picker).
  • Get in the right ballpark and use a retainer box with the Effect Material set to MI_ForceCGA_UI_Palette0 or MI_ForceCGA_UI_Palette1 to guarantee that you only use the correct 4 colors (recommended approach).

    Using a retainer box

Avoiding flickering artifacts

There are a couple of steps in the default UE4 post-processing chain that introduce temporal artifacts in order to improve overall image quality when doing realistic rendering.  These steps become very noticeable and objectionable when you do something like threshold down to 4 colors, so the example project disables them (setting r.Tonemapper.GrainQuantization to 0 and disabling post-process Anti-aliasing entirely, though you could also switch from temporal AA to FXAA instead). The DefaultEngine.ini changes to do this won’t transfer over if you just migrate the content from one project to another, so you may need to paste in:

[/Script/Engine.RendererSettings]
r.DefaultFeature.AntiAliasing=0
 
[SystemSettings]
r.Tonemapper.GrainQuantization=0

Resolution

Want a lower resolution that is a bit more like true CGA 320×200? Adjust the Screen Percentage on the post process component and set r.upscale.quality to 0 (nearest filtering) in the [SystemSettings] section of DefaultEngine.ini

Ideas for further improvement

Try combining it with an edge detection material (either on depth or on custom stencil if you want to limit the effect to foreground objects) to put black outlines around things.

Try other spatial variation patterns besides a 2×2 checkerboard; techniques like Real-time hatching would probably work quite well.

Credits

The map used in the example shots is from the “Hand Painted Environment” marketplace pack by Evgeniya Yaremko.

Planetary Garden

Ludum Dare 38:

For one reason or another I’ve never managed to participate in a Ludum Dare before this past weekend (LD 38). Planetary Garden was made under the compo rules (worked alone, created all new assets, finished within 48 hours of starting). However, I got a late start (3 PM Sat) and did not submit in time for the official deadline, so it’s technically a jam entry.

The theme was “a small world”, and I started riffing on various ideas for many connected small worlds: perhaps a platformer on a circular planet or mini golf where you switch worlds.  These ideas didn’t quite jell or seemed out of scope considering compo rules, and incremental games have been on my mind as well, so I ended up going in that direction (tho Planetary Golf seems like it has legs, might revisit it in the future).

You can download the compiled version for Windows as well as the project with source code and assets at itch.io, and vote / leave feedback on the LD 38 project page. Unless otherwise noted, assets created for the compo are placed under a CC0 license and game code under a MIT license.

Art Style:

Entering the compo means that you have to make all of your own art and audio (with some very limited exceptions for fonts and brushes/samples, etc… that are suitably transformed). I’m not a particularly good artist, so I went with a watercolor artistic style that let me leverage materials for most of the impact, and created the actual art as simple RGB masks (outer border, inner border/outline, and fill color). I wasn’t going for realism but just something evocative of watercolors, with variations in opacity and splotichiness generated by a couple of noise samples operating in screen space so it looks coherent across objects.

How to play:

  • Repopulate a barren planet (Earth?) with life by seeding new plants
  • When the time is right, enlist animals to help automate the process (one of them knows an ancient secret).
  • Eventually other things happen. No spoilers.
  • Note: Progress is saved between sessions, but time does not advance while the application is closed. Keep it open to continue amassing life.

Tempo Tantrum

The music is having a tantrum and can’t decide how fast to play. You move with the tempo, as do the enemies. Watch out for environmental objects like spike blocks, they don’t have ears and will keep moving regardless, so don’t get caught in their tracks when the music stops.

 

Download from itch.io and give it a go.  Here’s how to play:

  • Two players (or one ambidextrous player) race to the end point.
  • Don’t move when the music has slowed down, and avoid anything red.
  • Collect coins to raise your score.
  • WASD moves player 1 (green)
  • IJKL moves player 2 (blue)

The theme for the 2017 Train Jam was ‘unexpected anticipation’, which was pretty challenging to work with. The first thing that came to mind was Johann Sebastian Joust, which fits perfectly but already exists. We bounced some ideas back and forth and ended up wanting to do something similar to Joust or musical chairs with stop and go gameplay, leaving you anticipating needing to stop but not knowing exactly when. The environmental enemies give a nice risk-reward mechanic, do you try to cross their paths and hope you don’t get stuck, or do you go the long way around?

Jammers:

Additional assets:

  • Used the character model and animations from the free Couch Knights sample, which is licensed for use only with Unreal Engine based products

Boops, Beez, and Bears

In Boops, Beez, and Bears, your voice is your weapon: hum, whistle, laugh, or cry – whatever works for you, just do it fast! It’s a cross between between a horde-mode survival game and a participatory art experience; best enjoyed with a crowd, who are likely to be amused by your vocal antics while avoiding the annoying beez.

Continue reading “Boops, Beez, and Bears”

SharedJamUI plugin for UE4

I’ve started a plugin that implements some useful base widgets and a simple menu manager to create game user interfaces in Unreal Engine 4. It’s sort of a spiritual successor to the SharedXNA library used in most of my XNA games.

It’s open source under the zlib license, mirrored to GitHub at https://github.com/joat/SharedJamUI. There’s a bit of usage information in README.md, but it’s pretty early and should be considered ‘jam quality’ code that hasn’t been really battle tested yet. Drop me a line if you end up using it and have some feedback.

Super Simple Slime Kat Slalom

A 1..4 player local multiplayer game where cats (made out of slime) compete to grab snacks and get the best spot on the colored couches, strewn about in a lake of lava because why not.

Created for the Simple Jam in a weekend using Unreal Engine 4.12. Simple Jam aimed to keep things manageable by limiting the number of rules and assets to 5 each. Here is how I spent that budget:

Game rules:

  1. Roll down the ramp
  2. Transform to start flying
  3. The floor is lava, so don’t touch it
  4. Grab some snacks
  5. Secure the best seat on the couch

Imported assets:

  1. Chamfered cube
  2. Sphere
  3. Lake water setup (stretching the definition just a teensy bit)
  4. Cat model [saved for later]
  5. [saved for later]
Menu screen
Menu screen
Gameplay
Gameplay

Turns out learning Z-Brush in a few hours is not actually a thing, so there’s no cat model yet; use your imagination. I’m watching Z-brush tutorial videos now and will probably work on it a bit more post-jam as I had a lot of fun making this.

You can download and play it from itch.io (Windows only ATM).

Angry Duck Diver

Angry Duck Diver was created as part of the 2016 Train Jam (March 10th to March 12th).

It’s a bullet-heavy vertical scrolling shmup/STG which contains neither ducks nor diving. Instead you have to constantly balance your avarice and cowardice, building up bonuses and choosing the ideal moment to bank your points before you are destroyed.

The theme was maximum capacity and I interpreted that as a risk/reward mechanic where you increase your bonus gauge as you approach maximum capacity, but you also increase your hit box and risk destruction, losing all your unbanked points.

Train Jam
The Train Jam was an amazing experience, both as a jam and as a journey. The scenery is gorgeous and inspiring, and jammer disciplines seemed much more diverse / evenly spread than I’m used to at local jams (which tend to skew heavily towards programmers). I’m certainly planning on doing it again next year. However, one downside was the venue for the theme announcement/team formation before boarding the train; it was narrow and loud so it was hard to hear pitches or mingle with different folks pre-jam, and so I didn’t form or join a team before we got on the train.

Continue reading “Angry Duck Diver”

Unstoppable Grave Looter

An intrepid grave looter accidentally disturbed the ritual of the groundhog and was cursed to never stop running. Trapped in an eternal hell, they fall back on old habits and decide to loot some graves.

  • Each grave you destroy will either provide delicious loot or disturb the dead.
  • Collect ingredients to perform rituals that cleanse the restless dead. When enough have been gathered, cross over the altars dotted thru the cemetery.
  • Use your shield amulet in a pinch, or gather more armor from the merciful angels.

Made for the 2016 Global Game Jam

Continue reading “Unstoppable Grave Looter”

Cowtastrophe

Cowtastrophe is the game I worked on for the 2015 Global Game Jam (Jan 23 .. 25). It’s sort of a co-op cow sandbox score attack thingy.  We start by assuming a perfectly spherical cow…

Premise

Overlord Phil has ordered all of his minions (that means you and up to three of your friends) to bring him cows, lots and lots of cows!

What do we do now? Cooperate to make Phil happiest or compete against the other minions to raise your status. Poor cows…

How to play

  • Gather cows and deposit them into the ‘teleporter’ (marked by a hovering sphere) to gain points.
  • The overlord is a very fickle boss, changing the desired type of cow frequently. If you fulfill his current order, you’ll get lots of points, but any old cow will keep him pleased for a bit.
  • Feed cows hay first to fatten them up.
  • Keyboard+Mouse:
    • WASD to move
    • Mouse to look around
    • Space or Left-Mouse-Button to activate your cowscoop
  • Gamepad:
    • Left Stick to move
    • Right Stick to look around
    • A to activate your cowscoop
Gameplay shot 2
Gameplay shot 2

Team

Additional credits:

Download

Download the full package (including project files) or just the packaged game.

Tested on Windows and Mac, but the packaged release is for Windows only.  Multiplayer requires multiple gamepads (use the ~ key to enter the console and type  to add a 3rd or 4th player).