Skip to content

Game Systems

MichaelFisher1997 edited this page Jan 5, 2026 · 1 revision

Game Systems

Player controls, inventory management, and gameplay mechanics.


Application Controller

File: src/game/app.zig

The main game loop orchestrator managing all subsystems.

App State Machine

pub const AppState = enum {
    home,         // Main menu
    singleplayer, // World creation
    world,        // Active gameplay
    paused,       // Pause menu
    settings,     // Settings screen
};

State Flow

home → singleplayer → [seed input] → world ↔ paused → settings
         ↑                             ↓           ↓
         └─────────────────────────────┴───────────┘
                     (quit to title)

Day/Night Cycle

AtmosphereState manages:

  • Time system: 24,000 ticks per day
  • Sun/moon direction and intensity
  • Sky, horizon, fog colors
  • Smooth transitions between time periods
Period Time Range
Dawn 0.20 - 0.30
Day 0.30 - 0.70
Dusk 0.70 - 0.80
Night 0.80 - 0.20

Player Controller

File: src/game/player.zig

Physics-based player with collision detection.

Physical Constants

Constant Value Description
WIDTH 0.6 Collision box width
HEIGHT 1.8 Collision box height
EYE_HEIGHT 1.62 Camera offset from feet
WALK_SPEED 4.317 Ground speed (blocks/sec)
FLY_SPEED 10.0 Flight speed
GRAVITY 32.0 Downward acceleration
JUMP_VELOCITY 8.5 Initial jump (~1.25 blocks)
TERMINAL_VELOCITY 78.4 Max fall speed
REACH_DISTANCE 5.0 Block interaction range

Movement Modes

Mode Description
Walking Ground-based with gravity and jumping
Flying Creative mode flight (no gravity)
Noclip Pass through blocks (debug)

Controls

Input Action
W/A/S/D Horizontal movement
SPACE Jump (grounded) / Ascend (flying)
SHIFT Descend (flying)
SPACE (double-tap) Toggle fly mode (creative)
Left Click Break block
Right Click Place block
Mouse Look around

Physics Pipeline

1. Handle mouse look (yaw/pitch)
2. Detect double-tap fly toggle (0.3s window)
3. Calculate WASD movement direction
4. Apply gravity or flying movement
5. Resolve collisions (separate axes)
6. Sync camera to eye position
7. Update target block via raycast

Collision Detection

File: src/engine/physics/collision.zig

AABB-based collision against the voxel world.

Collision Result

pub const CollisionResult = struct {
    position: Vec3,    // Resolved position
    velocity: Vec3,    // Resolved velocity
    grounded: bool,    // Standing on solid
    hit_ceiling: bool, // Collided upward
    hit_wall: bool,    // Collided horizontally
};

Resolution Algorithm

Separate axis resolution (Y first for ground detection):

1. Move along Y axis (gravity/jumping)
   - Binary search to find contact
   - Set grounded or hit_ceiling
   - Zero Y velocity

2. Move along X axis
   - Resolve collision
   - Zero X velocity if hit

3. Move along Z axis
   - Resolve collision
   - Zero Z velocity if hit

Inventory System

File: src/game/inventory.zig

Block storage with hotbar and main inventory.

Layout

Section Slots Description
Hotbar 0-8 Quick access (9 slots)
Main 9-35 Storage (27 slots)
Total 36

ItemStack

pub const ItemStack = struct {
    block_type: BlockType,
    count: u8,  // Max 64
};

Methods

Method Description
init() Creative mode (all blocks)
initEmpty() Survival mode (empty)
getSelectedBlock() Current hotbar selection
selectSlot(slot) Select by index (0-8)
scrollSelection(delta) Scroll with wrapping
addItem(type, count) Add with stacking
removeFromSelected(count) Remove items
swapSlots(a, b) Swap slots

Block Interaction

Breaking Blocks

fn breakTargetBlock(player, world) {
    if (player.target_block) |target| {
        world.setBlock(target.x, target.y, target.z, .air);
        hand_renderer.swing();
    }
}

Placing Blocks

fn placeBlock(player, world, inventory) {
    if (player.target_block) |target| {
        const selected = inventory.getSelectedBlock() orelse return;
        
        // Calculate placement position (offset by face)
        const place_pos = target.position + target.face.getOffset();
        
        // Check player collision
        if (player.aabb.intersects(block_aabb)) return;
        
        world.setBlock(place_pos.x, place_pos.y, place_pos.z, selected);
        inventory.removeFromSelected(1);
        hand_renderer.swing();
    }
}

Settings Persistence

File: src/game/state.zig

Settings Structure

Setting Default Range
render_distance 15 4-32
mouse_sensitivity 50.0 10-200
vsync true
fov 45.0 30-120
shadow_quality 2 (High) 0-3
shadow_distance 250.0
anisotropic_filtering 16 0-16
msaa_samples 4 1/2/4/8
ui_scale 1.0 0.5-2.0
window_width/height 1920×1080
lod_enabled false

Persistence

  • Path: ~/.config/zigcraft/settings.json
  • Auto-loads on startup
  • Saves on settings close

Hand Renderer

File: src/game/hand_renderer.zig

First-person view of held block.

Properties

  • Positioned: right 0.5, down 0.6, forward 0.8
  • Scale: 0.4x with tilt for natural look
  • Follows camera orientation

Swing Animation

Property Value
Speed 5.0 (progress/sec)
Y offset Dip during swing
Z rotation Arc motion

Block Outline

File: src/game/block_outline.zig

Wireframe cube around targeted block.

Properties

Constant Value Description
LINE_THICKNESS 0.025 Edge width
EXPAND 0.002 Z-fighting prevention
  • 288 vertices (12 edges × double-sided quads)
  • Black color for contrast
  • Comptime-generated mesh

World Map

File: src/game/map_controller.zig

Overlay map with pan/zoom.

Controls

Input Action
M Toggle map
+/- / Scroll Zoom (0.05 - 128.0)
W/A/S/D Pan (keyboard)
Left Click + Drag Pan (mouse)
SPACE Center on player
ESC Close map

Display

  • 80% screen coverage
  • Semi-transparent background
  • Player position marker (red crosshair)
  • Biome-colored terrain

Seed Generation

File: src/game/seed.zig

Seed Resolution

1. If input empty → generate random seed
2. If all digits → parse as u64
3. Otherwise → FNV-1a hash the text

Functions

Function Description
randomSeedValue() Random from SDL ticks + counter
fnv1a64(bytes) FNV-1a 64-bit hash
seedFromText(text) Parse or hash
resolveSeed(input) Full resolution

Controls Reference

In-World

Key Action
W/A/S/D Movement
SPACE Jump / Fly up
SHIFT Fly down
ESC Pause menu
TAB Toggle mouse capture
F Toggle wireframe
T Toggle textures
V Toggle VSync
F2 Toggle FPS
F3 Toggle creative/survival
I Open inventory
M Open map
N Pause day/night
1-9 Select hotbar slot
Scroll Scroll hotbar
Left Click Break block
Right Click Place block

See Also


Source: src/game/ | Last updated: January 2026

Clone this wiki locally