Public/Private Properties (and Get/Set)

(Micro dev update: Freelance Chemist is making more sense than before and I’m feeling way better about it.  The VR pack is coming along really well and I’m super stoked.  We’ve got some type of prototype for all five demos now.)

So this is going to be a different type of post than usual – we’re gonna talk about code philosophy, so if you’re not into programming, you can skip it.

Somebody in a local game dev group asked about when to use public and private variables, and how getters and setters can help with the situation.  Here are some thoughts on the topic.


Awww yeah, code philosophy time!

As with all philosophy, this is just, like, my opinion, man.  Also this is somewhat Unity specific.

Public/Private

To get it out of the way:  Public variables are accessible by anyone, and private variables are only accessible by their owner.

The main reason you make something private is to avoid what people mean when they say “spaghetti code.” If you imagine the interconnections between your scripts, the lines between them should form an understandable structure instead of a massive tangle of wires. Making an object’s properties private is a good way to enforce encapsulation (making stuff self-contained), which in turn helps to keep your overall codebase tidy…so remember that making stuff private helps the most if you’re already trying to shape your overall code into some kind of sensible structure.

Also remember that spaghetti can end up functioning just as well as cleanly-organized code. The trouble arises because your code becomes harder to maintain and add to as it gets larger and less organized – if a value is being modified in weird ways from twenty different places and it needs a new feature, it’ll be much more difficult to implement than a different case where you can see all of the relevant code at once.  Similarly, spaghetti can cause an otherwise innocuous typo to go nuclear.

That said, public variables are not inherently bad for you. Think of a private variable as a BB gun with a safety switch. The safety switch is a helpful accident-prevention measure, but having the safety turned off doesn’t necessarily guarantee that you’ll shoot your eye out. It does, however, raise the risk by some degree (which depends on your general level of carelessness), and that one time out of a thousand…

In the same vein, having the safety on doesn’t guarantee that everyone is safe – maybe you’ll accidentally knock your gun through the slats in a high balcony and clock a passerby.

Get/Set

Getters and setters let you define an entity that is referenced and assigned to like a variable, but instead of being a normal variable, it’s actually a shortcut for a “get an output” function and a “set a value” function.

The following examples are written for C# in Unity – be aware that many programming languages (including UnityScript) do not include getters and setters.  Also be aware that getters and setters are never required to solve a problem since they could be replaced with normal functions, so they’re really just organizational tools.

Before we get back to encapsulation, here’s a basic get/set example that rounds a float input to the nearest even number, stores it as an integer, and outputs the current value as a float:

int integerValue=0;
float value {
    get {
        return (float)integerValue;
    }
    set {
        integerValue=Mathf.RoundToInt(value/2f)*2;
    }
}
value=9.5f;
// integerValue is now 10
Debug.Log(value);
// outputs "10.0" (as a float)

So…what does this have to do with making things public or private?  The magic trick is that you can have a public getter/setter that modifies otherwise-inaccessible private properties.

I’ve seen some coders use a private variable that’s directly controlled by public getters and setters, like this:

private float internalHealth;
public float health {
    get {
        return internalHealth;
    }
    set {
        internalHealth=value;
    }
}

Don’t do this.

(edit – this reddit user gives some insight about why you actually might want to do this)

It doesn’t provide any access control because the internal value can still be written directly from any outside script, so you might as well just make the internal value public and leave out the get/set entirely. In the gun analogy, we’ve made it so that switching off the safety causes the gun to fire immediately. There’s still a switch marked “safety,” but all we’ve really accomplished is moving the position of the trigger to the side of the gun.

As far as I know, getters and setters should only be used for one (or both) of two reasons:

1. “Something special” happens whenever the value is accessed
2. A value is read-only (to the public)

“Something special” can mean anything, since this is all just a shortcut for making little functions – for example, if you need to store a value in an awkward and unintuitive unit space, you can use a getter/setter to allow for people-friendly output/input while converting back and forth to the internal scale automatically. You could also do the same thing without a getter/setter, so again, it’s all a matter of preference. Be wary, though, because too much getting and setting might just wind up confusing you, especially if you ever happen to forget that a particular value isn’t a “real” variable.

Read-only values are more relevant to encapsulation – here’s an example of a private health value with a (small) degree of public access control.

private internalHealth;
public health {
    get { return internalHealth; }
}
public void TakeDamage(float damage, bool ignoreInvincibility=false) {
    if (invincible==false || ignoreInvincibility) {
        internalHealth-=damage;
    }
}
public void Heal(float healAmount) {
    TakeDamage(-healAmount, true);
}

If any script (including the one containing the example) tried to do…

health=0f;

…you’d get a compile-time error because health has a getter but no setter, which marks it as read-only.

Side note: You can still do insta-kills by using Mathf.Infinity as the input for TakeDamage, since the floating point standard requires proper handling of +/- infinity for arithmetic, greater/less than tests, etc, so stuff like this will still work as expected:

internalHealth-=Mathf.Infinity;
if (internalHealth<0f) {
    //always happens, unless health was somehow previously NaN or +infinity
    Die();
}

 

That’s all I’ve got for now – let me know if you have any questions or different ideas about how to make use of this stuff!

Quick notes

Hey hey – as usual, it’s been a little while.

Right to business: Freelance Chemist is in a weird spot.  I like the game, but the types of puzzles it contains are definitely not for everyone, and the storyline seems like a mega-super bummer to me because I made most of it when I was in a real shit-bag of a mood.  I don’t want to cancel it because we already had to do that with Titanium Frontier, so I’m still trying to figure out what to do with it.  It’s possible that it’ll still end up on Steam.  It also might end up being a free web game, like the good old days.  I’m not sure yet, but it’ll be something eventually.

I also wanted to mention that I’ve been using my Twitter account somewhat regularly lately, so that’s probably a better place to get development progress reports than over here.

Also I got an Oculus Rift, so I’ve been getting used to working with VR stuff.

It’s a giant slide for a person-sized hamster ball

Options and a new background

Freelance Chemist is getting closer and closer to completion…at this point, there are two puzzles that I still want to revise, but other than that, the only notable stuff left over is implementing the audio and visual assets as they roll in.

I spent today banging out the last major code hurdle – a pause screen/options menu.  Here’s how it’s looking:

Click for full size

Click for full size

Shocking!  Controversial!  International Gaming Publication Weekly calls it “pretty much just an options menu, and not really newsworthy at this time.”

More fluid game progress

Heyo –  the fluid game (which, if you haven’t been reading the post categories, is going to be titled “Freelance Chemist”) has been making more steady progress, though I’ve also started working on a contract programming job, so I can’t focus on it exclusively anymore.  I’ve now got all of the levels prototyped, and some of them have been tested and revised enough times to be release-ready (although they still might change before it’s all said and done).

I also received some initial background art from Leah Smith, the game’s visual artist, so I have some new screenies to share!  The set that I have so far is for Chapter 2, but these screenshots are all taken from not-chapter-two levels, so eventually they’ll have different settings…but using these backgrounds everywhere has already made the game much prettier (and it makes the remaining placeholder art look more placeholdery than ever).

As usual, click an image to see it in full size.

Updated goggles, now with visual detail for the effect to play with

Updated goggles, now with visual detail for the effect to play with

A melty screen transition effect – similar to the one used in post-1.1 versions of Not the Robots, except this time it’s more doper

A new fullscreen effect for a “glitchy video feed” look

Something else

The fluid puzzler is still making good progress – I made a first draft of the last missing puzzle yesterday, so now it’s all playtesting, revising, polishing, putting in stuff from the other team members as it arrives (audio, visual art, voice acting), and some miscellaneous stuff.  Still don’t really want to show too much of the puzzle content for fear of spoilers…

…so instead, here’s something new and totally unrelated.

Fullscreen shaders

Heyo – got another update that’s a little more…uh, visually interesting.

Specifically, the fluid game is going to have two segments that use fullscreen shader effects: one’s a flashback and has that classic “degraded film” effect going on, and the other involves the player character wearing a mask of some sort.

film effect

 

mask

The mask distortion is a little hard to see with the tiny amount of surface detail in the scene, but it shows up pretty well in the top-left and bottom-center.

The “mask” effect is controlled by an texture that looks like this (it’s a placeholder for the time being):

mask texture

This texture is intended to be a very “non-technical” image format – the white parts of the image are the parts of the screen that get distorted and darkened the most.  The idea is that it’ll be really easy to explain to our visual artist how the texture works, and then they’ll be able to make a higher-quality texture for us, without any hassle in the explanation.

 

A vague progress report

The fluid puzzler is coming along really well!  Since it’s a short-form puzzle game, I don’t want to show too much of its actual content for fear of ruining some of the fun.  The current plan is to have 21 levels, and as of today I have 11 that have at least a first draft.  Each puzzle needs to go through a few rounds of playtesting with fresh eyes, or else they’ll end up being shitty and frustrating.

We’ve found our visual artist and two voice actors, but I don’t have content from them yet, so I’ll save their intros for another time.

Here’s a quick screenshot that shows a text renderer that I implemented yesterday and today.  Not the most exciting tool…but a vital one for this game.  I couldn’t use Unity’s default text-mesh-generator, because it didn’t support some important features like smooth word-by-word reveals and wordwrap (which would have been a pain in the ass to work around).

Mild spoiler - the chemist mentioned is Louis Fieser, a real-life historical figure...

Still lots to do, but progress is looking good!

I’ve got bad news…and two kinds of good news

The bad news is that Titanium Frontier has been cancelled for some very frustrating financial reasons (and I don’t mean that we ran out of money – don’t worry, we’re fine).  If this is disappointing to you, too, contact me and I can explain the circumstances in further detail.

The first good news is that Not the Robots is about to get its biggest update so far – more information can be found on the Steam forums.  It adds a Save+Quit option for Campaign mode, improves performance (particularly for lower-end hardware), makes it easier to access You Find Yourself In A Room 2 (which can be unlocked with a cheat code now, instead of only by completing all 20 Challenge levels…which is extremely difficult), and various other tweaks and fixes, too.  I think it represents a noticeable increase in the overall quality of the game, and I hope that you guys will agree!

The other good news is that cancelling a project means we get to work on a new thing instead!  This one’s got a smaller scope – and this is probably going to be the general plan for a little while.  Smaller games, faster development times, cheaper prices, and we’ll expand further on the ideas that are received well by the audience.

First up:  A puzzle game centered around a fluid simulation!  The tech is in a similar vein as Spewer, an old game that I worked on…but this time there’s no platforming going on, so the gameplay’s focus is more on the fluid mechanics.  Can’t talk about the puzzle structure yet, but for now, I’ve got a fun little tech demo video.  More info soon!