Understanding the Code Behind the FPS Template

I’ve been poking around recent Roblox templates so I can study how professionals organize their code and after pokeing around for a couple hours, I have a few questions:

  1. No matter how hard I looked, I could not find where they used UserInputService to tell their code to run some shoot function when pressing M1. My only hint is that it has something to do with the ManualActivationOnly property, as it gets toggled off when the game detects mobile controls in the TouchInputController module script. The same goes for the enable and disable functions. When are those ran?

  2. I noticed how they used an unreliable remote event called ReplicateShot, which seems to be called when the server validates the shots fired by the player and displays the relevant information on screen (the hit sound, the hit marker, etc.). Why is this an unreliable remote event instead of a regular event? I would think it’s to make things go faster, but the ReplicateShot remote already gets bottlenecked by the initial remote event that gets fired when the client requests that a shot be validated by the server (since it’s a regular remote event). Also isn’t it kinda important to communicate to the player that their shots successfully hit someone? Why risk it being dropped in the first place?

  3. The way the Roblox Dev Team decided to optimize the client-server calls when validating shots is pretty cool, but why is it able to work? In case you don’t know, Roblox optimized their shot interactions by only sending the data needed to do basic validation checks (the player and the gun instances) alongside data needed to reproduce the shot’s raycasts from the server (the IDs of who supposedly got hit, where the shots where shot from, and the Random Seed value used to calculate the shot’s spread) instead of cramming the entire RayCastResults object into the remote event’s parameters. The only problem with this is the fact that it takes time for the data packet to be sent from the Client to Roblox’s servers, and people could have moved from their original positions in between this downtime. How does Roblox’s Dev Team account for this? Originally, I thought the server used the time it took for the packet to send and the player’s move speed to make a “safe area” of sorts around each potentially hit player, but that’s not how it was implemented at all. How do they account for player lag?

And those are the big 3ish questions I had after looking over things. Thanks for reading all the way through :slight_smile:

1 Like

UserInputService is not used to detect when the blasters should start or stop firing.
image
image

An UnreliableRemoteEvent is used to replicate bullets as the number of bullets fired can be fired in great succession. Bullet replication is purely audio-visual, so it’s okay if some are lost. Just because the RemoteEvent is “unreliable” doesn’t mean you’re losing packets left right and centre

Would love to see which template you’re referencing directly so I don’t have to look for it :joy:. I’ll use your explaination for this.

  1. #1, are they using tools? Tools have a .Activated() property. Maybe they’re using this? Tool | Documentation - Roblox Creator Hub

This event fires when the player clicks while the Tool is equipped. It is not fired if the Ctrl key is pressed during the click.

  1. I can’t say for sure without looking at the reference, but an educated guess is tht it’s not necessarily about making things “go faster”, there’s more to it than that. Reliable RemoteEvents guarantee that every packet is delivered in order. While this is great for important data (like shot validation), it introduces overhead. If every hit effect and sound was bundled into this validation RemoteEvent, it would increase the workload for the server. So basically, more data = higher network usage = slower response time for critical game mechanics. By separating the two (validation in a reliable event, VFX in an unreliable event), you prevent non-critical data (VFX) from slowing down the actual gameplay logic.
  2. Again, entirely taking your word for it here lol. I would guess that ROBLOX did this for 2 main reasons. Number one being that if the server just checked for the player’s current position at the time of validation, shots may appear that they “missed” the player, when they should have hit. Number two being that if the server fully strsuted the client’s hit results, it could lead to cheaters being able to exploit this. So, instead of trusting the client’s RayCastResult (which could be exploited), the server reconstructs the shot using those arguments that you mentioned. Whilst some games do introduce a “safe zone” giving leeway around the shot fire and validation, it has to be balanced carefully as some players may get an unfair advantage from abusing the lag compensation. All in all, trusting the client would allow hackers to fake hits. Instead, Roblox only accepts basic shot data from the client and re-runs the hit detection itself.

Hope this helps :slightly_smiling_face:

I’m making a gun system too, the unreliable remote event is for bullet client replication I must assume

This is such good stuff – exactly what you should be doing to learn new concepts. I’ve broken down all of the Roblox templates, and they are all masterpieces of traditional and outside-the-box thinking. The only time I’ve ever seen anything a bit shaky is in areas that do not impact the game, other than visually. There are two types of programming: direct and trickery. Roblox is very good at both. Make sure you keep that in mind as you look over the scripts.