Tutorial - Custom HUD Gauges
Sometimes in a mission you need to show the player some additional information they need to monitor. Maybe it’s a timer, maybe it's added instructions or a prompt to press some keys. It's all up to you how you want to use them. Either for good, or for awesome. Let's make a simple hud gauge and then have fun with it and sexps.
The HUD Gauge Table
This is a really useful wiki page when modifying the hud gauge table. There's some neat general hud configuration stuff, but we're not interested in that right now. Just the gauge config.
Actually, before we go any farther, we should sort of design our hud gauge first. We're going to need to know where to place it on the screen.
We'll just use the retail FS2 hud gauges for this tutorial. Go take your favorite VP viewer and open up sparky_fs2.vp, it contains all the graphical files for the game. Let us look in the hud folder for some files we can use.
Oh, look at escort1, 2 and 3. These will do nicely. Let's make a note of the dimensions of the files.
- Escort1.ani: 149x13
- Escort2.ani: 149x11
- Escort3.ani: 149x13
Horizontally we'll throw this on the right side of the screen, and vertically we'll throw it in the middle.
With that in mind, let's begin.
So our blank (modular) hud gauge will start off like this
#Gauge Config $Base: (1024,768) $Gauges: $End Gauges #End
Gauge Config starts us off, and $Base tells the game that all of our coordinates are based on a 1024x786 screen resolution. The game will take that into account when scaling things up or down. And $Gauges is all like "Hey, I got your hud gauges. Fresh gauges here." which gets closed off by $End Gauges and then #End closes the table for good.
So because our gauge is a custom gauge, on a new line right after $Gauges: we'll put in
This lets the game know this is a custom gauge (surprise surprise)
Next, setting the position. There's two ways to do this. Position: (x, y) And Origin: (percent x, percent y) Offset: (x, y)
Position sets the position to a point based on the base resolution specified. Putting position as (512, 384), or the middle of the screen, will make the gauge start there. As I said before, this will scale up with the resolution so it would always start in the middle of the screen. (Assuming $Scale Gauges is true)
Origin + Offset is a newer feature, only found in 3.7.1 and beyond. Instead of specifying a position, we specify where we want the gauge as a percentage of the screen. So if we want it to start in the middle of the screen we would go Origin: (0.5, 0.5). And then any more fine tuning would be done with Offset.
Which should you use? Origin and Offset is probably the better one if you've got builds that can support it. The issues with fullscreen + widescreen aren't as bad as with position and it’s a little easier to work with. I'll mostly cover Origin + Offset.
Position: Time for a bit of math. The position is the point where the top left corner of the bitmap is. So if we want to put this on the right hand side, we would take our base's horizontal resolution and subtract the bitmap's width from it.
1024 - 149 = 875
And then to make it start at the halfway point vertically, we just divide the base vertical resolution by 2.
768 / 2 = 384
Position: (875, 384)
Origin+Offset: This is a bit easier. Since origin works off of percentages of the screen's resolution, we specify 100% horizontal, 50% vertical.
Origin: (1.0, 0.5)
But wait, that would make the bitmap's top left corner be off screen now. That's where Offset comes in. Our bitmap is 149 px wide, so we just make the x offset the negative of the width.
Offset: (-149, 0)
REMEMBER! ONLY USE EITHER POSITION OR ORIGIN+OFFSET!
Next we need a name so we know what we're turning on or off. We'll just call this CustomGaugeA.
This is what the gauge will display by default. We'll put in "MFD Online". That's generic enough for now.
Text: MFD Online
These are optional, they modify where the text starts drawing. We'll put these in and make them both 0 for now. We'll modify them later.
X Offset: 0
Y Offset: 0
FreeSpace needs all the gauges to be part of a retail gauge type. This affects the hud gauge coloring and what flashes when the flash-hud-gauge sexp is used. It has to be one of these gauge types. I'm going to use CENTER_RETICLE since the reticle won't actually flash if we use that sexp, but it will flash our custom gauge.
Gauge Type: CENTER_RETICLE
If this is on, the gauge will shake when the camera shudders from afterburners or a weapon like the maxim (which uses the shudder flag). Its best when the central hud elements have slew on, and the edged ones have it off. We'll turn this to NO.
Active by default
If this is on, then the gauge will appear on at mission start. You probably want to keep the gauge off until you really need it so the hud isn't always cluttered, but we'll turn it on so we can see our results with no sexps.
Active by default: YES
At last we come to the actual bitmap file name. Just fill in the bitmap's name, no extension required.
So now the table should look like…
#Gauge Config $Base: (1024,768) $Gauges: +Custom: ;Position: (875, 384) Origin: (1, 0.5) Offset: (-149, 0) Name: CustomGaugeA Text: MFD Online X Offset: 0 Y Offset: 0 Gauge Type: CENTER_RETICLE Slew: NO Active by default: YES Filename: escort1 $End Gauges #End
I added the Position but I commented it out with a ;. You can uncomment position and then comment out origin + offset to see the difference between the two.
Let's go in game and see how it works.
I'm using the 2014 mediavps here and you'll see how our new gauge a larger and a bit more blurry. We can fix that by adding Scale Gauge: NO just above Origin. While we're at it, we should adjust the three offsets so it looks better.
So now I've got this…
#Gauge Config $Base: (1024,768) $Gauges: +Custom: ;Position: (875, 384) Scale Gauge: NO Origin: (1, 0.5) Offset: (-159, 0) Name: CustomGaugeA Text: MFD Online X Offset: 2 Y Offset: 2 Gauge Type: CENTER_RETICLE Slew: NO Active by default: YES Filename: escort1 $End Gauges #End
And it looks like this
Well we've got the top, so now we can take care of the middle and bottom. We can copy paste the entry a few times, changing a few parts.
The y component of the offset will increase by the height of the bitmap that is above it. So CustomGaugeB (which will used escort2) will have an offset of (-159, 13) and then C will have an offset of (-159, 24) and so on.
For text I wrote the Line number, and tweaked the X and Y offsets so they look nice in game. (X Offset: 1, Y Offset: 4
In game we've got something that now looks like…
Let's change all the active by defaults to NO now and make a mission that will use our new hud gauge.
Here's the table that I'm using.
#Gauge Config $Base: (1024,768) $Gauges: +Custom: Scale Gauge: NO Origin: (1, 0.5) Offset: (-159, 0) Name: CustomGaugeA Text: MFD Online X Offset: 2 Y Offset: 2 Gauge Type: CENTER_RETICLE Slew: NO Active by default: NO Filename: escort1 +Custom: Scale Gauge: NO Origin: (1, 0.5) Offset: (-159, 13) Name: CustomGaugeB Text: Line 1 X Offset: 4 Y Offset: 1 Gauge Type: CENTER_RETICLE Slew: NO Active by default: NO Filename: escort2 +Custom: Scale Gauge: NO Origin: (1, 0.5) Offset: (-159, 24) Name: CustomGaugeC Text: Line 2 X Offset: 4 Y Offset: 1 Gauge Type: CENTER_RETICLE Slew: NO Active by default: NO Filename: escort2 +Custom: Scale Gauge: NO Origin: (1, 0.5) Offset: (-159, 35) Name: CustomGaugeD Text: Line 3 X Offset: 4 Y Offset: 1 Gauge Type: CENTER_RETICLE Slew: NO Active by default: NO Filename: escort3 $End Gauges #End
Playing with HUD gauges
There won't be any real structure to this mission. This will just be a playground.
First lets have our hud gauge turn on 5 seconds after the mission starts and then flash to draw attention to it. The SEXP of choice here is either hud-set-active-gauge (which is deprecated in newer builds) or hud-set-custom-gauge-active (which is easier to use). I'll use hud-set-custom-gauge for the tutorial. Both work identically.
If we put a true argument in, the gauge will turn on, and if we put false in, it will turn off. And we just refer to the gauge by the name we put in the table. So simple!
Now what should we use the gauge for? Let's keep it simple and just use it to track our score and some other silly info. I've populated the mission with a bunch of Amazon Drones and an Amazon Advanced. Their score has been set to 10 points each, except for the big one, which will be worth 500.
So in the initial hud activation sexp, we will set up what each line is supposed to say.
There are four sexps we can use to change the hud gauge text.
This is the simplest. Just type in your text here and it will change the hud gauge you've referred too. Note you're only limited to 31 characters here.
This is quite similar, but only lets you choose a number. You can plug in status sexps that return values with this one.
This one will let you choose a message to the gauge. This lets you get around the 31 character limitation with hud-set-text, but it can be easy to make these messages too long! Still these can be easier to edit since you just look for the message in the editor. Also you can use sexp variables just like you can in normal messages with $variablename.
This is kind of a goofy name, but still pretty awesome. The sexp is basically hud-set-text but it gets put through the same directive keypress function so the game will change $keypress$ text to the correctly bound key. So if you put "Press $t$" and someone rebound "select target" to q, then the text would show up as "Press q".
So I will use hud-set-text to make CustomGaugeA say "Current Score". Then use for CustomGaugeB, I will use hud-set-text-num to relay the player's ship_score. CustomGaugeC will let us know how long it has been since we last killed a target with "Last kill: $seconds ago". And CustomGaugeD will let us know which button we use to target ships.
Now if we're feeding changing information into the hud gauges, we should keep in mind that they won't update by themselves, but they will retain their information between updates. So we can either check to see when we should update or just make them update once a second. We'll just do the simple thing here and update every second with repeating events.
Since only CustomGaugeB and C ever change, we only need to tell the event to change them. The only other thing I do is update the seconds variable which tells us how much time passed since our last kill. And there's another repeating event that updates the lastkill variable when we kill something.
So how did we do?
Hey, where's my 500 points?! I guess this is what I get for not playing on INSANE.
[Here's a link] to the mod with the custom hud gauge and mission file.
There's still a lot I didn't cover, but after covering these basics, I'm sure you have the ability to do just about anything you would need for your campaigns and missions. The only limit is your imagination!