---
title: "Packet 28: CreatePlayer"
description: "Creates a player character and also serves as the active roster format. Class, loadout, and all selected prefab names come from one committed selection."
canonical: "https://aosplay.net/protocol-168/packets/28"
markdown: "https://aosplay.net/docs/protocol-168/packets/28.md"
last_updated: "2026-07-16"
protocol: "Ace of Spades Battle Builder 168"
packet_id_decimal: "28"
packet_id_hex: "0x1C"
direction: "S→C"
family: "Players"
implementation_status: "Sent"
evidence: "Live-verified"
wire_size: "Variable: 21 + name + L + Σprefabs"
---

# Packet 28: CreatePlayer

> Creates a player character and also serves as the active roster format. Class, loadout, and all selected prefab names come from one committed selection.

- **Decimal ID:** 28
- **Hex ID:** 0x1C
- **Direction:** S→C
- **Family:** Players
- **Status:** Sent
- **Evidence:** Live-verified
- **Wire size:** Variable: 21 + name + L + Σprefabs

## Implementation note

Names must already be unique. This direction contains no field identifying which remote row the receiving client owns.

## Exact wire layout

The application packet ID is the first byte. The remaining rows are in decode order. Byte sizes exclude ENet headers, wrapper prefixes, LZF chunk framing, and compression effects.

| # | Field | Encoding | Bytes | Purpose | Condition |
| ---: | --- | --- | ---: | --- | --- |
| 0 | `packet_id` | u8 | 1 | Always 28 (0x1C). | — |
| 1 | `player_id` | u8 | 1 | Compact player-slot identifier. | — |
| 2 | `demo_player` | boolean u8 | 1 | demo player value. | — |
| 3 | `class_id` | u8 | 1 | Selected character class identifier. | — |
| 4 | `team` | u8 | 1 | team value. | — |
| 5 | `dead` | boolean u8 | 1 | dead value. | — |
| 6 | `local_language` | u8 | 1 | local language value. | — |
| 7 | `position` | 3 × fixed16 LE | 6 | X, Y, and Z components at 1/64-unit precision. | — |
| 8 | `orientation` | 3 × fixed16 LE | 6 | X, Y, and Z components at 1/64-unit precision. | — |
| 9 | `name` | NUL-terminated UTF-8 string | N + 1 | Null-terminated UTF-8/ASCII-compatible string. | — |
| 10 | `loadout_count` | u8 | 1 | L: tool count. | — |
| 11 | `loadout[]` | L × u8 | L | Ordered tool IDs. | — |
| 12 | `prefab_count` | u8 | 1 | prefab count value. | — |
| 13 | `prefabs[]` | repeated NUL strings | Σ(N + 1) | Selected prefab names. | — |

## Encoding conventions

- `LE` means least-significant byte first.
- `fixed16` is two-byte sign-magnitude at 1/64 precision.
- `orientation16` uses the measured 1/8192 orientation mapping.
- NUL strings consume their encoded byte length plus one `00` terminator.
- Counted arrays repeat immediately in the documented order.

## Related resources

- [HTML packet page](https://aosplay.net/protocol-168/packets/28)
- [Complete packet catalog](https://aosplay.net/protocol-168/packets)
- [Packet catalog in Markdown](https://aosplay.net/docs/protocol-168/packets.md)
- [Protocol 168 guide](https://aosplay.net/protocol-168)
