Skip to main content

What Is CraftyPlayer?

CraftyPlayer is the minimal platform contract for a connected player. It is intentionally game-agnostic:
  • no required 3D movement model,
  • no required health model,
  • no required scene structure.
This is what allows card games, RTS, 2D games, and 3D action games to all use the same multiplayer platform.

Core Contract (Signatures)

Identity

Player identity fields are assigned by the platform during connection:
  • peer_id: int
  • player_id: String
  • display_name: String
  • avatar: Dictionary

Custom Synced Variables

set_synced and get_synced are the core data sync mechanism. Use them for any gameplay data your clients need:
  • card hand summaries,
  • turn state,
  • unit stats,
  • score,
  • custom RPG state.
  • set_synced(key: String, value: Variant) -> void
  • get_synced(key: String) -> Variant
Keep authoritative game logic on server paths (Crafty.is_server()). Clients should render synced state, not decide outcomes.

Input (Read On Server)

Each connected player has an input proxy you read on the server:
  • player.input.movement -> Vector2
  • player.input.look_direction -> Vector2
  • player.input.is_action_pressed(action: String) -> bool
  • player.input.is_action_just_pressed(action: String) -> bool

CraftyCharacter3D (Optional 3D Template)

For 3D action games, use CraftyCharacter3D in your player.tscn. It includes:
  • CharacterBody3D movement-compatible node type,
  • health fields (health, max_health, is_alive),
  • helpers (respawn, damage, heal, kill, teleport),
  • same synced API (set_synced / get_synced).
Example:

Practical Rule

If your game needs built-in 3D character behavior, use CraftyCharacter3D. If your game is not a 3D character game, extend CraftyPlayer directly and sync your own state model.