I’ve been getting a FiveM server up and running starting with zero experience with Lua and having written only a car spawner in c# prior. It’s been a steep learning curve and we’ve been plagued with issues, primarily with fixing other people’s code. Some of the resources we’ve used are tedious but work and elements of others are just down right garbage. I accept that we are using resources written by a community of “developers” who have no experience and this is their way into coding, but seriously it amazes me what is left and is never corrected. I thought I’d throw some experience into the community to try to make a positive difference. Ok. It trying to offend anyone I’m just exhausted.
Any RP system is going to have a backend database to store player character progress. There’ll be a base table with an identifier linking all child tables together. Each resource slaps on some new functionality and you sometimes need to run sql that comes with it to create a new table. We had to do quite a bit of work to get kashacters running, even though the one we finally integrated was close to being perfect, was still missing some things. Anyway we ran the query to get the list of tables with identifier and owner columns and stuck that in the Lua table at the top of the server Lua file.I personally hate that step and found after a couple of months of dev that we hadn’t added more recent table names to that list so some info was being shared across characters. We have been fighting all sorts of performance issues, doing things like avoid repetition to be DRY and checking our thread loops timeouts aren’t killing things, moved some ESX code from server to main removeing recursive calls using set timeout calls plus a few other things. One thing I’d never really gotten around to was performance optimising the database. Now the average dude who has minimal coding experience knows very little about database theory but I’ve found a major architectural flaw in kashacters. That f’ing list of tables that is set so that when you switch characters all related assets are switched out…!!! Groan… So, let’s run a separate update statements PER table that has the steam/license code. I have 15 of these inclusive of the users table so to switch to another character a total of 30 individual update statements need to be executed, 15 to update license: to Char1: plus another 15 to change from Char2: to license:, PLUS one more to update the lastcharcter.charid, 31 individual update statements! The most expensive thing you can do is running multiple sql statements and 5 is insane in a single server callback. Heck with trewhud we found a server call to pull back stats that were already in memory for three values hitched our server to death even without the overhead of a database server to connect to.
So, what I’ve done with my system is eliminated the kashacters list of identifier tables and updated the functions to NOT loop and just run a single update statement for the identifier only on the users table. I have also assigned actual relationships between tables. MySQL is a “relational” database management system. Basic course / tutorials into database management cover how to set a relationship between tables where you pick a primary key on your root table and use that as a foreign key in child tables. A foreign key relationship is known as a “constraint” and has options on what to do if the key on the root table fails, known as UPDATE and DELETE conditions where you get to choose what to do with the foreign key in the child table. If you set them to “CASCADE” then the DBMS knows to automatically change the value in the child tables to the new value in the root table, if the root is deleted then the child tables are automatically deleted by the DBMS. Having this built into the database schema is the most efficient way to achieve these updates and you get it for free when you run a single update statement setting the identifier column if the relationship is set. Yet kashacters runs 15…
I understand that with kashacters they’ve provided a simple way to achieve this and it appears to be a good idea given that every ESX schema out their is different as each table comes bundled with resources and they don’t know what your schema already looks like. But it’s fundamentally wrong. They should have provided the information schema query to get a list of tables with identifier and owner columns, the should have pointed people to articles on how to correctly setup referential integrity with cascading update and deletes. Lua is a scripting language and binds to other libraries to interoperate with systems and is very slow compared with MySQL making decisions to do something internally. Everyone running kashacters, please do what I’ve done and remove another atrocious inefficiency from your systems.replace the Lua updates loops with relationships from the users.identifier column.
If you want to go a step further, you can reduce the number of calls from 3 (update license to char1, another update from char2 to license and the last character update) to 1. You can create a “stored procedure” on the database where you put the 3 update statements. The sproc will receive as arguments the license ( after the : ) and number of the tile clicked in the kashacters character selector UI.
The sproc will get the lastcharacter char internally (actually could be included as a sub query on an insert statement making it a set operation and even more efficient) then do the switching around server side using MySQL scripting code to setup the 2 update statements. This means from Lua you can simply make a single database call. Code run dbms server side is always extremely efficient, the biggest lag point being the connection to the database and sending queries through. A single connection is the most ideal situation you could achieve.
Whilst I’ve learned a lot about FiveM development I’m incredibly discouraged at the state of the open source modding community code. Being a developer shouldn’t be about hacking crap together as quickly as possible and throwing it out there just because it works then drive everyone else around the bend. I know people mean well but it’s so frustrating for people consuming this mess.
I hope this helps at least one server out there to clean up their system. By going through the exercise of stepping through every table it became an auditing process and I found a lot is mismatches with related column lengths and found places I could add indexes, such as vehicle plates to help add some more efficiencies.