Combat is entirely server-authoritative. When a player swings, the client sends a lightweight intent packet; the server performs a capsule-sweep hit test against all monsters in the area, applies damage and knockback, and broadcasts the results to every client in the Area of Interest (AoI). Monster AI runs as part of the game-simulation tick (every 33 ms by default) insideDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/kenzz55/ue5-iocp-mmo-server/llms.txt
Use this file to discover all available pages before exploring further.
GameWorld::StepMonsters(), advancing a per-monster state machine that transitions between idle patrolling, chasing, attacking, and returning to the spawn point.
Player Attack Flow
C_AttackReq (0x0231) — client sends attack intent
The client sends this packet when the player initiates an attack. No hit information is included; the server computes all hits independently.
Monotonically increasing counter per session; used to detect dropped or out-of-order attack packets.
Current step in the combo chain (1-indexed). The server tracks
lastComboStep on PlayerEntity to validate sequencing.Client-side timestamp; stored for latency logging and debug packets.
S_AttackAck (0x0232) — server acknowledges
Sent back to the attacking client only. The client uses
server_time_ms to calibrate its lag-compensated animation.Hit detection — ApplyDamageToMonstersInSweep
After acknowledging the attack, the server calls For each monster hit, a
GameWorld::ApplyDamageToMonstersInSweep() to determine which monsters were struck. The sweep is a capsule test along the player’s facing direction.HpChange result is produced and packaged into S_EntityHpChanged.S_AttackNotify (0x0233) — broadcast to AoI peers
Broadcast to all players within AoI of the attacker so they can play the attack animation on the correct character.
S_EntityHpChanged (0x0244) — HP update
Sent to all AoI observers whenever a hit lands on a monster (or a monster hits a player).
Player or Monster.
Entity that was hit.
HP after this change.
Maximum HP of the entity.
Negative for damage, positive for healing.
true if the entity’s HP reached 0.MonsterEntity
Each live monster is represented by aMonsterEntity struct held inside GameWorld. The fields below are the most operationally significant:
Monster AI State Machine
TheMonsterAiState enum drives every monster’s behaviour each simulation tick:
Idle → Chase
When a player enters
detectionRadius (600 units) the monster picks that player as its target and transitions to Chase, beginning to move toward them at moveSpeed (250 units/s).Chase → RangedAttack
While chasing, if the player is within
rangedAttackRadius (400 units) and the ranged cooldown has expired, the monster transitions to RangedAttack. It plays the ranged attack animation (rangedAttackActionSeconds ≈ 1.33 s) and deals rangedAttackDamage (10) at the hit frame (rangedAttackHitSeconds ≈ 0.57 s).Chase → MeleeAttack
If the player is within
meleeAttackRadius (140 units) the monster transitions to MeleeAttack. The melee animation takes meleeAttackActionSeconds ≈ 1.27 s with the hit at meleeAttackHitSeconds ≈ 0.43 s dealing meleeAttackDamage (10).Chase → Return
If the monster moves farther than
leashRadius (1500 units) from its spawn point, it abandons its target and transitions to Return, moving back to (spawnX, spawnY, spawnZ).Return → Idle
When the monster reaches within
MonsterReturnArrivalTolerance (1 unit) of the spawn point it transitions back to Idle and clears its target.RangedAttack / MeleeAttack → Chase
After the attack action completes (
attackActionRemainingSeconds reaches 0) the monster returns to Chase to re-evaluate range.AoI Broadcasting
All monster events are broadcast only to players within the configured AoI (MonsterAoiViewDistance, which equals MovementAoiViewDistance = 3000 units). AoI membership is refreshed every MonsterAoiRefreshIntervalSeconds (0.2 s).
| Packet ID | Name | Trigger |
|---|---|---|
| 0x0241 | S_SpawnMonster | Monster enters a player’s AoI |
| 0x0242 | S_DespawnMonster | Monster leaves a player’s AoI or is dead |
| 0x0243 | S_MonsterMoveNotify | Position update during Chase/Return |
| 0x0244 | S_EntityHpChanged | Any HP change (player or monster) |
| 0x0246 | S_MonsterAttackNotify | Melee attack started |
| 0x0248 | S_MonsterRangedShotNotify | Ranged projectile fired |
Knockback and Hit Reaction
When a player’s sweep hits a monster the server applies knockback using the following parameters fromMonsterEntity:
| Parameter | Value |
|---|---|
knockbackDistance | 60 units |
knockbackDurationSeconds | 0.18 s |
hitReactionDurationSeconds | 30/30 = 1.0 s |
hitReactionRemainingSeconds > 0 the monster is in a stunned state and cannot initiate new attacks. Knockback movement is resolved by the server and broadcast via S_MonsterMoveNotify.
Monster Respawn
When a monster’s HP reaches 0, the server removes it fromGameWorld, broadcasts S_DespawnMonster to all observers, and schedules a respawn after MonsterRespawnDelaySeconds (30 s). After the delay the monster is re-created at its original spawn point (identified by spawnPointId) with full HP and aiState = Idle.
Setting
EnableCombatDebugPackets = true in Common/Config.h (the compiled-in default) causes the server to emit two additional packets per attack event:- 0x0245
S_CombatDebugNotify— sent to the attacking player; includes sweep geometry (start/end/radius), the list of hit monster IDs, and the server-computed damage values. - 0x0247
S_MonsterCombatDebugNotify— broadcast to all AoI observers; includes the monster’s AI state, target ID, and current cooldown timers at the moment of the attack.