kieran Posted February 14, 2018 Share Posted February 14, 2018 (edited) So I've finally found the amazing dxscoreboard resource made by Awwu and can add rows by just setting players element data, but I am wondering if there's a less CPU intensive way to update the scoreboard as I am constantly setting clients data when they render, code is below (tested for one player only). exports.scoreboard:scoreboardAddColumn( "Wanted", 45 ) exports.scoreboard:scoreboardAddColumn( "Money", 55 ) function ScoreBoardWanted(thePlayer) for _,player in ipairs(getElementsByType("player")) do setElementData ( player, "Wanted", getPlayerWantedLevel ( ) ) setElementData ( player, "Money", getPlayerMoney ( ) ) end end addEventHandler("onClientRender", getRootElement(), ScoreBoardWanted) I noticed a lot of servers that use this panel now as it's easy, but I have noticed a change in FPS (5-15 loss) using it and I'm just curious if there's a less intensive way. As always, any help/info would be nice, thanks. Edited February 14, 2018 by kieran Link to comment
iMr.WiFi..! Posted February 14, 2018 Share Posted February 14, 2018 Hello, There are you: exports.scoreboard:scoreboardAddColumn( "Wanted", 45 ) exports.scoreboard:scoreboardAddColumn( "Money", 55 ) function ScoreBoardWanted( DataName ) if ( DataName == "Wanted" ) or ( DataName == "Money" ) then if ( getElementType( source ) == "player" ) then setElementData ( source, "Wanted", getPlayerWantedLevel ( ) ) setElementData ( source, "Money", getPlayerMoney ( ) ) end end end addEventHandler("onClientElementDataChange", getRootElement(), ScoreBoardWanted) If that helps you tell me! or put thanks to make it easier. 1 Link to comment
kieran Posted February 14, 2018 Author Share Posted February 14, 2018 11 hours ago, iMr.WiFi..! said: Hello, There are you: exports.scoreboard:scoreboardAddColumn( "Wanted", 45 ) exports.scoreboard:scoreboardAddColumn( "Money", 55 ) function ScoreBoardWanted( DataName ) if ( DataName == "Wanted" ) or ( DataName == "Money" ) then if ( getElementType( source ) == "player" ) then setElementData ( source, "Wanted", getPlayerWantedLevel ( ) ) setElementData ( source, "Money", getPlayerMoney ( ) ) end end end addEventHandler("onClientElementDataChange", getRootElement(), ScoreBoardWanted) If that helps you tell me! or put thanks to make it easier. Thanks, helps a lot! Link to comment
kieran Posted February 14, 2018 Author Share Posted February 14, 2018 (edited) Sorry but doesn't actually work, the problem is..... I don't want to get when the players data changes, I do want to get when their money/wanted level changes. The reason I use setElementData is because this resource uses onClientElementDataChage or something similar to update the scoreboard, this is why is uses setElementData (I think), so far onClientRender is the only thing that keeps it updated, is there something to detect when money/wanted level changes? Thanks again. Edited February 14, 2018 by kieran Link to comment
NeXuS™ Posted February 14, 2018 Share Posted February 14, 2018 The only way you could do it is addDebugHook, but it may degrade script performance. 1 Link to comment
Moderators IIYAMA Posted February 15, 2018 Moderators Share Posted February 15, 2018 Isn't your network getting :Oed up? You might want to do: /shownetstat while running this with multiple players. Which is also possible for causing the frame/cpu lagg. Link to comment
kieran Posted February 16, 2018 Author Share Posted February 16, 2018 (edited) 13 hours ago, IIYAMA said: Isn't your network getting :Oed up? You might want to do: /shownetstat while running this with multiple players. Which is also possible for causing the frame/cpu lagg. It is :Oing up ... As it is setting element data when player renders, the point of creating this topic was hopefully to limit the players rendering so the element data isn't so much... But I am not used to using a script with exports or anything, I can't think of any way to add delays, the setElementData is only for the column in the scoreboard, that's all it effects, I have noticed even more FPS drops as today I added play time to scoreboard which uses getTickCount. Bear with me here because I am confusing myself, but I believe that I can't use onClientElementDataChange as no data is being changed until I setElementData to update the scoreboard from the dxscoreboard resource, I believe it uses onClientElementDataChange and this is how it sets the columns text in the scoreboard, but I am not entirely sure.... The frame rate is the same on most servers as this resource is now famous across the MTA community, having its own wiki page and everything, replacing the old one for good on professional (well scripted, active) servers, so this topic was an attempt to find an answer on how to solve the FPS drops, and I believe the issue lays within the real time updating for money/teams/play time, so I came to the conclusion most servers must use onClientRender as it's the easiest way, so if there's an answer to this problem it might help some other servers/developers using this scoreboard. Bear in mind my server is purely for testing scripts (so 5 players max), rolling out stuff that's helpful on the community or resources other developers can build on, small simple resources, but tricky and confusing at the same time to try save them the headache of doing something from scratch, I don't know if there's a solution but the following code is my full scoreboard (well the exports). exports.scoreboard:scoreboardAddColumn( "Wanted", 43 ) --Wanted string here exports.scoreboard:scoreboardAddColumn( "Money", 55 ) exports.scoreboard:scoreboardAddColumn( "Play Time", 55 ) function ScoreBoard(thePlayer) for _,player in ipairs(getElementsByType("player")) do setElementData ( player, "Wanted", getPlayerWantedLevel ( ) ) --Updates wanted string by getting players wanted level setElementData ( player, "Money", getPlayerMoney ( ) ) --Updates "Money" by getting players money end --play time if not savedTime then savedTime = getTickCount () --Store the system tick count, this will be 0 for us end currentCount = getTickCount () local secs = currentCount - savedTime local mins = getElementData ( localPlayer, "PlayTimeMin" ) local hours = getElementData ( localPlayer, "PlayTimeHour" ) secs = math.floor(secs/1000) --Convert MS to seconds, and round to closest whole number if hours == false then --If it got boolean from hour/min set them to 0 as they'd be false setElementData( localPlayer, "PlayTimeHour", 0 ) end if mins == false then setElementData ( localPlayer, "PlayTimeMin", 0 ) end if secs >= 60 then --Every 60 secs add a minute to players data setElementData ( localPlayer, "PlayTimeMin", (getElementData ( localPlayer, "PlayTimeMin" ) or 0) + 1 ) savedTime = false --Set saved time to false so it starts counting secs from 0 again end if mins > 60 then --If minutes over 60, add a hour to players data and set their mins to 0 setElementData ( localPlayer, "PlayTimeHour", (getElementData ( localPlayer, "PlayTimeHour" ) or 0) + 1 ) setElementData ( localPlayer, "PlayTimeMin", 0 ) if string.len(hours) == 1 then --If hours are less than 9 add 0 plus the number setElementData ( localPlayer, "Play Time", '0'..hours..':'..mins ) else --Else just add the number setElementData ( localPlayer, "Play Time", hours..':'..mins ) end elseif mins < 60 then --If minutes are under 60 then add a minute to players data if string.len(mins) == 1 then if string.len(hours) == 1 then --If hours are less than 9 add 0 plus the number setElementData ( localPlayer, "Play Time", '0'..hours..':0'..mins ) else --Else just add the number setElementData ( localPlayer, "Play Time", hours..':0'..mins ) end else if string.len(hours) == 1 then setElementData ( localPlayer, "Play Time", '0'..hours..':'..mins ) else setElementData ( localPlayer, "Play Time", hours..':'..mins ) end end end end function addRender() addEventHandler("onClientRender", getRootElement(), ScoreBoard) end addEvent("addScoreboardRender", true) addEventHandler("addScoreboardRender", root, addRender) Confusing, but it works..... for rendering mins/hours can be moved outside the function and made global, then be updated when the event handler is added (on login) hope it helps you understand what I'm doing, I have potato PC btw, so it's why my FPS is so low, but hey, I can at least make stuff playable for other potato PCs. Thanks for help, but guess this is just the way of the potato. Edited February 16, 2018 by kieran Link to comment
iMr.WiFi..! Posted February 16, 2018 Share Posted February 16, 2018 On 2/14/2018 at 22:36, kieran said: Sorry but doesn't actually work, the problem is..... I don't want to get when the players data changes, . The reason I use setElementData is because this resource uses onClientElementDataChage or something similar to update the scoreboard, this is why is uses setElementData (I think), so far onClientRender is the only thing that keeps it updated, is there something to detect when money/wanted level changes? Thanks again. Dude, did you even read event name? it's When Element Data Change! That's mean what do you want: On 2/14/2018 at 22:36, kieran said: I do want to get when their money/wanted level changes and the only thing can detect when money/wanted level changes is "onClientElementDataChange" by setElementData! Link to comment
Moderators IIYAMA Posted February 16, 2018 Moderators Share Posted February 16, 2018 On the brick of annihilation: bool setElementData ( element theElement, string key, var value [, bool synchronize = true ] ) Put it to FALSE setElementData ( theElement, key, value, false ) 1 Link to comment
kieran Posted February 16, 2018 Author Share Posted February 16, 2018 9 hours ago, iMr.WiFi..! said: and the only thing can detect when money/wanted level changes is "onClientElementDataChange" by setElementData! I've tried and that doesn't work for players money changing, anyway, like an idiot I forgot you could make data so it's only client side, so useful reminder from IIYAMA. Thanks all for help. 1 Link to comment
Antix Posted February 16, 2018 Share Posted February 16, 2018 This functions constantly loops through all players every frame, which is extremly excessive. You could limit the looping to every 500 ms like this: local lastDataSet = 0 local dataSetCooldown = 500 -- in ms exports.scoreboard:scoreboardAddColumn( "Wanted", 45 ) exports.scoreboard:scoreboardAddColumn( "Money", 55 ) function ScoreBoardWanted(thePlayer) -- if getTickCount is smaller than the last time we set the elementdata, return false, else loop through all players and set the cooldown if ( getTickCount( ) < lastDataSet + dataSetCooldown ) then return false end for _,player in ipairs( getElementsByType("player") ) do setElementData ( player, "Wanted", getPlayerWantedLevel ( ) ) setElementData ( player, "Money", getPlayerMoney ( ) ) end lastDataSet = getTickCount( ) end 1 Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now