Reference · Updated 2552.10.09.16.40
Udemy FPS reuse review for System Link
7 October 2026
7 October 2026
#Recommendation
The course project has useful ideas for elimination medals, queued HUD announcements, and match statistics. These fill gaps identified in System Link's multiplayer plan and support its goal of making nights with friends memorable. Adapt those ideas inside SystemLinkCore, preserving the existing Gameplay Ability System (GAS), damage pipeline, and per-player UI.
The best first slice is a server-confirmed elimination record that updates kills and deaths and produces a queued Double Kill or Revenge notification. That establishes a foundation for a scoreboard and eventual session history. Importing the course's complete character, combat, or health system would duplicate working System Link systems and introduce avoidable integration work.
#What is available
The reviewed course checkout contains 47 tracked files, including 38 C++ headers and implementation files, four configuration files, and the project/build descriptors. Its commit is 1e585ffc27852aca2247d22cb80d7b8e60606f4a named Auto Reload Fix. The source identifies Druid Mechanics as copyright holder. [D1]
There is no Content directory in this checkout; .gitignore excludes both Content and Plugins. The configured /Game/Maps/FPSMap.FPSMap is therefore absent. References to weapon animations, materials, icons, widgets, and input actions describe dependencies, not available assets. The checkout does not provide a playable course level or an art library to migrate.
The course descriptor selects Unreal 5.8, while System Link selects 5.7. C++ ideas can be reimplemented against 5.7 and compiled there. If course assets are obtained later, establish the version in which they were saved: Epic documents that assets saved by a newer engine are not generally loadable in an older engine. Changing the project association is not an asset downgrade. [E1]
#Reuse priorities
| Candidate | Value | Recommended treatment | Effort |
|---|---|---|---|
| Medals and revenge rules | High | Adapt rule design to confirmed deaths | Medium |
| Announcement queue | High | Extend the existing System Link HUD | Low to medium |
| Score and leader tracking | High | Reimplement as replicated match state | Medium to high |
| Statistics for session history | Medium now | Use field ideas; add durable records later | High for persistence |
| Ammo reconciliation | Conditional | Reference when investigating latency issues | Medium |
| Reticles and third-person IK | Low incremental | Use as comparison/debugging examples | Low to inspect |
| Combat, health, respawn and online | Low or absent | Retain System Link implementations | High to replace |
Effort is a relative integration assessment, not a delivery estimate. Findings come from source inspection; neither project was built or run for this review. System Link's current working files, including map-select changes, were included in the comparison. Recommendations are proposals, not implemented features.
<!-- pagebreak -->
#Elimination medals are the strongest fit
UEliminationComponent receives a shot report and classifies lethal hits. It recognizes headshots, consecutive kills within a configurable interval, kill streaks, revenge against the previous killer, stopping a streak, first blood, and changes in the lead. The defaults are a two-second multikill window and five kills for a streak. These are course tuning values, not recommendations for System Link. [D2]
The course flags are Halo's medals under other names:
| Course flag | Rule | Halo name |
|---|---|---|
Headshot | killing hit's bone is head | Headshot |
Sequential | kill within the multikill window of the last | Double / Triple / Overkill / Killtacular… |
Streak | five or more kills since spawn | Killing Spree / Frenzy / Running Riot… |
Showstopper | victim was on a streak | Killjoy |
Revenge | victim was the last player to kill you | Revenge |
FirstBlood | first kill of the match | First Strike |
Dethrone | victim was the sole leader | no medal; "killed the leader" |
GainedTheLead / TiedTheLeader / LostTheLead | leader set changed | Slayer announcer lead lines |
This is a close fit for SystemLinkVision.md, which explicitly calls for revenge rivalries, kill streaks, memorable moments, and nightly awards. System Link's native PlayerState and gameplay GameMode do not currently implement this medal or scoring layer; SuccessCriteria.md still lists score display and kill feed as incomplete. [S1, S2]
Adapt the rules, then broaden their input. The course reports eliminations from gunfire. System Link needs one server-side death record covering bullets, shotgun pellets, melee, grenades, teleporter damage, suicides, and environmental deaths. Awarding a kill per pellet or from a cosmetic hit event would produce incorrect scores. The record should identify the attacker and victim, damage source, server time, and whether the death qualifies for each rule.
Keep life-specific counters separate from match totals. Reset a player's current streak on death, reset first blood and match leaders on a new match, and retain the completed match's summary for later session history. Use stable player identifiers in stored history; a pawn pointer or display name is not a durable identity.
For a first implementation, use Double Kill, Revenge, and Streak Stopped. They demonstrate timing, player relationships, and a victim's prior state. Add headshot awards only after agreeing how lethal head hits interact with System Link's shields, pellets, and weapon rules. The course's headshot flag is a bone-name check; it does not implement a shield-aware headshot damage rule. [D2, D5, S3]
#Queue medals through the existing HUD
The course's USpecialElimData maps medal types to text and icons. AShooterPlayerState decodes multiple medal flags, places presentation records in a FIFO queue, and displays them on a timer. This is useful when one kill earns several announcements. [D3]
System Link already has FSLNotificationData, USLNotificationWidget, and USLHUDWidget::ShowTimedNotification. The missing piece is scheduling: ShowTimedNotification clears the notification container and cancels the current timer, so several calls replace one another. It also shares that container with pickup prompts. [S4]
Add a local queue with explicit priority, duration, and cancellation rules, or give medals their own HUD container. Decide whether a medal can interrupt a pickup prompt. Keep the queue with the owning local player or HUD, use the existing per-player layout, and clean up on travel or HUD destruction. Presentation records should copy immutable medal definitions instead of changing shared data assets.
The course calls AddToViewport, and its centering helper uses the whole viewport. System Link's primary layout already uses AddToPlayerScreen for split-screen. Route medals into that layout so each local player sees their own messages. Use GAS cues for applicable gameplay cosmetics and replicated state for scores; a temporary announcement must never be the only record of a score change. [D3, S4]
Medal identity and delivery. Name medals as native gameplay tags (SLTags::Medals::*) rather than a bitmask; the tag is then also the key for the medal definition and the announcer sound. A medal popup is for the earning player only, so a Client RPC is the right delivery here, not a GameplayCue (cues are for cosmetics every client sees). Keep the course's one good network habit: bundle every medal one kill earns into a single RPC.
<!-- pagebreak -->
#Use the scoring model as a starting reference
The course puts cumulative kills, deaths, hits, misses, headshot kills, revenge kills, best streak, and several awards on PlayerState. GameState derives the leader set from player scores and supports ties. Those are useful responsibilities to carry into System Link's forthcoming match rules. [D3, D4]
The implementation is incomplete for System Link's needs. Its custom statistics are ordinary private fields, not replicated properties. Client RPCs broadcast score values to widgets without updating the client's ScoredElims field. The result is a live notification path, not a reliable scoreboard snapshot for a late joiner or a rebuilt HUD. The leader list likewise has no replication declaration. [D3, D4]
Implement replicated match statistics on ASLPlayerState and shared match state on a gameplay GameState. Derive scoring on the server, notify the UI when replicated values change, and initialize a newly created widget from the current state. Preserve the ASC and granted ability handles already owned by ASLPlayerState; replacing this class would disrupt System Link's existing respawn design. [S2]
The course does not supply teams, assists, betrayal policy, a match timer, score-limit victory, an end-of-match results flow, or persistent session records in the inspected source. IsNowWinner is a setter, not an implemented match-completion system. These remain System Link work.
#Integrate at the confirmed death boundary
System Link already has the necessary entry point. USLHealthAttributeSet::PostGameplayEffectExecute detects depleted health, guards against the Dead tag, stores PendingKiller, and forwards the damage effect context into the death ability. USLGameplayAbility_Death applies the dead effect, cancels abilities, drops inventory, and calls the authority-side OnDeathStarted hook. [S3]
Create the elimination record once in that authoritative flow, while the damage context and player identities are still available. The existing OnDeathStarted hook takes no damage payload, so implementation needs either a captured record or an explicit parameter/delegate carrying that context. Do not infer every killer by casting PendingKiller to a pawn: a grenade, world actor, or destroyed causer needs different attribution.
Resolve player ownership from the effect context and the relevant instigator/causer, then apply the chosen game-type rules. Use an explicit processed-death guard or event identifier so repeated damage callbacks cannot award multiple kills. Do not wait for a death animation or respawn timer to award the elimination.
For session history, append completed-match records with stable identities, map and mode, final scores, and selected events. The course's in-memory counters and weak pointer to the previous attacker do not survive a full session lifecycle. Travel, reconnects, and saving/loading need deliberate handling.
Roadmap fit: complete the active lobby/map-selection work, then add this layer with teams and match rules. An older section of MultiplayerPlan.md says there is no GameState subclass; the current tree now contains ASLLobbyGameState. A gameplay match-state layer is still needed. Do not treat that older statement as the current lobby status. [S1, S5]
<!-- pagebreak -->
#Smaller ideas worth keeping nearby
#Ammo reconciliation as a debugging reference
AWeapon::Local_Fire tracks locally predicted shots with Sequence. On acknowledgement, Rep_Fire starts from the server's ammo value and subtracts the remaining unacknowledged shots. This compact example explains why simply replacing a predicted ammo count with an older server count can make the HUD jump. [D6]
System Link already applies fire-mode ammo effects through GAS, mirrors weapon ammo into its weapon actor, and broadcasts ammo changes. Do not add the course counter on top of that flow: two prediction mechanisms can disagree. Keep the example for a targeted investigation only if latency testing exposes ammo rollback or firing-after-empty problems. A robust implementation would also account for rejected shots, reloads, and weapon changes. [S6]
#Reticle reactions and widget lifecycle
The course reticle independently interpolates firing, aiming, and target-hover contributions into material parameters. Its reticle and reserve-ammo widgets detach from the old pawn and bind to the new pawn after possession changes. This is useful reference material for HUD timing bugs. [D7]
System Link already exposes spread, fire, ADS, target classification, reticle caching, and initial-state seeding. Preserve those interfaces and borrow only an individual visual behavior that improves the current reticle. The actual course reticle and ammo materials are absent, so their appearance cannot be assessed or imported from this checkout. [S7]
#Third person hand placement
CalculateFABRIKSocketTransform reads a weapon socket in world space and converts it into the character's right-hand bone space. This is a useful compact comparison when checking hand placement. The character also includes aim-offset and turn-in-place calculations. [D8]
System Link already produces separate FP and TP left-hand IK snapshots through its weapon view drivers. The current board's SL-27 concerns Blueprint hookup and visual tuning. Compare coordinate spaces when diagnosing that work; the course does not provide a replacement animation graph or a finished fix for System Link's skeleton. [S8]
#Systems with little reuse benefit
Retain System Link's data-driven weapons, GAS equip/fire flow, action locks, pickups, sidearm, shield and overshield damage, and respawn timers. The course has a smaller manual RPC-driven combat component and a simple health component. Swapping them in would remove or duplicate existing behavior.
The inspected course source also contains no session browser, LAN hosting/joining service, lobby/map picker, local profile system, or split-screen UI framework. System Link already has relevant code in these areas. Its current Join-screen and loading-screen work cannot be filled by this course checkout. CommonUI being enabled in the course descriptor is not evidence of a supplied front-end system. [D1, S5]
<!-- pagebreak -->
#Issues to avoid when adapting the course code
These are static code findings and predicted consequences, not failures reproduced in a running course build.
#Client supplied hits are trusted
Server_FireWeapon_Implementation accepts the client's FHitResult, uses its actor and bone name for damage and headshot classification, and checks only the current weapon and positive ammo. The shown path does not retrace the hit or enforce fire cadence on the server. Server_CycleWeapon also accepts an index that later reaches unchecked inventory indexing. These are reasons to retain System Link's combat path rather than importing this component. System Link already retraces submitted shots server-side; this review does not certify the completeness of its own validation. [D5, S6]
#Reload completes from a server anim notify
Notify_ReloadWeapon finishes the reload from an animation notify on the server. The server does not reliably tick a remote client's montage, so notify-driven authority fails for clients. System Link hit this as BUG-023 (Footguns.md, GAS/animation); keep authority on a timer or RPC and use notifies for local effects only.
#The host can lose the final round of damage
For a locally controlled listen-server pawn, Local_Fire decrements ammo before Server_FireWeapon checks whether ammo is positive. Starting with one round therefore reaches the server function with zero ammo, which returns before applying damage or reporting the shot. Include this exact host/client case in any reuse test. [D5, D6]
#Statistics contain edge cases
AddSequentialElim decrements every lower sequence bucket when a sequence grows. After a completed double kill, a later sequence that reaches four kills decrements the double bucket at both its third and fourth kills, erasing the earlier double. Track the current sequence separately, then finalize its size once. [D3]
UpdateHighestStreak is called only after the five-kill streak threshold is reached, so a player's best run of one to four kills remains zero. Highest streak and award eligibility need independent updates. Also, ChangeHealthByAmount returns lethal whenever the resulting health is zero, even when death has already begun; suppress repeated elimination processing at the death boundary. [D2, D9]
#Presentation assumes complete data and one viewport
Medal lookup uses ensure followed by dereferencing the data asset and FindChecked. Missing configuration can therefore still fail. It mutates entries in the shared medal data asset with per-event counts. The native code creates medal widgets but does not remove them; any removal behavior depends on absent Blueprint assets. The Lost the Lead path bypasses the queue. Add safe lookups, immutable event data, explicit lifetime cleanup, and consistent scheduling. [D3]
#Some helpers need defensive checks
AddAmmo inserts a new ammo category with the supplied amount and then adds the same amount again, doubling the first grant. The respawn helper uses ensure for an empty PlayerStart list but proceeds to choose and index a start. These are small examples of why copying whole helpers without review is risky. [D5, D9]
#Source and asset permissions
The checked-out source carries Copyright Druid Mechanics, and the tracked file list contains no license file. Commercial copying and redistribution rights are therefore not established by this checkout. Confirm the applicable course/source terms before incorporating source, and check any separately obtained art or audio on its own terms. This report recommends designs to adapt and does not assert a license grant.
<!-- pagebreak -->
#Proposed implementation sequence
#First establish authoritative scoring
Define a minimal elimination record and process it once per death. Add replicated kills and deaths to the existing PlayerState and a match-state owner for first blood and leaders. Cover self-kills, environmental deaths, and the selected team/betrayal rules. Initialize score widgets from replicated state, with change delegates for subsequent updates. This is the foundation; a medal popup alone does not establish reliable scoring.
#Then add three medal rules and a local queue
Implement Double Kill, Revenge, and Streak Stopped against confirmed elimination records. Create System Link medal definitions with text, icon, priority, and duration. Extend the HUD with a queue or dedicated medal container, keeping each local player's messages separate. Clear transient presentation on travel and explicitly reset match/life rule state at the appropriate boundaries.
#Extend into match results and session history
Add lead changes and first blood after score/tie behavior is settled. Implement score/time limits and a final results snapshot with the match-flow work already planned. Persist a compact completed-match record later, so multi-match evenings can accumulate history without depending on living pawns or UI widgets. Separate gameplay score from recognition: earning multiple medals for one kill should not accidentally award multiple Slayer points.
#Verification that would make the adaptation credible
| Scenario | Expected result |
|---|---|
| Bullet, melee, grenade and teleporter kill | One death and the correct credited player |
| Shotgun pellets or duplicate lethal callbacks | One elimination regardless of callback count |
| Double then four kills in a separate sequence | Earlier double remains in match statistics |
| Revenge, respawn and disconnect | Relationship rules are explicit and do not use stale pawns |
| Host and remote client fire their last round | Both shots apply damage and consume one round |
| Late join or HUD reconstruction | Current scores appear without replaying old RPCs |
| Two local players earn medals together | Each notification stays in its own player region |
| Medal burst alongside a pickup prompt | Chosen priority is respected; no accidental replacement |
| Tie, leader disconnect and new match | Leaders update; match-local awards reset |
| Travel, HUD removal or missing medal entry | Timers clean up and missing data fails gracefully |
Run pure rule tests for timing, sequence accounting, ties, and duplicate deaths. Verify the integration in listen-server play with two clients and local split-screen, including simulated latency. Add a dedicated-server pass if that becomes a supported target; source branches mentioning dedicated servers are not proof that animation-driven behavior works there.
The recommended next task is a short scoring-and-medals design specification tied to the existing multiplayer plan. Keep the current map-selection work as the active priority and schedule implementation with match rules.
<!-- pagebreak -->
#Evidence index
Course paths below are relative to C:\3D-DEV\UE5_MultiplayerFPS\UE5_Multiplayer_FPS. D2 through D9 paths start in Source/FPS/. Line numbers refer to the reviewed checkout.
- D1 —
FPS.uproject:3,Source/FPS/FPS.Build.cs,.gitignore,Config/DefaultEngine.ini:4, and the tracked-file inventory at commit1e585ff. Establishes engine selection, module dependencies, excluded content, and absent map dependency.
- D2 —
Private/Elimination/EliminationComponent.cpp:14and:24, plusPublic/ShooterTypes/ShooterTypes.h:58. Medal types, timing, streak logic, revenge, and leader events.
- D3 —
Public/Player/ShooterPlayerState.h:64;Private/Player/ShooterPlayerState.cpp:55,:155,:160,:189,:209,:232;Public/Data/SpecialElimData.h:12;Private/UI/Elims/ScoreWidget.cpp:10;Private/UI/Elims/SpecialElim.cpp:22. Statistics, RPC score updates, queue, asset mutation, and viewport placement.
- D4 —
Private/Game/ShooterGameStateBase.cpp:18andPublic/Game/ShooterGameStateBase.h:23. Leader sorting, ties, first-blood state, and non-replicated leader storage.
- D5 —
Private/Combat/CombatComponent.cpp:92,:115,:144,:163,:235,:293. Inventory indexing, reload/ammo logic, client trace submission, and server damage processing.
- D6 —
Private/Weapon/Weapon.cpp:97,:138,:153,:158,:174. Trace, local ammo deduction, acknowledgements, and mesh visibility.
- D7 —
Private/UI/ShooterReticle.cpp:69,:91andPrivate/UI/ReserveAmmo.cpp:46. Reticle interpolation and possession rebinding.
- D8 —
Private/Character/ShooterCharacter.cpp:83,:126,:184,:299,:325. Server report binding, turn-in-place, hand-space conversion, damage, and death.
- D9 —
Private/Health/HealthComponent.cpp:31andPrivate/Game/ShooterGameModeBase.cpp:10. Lethal return semantics and random respawn selection.
System Link paths are relative to C:\3D-DEV\HaloProject\SystemLink5.7\SystemLink. Native paths below start in Plugins/SystemLinkCore/Source/SystemLinkCore/. Baseline commit was f29bca1b on lobby-map-select, with existing local changes.
- S1 —
Docs/SystemLinkVision.md,Docs/MultiplayerPlan.md,Docs/SuccessCriteria.md,Docs/CurrentFocus.md,Docs/KanbanBoard/cards.json. Product fit, planned scoring, and current queue.
- S2 —
Public/Player/SLPlayerState.handPrivate/Game/SLGameModeBase.cpp. Current state ownership and respawn implementation.
- S3 —
Private/AbilitySystem/Attributes/SLHealthAttributeSet.cpp:52,Private/AbilitySystem/Abilities/SLGameplayAbility_Death.cpp:63, andPrivate/AbilitySystem/Executions/SLDamageExecution.cpp:34. Existing death boundary, context, and shield-aware damage.
- S4 —
Public/UI/SLNotificationWidget.h,Private/UI/SLHUDWidget.cpp:339and:370,Private/UI/SLPlayerHUD.cpp:101. Notification replacement and per-player layout.
- S5 —
Private/Game/SLLobbyGameState.cpp,Private/Online/SLSessionService_LAN.cpp,Public/UI/SLMapSelectWidget.h,Public/Settings/SLPlayerProfileSubsystem.h. Existing lobby, sessions, map-selection work, and profile support.
- S6 —
Private/AbilitySystem/Abilities/SLGameplayAbility_Fire.cpp:202and:541,Private/Weapons/SLWeaponActor.cpp:14,Private/Weapons/SLWeaponsComponent.cpp:931. Ammo effects/replication and server shot retracing.
- S7 —
Public/UI/SLReticle.handPublic/UI/SLHUDWidget.h. Reticle events, caching, and state seeding.
- S8 —
Private/Character/SLCharacterBase.cpp:962, weapon view drivers underPrivate/Weapons/ViewDrivers/, andDocs/LeftHandIK.md. Existing per-view hand targets.
E1 — Epic Games documentation on asset and package versioning, consulted 7 October 2026. Supports the newer-asset/older-engine compatibility constraint.