Portals Functions
These helpers are available inside a JavaScript Function. Keep a script focused: read named state, make one decision, then change a named task or value.
Read a task: $TN{Task name}
Use numeric task state values:
| State | Value |
|---|---|
| Not Active | 0 |
| Active | 1 |
| Completed | 2 |
if ($TN{TutorialComplete} === 2) {
SetTask('OpenLobby', 'Active', 0);
}
Read a value: $N{Value name}
const hasEnoughStars = Number($N{Stars}) >= 3;
if (hasEnoughStars) {
SetTask('UnlockGallery', 'Active', 0);
}
Initialize a value intentionally before relying on it. The task or variable configuration controls whether it is private, persistent, or shared.
SetTask(name, state, delay)
SetTask('taskName', 'NotActive' | 'Active' | 'Completed', delaySeconds);
Examples:
SetTask('ShowWelcome', 'Active', 0);
SetTask('ResetPuzzle', 'NotActive', 5);
SetTask('BadgeEarned', 'Completed', 1.5);
Create the task first
Create the named task in Interactive Studio before calling SetTask(). If the
name does not match an existing single-player or multiplayer task, Portals
creates a temporary, non-persistent single-player task so the call can finish.
That fallback has no configured no-code behavior, quest setup, or visible
effects. It is useful as a safety fallback, not as a game-design workflow.
Use a configured task when you need an effect, a quest-visible objective, persistence, or shared state.
SetVariable(name, value, delay)
SetVariable('valueName', value, delaySeconds);
Examples:
SetVariable('Coins', 0, 0);
SetVariable('StatusText', 'Ready', 0);
SetVariable('CooldownReady', 1, 3);
The third argument is a delay in seconds. It is not an update operation.
SelectRandom(choice1, choice2, ...)
SelectRandom() returns one of the values you pass to it. Give it at least one
choice.
const greeting = SelectRandom('Welcome!', 'Good to see you!', 'Ready to explore?');
SetVariable('Greeting', greeting, 0);
Use this for a small variation such as a greeting, message, or next option.
When your rule is about selecting players, use
SelectRandomPlayers() from multiplayer functions
instead.
PrintString(list)
PrintString() turns a list into one comma-separated text value. It expects a
list, such as the array returned by SelectPlayersParameters().
const blueTeam = SelectPlayers({{Players}}, 'Team', 'Blue');
const teamLabels = SelectPlayersParameters(blueTeam, 'Team');
SetVariable('BlueTeamLabels', PrintString(teamLabels), 0);
This helper returns text; it does not print a developer log. Use it when a list needs to become a readable value for a normal Portals flow. Every item in the list must have the requested parameter. Filter the list by that same configured parameter first, as in the example above.
UpdateMultiplayerNumericVariable(name, value, operation, delay)
Use this only for a numeric variable configured as multiplayer:
UpdateMultiplayerNumericVariable('TeamScore', 1, 1, 0);
| Operation | Result |
|---|---|
| 0 | Set to value |
| 1 | Add value |
| 2 | Subtract value |
| 3 | Multiply by value |
| 4 | Divide by value |
For a shared point event, use operation 1 (Add). Avoid reading TeamScore, adding one locally, and calling SetVariable() because simultaneous updates can overwrite one another.
Read a leaderboard: GetLeaderboard(name)
GetLeaderboard is asynchronous. Give it the same leaderboard name you configured in the Leaderboard tool and use with the no-code leaderboard effects.
try {
const rows = await GetLeaderboard('MyBoard');
const leader = rows[0];
if (leader) {
SetVariable('TopScore', leader.score, 0);
}
} catch (error) {
SetVariable('LeaderboardAvailable', 0, 0);
}
It resolves to an array of entries shaped like { rank, name, score, isLocalPlayer }. Rank is 1-based. On a time-based leaderboard, score is measured in milliseconds. An empty array is a valid result when the board has no entries; use try and catch for a failed request instead.
Portals supplies the current room context automatically. Do not add credentials, secrets, account IDs, or manual backend calls to your script. This helper reads existing leaderboard results; create the board and submit scores with the normal no-code leaderboard setup first.
Call a no-code effect
Use UseEffector only with a numeric item ID and a supported effect type. For example:
UseEffector(12345, 'ShowObject', '{}');
Replace 12345 with the real numeric ID of the item that should receive the effect. Do not use this API to invoke another JavaScript Function.
A conditional quest recipe
const mapFound = $TN{FindMap} === 2;
const starsReady = Number($N{Stars}) >= 3;
if (mapFound && starsReady) {
SetTask('OpenMountainPath', 'Active', 0);
SetVariable('PathHintShown', 1, 0);
}
Use task effects to reveal the path and show any visible content. This script is only the rule.
What not to use
- Do not call undocumented helpers.
- Do not rely on browser APIs or use code as a secret store.
- Do not use legacy inline change subscriptions. Use Trigger On Tasks Change and explicit $TN{...} or $N{...} references.
- Do not create task names on the fly; create and configure them in Interactive Studio first.
For a compact side-by-side list, see the quick reference.
