1. Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

Dismiss Notice
This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Other Don't use YAML.

Discussion in 'Tutorials' started by Rezz, May 30, 2017.

  1. Rezz

    Resource Staff Addon Developer

    Joined:
    Jan 24, 2017
    Messages:
    80
    Likes Received:
    35
    Medals:
    Unfortunately, YAML is one of the most inefficient things you can do in Skript. It may seem like a convenience -- or even a necessary enhancement -- at first glance, but the harsh reality is: no existing addon gets it right.

    Why use YAML?

    Before we dive deep into the dirty details of Skript’s disgracefully bad YAML support, let’s first understand why it’s used despite Skript’s built-in configurable options. Skript’s goal is to give absolutely anyone, regardless of prior programming knowledge, the ability to modify and customize their server. In fact, Skript’s level of entry is so low many people inevitably find themselves picking it up as their first programming language (whether or not that’s a good thing is a debate for another day). Those who eventually become comfortable with their scripting abilities then try to emulate regular Java plugins as much as possible, and this is where YAML comes to mind.

    YAML is the configuration file format officially supported by Bukkit (and its forks, like Spigot), which makes YAML an obvious choice for plugins wanting easy-to-implement and easy-to-manage configs; a majority of plugins use ‘config.yml’ as their sole means of customization. So any script author who wants to create an accurate plugin illusion would use ‘config.yml’ too, right?

    What’s wrong with YAML?

    The problem with YAML in Skript is that every addon that supports it parses YAML files every single time their syntax is used. In other words, whenever you retrieve a single value from a YAML file, ALL bytes are read, ALL values are parsed, and EVERYTHING but the specific value you were looking for is immediately thrown away. This is the exact opposite of how YAML is used by actual plugins; YAML files aren’t parsed over and over again, they’re parsed once and stored in memory -- much like Skript’s own variables.

    See for yourself:

    All three addons behave in the same way: parse the entire file, get the value, and discard everything. Again, this is the exact, polar opposite of normal plugin behavior. It’s also terrible for performance; reading a file from disk isn’t a light operation, but then also parsing its contents every single time is icing on the cake. Using YAML in any of your scripts (in its current state, at least) is a guaranteed performance cut.

    How bad is it?

    I created a simple test script to demonstrate the performance of Skript variables versus YAML files. The data speaks for itself.

    Generating 3000 random values, and retrieving 500 random values:
    [​IMG]

    Generating 2500 random values, and retrieving 2500 random values:
    [​IMG]

    The script:
    Code (Skript):
    1. #
    2. #   Variables vs. YAML Test
    3. #   -----------------------
    4. #   By: RezzedUp
    5. #   -----------------------
    6. #   Requires:
    7. #   - Skript 2.2 (functions)
    8. #   - SkUtilities (yaml & files)
    9. #
    10.  
    11. #
    12. #   Change the values below to test different scenarios.
    13. #
    14. #   PAUSE: How long the script should wait when it encounters its 'pause' state.
    15. #
    16. #   *_TESTS: The number of tests to run. This value modifies the number of unique
    17. #            values generated for 'set' tests, and how many values are randomly
    18. #            selected for 'get' tests.
    19. #
    20. #   *_PAUSE: The number of tests to run before the script should enter its 'pause' state.
    21. #            This prevents the server from crashing (because YAML is incredibly inefficient),
    22. #            but please remember that this will also increase test-time.
    23. #
    24.  
    25. options:
    26.  
    27.     PAUSE: wait 2 ticks
    28.  
    29.     SET_TESTS: 2500
    30.     SET_PAUSE: 250
    31.  
    32.     GET_TESTS: 2500
    33.     GET_PAUSE: 250
    34.  
    35. on script load:
    36.  
    37.     delete {test::*}
    38.  
    39. on script unload:
    40.  
    41.     delete {test::*}
    42.  
    43. function randomString(length: integer = 20, alphabet: string = "abcdefghijklmnopqrstuvwxyz0123456789-_") :: string:
    44.  
    45.     set {_chars::*} to {_alphabet} split at ""
    46.     set {_string} to ""
    47.  
    48.     while length of {_string} is less than {_length}:
    49.  
    50.         set {_string} to "%{_string}%%random element out of {_chars::*}%"
    51.      
    52.     return {_string}
    53.  
    54. command /test:
    55.     trigger:
    56.  
    57.         delete {test::*}
    58.      
    59.         send "&aSetting {@SET_TESTS} variables..."
    60.      
    61.         set {_var-set-start} to now
    62.         set {_var-set-iterations} to 0
    63.      
    64.         while {_var-set-iterations} is less than {@SET_TESTS}:
    65.      
    66.             set {_key} to randomString()
    67.          
    68.             {test::%{_key}%} isn't set
    69.          
    70.             set {test::%{_key}%} to {_key}
    71.          
    72.             add 1 to {_var-set-iterations}
    73.          
    74.             mod({_var-set-iterations}, {@SET_PAUSE}) is 0
    75.          
    76.             {@PAUSE}
    77.          
    78.             send "Set %{_var-set-iterations}% variables. %difference between now and {_var-set-start}% since starting."
    79.          
    80.         set {_var-set-time} to difference between now and {_var-set-start}
    81.         send "&6Variable-set test:&f %{_var-set-time}%"
    82.          
    83.         if file "test.yml" exists:
    84.             delete file "test.yml"
    85.         create file "test.yml"
    86.          
    87.         send "&aSetting {@SET_TESTS} YAML values..."
    88.          
    89.         set {_yaml-set-start} to now
    90.         set {_yaml-set-iterations} to 0
    91.      
    92.         loop {test::*}:
    93.      
    94.             set yaml value loop-index from file "test.yml" to loop-value
    95.             add 1 to {_yaml-set-iterations}
    96.          
    97.             mod({_yaml-set-iterations}, {@SET_PAUSE}) is 0
    98.          
    99.             {@PAUSE}
    100.          
    101.             send "Set %{_yaml-set-iterations}% YAML values. %difference between now and {_yaml-set-start}% since starting."
    102.          
    103.         set {_yaml-set-time} to difference between now and {_yaml-set-start}
    104.         send "&6YAML-set test: &f%{_yaml-set-time}%"
    105.      
    106.         #
    107.         #   GET TESTS
    108.         #
    109.      
    110.         send "&aTesting {@GET_TESTS} random variables"
    111.      
    112.         set {_var-get-start} to now
    113.      
    114.         loop {@GET_TESTS} times:
    115.      
    116.             set {_var-get-key} to a random element out of {test::*}
    117.             set {_var-get-value} to {test::%{_var-get-key}%}
    118.          
    119.             mod(loop-number, {@GET_PAUSE}) is 0
    120.          
    121.             {@PAUSE}
    122.      
    123.             send "Got %loop-number% values. %difference between now and {_var-get-start}% since starting."
    124.      
    125.         set {_var-get-time} to difference between now and {_var-get-start}
    126.         send "&6Variable-get test: &f%{_var-get-time}%"
    127.      
    128.         send "&aTesting {@GET_TESTS} random YAML values"
    129.      
    130.         set {_yaml-get-start} to now
    131.      
    132.         loop {@GET_TESTS} times:
    133.      
    134.             set {_yaml-get-key} to a random element out of {test::*}
    135.             set {_yaml-get-value} to yaml value {_yaml-get-key} from file "test.yml"
    136.          
    137.             mod(loop-number, {@GET_PAUSE}) is 0
    138.          
    139.             {@PAUSE}
    140.      
    141.             send "Got %loop-number% YAML values. %difference between now and {_yaml-get-start}% since starting."
    142.              
    143.         set {_yaml-get-time} to difference between now and {_yaml-get-start}
    144.         send "&6YAML-get test: &f%{_yaml-get-time}%"
    145.      
    146.         send "&f--- RESULTS: ---"
    147.         send "&bSet {@SET_TESTS} variables test:&f %{_var-set-time}%"
    148.         send "&3set {@SET_TESTS} YAML values test: &f%{_yaml-set-time}%"
    149.         send "&bGet {@GET_TESTS} variables test: &f%{_var-get-time}%"
    150.         send "&3Get {@GET_TESTS} YAML values test: &f%{_yaml-get-time}%"
    151.  

    What variables can do in seconds takes minutes in YAML. Also, notice how the tests must 'pause' every so often: YAML in Skript is so inefficient, this test will crash the server without taking breaks.

    What should be used instead?

    Use Skript’s built-in tools, like options and variables. The only legitimate use case for YAML in Skript is checking other plugins’ configs; anything else should be off limits.

    More info will be added later (work in progress).
     
    #1 Rezz, May 30, 2017
    Last edited: Jun 26, 2017
    • Like Like x 3
    • Informative Informative x 3
    • Agree Agree x 2
    • Useful Useful x 1
  2. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    I'm currently am making a guild plugin, for that I am using yml (skultilities), so I cannot use variables because I cannot store more than one information inside, maybe we can, but due to my knowledge I found yaml more comfortable for storing guild name, allies, enemies, home, chunks, members, moderator and master.

    Though this might be troublesome for me in the future, if I have too many players on my server.

    Anyways, thanks for sharing this with us. Good thing to know!
     
    • Like Like x 1
  3. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Can't you use this?

    {guilds::GUILDNAME::allies::*}
    {guilds::GUILDNAME::enemies::*}
    {guilds::GUILDNAME::homes::*}
    {guilds::GUILDNAME::chunks::*}
    {guilds::GUILDNAME::master::*}
    {guilds::GUILDNAME::mods::*}
    {guilds::GUILDNAME::member::*}

    I made a mail system for my server that stores like this:

    {mail::MAILOWNER::MAILSENDER::MESSAGE}

    So the players can receive up to 4 messages from another player (this cap I made to avoid spam and to don't let the variable get too big.

    Here is the code if you want to take a look, but it's in portuguese (the messages), but the idea you can get from it:

    Code (Skript):
    1. command /mail [<text>] [<text>] [<text>]:
    2.   trigger:
    3.     if {mail.%player%} is not set:
    4.       set {mail.%player%} to true
    5.       set {mail::%player%} to "%player%"
    6.     if arg 1 is not set:
    7.       if size of {mail::%player%::*} = 0:
    8.         message "[&cMail&r] &aVocê não tem nenhuma mensagem."
    9.       if size of {mail::%player%::*} >= 1:
    10.         message "[&cMail&r] &aVocê tem mensagens de &e&n%size of {mail::%player%::*}%&r&a remetente(s)!"
    11.         message "[&cMail&r] &aDigite &d/mail ler &apara ler as mensagens"
    12.       message "[&cMail&r] &aUse &d/mail &chelp &apara informações."
    13.       stop
    14.     if arg 1 is "help" or "ajuda":
    15.       if arg 2 is "ler":
    16.         message " "
    17.         message "[&cMail&r] &aAo usar o comando &d/mail &cler&a, o plugin irá checkar se você possui mensagens em sua caixa de entrada."
    18.         message "[&cMail&r] &aCaso existam mensagens na sua caixa de mensasgem, irão aparecer a lista de remetentes."
    19.         message "[&cMail&r] &aPara ler as mensagens, será necessário digitar &d/mail ler &cNICK&a, substituindo &cNICK&a pelo nick do player da lista de remetentes."
    20.         message "[&cMail&r] &6É possível imprimir as mensagens recebidas. Veja mais sobre digitando &d/mail help &cimprimir"
    21.         stop
    22.       if arg 2 is "imprimir":
    23.         message " "
    24.         message "[&cMail&r] &aAo usar o comando &d/mail &cimprimir&a, o plugin irá checkar se você possui mensagens em sua caixa de entrada."
    25.         message "[&cMail&r] &aCaso existam mensagens na sua caixa de mensasgem, o plugin te lembrará de ter um livro em mãos para imprimir, no livro, as mensagens."
    26.         message "[&cMail&r] &aCom os livros em mãos, digite &d/mail imprimir &apara armazenar em um livro todas as mensagens"
    27.         message "[&cMail&r] &6OBS: &aesse comando seta uma página por mensagem, com no máximo de 50 páginas por livro, há o limite de 50 mensagens impressas num livro."
    28.         message "[&cMail&r] &6Esse comando não irá limpar sua caixa de mensagens. Veja mais sobre digitando &d/mail help &capagar"
    29.         stop
    30.       if arg 2 is "apagar":
    31.         message " "
    32.         message "[&cMail&r] &aAo usar o comando &d/mail apagar&a, o plugin irá checkar se você possui mensagens em sua caixa de entrada."
    33.         message "[&cMail&r] &aCaso existam mensagens na sua caixa de mensasgem, será possível apagar todas as mensagens de um remetente."
    34.         message "[&cMail&r] &aPara apagar todas as mensagens de um remetende, digite &d/mail apagar &cNICK&a"
    35.         message "[&cMail&r] &aVocê pode apagar todas as mensagens recebidas digitando &d/mail apagar &ctudo&a"
    36.         message "[&cMail&r] &6Saiba como armazenar mensagens digitando &d/mail help &cimprimir"
    37.         stop
    38.       if arg 2 is "enviar":
    39.         message " "
    40.         message "[&cMail&r] &aAo usar o comando &d/mail &cenviar&a, informações sobre como enviar mensagens serão mostradas."
    41.         message "[&cMail&r] &aPara enviar uma mensagem, utilize o comando &d/mail enviar &dNICK MENSAGEM"
    42.         message "[&cMail&r] &aPara entender os limites, digite &d/mail help &climites"
    43.         stop
    44.       if arg 2 is "limites":
    45.         message " "
    46.         message "[&cMail&r] &aCada mensagem tem o limite de 150 caracteres."
    47.         message "[&cMail&r] &aComo forma de evitar abusos, é possivel enviar até 4 mensagens para cada player. Só é possível enviar mensagens para jogadores que logaram no servidor após a implementação do e-mail"
    48.         message "[&cMail&r] &aAo enviar 4 mensagens para um player, você ficará impedido de enviar mensagem para este player até que o mesmo limpe a caixa de entrada"
    49.         message "[&cMail&r] &aPor isso, é importante manter sua caixa de mensagens limpa. Saiba mais digitando &d/mail help &capagar"
    50.         message "[&cMail&r] &aÉ possível armazenar as mensagens em um livro. Veja sobre digitando &d/mail help &cimprimir"
    51.         stop
    52.       message "[&cMail&r] &d/mail help &cler - &6Informações sobre leitura de mensagens."
    53.       message "[&cMail&r] &d/mail help &capagar - &6Informações sobre como apagar mensagens."
    54.       message "[&cMail&r] &d/mail help &cimprimir - &6Informações sobre como transcrever para livros as mensagens."
    55.       message "[&cMail&r] &d/mail help &cenviar - &6Informações sobre como enviar uma mensagem para um player."
    56.       message "[&cMail&r] &d/mail help &climites - &6Informações sobre os limites de mensagem."
    57.       stop
    58.     if arg 1 is "ler" or "read":
    59.       if size of {mail::%player%::*} = 0:
    60.         message "[&cMail&r] &aVocê não tem nenhuma mensagem."
    61.         stop
    62.       if arg 2 is set:
    63.         loop {mail::%player%::*}:
    64.           if loop-index = arg 2:
    65.             set {_loop} to size of {mail::%player%::%arg 2%::*}
    66.           set {_num} to 0
    67.           loop {_loop} times:
    68.             add 1 to {_num}
    69.             wait 2 tick
    70.             message "[&cMail&r] %{mail::%player%::%arg 2%::%{_num}%}%"
    71.           wait 2 tick
    72.           message "[&cMail&r] &aPara apagar essas mensagens, digite &d/mail apagar &c%arg 2%"
    73.           stop
    74.       if size of {mail::%player%::*} >= 1:
    75.         message "[&cMail&r] &aRemetentes: &d%{mail::%player%::*}%"
    76.         message "[&cMail&r] &aDigite &d/mail ler &cNICK &a para ler as mensagens enviadas por um anão da lista acima."
    77.         stop
    78.     if arg 1 is "imprimir" or "print":
    79.       message "[&cMail&r] &cTemporariamente desativado"
    80.       stop
    81. #      if size of {mail::%player%::*} = 0:
    82. #        message "[&cMail&r] &aVocê não tem nenhuma mensagem para imprimir!"
    83. #        stop
    84. #      if player's tool is a book:
    85. #        remove 1 book from the player's tool
    86. #        set {_pages} to 0
    87. #        loop {mail::%player%::*}:
    88. #          loop {mail::%player%::%loop-value%::*}:
    89. #            add 1 to {_pages}
    90. #            if {_pages} = 50:
    91. #              message "[&cMail&r] &cERRO! A impressão é limitada em 50 páginas. Parando impressão."
    92. #              exit 3 sections
    93. #            add a page with data "%loop-value-2%" to book {_book}
    94. #        give player 1 of {_book}
    95. #        stop
    96.       message "[&cMail&r] &aTenha em mãos um livro em branco e digite &d/mail imprimir &a novamente"
    97.       stop
    98.     if arg 1 is "apagar" or "delete":
    99.       if size of {mail::%player%::*} = 0:
    100.         message "[&cMail&r] &aVocê não tem nenhuma mensagem."
    101.         stop
    102.       if arg 2 is not set:
    103.         message "[&cMail&r] &aVocê pode receber até 4 mensagens de cada player"
    104.         message "[&cMail&r] &aÉ importante manter sempre a caixa de entrada limpa para poder receber mensagens"
    105.         message "[&cMail&r] &aReceber 4 mensagens de um player não impede de receber mensagens de outros, mas apenas deste que lhe enviou 4 mensagens"
    106.         message "[&cMail&r] &aPara apagar todas as mensagens, independente de quem tenha enviado, digite &d/mail apagar tudo"
    107.         message "[&cMail&r] &aPara apagar as mensagens recebidas de um player, digite &d/mail apagar &cNICK"
    108.         stop
    109.       if arg 2 is "tudo":
    110.         clear {mail::%player%::*}
    111.         message "[&cMail&r] &aTodas as mensagens foram apagadas!"
    112.         stop
    113.       if arg 2 is set:
    114.         loop {mail::%player%::*}:
    115.           if loop-index = arg 2:
    116.             clear {mail::%player%::%arg 2%::*}
    117.             clear {mail::%player%::%arg 2%}
    118.             message "[&cMail&r] &aMensagens recebidas de %arg 2% foram apagadas!"
    119.             stop
    120.     if arg 1 is "enviar" or "send" or "s":
    121.       if arg 2 is not set:
    122.         message "[&cMail&r] &aO limite de 4 mensagens é individual, vide &d/mail help &climites"
    123.         message "[&cMail&r] &aUse o comando &d/mail enviar &cNICK &eMENSAGEM AQUI &apara enviar uma mensagem."
    124.         stop
    125.       if arg 2 is set:
    126.         if arg 2 = player:
    127.           message "[&cMail&r] &cERRO! &fVocê está tentando enviar uma mensagem para você mesmo!"
    128.           stop
    129.         if {mail.%arg 2%} is true:
    130.           set {_encontrado} to true
    131.           if {mail::%arg 2%::%player%} is not set:
    132.             set {mail::%arg 2%::%player%} to "%player%"
    133.         if {_encontrado} is not set:
    134.           message "[&cMail&r] &cERRO! &fEsse jogador ainda não teve sua caixa de e-mail ativada."
    135.           stop
    136.         if size of {mail::%arg 2%::%player%::*} = 4:
    137.           message "[&cMail&r] &cERRO! Já existem 4 mensagens suas lidas e/ou não apagadas na caixa do seu remetente"
    138.           message "[&cMail&r] &aLembre-o de apagar as suas mensagens usando o comando &d/mail apagar %player%"
    139.           message "[&cMail&r] &aLeia sobre os limites usando &d/mail help &climites"
    140.           stop
    141.         if arg 3 is not set:
    142.           message "[&cMail&r] &cERRO! Mensagem em branco."
    143.           stop
    144.         if arg 3 is set:
    145.           set {_check} to length of arg 3
    146.           if {_check} < 6:
    147.             message "[&cMail&r] &cERRO! Spam detectado!"
    148.             log "%player% TENTOU enviar ao %arg 2% (razao: <6): %arg 3%" to "Mail/mail.log"
    149.             stop
    150.           if {_check} > 151:
    151.             message "[&cMail&r] &cERRO! Limite de 150 caracteres por mensagem"
    152.             log "%player% TENTOU enviar ao %arg 2% (razao: >150): %arg 3%" to "Mail/mail.log"
    153.             stop
    154.           add "&9%player% diz: &7&o%arg 3%" to {mail::%arg 2%::%player%::*}
    155.           log "%player% enviou para o %arg 2%: %arg 3%" to "Mail/mail.log"
    156.           message "[&cMail&r] &aParabéns, &b%player%&a, você enviou uma mensagem para o &d%arg 2%&a."
    157.           if size of {mail::%arg 2%::%player%::*} = 4:
    158.             message "[&cMail&r] &aVocê já enviou &d4&a mensagens para esse remetente. Este é o limite de mensagens. Saiba mais digitando &d/mail help limites"
    159.             stop
    160.           if size of {mail::%arg 2%::%player%::*} = 3:
    161.             message "[&cMail&r] &aVocê já enviou &d3 &ade &d4 &amensagens para esse remetente. Saiba mais digitando &d/mail help limites"
    162.             stop
    163.           if size of {mail::%arg 2%::%player%::*} = 2:
    164.             message "[&cMail&r] &aVocê já enviou &d2 &ade &d4 mensagens para esse remetente. Saiba mais digitando &d/mail help limites"
    165.             stop
    166.           message "[&cMail&r] &aVocê já enviou &d1 &ade &d4 mensagens para esse remetente. Saiba mais digitando &d/mail help limites"
    167.           stop
    168.       message "[&cMail&r] &cERRO! &aDigite &d/mail enviar &cNICK &eMENSAGEM AQUI"
    169.       stop
    170.     message "[&cMail&r] &cERRO! &aComando inválido! Digite &d/mail help &apara ver os comandos disponíveis!"
     
    • Agree Agree x 1
  4. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    @aescraft - Yes you can but I wanted a configuration, where most of the things can be set changed from a notepad++. Not from in-game.
     
  5. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Why would you want to do that? Just give your players the access to the right commands and let them do their stuff, create factions, add players, remove players, etc.

    You could log the creation and the modifications of clans by logs, like I log all messages sent via my mails system:

    my log sytem - very simple:
    Code (Skript):
    1. log "%player% sent a mail to %arg 2%: %arg 3%" to "Mail/mail.log"
    %player% is the one who used the command.
    %arg 2% is the receipt of the message.
    %arg 3% is the message itself.

    I save it all to a single log.

    But you could save to diferent logs, each for each receipt doing this:
    Code (Skript):
    1. log "%player% sent a mail to %arg 2%: %arg 3%" to "Mail/%ARG2%/mail.log"
    Look that I added another folder. There's the mail, inside will be created a folder for the receipt %arg 2%, and inside, ALL messages send from any player to the %arg 2% would be logged.

    in your case, here is an exemple:

    creation of guild:
    Code (Skript):
    1. log "%player% created FACTIONAME" to "guilds/FACTIONNAME/factionhistory.log"
    add of player:
    Code (Skript):
    1. log "%player% added %PLAYERNAME / ARG X% to the FACTIONNAME" to "guilds/FACTIONNAME/factionhistory.log"
    removal of a player:
    Code (Skript):
    1. log "%player% removed %PLAYERNAME / ARG X% from the FACTIONNAME" to "guilds/FACTIONNAME/factionhistory.log"
    etc.

    But it's up to you.
     
  6. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    I wish there is a Dislike button...

    I don't understand why youre saying "DON'T USE YAML"

    Just let the user what he like. example i work evertime with yaml and i have no problem with loading variables?


    I got already a Full Remade SkyBlock without any Variables, all is with YAML Configure. And i have no problem with it (No laggs or somethings).

    I wish this post will be removed.

    Let the user what he want...
     
    • Like Like x 1
  7. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Sorry, but I can't agree with that.

    I need to somewhere store a large quantities of data. Would you recommend to store 4000 chunk files, 3500 playedata files in variables? From my personal testing, yaml is bad only if:
    • You store thousands of lines of data in one file
    • Create unneeded folders for, in example, every player
    • Use yaml data in operations where the data repeats and doesn't change at all
    With all that said, I would recommend this to everyone who uses yaml:
    1. If possible, store in separete files than in one file. For example, don't store playerdata in one file, create separete file for every player, it will be much easier for skript to find file than player in thousands of lines
    2. If you have data like configuration values in yaml file, free feel to place them in variables on script load
    3. Try to minimise yaml usage, for example, I've seen coordinates stored in 5 lines, it is possible to store them in one line too..
    4. Run tests before public release. Every unneeded yaml usage can lower perfomance, try to think about every operation from large perapective..
    I hope I covered most of my thoughts, they might be wrong, this is from my experience with 50-100 players activly playing in server that uses yaml in most of operations.
     
    • Like Like x 2
  8. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Did you read the post? I think I explain myself thoroughly.

    No, you do have a problem. YAML in Skript is too inefficient; ignoring it (or deciding that you don't care about its terrible performance) doesn't make the problem go away.

    That's horrifying. YAML isn't a replacement for variables.

    This thread is simply warning people about how using YAML in Skript will negatively impact your server's performance. Why remove it?

    I can't force anyone to stop using YAML. You're free to use it as much as you like. :emoji_stuck_out_tongue_closed_eyes:


    - - - - - - - - - - - - - -


    Yes. This is what variables were made for.

    YAML in Skript will always be bad as long as its syntaxes parse files every single time they're used. The moment an addon creates a parse-once solution, YAML will finally be viable.

    These are great tips in general, thanks for your input. :emoji_smile:
     
    • Agree Agree x 5
  9. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Of course variables will be faster in any case, but it is SO MUCH easier to modify yaml files than varables..
     
    • Like Like x 1
  10. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Why not just we all use JSON instead? Problem solved.
     
    • Like Like x 1
    • Agree Agree x 1
  11. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    I agree. skript-json by @btk5h implements it perfectly: parse once and save to a variable.
     
  12. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    I agree that JSON is a lot better than YAML but it is still not optimal. Here are three issues:

    - You need SkUtilities
    - The output of "variable to JSON" returns a one line representation of the JSON
    - JSON is ugly (and error prone if you try to write/change things)
    - JSON does not allow comments (kind of stupid if you want to make config files...)

    skript-json is only good if you never have to read/change the data.


    YAML is in itself not a bad idea and definitely a good choice for configs. We just lack an
    addon with a decent implementation. Here are the features that are currently missing:

    - Load YAML file to list variable
    - Save list variable to YAML file (without overriding the comments)


    And for everyone who wants to use YAML as a database: DON'T!
    YAML is for config files and nothing else.
     
    • Like Like x 1
    • Agree Agree x 1
  13. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    So sad that skript-json doesn't support hjson.
     
  14. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Retaining comments isn't possible with the YAML library provided by Bukkit (SnakeYAML).
     
  15. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    hmm this is good information however options can't be called in different scripts and using variables would fill up the .cvs file if storing a large amount of information which would lead to performance drop anyway
     
  16. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Thanks for posting this. Maybe not too fitting in tutorials but it doesn't fit all that much anywhere else either.
    Large amounts of variables really aren't a big of a deal as people think. One person says they are then everyone goes on says that to anyone who asks from now on. I know servers with literally over 250k variables that have no issues with performance because of variables.
    Just enable effect commands then you can just do things like
    Code (Skript):
    1. !set {whatever} to "whatever"
    from in game or console. If you're talking about user facing settings, its easy to use a system that is actually well implemented like skript-json (which i'll give you it isn't as easy to edit a json file than a yaml file) or just make your own system for configurations if you can't use skript options for some reason...
     
    • Agree Agree x 1
  17. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Interesting topic, I never knew YAMLs had to go through crazy shit JUST to find one value. I avoided using YAMLs for player data because I knew how inefficient that would be anyways. But, the fact that it takes more than quintuple the time to retrieve yaml values than variables is just embarrassing. Is there a possible way devs can make YAMLs more efficient in targeting single values?
     
  18. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    The OP covers this... a perfect system would be like skript-json where the file is parsed once then you can reference it like {_yaml::value::value}
     
  19. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    Iv been using yaml seems like Ill have to do the switch to variables
     
  20. ShaneBee

    Supporter + Addon Developer

    Joined:
    Sep 7, 2017
    Messages:
    2,106
    Likes Received:
    150
    See it took me a week to learn yaml completely and I don't have to the time to go through that anymore lol.
     
Loading...