Flag System
Flag System
Section titled “Flag System”The Flag System provides a simple way to track player state and progress using boolean flags. Flags are true/false values that persist across sessions and can be used throughout Journey’s systems for conditional logic.
Overview
Section titled “Overview”Flags in Journey offer:
- Boolean State Tracking: Track what players have done (true/false only)
- Conditional Logic: Control access to content based on flags
- Cross-System Integration: Use flags in tasks, zones, timelines, and scripts
- Persistent Storage: Flags persist across server restarts and player sessions
- Simple Management: Easy commands and MoLang API
Important: Flags are boolean only. There are no numeric flags, counter flags, or expiry times.
Basic Flag Operations
Section titled “Basic Flag Operations”Setting Flags
Section titled “Setting Flags”Via MoLang Functions:
q.player.add_flag('tutorial_complete')q.player.add_flag('visited_cerulean_city')q.player.add_flag('gym_leader_defeated_brock')Via Task Rewards:
{ "type": "script", "data": { "scripts": [ "q.player.add_flag('quest_chain_1_complete');" ] }}Checking Flags
Section titled “Checking Flags”In Task Start Requirements:
{ "start_requirement": "q.player.has_flag('tutorial_complete')"}In Event Filters:
{ "filter": "q.player.has_flag('elite_four_access')"}In MoLang Scripts:
// Returns 1.0 if flag exists, 0.0 if notq.player.has_flag('special_ability_unlocked')
// Use in conditionsq.player.has_flag('champion_defeated') ? 1.0 : 0.0Removing Flags
Section titled “Removing Flags”// Remove a flag completelyq.player.remove_flag('temporary_buff')Flag Naming Conventions
Section titled “Flag Naming Conventions”Use consistent naming patterns for better organization:
Category Prefixes
Section titled “Category Prefixes”tutorial_* // Tutorial-related flagsquest_* // Quest completion flagsgym_* // Gym-related achievementsstory_* // Main story progressevent_* // Special event participationachievement_* // General achievementsunlock_* // Feature/area unlocksvisited_* // Location discoverydefeated_* // Boss/trainer defeatscollected_* // Item/collectible flagsExamples
Section titled “Examples”tutorial_completequest_starter_town_finishedgym_badge_boulderstory_chapter_1_completeevent_summer_festival_2024achievement_catch_100_pokemonunlock_elite_four_accessvisited_mount_silverdefeated_champion_redcollected_all_gym_badgesCommon Usage Patterns
Section titled “Common Usage Patterns”Tutorial Progression
Section titled “Tutorial Progression”Track player tutorial progress:
{ "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');" ] } } ]}Quest Chain Management
Section titled “Quest Chain Management”Control access to quest chains:
{ "name": "Elite Four Challenge", "start_requirement": "q.player.has_flag('all_gym_badges') && q.player.has_flag('victory_road_complete')", "tasks": []}Achievement Tracking
Section titled “Achievement Tracking”Track player achievements through flags:
{ "event": "POKEMON_CAUGHT", "filter": "q.pokemon.species.identifier == 'cobblemon:mewtwo'", "target": 1, "rewards": [ { "type": "script", "data": { "scripts": [ "q.player.add_flag('achievement_legendary_captured');", "q.player.tell_minimessage('<gold>Achievement Unlocked: Legendary Trainer!');" ] } } ]}Feature Unlocks
Section titled “Feature Unlocks”Unlock features based on progress:
{ "level_rewards": [ { "level": 25, "rewards": [ { "type": "script", "data": { "scripts": [ "q.player.add_flag('unlock_breeding');", "q.player.tell_minimessage('<green>Pokémon breeding unlocked!');" ] } } ] } ]}Compound Conditions
Section titled “Compound Conditions”Combine multiple flags for complex logic:
AND Logic
Section titled “AND Logic”{ "start_requirement": "q.player.has_flag('gym_badge_boulder') && q.player.has_flag('gym_badge_cascade')"}OR Logic
Section titled “OR Logic”{ "start_requirement": "q.player.has_flag('champion_path_complete') || q.player.has_flag('admin_override')"}NOT Logic
Section titled “NOT Logic”{ "filter": "!q.player.has_flag('already_claimed_reward')"}Complex Combinations
Section titled “Complex Combinations”{ "start_requirement": "(q.player.has_flag('badge_1') && q.player.has_flag('badge_2') && q.player.has_flag('badge_3')) || q.player.has_flag('skip_gyms')"}Flag Categories
Section titled “Flag Categories”Story Progression Flags
Section titled “Story Progression Flags”Track main story advancement:
story_prologue_completestory_chapter_1_completestory_chapter_2_completestory_rival_first_battlestory_legendary_awakenedstory_final_battle_completeAchievement Flags
Section titled “Achievement Flags”Track player accomplishments:
achievement_first_catchachievement_100_catchesachievement_shiny_hunterachievement_gym_challengerachievement_championachievement_pokedex_completeAccess Flags
Section titled “Access Flags”Control feature and area access:
unlock_pc_storageunlock_tradingunlock_breedingunlock_competitive_battlesunlock_elite_fourunlock_post_game_contentEvent Flags
Section titled “Event Flags”Track special event participation:
event_halloween_2024_participantevent_tournament_winnerevent_community_day_attendedevent_legendary_raid_completedIntegration Examples
Section titled “Integration Examples”Quest Requirements with Multiple Flags
Section titled “Quest Requirements with Multiple Flags”{ "name": "Elite Four Champion Challenge", "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')"}Zone-Based Flag Setting
Section titled “Zone-Based Flag Setting”{ "event": "ENTER_ZONE", "filter": "q.zone.uuid == 'champion-room-uuid' && !q.player.has_flag('visited_champion')", "target": 1, "rewards": [ { "type": "script", "data": { "scripts": [ "q.player.add_flag('visited_champion');", "q.player.tell_minimessage('<gold>You have reached the Champion!');" ] } } ]}Progressive Content Unlocking
Section titled “Progressive Content Unlocking”Set flags progressively as players complete objectives:
{ "tasks": [ { "id": "defeat_gym_1", "rewards": [ { "type": "script", "data": { "scripts": ["q.player.add_flag('gym_badge_1');"] } } ] }, { "id": "defeat_gym_2", "rewards": [ { "type": "script", "data": { "scripts": ["q.player.add_flag('gym_badge_2');"] } } ] } ]}Then check all flags for unlock:
{ "name": "Elite Four Access", "start_requirement": "q.player.has_flag('gym_badge_1') && q.player.has_flag('gym_badge_2') && q.player.has_flag('gym_badge_3') && q.player.has_flag('gym_badge_4') && q.player.has_flag('gym_badge_5') && q.player.has_flag('gym_badge_6') && q.player.has_flag('gym_badge_7') && q.player.has_flag('gym_badge_8')"}MoLang Flag Functions
Section titled “MoLang Flag Functions”Available Functions
Section titled “Available Functions”// Check if player has a flag (returns 1.0 or 0.0)q.player.has_flag('flag_name')
// Add a flag to the playerq.player.add_flag('flag_name')
// Remove a flag from the playerq.player.remove_flag('flag_name')Usage in Filters
Section titled “Usage in Filters”// Simple checkq.player.has_flag('tutorial_complete')
// With conditionq.player.has_flag('champion_defeated') == 1.0
// Negationq.player.has_flag('banned') == 0.0// Or!q.player.has_flag('banned')
// Multiple flagsq.player.has_flag('badge_1') && q.player.has_flag('badge_2')Best Practices
Section titled “Best Practices”Flag Naming
Section titled “Flag Naming”✅ DO:
- Use descriptive names:
tutorial_complete - Use consistent prefixes:
quest_,gym_,story_ - Use underscores:
visited_pallet_town - Name as boolean statements:
has_completed_tutorial
❌ DON’T:
- Use spaces:
tutorial complete - Be vague:
flag1,temp,done - Mix naming schemes:
tutorialCompletevstutorial_complete
Flag Management
Section titled “Flag Management”✅ DO:
- Document important flags in your project
- Use flags for persistent state only
- Clean up obsolete flags when updating content
- Test flag conditions before deployment
❌ DON’T:
- Use flags for temporary state (use in-memory state instead)
- Create hundreds of player-specific flags without need
- Change flag names without migration plan
- Rely on undocumented flags
Performance
Section titled “Performance”✅ DO:
- Check flags in conditional logic (very fast)
- Use compound conditions efficiently
- Batch flag operations in scripts
❌ DON’T:
- Set the same flag repeatedly (check first if needed)
- Create unnecessary flags
- Use complex nested conditions (simplify where possible)
Limitations
Section titled “Limitations”What Flags ARE:
Section titled “What Flags ARE:”✅ Boolean values (true/false) ✅ Persistent across sessions ✅ Per-player storage ✅ Cross-system compatible
What Flags are NOT:
Section titled “What Flags are NOT:”❌ Not counters - Cannot store numbers (use levelables for progression) ❌ Not timers - Cannot store expiry times ❌ Not values - Cannot store strings or data ❌ Not temporary - Not designed for short-term state (minutes/seconds)
Alternatives for Other Data
Section titled “Alternatives for Other Data”If you need counters:
Section titled “If you need counters:”Use Levelables for numeric progression:
q.player.levelable_level('pokemon_caught_count')q.player.progress_levelable('pokemon_caught_count', 1)If you need temporary state:
Section titled “If you need temporary state:”Use task progress or in-memory tracking.
If you need timed effects:
Section titled “If you need timed effects:”Use timeline system for timed sequences.
If you need complex data:
Section titled “If you need complex data:”Store in custom NBT or external database.
Storage Details
Section titled “Storage Details”Flags are stored in player data via Cardinal Components:
- Location:
world/data/cardinal-components/<player-uuid>.dat - Format: NBT data within
JourneyDataObject - Persistence: Automatic on data change, periodic saves, disconnect, shutdown
The flag system provides a simple, efficient way to track boolean player state throughout Journey’s systems. Use flags for persistent “did the player do X?” checks, not for counters, timers, or complex data storage.