Jump to content

DiSaMe

Distinguished Members
  • Posts

    1,461
  • Joined

  • Last visited

  • Days Won

    34

Posts posted by DiSaMe

  1. Recording 60 frames per second? What the hell are you going to do with that much?

    My estimates:

    10 players in range

    Recording at 10 FPS

    12 frequently updated values for position, position velocity, rotation, rotation velocity (race gamemode)

    10 players x 10 FPS x 12 values = 1200 values per second to write

    1200 x 10 s = 12000 values in RAM to store

  2. Traffic is created and destroyed in generate.lua file, spawnTrafficInSquare and despawnTrafficInSquare functions.

    As for positions on road, you can look at load_paths.lua to see where the data is stored. conn_n1[connection_id] and conn_n2[connection_id] are the nodes where connection starts and ends and if it is bent around a node, that node is stored in conn_nb table.

    The last thing you want to do, linking/unlinking the vehicles to/from traffic, is not something what this resource was designed for. Maybe you could achieve this if you did the same what is done on creation/removal of vehicles, minus the createVehicle/destroyElement calls (using already existing vehicle instead), but the resource itself is not well-designed overall because I was after speed, not flexibility when I was making it.

  3. function callFunctionWithSleeps(calledFunction, ...) 
        local co = coroutine.create(calledFunction) --we create a thread 
        coroutine.resume(co, ...) --and start its execution 
    end 
      
    function sleep(time) 
        local co = coroutine.running() 
        local function resumeThisCoroutine() --since setTimer copies the argument values and coroutines cannot be copied, co cannot be passed as an argument, so we use a nested function with co as an upvalue instead 
            coroutine.resume(co) 
        end 
        setTimer(resumeThisCoroutine, time, 1) --we set a timer to resume the current thread later 
        coroutine.yield() --we pause the execution, it will be continued when the timer calls the resume function 
    end 
      
    -----------example----------- 
      
    function pauseExample(a, b, c) 
        outputChatBox("Started the execution. a value: "..tostring(a)) 
        sleep(5000) 
        outputChatBox("Waited 5 seconds. b value: "..tostring(b)) 
        sleep(5000) 
        outputChatBox("Waited 10 seconds, finishing the execution. c value: "..tostring(c)) 
    end 
      
    callFunctionWithSleeps(pauseExample, 1, 2, 3) 
    

    Not tested, but should work. Keep in mind, however, that this exact implementation won't display errors within the called function, because coroutine.resume returns the error as a string instead of propagating it to the caller.

    • Like 3
  4. You can work with binary files, since you can use string.byte on strings to get the values of bytes. That's what my bytedata script does, though it has problems reading the floating point values, and it's probably because of reduced precision on client, as using it on standalone Lua interpreter gave correct results. Nevertheless, built-in functions for binary file processing would be much faster.

  5. Use fetchRemote to download the data, then parse the HTML (and optionally CSS/JavaScript) data in Lua, that's how it goes. I don't see a reason why anything else would be needed.

  6. Acutely they do cause lag... especially on the client side, however, you might not notice it if its just you and a couple of friends play on the server.

    That doesn't make any sense at all. Number of players does not influence the execution of timers. What's more, I just started 20000 timers on the server and they increased the CPU usage like by 10%. Even if I give them 50 ms interval, they reduce the server FPS from 145 to 120, with CPU usage being about 60-70%. In addition, implementing timers in Lua using onClientRender/onClientPreRender and getTickCount would probably cause bigger slowdowns. Even if that weren't true, code readability is more important than performance because reliability comes from readability and slowly working code is better than not working code.

  7. There are no "string types", the script simply converts the numeric and string data into a string which looks like the same values stored in RAM or HDD. Format argument (the first values passed to dataToBytes and bytesToData functions) describes what data you store/retrieve.

    For example, if you want to store two 2-byte integers v1, v2 and a 4-byte integer v3 (all signed and little-endian), this is how it would look like:

    local packed = dataToBytes("ssi", v1, v2, v3) 
    

    "s" means a 2-byte integer and "i" means a 4-byte integer. So it's "s" for v1, another "s" for v2 and "i" for v3. And now the string packed contains a string whose length is 8 characters. First two bytes contain the value of v1, the following two bytes contain v2 and the last four bytes contain v3. If type identifiers in the format string are repeating, you can put a number before the letter instead of repeating it. In this case, you can substitute "ssi" with "2si".

    Now, when you need to get the values from the string packed, you need to use bytesToData with the same format string and it will return the values which were passed to bytesToData:

    v1, v2, v3 = bytesToData("ssi", packed) 
    

    If my explanation wasn't good enough, you could try reading this: http://docs.python.org/3.3/library/struct.html . I made the functions to work like struct.pack and struct.unpack in Python do.

    By the way, it looks like the example in my website has some mistakes. Also, I noticed that while the floating point data works on standalone Lua interpreter, it gives incorrect results on MTA client (not sure about the server). This is probably because of reduced mathematical precision of calculations on the client.

    So I hope that's enough info for you :)

×
×
  • Create New...