Skip to content

Weapon Knockback Test Plan

Yogesh Sevda edited this page Oct 22, 2026 · 2 revisions

Overview

Test plan for the weapon knockback fix (#302, merged in PR #410). How the fix works is on the Weapon Knockback page.

What I'm checking:

  • An enemy hit by a weapon gets pushed back and stops chasing for a moment.
  • It gets pushed away from the player, not from the middle of the hitbox.
  • It starts chasing again afterwards, and normal enemy movement hasn't changed.

There are unit tests for the logic, and manual tests in-game for what it actually looks like.

Test Environment

  • Unit tests: JUnit 5 + Mockito with GameExtension. The tests use a real Box2D PhysicsService and a mocked GameTime so the frame time can be controlled.
  • Manual tests: desktop build
  • Controls: J light attack, K heavy attack, WASD to move
  • Debug terminal (F1): weapon knife|sword|bow to equip, upgrade knife for the flurry, debug on to see hitboxes

To run just these tests:

cd source
./gradlew :core:test --tests "*PhysicsMovementComponentTest" --tests "*TouchAttackComponentTest"

(On Windows PowerShell it's .\gradlew.bat.)


Unit Tests

PhysicsMovementComponentTest

Test What it checks Expected
staggerKeepsKnockbackVelocityInsteadOfSteeringBack This is the actual bug: steering shouldn't cancel knockback. After stagger(0.1f), an update leaves the knocked-back velocity (-4) alone instead of resetting it to the chase speed (2.5).
steeringResumesOnceStaggerExpires Enemies don't stay stunned forever. Once the time is up, isStaggered() is false and the enemy goes back to chase speed.
shorterStaggerDoesNotCutALongerOneShort Two hits close together don't shorten the first stagger. After stagger(0.5f) then stagger(0.01f), it's still staggered 5 frames later.
negativeStaggerIsRejected Bad input. stagger(-1f) throws IllegalArgumentException.

Not covered by automated tests

  • How far enemies fly and how long they pause is about game feel, so it's tuned by playing rather than tested.
  • There's no unit test yet for a hit that both knocks back and immobilises (the Medusa case). It was checked manually in review. A test that staggers and freezes the same entity and checks it still moves would close this gap.
  • Enemies that set their own velocity in an AI task (dash, stampede) and bosses with their own movement get pushed but not staggered. This is listed as a limitation on Weapon Knockback.
  • The full weapon -> hitbox -> enemy flow in an actual dungeon is only tested manually. The unit tests test TouchAttackComponent and PhysicsMovementComponent directly.

AI Declaration

Claude (Anthropic, Claude Code) was used to help write the tests and draft this test plan. I reviewed it before publishing.

## Overview

Test plan for the weapon knockback fix ([#302](https://github.com/UQcsse3200/2026-studio-4/issues/302), merged in [PR #410](https://github.com/UQcsse3200/2026-studio-4/pull/410)). How the fix works is on the [Weapon Knockback](Weapon-Knockback) page.

What I'm checking:

  • An enemy hit by a weapon gets pushed back and stops chasing for a moment.
  • It gets pushed away from the player, not from the middle of the hitbox.
  • It starts chasing again afterwards, and normal enemy movement hasn't changed.

There are unit tests for the logic, and manual tests in-game for what it actually looks like.

Test Environment

  • Unit tests: JUnit 5 + Mockito with GameExtension. The tests use a real Box2D PhysicsService and a mocked GameTime so the frame time can be controlled.
  • Manual tests: desktop build
  • Controls: J light attack, K heavy attack, WASD to move
  • Debug terminal (F1): weapon knife|sword|bow to equip, upgrade knife for the flurry, debug on to see hitboxes

To run just these tests:

cd source
./gradlew :core:test --tests "*PhysicsMovementComponentTest" --tests "*TouchAttackComponentTest"

(On Windows PowerShell it's .\gradlew.bat.)


Unit Tests

PhysicsMovementComponentTest

Test What it checks Expected
staggerKeepsKnockbackVelocityInsteadOfSteeringBack This is the actual bug: steering shouldn't cancel knockback. After stagger(0.1f), an update leaves the knocked-back velocity (-4) alone instead of resetting it to the chase speed (2.5).
steeringResumesOnceStaggerExpires Enemies don't stay stunned forever. Once the time is up, isStaggered() is false and the enemy goes back to chase speed.
shorterStaggerDoesNotCutALongerOneShort Two hits close together don't shorten the first stagger. After stagger(0.5f) then stagger(0.01f), it's still staggered 5 frames later.
negativeStaggerIsRejected Bad input. stagger(-1f) throws IllegalArgumentException.

The tests that were already in this class still pass, so normal movement isn't affected.

TouchAttackComponentTest

Test What it checks Expected
knockbackPushesEnemyAwayFromWielderAndStaggersIt Push comes from the player, and the hit staggers the enemy. Player at x=0, enemy at x=1, hitbox centred past the enemy at x=2. The enemy moves in the positive direction (away from the player) and is staggered.
enemyResumesChasingAfterKnockbackStagger The enemy chases again after being hit. After KNOCKBACK_STAGGER seconds it's not staggered anymore and moves back towards its target.
noKnockbackMeansNoStagger Hits with no knockback (like knife slashes) keep the enemy in range. Knockback 0 doesn't stagger the enemy.

All the existing tests in this class (repeat contact damage, cooldowns, concealment, disposal) still pass, so enemies hitting the player still works the same.

CI

Check What it covers
Game Unit Tests All the tests above plus the rest of the project.
Java Format google-java-format (./gradlew formatCheck).
SonarCloud Quality gate, no new issues. I split attack() into applyKnockback() to get its cognitive complexity under 15.
Javadoc Test Build Javadoc on the new public methods (stagger, isStaggered, setKnockbackSource).

Manual Tests

Setup: run the game, go into a dungeon room with enemies, press F1, equip a weapon (weapon knife / weapon sword / weapon bow), optionally debug on, then F1 again to close.

Test Steps Expected
Sword pushes back Swing the sword (J) at an enemy walking towards you. It gets pushed away and pauses for a moment before coming back.
Sword direction Let an enemy get to your side and hit it with the start or end of the swing. It always goes away from the player, never towards.
Bow pushes back Shoot an enemy that's coming at you. It gets pushed back in the direction the arrow was going and pauses.
Medusa Hit Medusa in the first dungeon with each weapon. She's pushed back, pauses for her hit recovery, then chases again. (Found in review: before the fix her freeze cancelled the push.)
Freeze still works Use a freeze bomb on an enemy without attacking it. It stays completely still until the freeze ends.
Knife flurry upgrade knife, then K next to an enemy. The two slashes don't push it, the last stab does.
Enemy comes back Hit an enemy once and wait. After about a quarter of a second it walks back at normal speed.
Repeated hits Keep hitting the same enemy as it comes back. It gets pushed every time and never gets stuck or stops chasing.
Less damage taken Stand still and keep attacking one enemy. You take a lot less contact damage than before the fix.
Walls Knock an enemy into a wall. It stops at the wall, doesn't go through.
Player unchanged Let an enemy touch you. You still get pushed and damaged like before, and player movement feels the same.
Enemies unchanged when not hit Walk around without attacking. Enemies chase at normal speed like before.

Not covered by automated tests

  • How far enemies fly and how long they pause is about game feel, so it's tuned by playing rather than tested.
  • There's no unit test yet for a hit that both knocks back and immobilises (the Medusa case). It was checked manually in review. A test that staggers and freezes the same entity and checks it still moves would close this gap.
  • Enemies that set their own velocity in an AI task (dash, stampede) and bosses with their own movement get pushed but not staggered. This is listed as a limitation on [Weapon Knockback](Weapon-Knockback).
  • The full weapon -> hitbox -> enemy flow in an actual dungeon is only tested manually. The unit tests test TouchAttackComponent and PhysicsMovementComponent directly.

AI Declaration

Claude (Anthropic, Claude Code) was used to help write the tests and draft this test plan. I reviewed it before publishing.

Table of Contents

Home

Getting Started

Game Engine

Entities and Components
Input Handling

Features

Components
Achievements
Player
Items and Inventory
Enemies
Bosses
Interactable NPCs
Cutscenes and Dialogue
Training Grounds
Music
Weapons
Abilities & Spells
Rooms and Dungeons
Game Screens and Areas
UI

Test Plans

Team 1
Team 2

Troubleshooting

Clone this wiki locally