| name | machin-game-demo-player |
| description | Build, run, and modify machin-game-demo-player — a first-person 3D playground with walking, jumping, platform stepping, object pushing, and walk/fly camera toggle. Use when working on this repo or as the reference for first-person player controllers and interactive physics in machin. |
machin-game-demo-player
A first-person 3D playground — walk on platforms, jump between them, push objects around. Toggle walk/fly with F. Written in machin (MFL) via raylib's C FFI.
Shared game-dev setup, the FFI surface, and gotchas live in the canonical machin-gamedev skill. This file covers the specifics of this demo.
Build & run
./build.sh
./machin-game-demo-player
Needs machin v0.48.0+, a C compiler, raylib, and a display.
Architecture
Player data (local variables in main)
px, py, pz — world position (camera at (px, py + EYE_H, pz))
pvx, pvy, pvz — velocity
yaw, pitch — look direction
grounded — 1 if on a surface
walk_mode — 1 = walking, 0 = flying
Walk-mode loop (per frame)
- Mouse look: yaw/pitch accumulate from
GetMouseDelta() (clamped pitch ±80°).
- Input direction: WASD produces a horizontal direction vector from
sin(yaw)/cos(yaw). Normalized and scaled by speed.
- Acceleration:
vel += (target - vel) × clamp(accel·dt, 0, 1) — smooth interpolation toward the input direction, frame-rate independent.
- Gravity + integration:
pvy += GRAVITY·dt; pos += vel·dt.
- Ground collision:
if foot < 0: foot=0, vel.y=0, grounded=1, friction applied.
- Platform collision: for each platform, check XZ bounds + foot near top.
- Object collision: for each object, sphere-sphere push-apart.
- Object physics: objects have their own gravity, ground collision, and platform collision.
Walk/Fly toggle
Pressing F flips walk_mode. On transition to walk mode, the current fly camera position/orientation is transferred to the player, so you fly to a spot, press F, and land there looking in the same direction.
Scene
- 4 platforms (
Plat struct: position, half-extents, color)
- 5 pushable objects (
PushObj struct: position, velocity, radius, color)
- Both stored as
[]Plat and []PushObj, built at startup
Rendering
A draw_scene(cam, platforms, objects, ...) helper renders the full scene:
DrawGrid for the ground
DrawCube for each platform
DrawSphere for each pushable object
- Semi-transparent
DrawSphere at the player's feet (shadow ring)
- Crosshair (
+) and HUD drawn in screen space after EndMode3D
Patterns worth copying
- Player-facing movement from yaw. Horizontal movement direction is computed from
sin(yaw)/cos(yaw) — the same yaw that controls the view direction. This means W always moves the player where they're looking, even when looking up/down.
- Smooth acceleration. Instead of instant velocity, interpolate:
vel += (input - vel) × min(accel·dt, 1). This gives smooth starts and stops without explicit state machines.
- Toggle between first-person and free camera. The F key flips a bit. Walk mode uses the player controller; fly mode uses the standard fly camera (from solar). This is essential for debugging — the developer can fly away to see the full scene layout.
- Platform collision as a snap test. For each platform, check if the player foot is within the platform's XZ bounds AND within a tolerance of the platform top. If so, snap the foot to the top. This handles stepping up onto platforms naturally.
- Simple object pushing. Sphere-sphere collision between player and objects. The push is proportional to the overlap, applied to both player and object. Objects have their own physics (gravity, ground friction).
Modifying
- Scene layout: change the
platforms = append(...) and objects = append(...) blocks in main(). Add more platforms or objects.
- Player stats: adjust
WALK_SPD, SPRINT_SPD, JUMP_VEL, EYE_H, P_RADIUS at the top of the file.
- Gravity: change
GRAVITY — negative = down, zero = space.
- Physics: adjust
FRICTION (higher = more slippery), accel (higher = snappier movement).
- Camera FOV: change the 60.0 in
Camera3D{..., 60.0, 0}.
Future directions
- Ramp/slope walking — the player climbs angled surfaces by projecting their foot onto the surface normal.
- Pick up / throw objects — press E to grab the nearest object, SPACE to throw.
- Collectibles / scoring — walk over glowing pickups to score points.
- Simple enemies — AI that patrols and chases the player on the platforms.
- Portal / teleport — step through a glowing ring to teleport to another platform.