Writing an FPS framework, part 2 (2020)

I was more talking about your common script kiddie doing Hit:FireServer(essentialy everyone in the map) than detecting the hit itself

2 Likes

Oh! Well, thanks for replying!

i cant observe the conventions of common english and grammer ;-;

1 Like

What’s your studio theme looks good on the eyes.

studio dark and a custom code editor theme i havent used for over a year now

I want to get some clarification on this. With my game, I am doing this from the client (I’m using FastCast too)

PlayerHit:FireServer(
					HitPlayer,
					result.Instance,
					result.Position,
					cast.UserData
				)

but I’m unsure what sanity checks I can use on the server, this is all I really have atm :confused:

--// Ray hit
local function Hit(player, playerHit, hitInstance, hitPosition, castData)
	if player == playerHit then return end -- Creator can't tag themselves
	
	local Teams = GameSettings:GetAttribute("Teams")
	if player.Team == playerHit.Team and Teams then return end -- Can't tag your own team
	
	local Humanoid = playerHit.Character:FindFirstChildWhichIsA("Humanoid")
	if not Humanoid then return end

so for anyone that wants to add a new offset to the system, heres how i did it after messing around with a lot of stuff in the update function:
(blackshibe approved)

first make your offset, like idle, aim, etc. in my case im making a sprint offset

next, copy the equip offset’s lines of code, so you’ll have something like this

local sprintOffset = equipOffset:Lerp(self.viewmodel.offsets.sprint.Value, self.lerpValues.sprint.Value)

but replace the “equipOffset” with the last offset you’ve added before the current one you’re writing, in my case the last one is equipOffset.

now, do this

local finalOffset = sprintOffset -- replace sprintOffset with your own

this should hopefully work, if blackshibe wants to correct anything wrong i did, hes free to, ill edit it if theres anything wrong i did, this is just how i did it myself

2 Likes

This is a really amazing tutorial! The functionality is versatile and I can add onto it with more features, and I’ve learned a lot of things, especially how metatables are useful. I’ve scrapped my old FPS project in favour of this framework tutorial and the development’s gone much better.

I haven’t really encountered problems until now, I can’t really get ammo working. I keep a realtime ammo table on the client and a secure version on the server (updates every fire/reload), but there’s an issue. Getting the ammo table from server to client isn’t working because the table becomes nil when the server returns it to the client, even though it was there when I printed it before return?

In the fire event I subtract 1 from the current ammo table on the server, then I pass that new ammo table from the server onto the FastCastHandler that fired the event. Then the FastCastHandler returns that to the client. But the table doesn’t exist when the server script returns it?

Server code below:

if weaponTable.ammoData[weaponTable.weaponIndex].current < 1 then return end
-- the statement above is not the issue, I tested it
remotes.Fire:FireAllClients(player, rawOrigin, rawDirection)
	
weaponTable.ammoData[weaponTable.weaponIndex].current -= 1
-- this line of code above works
print(weaponTable.ammoData[weaponTable.weaponIndex].current) -- this doesn't print nil?

--
-- animation code in this space
--

return weaponTable.ammoData -- It returns a nil value for some reason when the event is fired on the FastCastHandler, even though it just printed the actual table??

Code on FastCastHandler:
(isReplicated is false when fired from the client, I’m sure)

function fastcastHandler:fire(origin, direction, properties, isReplicated, repCharacter)


	local rawOrigin = origin
	local rawDirection = direction
	local ammoData
	
	--
	-- raycast code here
	--
	
	if not isReplicated then
		ammoData = replicatedStorage.WeaponRemotes.Fire:FireServer(rawOrigin, direction, id)
	end

	--
	-- blacklist code here
	--

	-- fire the caster
	local activeCast = mainCaster:Fire(origin, direction * properties.firing.range, properties.firing.velocity, castBehavior)
	activeCast.UserData = {properties = properties, id = id}
	
	print(ammoData)
	return ammoData

Code on client:

if self.ammoData[self.weaponIndex].current < 1 then return end
-- this condition works above, but doesn't work after the first shot because the new ammoData table is nil

--
-- raycast code and muzzle flash here
--

-- this is where the module breaks later because the new ammoData table from the server is nil. I don't know why
local ammoData = fastCastHandler:fire(origin, direction, self.settings, false, self.character)
self.ammoData = ammoData

I’m trying to see if I can solve this issue, but right now I’m pretty much stumped.
Thanks if you can provide any assistance.

You can’t return values to the client via RemoteEvents, and neither should you (Invoking RemoteFunctions is rather slow)

You should only synchronize the client and server ammo when reloading, otherwise it’s a bit too much for the network

1 Like

this is incredible although its been a while since i first completed this tutorial. i managed to modify it into my own thing :slight_smile:

I’m confused, how do I animate it, I do know how to use Moon Animator, but where? I have no idea at all where I’m supposed to just use the viewmodel to animate.

Oh, and how do I do a reload animation?

first you need to play the game, copy the viewmodel and then stop playing, then paste it in. if your gonna try to use blender (which i recommend doing, made my animations so much better), set the pos and orientation to 0, 0, 0. then you can animate to your hearts content.

another post because yes.

also sorry for reviving this but i thought people should know

after using this framework a lot and adding on to it, it lagged to hell when firing for more then 5 seconds auto, and i found the issue

apparently doing a for _, v in pairs() loop for the muzzle flash really bumped down performance (atleast for me, idk if it does it for anyone else)

to get around this you should just do what you do directy on the particle emitters so that they dont slow down your game. (the issue might be because i replaced the .Enabled stuff with :Emit(), dunno if that’s the issue or not)

thanks for mentioning this, I will update the test place code shortly

1 Like

Yeah sorry for reviving this but are u planning of making a 2021 (2022) version of this?

probably not, this version by itself is already fairly good for a starting coder (like me back then)

No.

I don’t plan to make another open source resource again, ever. the concepts of this tutorial still apply today even if i haven’t bothered to fully update everything to the latest.

3 Likes

Thx for answering my question!
also im having a problem that I did not have before and i really have no clue heres a video:

can you check your unequip function, something might be wrong with it. i cant really tell what the problem is