Flag System
Flag System
Section titled “Flag System”Flags are the simplest and most versatile tool in Journey. They’re true/false values attached to each player that persist across sessions and server restarts. Think of them as checkboxes: “Has this player completed the tutorial? Yes or no.”
Despite their simplicity, flags are the glue that connects Journey’s systems together. Tasks set flags when completed, zones check flags before granting access, NPC visibility depends on flags, and quest chains gate behind flag requirements.
Quick Start
Section titled “Quick Start”Here’s the fastest way to understand flags:
Set a flag: q.player.add_flag('tutorial_complete')Check a flag: q.player.has_flag('tutorial_complete') → returns 1.0 (true) or 0.0 (false)Remove a flag: q.player.remove_flag('tutorial_complete')That’s it. Three functions cover everything flags do.
How to Use Flags
Section titled “How to Use Flags”Setting Flags via Task Rewards
Section titled “Setting Flags via Task Rewards”The most common pattern — set a flag when a player finishes a task:
{ "type": "script", "data": { "scripts": [ "q.player.add_flag('gym_badge_boulder');" ] }}Setting Flags via Commands
Section titled “Setting Flags via Commands”Admins can manage flags directly:
/flag <player> add tutorial_complete/flag <player> remove tutorial_completeChecking Flags in Task Requirements
Section titled “Checking Flags in Task Requirements”Gate a quest behind a flag:
{ "start_requirement": "q.player.has_flag('tutorial_complete')"}Checking Flags in Event Filters
Section titled “Checking Flags in Event Filters”Only count events when a flag is set:
{ "event": "POKEMON_CAPTURE", "filter": "q.player.has_flag('catching_challenge_active')", "target": 10}Practical Patterns
Section titled “Practical Patterns”Gym Badge Progression
Section titled “Gym Badge Progression”Set a flag for each gym badge, then require all 8 for the Elite Four:
Each gym quest reward:
{ "type": "script", "data": { "scripts": ["q.player.add_flag('gym_badge_boulder');"] }}Elite Four quest requirement:
{ "start_requirement": "q.player.has_flag('gym_badge_boulder') && q.player.has_flag('gym_badge_cascade') && q.player.has_flag('gym_badge_thunder') && q.player.has_flag('gym_badge_rainbow') && q.player.has_flag('gym_badge_soul') && q.player.has_flag('gym_badge_marsh') && q.player.has_flag('gym_badge_volcano') && q.player.has_flag('gym_badge_earth')"}Tutorial Flow
Section titled “Tutorial Flow”Prevent advanced content until the tutorial is done:
{ "name": "Advanced Battle Tutorial", "start_requirement": "q.player.has_flag('basic_tutorial_complete') && !q.player.has_flag('advanced_tutorial_complete')", "rewards": [ { "type": "script", "data": { "scripts": ["q.player.add_flag('advanced_tutorial_complete');"] } } ]}The ! operator means “NOT” — so this quest only appears when the basic tutorial is done but the advanced one isn’t.
One-Time Rewards
Section titled “One-Time Rewards”Prevent players from claiming a reward twice:
{ "event": "ENTER_ZONE", "filter": "q.zone.uuid == 'treasure-room-uuid' && !q.player.has_flag('claimed_treasure')", "target": 1, "rewards": [ { "type": "script", "data": { "scripts": [ "q.player.add_flag('claimed_treasure');", "q.player.tell_minimessage('<gold>You found the hidden treasure!');" ] } } ]}Feature Unlocks
Section titled “Feature Unlocks”Unlock server features as players progress:
{ "type": "script", "data": { "scripts": [ "q.player.add_flag('unlock_breeding');", "q.player.tell_minimessage('<green>Pokemon breeding is now unlocked!');" ] }}Combining Conditions
Section titled “Combining Conditions”AND — Both must be true
Section titled “AND — Both must be true”"q.player.has_flag('badge_1') && q.player.has_flag('badge_2')"OR — At least one must be true
Section titled “OR — At least one must be true”"q.player.has_flag('champion_defeated') || q.player.has_flag('admin_override')"NOT — Must be false
Section titled “NOT — Must be false”"!q.player.has_flag('already_claimed')"Complex Logic
Section titled “Complex Logic”"(q.player.has_flag('badge_1') && q.player.has_flag('badge_2')) || q.player.has_flag('skip_gyms')"Naming Conventions
Section titled “Naming Conventions”Good flag names are descriptive and consistent. Here are recommended patterns:
| Prefix | Use Case | Examples |
|---|---|---|
tutorial_ | Tutorial progression | tutorial_complete, tutorial_battle_done |
quest_ | Quest completion | quest_starter_town_done, quest_oak_met |
gym_badge_ | Gym achievements | gym_badge_boulder, gym_badge_cascade |
story_ | Main story progress | story_chapter_1, story_rival_defeated |
unlock_ | Feature unlocks | unlock_breeding, unlock_elite_four |
visited_ | Location discovery | visited_mount_silver, visited_lavender_town |
defeated_ | Boss/trainer defeats | defeated_champion_red, defeated_elite_four |
event_ | Special events | event_summer_festival, event_raid_completed |
achievement_ | Achievements | achievement_shiny_hunter, achievement_pokedex_100 |
Molang Functions Reference
Section titled “Molang Functions Reference”| Function | Returns | Description |
|---|---|---|
q.player.has_flag('name') | 1.0 or 0.0 | Check if flag exists |
q.player.add_flag('name') | — | Add a flag |
q.player.remove_flag('name') | — | Remove a flag |
Important Limitations
Section titled “Important Limitations”Flags are boolean only. They can only be true (exists) or false (doesn’t exist). They cannot:
- Store numbers (use Levelables for numeric progression)
- Store text or data
- Expire after a time period
- Count occurrences (use task targets for counting)
If you need to track “how many Pokemon has this player caught?”, use a Levelable. If you need “has this player caught a Pokemon?”, use a flag.
Storage
Section titled “Storage”Flags are stored in player data via Cardinal Components and persist across:
- Server restarts
- Player disconnects and reconnects
- Dimension changes
They are per-player and cannot be shared between players (use Global Tasks for shared progress).