Split Read/Write Permissions: var<private> Ammo<public>
You just learned var — here's an engineering upgrade you can use right away: Verse lets you control "who can change" and "who can read" a class member variable separately. Two specifiers each guard one end, and you get read-only properties without writing a single getter function.
1. The Problem: Let Others Look, Not Touch
You're building a weapon rack device with a var Ammo:int tracking the ammo count. Other Blueprints frequently need to read it — the UI shows remaining ammo, the rules logic checks whether firing is allowed. But you absolutely do not want anyone else casually wiring in a Set node to change it: the ammo count should only ever be changed by the weapon rack itself, when reloading or firing. Once anyone can write it, the day the ammo mysteriously becomes 999, you'll be trawling the entire project for that one offending Set wire.
The standard answer in many languages: make the variable private, then write a dedicated public "read function" (a getter) to hand out for others to read. It works, but every variable needs its own such boilerplate function, which gets tiresome fast. Verse's answer is far more elegant — because it treats "read" and "write" as two permissions that are each their own thing.
2. The Syntax: Two Specifiers, Each Guarding One End
The rule in one sentence: the angle-bracket setting hung on var guards the "write" permission (who can wire in a Set); the one hung on the variable name guards the "read" permission (who can read its value). So you can declare this:
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/Diagnostics }
weapon_rack := class:
# The specifier on the name guards reads: public = anyone can read
# The specifier on var guards writes: private = only this class can set
var<private> Ammo<public>:int = 10
Reload<public>():void =
set Ammo = 30
Blueprint translation: Ammo<public> means any Blueprint can read its value — once you hold a Rack:weapon_rack, printing Rack.Ammo with Print String faces no obstacle at all. Meanwhile var<private> means only nodes inside weapon_rack itself may wire a Set into it — anyone outside trying set Rack.Ammo = 999 gets rejected the moment they hit Compile. Want to change the ammo? Come in through the front door this class opened for you: the Reload() function.
That's a "read-only variable" for free: to the outside, it's an exhibit behind glass — look, don't touch; to the inside, it's still the family backpack slot, wire in Set whenever needed. Loosening the write permission by one notch is common too: var<protected> Ammo<public>:int = 10 lets Child Blueprint Classes change it as well — a good fit for device families where "the base class sets the rules, the child classes make the variants".
3. The Four Access Levels at a Glance
Both positions — read and write — use the same set of access settings (specifiers):
| Specifier | Who Can Access |
|---|---|
<public> |
Anywhere |
<internal> (default) |
Within the same module |
<protected> |
This class and its subclasses |
<private> |
Only this class |
Note the default: write nothing, and the access level is <internal> — visible within the same module (asset folder), not globally public. That also explains why "everything works fine without this setting" in small projects: everything lives in one module, so internal is plenty; once the project splits into several modules, permission issues surface — and by then you'll already know this trick.
Usage advice mirrors the main lesson's constant philosophy: default to strict, loosen when needed. Declare state-holding variables as "read public, write private" first; if a legitimate need for outside changes actually appears, then consider loosening the write permission — or open up a dedicated update function for others to call.
4. Quick Quiz
What does the declaration var<private> Score<public>:int = 0 mean?
Sources
Compiled from Epic's official documentation and community tutorials: Specifiers and Attributes in Verse (official docs) ↗ · UEFN Verse: Access Specifiers (Romero Blueprints, with examples of each combination) ↗