Jump to content

Spawning players is hell in my server


jkub

Recommended Posts

I have 2 scripts that handle spawns for players when they join my server. A login GUI and another GUI that lets you select your spawn location. Half the time the actual spawning works and other times not. Often when players select a spawn location and press the spawn button the player is either spawned "falling" under the middle of the map or they don't spawn at all. Then I get a infinite running script flooding my debug and it causes a tremendous FPS drop for most if not all clients. Probably bogs the server too.

If I try to loop the code to make sure it spawns the player it still becomes inaffective at times and does not spawn the player and of course causes an infinite loop which will soon be aborted. If I run a simple check to see if the player is not in the middle of the map then it still dont work.

Sometimes players even report black non manipulative screens

function server_SpawnClient ( x, y, z, rot, skin, interior, dimension, team )
setTimer ( spawnPlayer, 1000, 1, client, x, y, z, rot, skin, interior, dimension, team )
--spawnPlayer ( client, x, y, z, rot, skin, interior, dimension, team )
setTimer ( setCameraTarget, 1000, 1, client, client )
fadeCamera ( client, false, 1.0, 0, 0, 0 )
setTimer ( fadeCamera, 2000, 1, client, true, 3.0 )
triggerClientEvent ( client, "playerSpawnedComplete", client )
local cX, cY, cZ = getElementPosition ( client )
if cX == 0 and cY == 0 and cZ == 0 then
	server_SpawnClient()
end
end

EDIT: One other related problem I have is that a specific player in my server says that when he logs in, not only can he not spawn correctly, but his ping sky rockets.

There are 2 main ways to spawn in my server upon joining.

1. Login_Gui (If you do not log in or register, there is a button you can click that says "play as guest" which spawns you at the LV airport)

2. Spawn GUI. This is the script that handles the spawns for any player who either logs in or registers. This is where I think the most of the problem may be coming from, however I call events from the login_gui script and the events get answered in this script.

Link to comment

You explained what your problem is, you know what is causing it then why did you ask us here if you know everything you need to know to fix it yourself?

BTW, never ever check if coords are equal to some specific number, like if x == 0 and y == 0 and z == 0 then because they will never be equal to 0. Basically, never compare float numbers.

Link to comment

Well Thanks but I explained actually where my problem might be. I just don't see whats wrong with it, other then the fact that you explained that I shouldn't compare floats.

I have always had this same exact problem with any spawn script I have made.

I guess I will change my float comparison thing and get back.

Link to comment

We don't know much about your problem without more code... You just showed a little piece of code that spawns player after 1 sec., fades camera in/out and triggers client event. I even wondered why you checked if player is at 0,0,0 before he was spawned. Also, why do you set a timer? You can spawn the player and fade camera in at the same time. Besides, you don't need your arguments in your fadeCamera (line 5) apart from client and false because rest of your arguments are the same as default parameter values.

Don't forget to debug your script.

Link to comment

The fade camera functions are obviously for pure aesthetic purposes because I didn't like the plain old spawn. I use a timer for spawn player because I don't want the player spawning until the screen is completely black from the fade camera function. Then when the player is spawned, the camera fades back in. My reason for checking the players position as 0, 0, 0 is my asnine way of checking if the player is spawned or not, the significance behind that is that, after I call my spawnPlayer I wanted to make sure the player still was not stuck in the middle of the map falling.

I later discovered the isPedOnGround which in turn didn't really help. I even tried looking into the play script for how it spawns its players. To my discovery it uses a "repeat" loop which seems to work every time. I tried using the same exact method and it is just affective as my other methods, it even has the occasional infinite running script error to where it bogs down the server and clients in the process.

Here is a shitload of code from client side.

function spawnClick ( button ) 
if button == "left" then
if source == spawnButton then
local row, col = guiGridListGetSelectedItem ( spawnList )
if row == -1 then
outputChatBox ( "*You have to select a location to spawn first!", 255, 0, 0 )
else
if row == location1 then
				spawnX = 1130.0665 + math.random ( 1, 3 )
				spawnY = -1488.45678
				spawnZ = 22.76903
				rot = 0
elseif row == location2 then
				spawnX = -1757.7215 + math.random ( 1, 3 )
				spawnY = 957.9381
				spawnZ = 24.8828
				rot = 180
elseif row == location2b then
				spawnX = 2223.3437
				spawnY = -1160.2365
				spawnZ = 26
				rot = 0
elseif row == location2c then
				spawnX = 2512.5363
				spawnY = -1673.1607
				spawnZ = 13.4983
				rot = 74
elseif row == doherty then
				spawnX = -2023.8781
				spawnY = 156.6600
				spawnZ = 29
				rot = 270
elseif row == batteryPoint then
				spawnX = -2631.9372
				spawnY = 1381.6345
				spawnZ = 7.1704
				rot = 180
elseif row == location3 then
				spawnX = 2028.0147
				spawnY = 1916.1400 + math.random ( 1, 3 )
				spawnZ = 12.3284
				rot = 260
elseif row == lastResort then
				spawnX = 2368.5908 
				spawnY = 1660.3601 
				spawnZ = 11
				rot = 270
elseif row == highRoller then
				spawnX = 1955.9962 
				spawnY = 1342.9613 
				spawnZ = 16
				rot = 270
end
			skin = math.random ( 0, 288 )
			interior = 0
			dimension = 0
team = user_Team
triggerServerEvent ( "spawnWindow_SpawnPlayer", getLocalPlayer(), spawnX, spawnY, spawnZ, rot, skin, interior, dimension, team )
end
elseif source == spawnList then
local row, col = guiGridListGetSelectedItem ( spawnList )
if row == -1 then
--no row was selected
else
if row == location1 then
setCameraMatrix ( 1170.7250, -1481.7625, 30.4994, 1131.1616, -1495.6624, 22.7690 )
elseif row == location2 then
setCameraMatrix ( -1736.7707, 959.3780, 24.8828, -1838.4617, 906.7504, 49.3268 )
elseif row == location2b then
setCameraMatrix ( 2193.6376, -1108.1195, 24.8521, 2205.5949, -1138.3500, 34.2421 )
elseif row == location2c then
setCameraMatrix ( 2442.3122, -1655.8826, 27.9151, 2510.4106, -1676.0703, 13.5468 )
elseif row == location3 then
setCameraMatrix ( 2132.0070, 1945.4909, 10.6828, 1979.1539, 1916.1916, 95.1458 )
elseif row == doherty then
setCameraMatrix ( -2015.3387, 184.3074, 27.6875, -2034.9644, 166.5152, 30.9673 )
elseif row == batteryPoint then
setCameraMatrix ( -2580.9016, 1359.5323, 15.3211, -2614.8896, 1381.2315, 12.5663 )
elseif row == lastResort then
setCameraMatrix ( 2397.0244, 1663.3498, 16.6667, 2367.6035, 1652.3618, 10.8203 )
elseif row == highRoller then
setCameraMatrix ( 2036.9645, 1343.3657, 10.8203, 2010.3544, 1343.3742, 11.9886 )
end
end
end
end
end

The idea behind all these arguments for setCameraMatrix is not only for aesthetic purposes but I also try to make the code load the area where the player wants to spawn into memory so it won't take as long, or they have less chance of falling through an LOD map.

Here is my current code for server.

addEvent ( "spawnWindow_SpawnPlayer", true )
 
function server_SpawnClient ( x, y, z, rot, skin, interior, dimension, team )
setTimer ( spawnPlayer, 1000, 1, client, x, y, z, rot, skin, interior, dimension, team )
setTimer ( setCameraTarget, 1000, 1, client, client )
fadeCamera ( client, false, 1.0, 0, 0, 0 )
setTimer ( fadeCamera, 2000, 1, client, true, 3.0 )
triggerClientEvent ( client, "playerSpawnedComplete", client )
end
 
addEventHandler ( "spawnWindow_SpawnPlayer", getRootElement(), server_SpawnClient )

Link to comment

Sorry, if I missed something, but who is "client" in your serverside script?

Is that supposed to be "source"?

"client" is never given to the function, so I would wonder, why it would even spawn you once.

But apart from that I would advise you to use tables. That would make the repeated elseif's unnecessary, since the script would get the respective data from a table using the row as index.

That would definitely shorten your script to at least the half and would make it more readable and dynamic.

But that's optional and just a tip ;)

Link to comment

Okay, but I don't see, where you declare the 'client' variable.

You don't pass on an argument called 'client' and there seems to be no global 'client' variable in existence.

Do you actually mean 'source', which would be the cause of the event triggering, hence the player, who needs to be spawned?

You could do it like this:

locations = 
{
{spawnX = 1000.0, spawnY = 500.0, spawnZ = 10.0, spawnRot = 90.0}, -- location 1
{spawnX = 2000.0, spawnY = -100.0, spawnZ = 18.0, spawnRot = 270.0}, -- location 2
{spawnX = -600.0, spawnY = -450.0, spawnZ = 53.0, spawnRot = 0.0}, -- location 3
-- and so on...
}
 
function spawnClick (button)
-- some code...
local row, col = guiGridListGetSelectedItem ( spawnList )
if row ~= -1 then -- if player selected an item
triggerServerEvent ( "spawnWindow_SpawnPlayer", getLocalPlayer(), locations[row].spawnX, locations[row].spawnY, locations[row].spawnZ, locations[row].spawnRot, skin, interior, dimension, team )
end
end

That's just a simplified code and example, but you should get the idea.

Link to comment

@MaddDogg

Read more about addEventHandler, please.

@jkub

I would suggest you use table but have it in server-side script instead of client-side because if client will hack your script somehow he'll be able to change the coords to whatever value he wants therefore spawn anywhere. Then just triggerServerEvent with the "id" (row number) of the selected spawn location.

I wonder why you don't know anything about tables yet. Anyway, as MaddDogg said, you could use row id to identify spawn location in a table, something like this:

local spawnLocations = {
{ 1234.5678, 1.58,     10, 0 }, -- table 1: x, y, z, rotation
{ 123.5678,  14.5678,  11, 0 }, -- table 2: x, y, z, rotation
{ 12.5678,   134.57,   12, 0 }, -- etc.
{ 1.5678,    1234.568, 13, 0 }, -- etc.
};
-- this table has a set of tables of spawn coords which you can use easily
-- lets say selectedRow will be 2:
selectedRow = 2; -- you send row id with triggerServerEvent and use it instead of the 2
 
-- this will take data from table #2 from the spawnLocations table above
x = spawnLocations[ selectedRow ][ 1 ]; -- x of selected spawn location (123.567)
y = spawnLocations[ selectedRow ][ 2 ]; -- y ... (14.5678)
z = spawnLocations[ selectedRow ][ 3 ]; -- z ... (11)
r = spawnLocations[ selectedRow ][ 4 ]; -- rotation ... (0)
-- You can assign the values from table to a variable if you don't want your spawnPlayer function to be very long

But still, I don't see any problem with your script... What is your client-side event "playerSpawnedComplete" for? May it cause any problems? Show us.

Link to comment

Thanks 50p and MaddDogg. Putting the coords in a table was a really good idea.

The "playerSpawnedComplete" is for closing the GUI and hiding the cursor. It also is used to trigger a function from a seperate resource (My welcome window) which shows vital information, rules, etc... I put that in the server function instead of putting it clientside because I wanted to make sure the GUI does not close until the player is spawned, which obviously fails in several different languages. But I am wanting to keep it there for the sole purpose of triggering my welcome window.

I used the table for my client side setCameraMatrices because I didn't see a problem with it and I thought as well that it would make the script cleaner and reduce repeating myself.

Here is the revised part of the client script that matters

addEvent ( "loginAttempt", true )
addEvent ( "closeLoginGUI", true )
addEvent ( "playerSpawnedComplete", true )
 
cameraCoords = {
{ 1170.7250, -1481.7625, 30.4994, 1131.1616, -1495.6624, 22.7690 }, --Verona Mall
{ 2193.6376, -1108.1195, 24.8521, 2205.5949, -1138.3500, 34.2421 }, --Jefferson Motel
{ 2442.3122, -1655.8826, 27.9151, 2510.4106, -1676.0703, 13.5468 }, --Grove Street
{ -1736.7707, 959.3780, 24.8828, -1838.4617, 906.7504, 49.3268 }, --Financial District Hotel 
{ -2015.3387, 184.3074, 27.6875, -2034.9644, 166.5152, 30.9673 }, --Doherty Garage
{ -2580.9016, 1359.5323, 15.3211, -2614.8896, 1381.2315, 12.5663 }, --Jizzy's Pleasure Domes
{ 2132.0070, 1945.4909, 10.6828, 1979.1539, 1916.1916, 95.1458 }, --The Visage
{ 2397.0244, 1663.3498, 16.6667, 2367.6035, 1652.3618, 10.8203 }, --Last Resort Motel
{ 2036.9645, 1343.3657, 10.8203, 2010.3544, 1343.3742, 11.9886 } --The High Roller
}
 
function spawnClick ( button ) 
if button == "left" then
if source == spawnButton then
local row, col = guiGridListGetSelectedItem ( spawnList )
if row == -1 then
outputChatBox ( "*You have to select a location to spawn first!", 255, 0, 0 )
else
if isTransferBoxActive() == false then
				skin = math.random ( 0, 288 )
				interior = 0
				dimension = 0
team = user_Team
triggerServerEvent ( "spawnWindow_SpawnPlayer", getLocalPlayer(), row, skin, interior, dimension, team )
else
outputChatBox ( "*For stability/safety reasons, you need to wait for the resources to finish downloading before you spawn*", 255, 175, 0 )
end
end
elseif source == spawnList then
local row, col = guiGridListGetSelectedItem ( spawnList )
if row == -1 then
--no row was selected
else
			x = cameraCoords[ row + 1 ][ 1 ]
			y = cameraCoords[ row + 1 ][ 2 ]
			z = cameraCoords[ row + 1 ][ 3 ]
			lookX = cameraCoords[ row + 1 ][ 4 ]
			lookY = cameraCoords[ row + 1 ][ 5 ]
			lookZ = cameraCoords[ row + 1 ][ 6 ]
setCameraMatrix ( x, y, z, lookX, lookY, lookZ )
end
end
end
end
 
function openSpawnWindow ( success )
if success == true then
guiSetVisible ( spawnWindow, true )
showCursor ( true )
end
end
 
function openSpawnWindowOnRegister()
guiSetVisible ( spawnWindow, true )
showCursor ( true )
end
 
function closeSpawnWindow()
guiSetVisible ( spawnWindow, false )
showCursor ( false )
end
 
addEventHandler ( "loginAttempt", getRootElement(), openSpawnWindow )
addEventHandler ( "closeLoginGUI", getRootElement(), openSpawnWindowOnRegister )
addEventHandler ( "playerSpawnedComplete", getRootElement(), closeSpawnWindow )

I had remembered from past scripts that rowIDs in a gridlist start at 0 and a table seems to start at 0. That is why I put the row + 1 in each variable. In order to sync them together<

and here is the revised server side script

addEvent ( "spawnWindow_SpawnPlayer", true )
 
local spawnLocations = {
{ 1130.0665, -1488.45678, 23, 0 }, --Verona Mall
{ 2223.3437, -1160.2365, 26, 0 }, --Jefferson Motel
{ 2512.5363, -1673.1607, 14, 74 }, --Grove Street
{ -1757.7215 , 957.9381, 25, 180 }, --Financial District Hotel
{ -2023.8781, 156.6600, 29, 270 }, --Doherty Garage
{ -2631.9372, 1381.6345, 8, 180 }, --Jizzy's Pleasure Domes
{ 2028.0147, 1916.1400, 13, 260 }, --The Visage
{ 2368.5908, 1660.3601, 11, 270 }, --Last Resort Motel
{ 1955.9962, 1342.9613, 16, 270 } --The High Roller
}
 
function server_SpawnClient ( rowID, skin, interior, dimension, team )
----
x = spawnLocations[ rowID + 1 ][ 1 ]
y = spawnLocations[ rowID + 1 ][ 2 ]
z = spawnLocations[ rowID + 1 ][ 3 ]
rot = spawnLocations[ rowID + 1 ][ 4 ]
----
setTimer ( spawnPlayer, 1000, 1, client, x, y, z, rot, skin, interior, dimension, team )
setTimer ( setCameraTarget, 1000, 1, client, client )
fadeCamera ( client, false, 1.0, 0, 0, 0 )
setTimer ( fadeCamera, 2000, 1, client, true, 3.0 )
triggerClientEvent ( client, "playerSpawnedComplete", client )
end
 
addEventHandler ( "spawnWindow_SpawnPlayer", getRootElement(), server_SpawnClient )

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...