Zone Visualization
This document describes how different game zones are visually represented in the Rummage UI.
Zone Types
Magic: The Gathering defines several game zones, each with unique visualization requirements:
- Battlefield: Where permanents are played
- Hand: Cards held by a player
- Library: A player's deck
- Graveyard: Discard pile
- Exile: Cards removed from the game
- Stack: Spells and abilities waiting to resolve
- Command Zone: Special zone for commanders and emblems
Visual Representation
Each zone has a distinct visual style to help players quickly identify it:
Battlefield
- Layout: Grid-based layout with flexible positioning
- Background: Textured playmat appearance
- Borders: Subtle zone boundaries for each player's area
- Organization: Cards automatically group by type (creatures, lands, etc.)
#![allow(unused)] fn main() { fn create_battlefield_zone(commands: &mut Commands, materials: &UiMaterials) { commands.spawn(( SpatialBundle::default(), Node { background_color: materials.battlefield_background.clone(), ..default() }, BattlefieldZone, Name::new("Battlefield Zone"), )); } }
Hand
- Layout: Fan or straight-line arrangement
- Background: Semi-transparent panel
- Privacy: Only visible to the controlling player (except in spectator mode)
- Interaction: Cards rise when hovered
Library
- Visualization: Stack of cards showing only the back
- Counter: Numerical display of remaining cards
- Animation: Cards visibly draw from top
Graveyard
- Layout: Stacked with slight offset to show multiple cards
- Visibility: Top card always visible
- Interaction: Can be expanded to view all cards
Exile
- Visual Style: Distinct "removed from game" appearance
- Organization: Grouped by source when relevant
- Special Effects: Subtle visual effects to distinguish from other zones
Stack
- Layout: Cascading arrangement showing pending spells/abilities
- Order: Clear visual indication of resolution order
- Targeting: Visual connections to targets
- Animation: Items move as they resolve
Command Zone
- Prominence: Visually distinct and always accessible
- Commander Display: Shows commander card(s)
- Tax Counter: Visual indicator of commander tax
Zone Transitions
When cards move between zones, the transition is animated to provide visual feedback:
#![allow(unused)] fn main() { fn animate_zone_transition( commands: &mut Commands, card_entity: Entity, from_zone: Zone, to_zone: Zone, animation_assets: &AnimationAssets, ) { // Calculate start and end positions let start_pos = get_zone_position(from_zone); let end_pos = get_zone_position(to_zone); // Create animation sequence commands.entity(card_entity).insert(AnimationSequence { animations: vec![ Animation::new_position(start_pos, end_pos, Duration::from_millis(300)), Animation::new_scale(Vec3::splat(0.9), Vec3::ONE, Duration::from_millis(150)), ], on_complete: Some(ZoneTransitionComplete { zone: to_zone }), }); } }
Zone Interaction
Zones support various interactions:
- Click: Select the zone or expand it for more detail
- Drag-to: Move cards to the zone
- Drag-from: Take cards from the zone
- Right-click: Open zone-specific context menu
- Hover: Show additional information about the zone
Zone Components
Zones are implemented using several components:
#![allow(unused)] fn main() { #[derive(Component)] pub struct ZoneVisualization { pub zone_type: Zone, pub owner: Option<Entity>, pub expanded: bool, pub card_count: usize, pub layout_style: ZoneLayoutStyle, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ZoneLayoutStyle { Grid, Stack, Fan, Cascade, List, } }
Zone Systems
Several systems manage zone visualization:
- Zone Layout System: Positions cards within zones
- Zone Transition System: Handles card movements between zones
- Zone Interaction System: Processes player interactions with zones
- Zone Update System: Updates zone visuals based on game state
#![allow(unused)] fn main() { fn update_zone_visuals( mut zone_query: Query<(&mut ZoneVisualization, &Children)>, card_query: Query<Entity, With<Card>>, game_state: Res<GameState>, ) { for (mut zone, children) in zone_query.iter_mut() { // Update card count zone.card_count = children.iter() .filter(|child| card_query.contains(**child)) .count(); // Update visuals based on card count and zone type // ... } } }
Multiplayer Considerations
In multiplayer games, zones are arranged to clearly indicate ownership:
- Player Zones: Positioned relative to each player's seat
- Shared Zones: Positioned in neutral areas
- Opponent Zones: Scaled and positioned for visibility
Accessibility Features
Zone visualization includes accessibility considerations:
- Color Coding: Zones have distinct colors that work with colorblind modes
- Text Labels: Optional text labels for each zone
- Screen Reader Support: Zones announce their type and contents
- Keyboard Navigation: Zones can be selected and manipulated via keyboard
Integration
Zone visualization integrates with:
- Layout System: Zones are positioned by the layout system
- Card Visualization: Cards appear differently based on their zone
- Responsive Design: Zones adapt to different screen sizes
For more details on specific zone implementations, see the relevant game rules documentation.