-
Notifications
You must be signed in to change notification settings - Fork 0
Game Systems
MichaelFisher1997 edited this page Jan 5, 2026
·
1 revision
Player controls, inventory management, and gameplay mechanics.
File: src/game/app.zig
The main game loop orchestrator managing all subsystems.
pub const AppState = enum {
home, // Main menu
singleplayer, // World creation
world, // Active gameplay
paused, // Pause menu
settings, // Settings screen
};home → singleplayer → [seed input] → world ↔ paused → settings
↑ ↓ ↓
└─────────────────────────────┴───────────┘
(quit to title)
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 |
File: src/game/player.zig
Physics-based player with collision detection.
| 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 |
| Mode | Description |
|---|---|
| Walking | Ground-based with gravity and jumping |
| Flying | Creative mode flight (no gravity) |
| Noclip | Pass through blocks (debug) |
| 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 |
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
File: src/engine/physics/collision.zig
AABB-based collision against the voxel world.
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
};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
File: src/game/inventory.zig
Block storage with hotbar and main inventory.
| Section | Slots | Description |
|---|---|---|
| Hotbar | 0-8 | Quick access (9 slots) |
| Main | 9-35 | Storage (27 slots) |
| Total | 36 |
pub const ItemStack = struct {
block_type: BlockType,
count: u8, // Max 64
};| 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 |
fn breakTargetBlock(player, world) {
if (player.target_block) |target| {
world.setBlock(target.x, target.y, target.z, .air);
hand_renderer.swing();
}
}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();
}
}File: src/game/state.zig
| 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 | — |
-
Path:
~/.config/zigcraft/settings.json - Auto-loads on startup
- Saves on settings close
File: src/game/hand_renderer.zig
First-person view of held block.
- Positioned: right 0.5, down 0.6, forward 0.8
- Scale: 0.4x with tilt for natural look
- Follows camera orientation
| Property | Value |
|---|---|
| Speed | 5.0 (progress/sec) |
| Y offset | Dip during swing |
| Z rotation | Arc motion |
File: src/game/block_outline.zig
Wireframe cube around targeted block.
| 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
File: src/game/map_controller.zig
Overlay map with pan/zoom.
| 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 |
- 80% screen coverage
- Semi-transparent background
- Player position marker (red crosshair)
- Biome-colored terrain
File: src/game/seed.zig
1. If input empty → generate random seed
2. If all digits → parse as u64
3. Otherwise → FNV-1a hash the text
| Function | Description |
|---|---|
randomSeedValue() |
Random from SDL ticks + counter |
fnv1a64(bytes) |
FNV-1a 64-bit hash |
seedFromText(text) |
Parse or hash |
resolveSeed(input) |
Full resolution |
| 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 |
- Block Types - Available blocks
- Input System - Input handling
- UI System - Menu rendering
Source: src/game/ | Last updated: January 2026