S.O.A.P
2025.08 - Now
A third-person action game where players clean floors, defeat enemies and earn points in an arena.
- Project
- Academic team project
- Engine
- Unreal Engine
Demo
Team trailer · April 2026
Gameplay flow
Move
Slide and drift through the arena.
Clean
Clean the floor to increase coverage.
Contest
Fight enemies and reclaim re-dirtied areas.
Return to move
My contribution
- Interactive Ground
- Built all functionality related to cleaning the floor and changing its surface state.
- UI implementation
- Implemented every UI feature: the in-game HUD, title screen, settings and other interface screens.
- Scoring system
- Developed the complete score calculation system.
- Music & audio
- Composed the BGM, sourced sound effects and implemented the entire audio system.

Inspiration
The team combined cleaning with score-based arena combat. Enemies can re-dirty the floor, so clearing an area once does not secure it for the rest of the round.
Gameplay
Soap Shoes preserve momentum. Players slide, drift and use slopes to turn or reposition instead of stopping immediately.
Cleaning increases floor coverage; defeating enemies adds points. Re-dirt trails force players to decide whether to clear an area again or keep moving.
Bath Bomb cleans an area in a burst. Bubble Wand applies coverage at range, letting players clean ahead while moving.
Technical Implementation
Interactive Ground
I built the Interactive Ground system. Its drawing pipeline connects three different spaces: a collision in the world, a position in the surface’s UVs, and pixels in a Render Target.
Ground cleaning in play
The player leaves a visible cleaning trail while moving. The score changes in the HUD as the ground is cleaned, showing the surface system and UI together.
Resolve the contact
Trace the surface and validate its collision UV.
Convert the scale
Translate world-sized brushes into texture pixels.
Update the surface
Select the clean / dirty material and draw to the Render Target.
Collision and UV mapping
BP_Canvas → Splash traces vertically around the supplied world position, ignoring the player. It extracts collision UVs from the hit and identifies the target Canvas.
Both the hit and UV lookup must succeed before Paint is called. This keeps a failed surface lookup from becoming a paint operation at an unintended texture position.
Brush size conversion
A fixed pixel-sized brush would cover different world distances on differently scaled surfaces. UpdateCanvasMetrics derives canvas width and height from the mesh’s local bounds × world scale.
Paint uses those dimensions to calculate the brush footprint on each texture axis, then subtracts half the footprint to centre the mark on the UV-derived position.
World brush size ÷ canvas world sizeRender Target resolutionBrush size in pixels
Calculated separately for X and Y.
Cleaning and dirt rendering
Cleaning and re-dirtying share the same positioning and sizing calculations. In BP_Canvas → Paint, the Dirty flag selects the brush material for that operation.
Begin Draw → Draw Material → End Draw writes that change into the Render Target.
UI, scoring and audio
I implemented Interactive Ground, score calculation and every UI feature, including the HUD, title screen and settings. Surface changes feed the coverage and score feedback shown during play.
The project uses Unreal Blueprints and UMG. I also composed the BGM, sourced sound effects and implemented the audio system.
Related AI project
Boss decision system
For a separate AI course, I built a Boss action-selection algorithm on top of SOAP. It scores combat conditions and selects between behaviors supplied by teammates.
View Boss AI case study and demo ↗S.O.A.P
Back to overview ↑
