Ricochet rules and caster-owned marks

Bencci

An Unreal Engine 5.8 and C++ arena game in development. Its Q projectile ricochets off geometry, applies caster-owned marks and rejects consecutive hits on the same target.

Role
Solo Programmer and Designer
Context
  • Personal project
  • in development
Period
In development
Status
  • Private repository
  • available to discuss in interview
  • Unreal Engine 5.8
  • C++
  • Gameplay Ability System
  • Enhanced Input
Bencci project title with Unreal Engine 5.8, C++ and Gameplay Ability System labels
Bencci is an in-development private Unreal Engine project.

Current development

Bencci is my solo Unreal Engine 5.8 arena project in development. Deadeye is a working character name. Its Q ricochets, damages targets and applies caster-owned marks.

The repository is private. I can walk through the implementation and design decisions in an interview.

The projectile-routing rule

A ricochet can bring a projectile back into the same target. I wanted geometry and target placement to matter without letting repeated contact with one opponent become the default source of damage.

The projectile remembers its last valid target. Consecutive hits on that target are rejected. A valid hit on another target replaces that history, making the first target eligible again.

Consecutive contactA → A

Second contact rejected

Another valid target in betweenA → B → A

A becomes eligible again

The rule is implemented and tested in runtime. Consecutive hits on the same target are rejected, while A → B → A correctly makes the first target eligible again.
Deadeye Q ricochet and mark test.

Planning the shot

A wall bounce alone does not make the same opponent eligible again. The player needs another valid target in the route before returning to the first. That makes firing angle, nearby geometry and the positions of other opponents part of planning the shot.

Owning the setup

Caster-owned marks prevent one Deadeye using another’s setup without landing Q. One active mark means switching targets gives up the previous setup. I chose that limit to restrain early damage potential and leave room for Evolution scaling.

Implementation

C++ handles collision and target history. GAS owns ability state, damage, cooldown and mark expiry, with target visuals. Blueprint defaults and ability data expose configuration checked by editor validation.

Cast commitment blocks input-spam cancellation and releases the action lock at launch. Shared GAS state avoids competing cooldown/UI timers. Stable slots keep controls consistent when future ability versions change.

What I have tested

Single-player and two-player listen-server/client PIE checks covered Q damage, cooldown, mark application, expiry and visual feedback.

I tested both consecutive-hit rejection and A → B → A routing in multiplayer PIE.

Planned, not implemented or tested

Next steps

W bonus damage, E teleport to an owned mark, Evolution and modifiers are planned. Dodging Q denies setup. Marks are intended to signal a possible future follow-up.

Inspired by player-built walls and destructible environments, I plan to explore changing terrain. Player control over angles, routes and safe positions could reduce repeated spatial solutions and map fatigue.