Measuring time ingame

Discussion in 'Utilities and programming' started by fetthaufen, Aug 22, 2013.

  1. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    I was thinking about adding a timer to my track but somehow the trigger object, which i would think you would need to do that, crashes the game. I have no experience with scripting in torque or anything so there might be other ways that i am not aware of. If you know any please let me know.

    In the meantime i came up with an interesting way to at least measure the time manually ingame.

    I added this code
    Code:
    //measure time
    $lasttimepressed=0;
    function echoTimePassed()
    {
       if($lasttimepressed > 0)
       {
          echo((getRealTime()-$lasttimepressed)/1000 @ " seconds");
       }
       else
       {
          echo("0 seconds");
       }
       $lasttimepressed=getRealTime();
    }
    
    
    moveMap.bindCmd(keyboard, o, "echoTimePassed();", "");
    to this file
    Code:
    BeamNG.drive-0.3\scripts\client\inputmaps\keyboard.inputmap.cs
    Everytime you press "o" there will be a line written in the console showing you the number of seconds that passed since you last pressed the button. So if you press "o" every time you pass the starting line you can look up your times in the console afterwards :)
     
  2. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    I found out that you can also display the measured time on screen so you don't need to look it up in the console.

    Add this code instead of the original code:
    Code:
    //measured time display
    $timepassedGuiActive = false;
    $timepassedGuiCtrl = new GuiTextCtrl()
    {
       text = "0 sec.";
       profile=new GuiControlProfile( testProfile ) {  
          fontColor = "0 0 150 255";  
          fontSize = "20";  
          fontType = "lucida console";  
       };
    };
    
    function toggleTimePassedGui()
    {
       if($timepassedGuiActive)
       {
          Canvas.popdialog( $timepassedGuiCtrl );
          $timepassedGuiActive=false;
       }
       else
       {
          Canvas.pushdialog( $timepassedGuiCtrl );
          $timepassedGuiActive=true;
       }
    }
    moveMap.bindCmd(keyboard, u, "toggleTimePassedGui();", "");
    
    //measure time
    $lasttimepressed=0;
    function echoTimePassed()
    {
       if($lasttimepressed > 0)
       {
          echo((getRealTime()-$lasttimepressed)/1000 @ " seconds");
          $timepassedGuiCtrl.setText((getRealTime()-$lasttimepressed)/1000 @ " sec.");
       }
       else
       {
          echo("0 seconds");
          $timepassedGuiCtrl.setText("0 sec.");
       }
       $lasttimepressed=getRealTime();
    }
    
    moveMap.bindCmd(keyboard, o, "echoTimePassed();", "");
    use "u" to toggle the display and "o" to measure the time. I couldn't find out how to change the position on screen maybe somebody knows how to do that.

    There's probably a better place for this logic but i was too lazy to find out...
     
  3. Mihax209

    Mihax209
    Expand Collapse

    Joined:
    Aug 7, 2013
    Messages:
    14
    Ah ha! I've been looking for that.
    By "trigger object" you mean the floating purple rectangles in the start\finish line in the track?
     
  4. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    For me it's not purple but yellowish. You can find it under Objects->Level->Trigger and you can add script code to it that triggers when the player enters or leaves the trigger volume (which you can resize). The problem is that instead of executing the script code it just crashes as soon as the player enters the trigger volume... i hope this is a BeamNG bug because i tried a lot and didn't get it to work...

    The only workaround that i would see is if there were script code to check for a collision between the player and some of the other level objects (like Zone, PhysicalZone) but i couldn't find any.
     
  5. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    I don't know how but i overlooked that there is a "BeamNGTrigger" that doesn't crash! But ... it seems that you can't really do much with it because you don't have access to anything it seems ... i'm getting errors like this:
    Code:
    ***FATAL LUA ERROR: [string "line"]:1: attempt to call global 'getRealTime' (a nil value)
    
    So if anyone knows how to access global functions???
     
  6. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    So this lua error is not a scope problem as i first suspected but related to the fact that trigger use lua and that's not the same script language that we find inside .cs files :eek:.

    I haven't yet found out how to print text directly on screen but timing inside the console works ...
    timing.jpg
    I put this code inside a beamngtrigger
    Code:
    local currentTime = os.clock()
    if lastTime and lastTime > 0 then
    print(currentTime-lastTime.." sec.")
    else
    print("timing start")
    print("......................")
    end
    lastTime = currentTime
     
  7. Mr.Hankey

    Mr.Hankey
    Expand Collapse

    Joined:
    Aug 9, 2012
    Messages:
    29
    Where exactly did you put it? I couldn't find a working callback for the BeamNGTrigger object
     
  8. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    I used the "enterCommand" callback. Not sure if it's important but i set TriggerMode to "Contains".

    Code:
    new BeamNGTrigger(TimingTrigger) {
          TriggerType = "Box";
          TriggerMode = "Contains";
          enterCommand = "local currentTime = os.clock()\nif lastTime and lastTime > 0 then\nprint(currentTime-lastTime..\" sec.\")\nelse\nprint(\"timing start\")\nprint(\"......................\")\nend\n\nlastTime = currentTime\n";
          tickPeriod = "100";
          debug = "0";
          triggerColor = "255 192 0 45";
          position = "54.8618 -86.4739 2.43204";
          rotation = "0 0 -1 30.2523";
          scale = "31.1013 1 8.76881";
          canSave = "1";
          canSaveDynamicFields = "1";
       };
     
  9. Incognito

    Incognito
    Expand Collapse

    Joined:
    Aug 4, 2013
    Messages:
    246
    To display the time on the screen can be used BeamEngine.canvasTexture .
    Wrote a simple class to display the time, but I do not know how to link it with the trigger, the game crashes when the trigger fires.
    Perhaps one of the developers can help? :)
    Code:
    local M = {}
    
    local lastTime = 0
    
    local ct    = nil
    local c     = nil
    local paint = {}
    
    local function initPaint()
        local fontName = "Roboto-Light.ttf"
        local tf = SkTypeface.CreateFromFile(fontName, kNormal)
        
        paint.fontLeft = SkPaint()
        paint.fontLeft:setAntiAlias(true)
        paint.fontLeft:setColor(SK_ColorWHITE)
        paint.fontLeft:setTextAlign(kLeft_Align)
        paint.fontLeft:setTextSize(20)
        paint.fontLeft:setTypeface(tf)
    end
    
    local function printTime()
        if not ct then
            ct = BeamEngine.canvasTexture
        end
        c = ct:getCanvas()
        ct:clear()
        
        if ( paint.fontLeft == nil ) then
            initPaint()
        end    
        
        local currentTime = os.clock()
        local txt = string.format("Time: %f", currentTime - lastTime)
        local x = 0
        local y = 70
        c:drawText(txt, string.len(txt), x, y, paint.fontLeft)
    end
    
    local function update()
        lastTime = os.clock()
    end
    
    M.update     = update
    M.printTime  = printTime
    
    return M
     
  10. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    This is awesome ! I tried your code and it works for me ... i just made it more "functional" without classes since i have no idea how to even code in lua :D

    Code:
    local currentTime = os.clock()
    if lastTime and lastTime > 0 then
        if not ct then
            ct = BeamEngine.canvasTexture
        end
        
        c = ct:getCanvas()
        ct:clear()
        
        if paint == nil then
            paint = {}
        end
        
        if paint.fontLeft == nil then
            paint.fontLeft = SkPaint()
            paint.fontLeft:setAntiAlias(true)
            paint.fontLeft:setColor(SK_ColorWHITE)
            paint.fontLeft:setTextAlign(kLeft_Align)
            paint.fontLeft:setTextSize(20)
            paint.fontLeft:setTypeface(SkTypeface.CreateFromFile("Roboto-Light.ttf", kNormal))
        end
        
        local txt = currentTime-lastTime.." sec."
        
        c:drawText(txt, string.len(txt), 0, 70, paint.fontLeft)
        print(txt)
    else
        print("timing start")
        print("......................")
    end
    
    lastTime = currentTime
    It's not refined yet i just had a quick go at it to see if it works...
    Your code was probably supposed to be saved in a .lua file right? And inside the trigger you only had a simple function call? Could you explain to me how this system works? Is the engine simply loading all lua files? Where did you look up all the commands and classes you used?
     
  11. Incognito

    Incognito
    Expand Collapse

    Joined:
    Aug 4, 2013
    Messages:
    246
    No. You need to specify which files to load. There are two separate systems (do not know how it is correct to call): vehicle scripts (lua\vehicle) and systems scripts (lua\system), they work separately from each other. Something like this :D

    I wanted to make a simple call two functions in the trigger. I created the timer.lua (the content posted above), and put it in lua\system . In lua\system\main.lua I added with a new line:
    Code:
    timer     = require("timer")
    after this line:
    Code:
    json      = require("json")
    And if call the function timer.update() and timer.printTime() in the console - all works fine. If try to call them in the trigger - game crashes (I also tried to do as well as you do (just a little more beautiful view), but also get the game crashes).
    In scripts game (lua folder) :) Just opened them and saw how it works. Prior to this experience with lua did not have (but have experience in other programming languages)
     
    #11 Incognito, Aug 26, 2013
    Last edited: Aug 26, 2013
  12. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    I think the problem might be that you are using Objects->Level->Trigger (which crashes no matter what code you put in it) and not Objects->BeamNG->BeamNGTrigger (which doesn't crash)

    I tried the same thing but there was nothing paint related when i went through them ;)
     
  13. Incognito

    Incognito
    Expand Collapse

    Joined:
    Aug 4, 2013
    Messages:
    246
    Right. Now, the game does not crash, but when the car crosses the trigger - nothing happens o_O
    If you do not have such problems - try to use lua files as I described above. I wonder if it will work :)
     
  14. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    If i do it as you explained (with main.lua and timer.printTime ...) it works too, maybe it didn't show up on your screen because you need to activate the trigger 2 times (depending on which version you tried).
    We should add laps and sector times too ... now that i understand how it's done i really like the "class" approach.
     
  15. Incognito

    Incognito
    Expand Collapse

    Joined:
    Aug 4, 2013
    Messages:
    246
    The problem was that the mode "contains", probably means that the cars must be completely in the trigger (or part of the car), but the pick-up a little more than trigger. So, trigger mode "center" works good :)
     
  16. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    I just finished a new version, it's based on the source code Incognito provided.
    laptimer.jpg

    It's now possible to divide the track into sectors and it will also show the best time driven so far (it will also save this best time to a file and load it when you restart the map).
    I attached a zip file which includes the laptimer and updated .mis files for my track estering and the stock track Industrial so you can try it without doing much just extract it to the BeamNG folder.
     

    Attached Files:

  17. reginald

    reginald
    Expand Collapse

    Joined:
    Aug 23, 2013
    Messages:
    29
    just trying this on the industrial map. the clock does not seem to start / be running? (I see it on screen..) Am I missing something? thanks!
     
    #17 reginald, Sep 22, 2013
    Last edited: Sep 22, 2013
  18. fetthaufen

    fetthaufen
    Expand Collapse

    Joined:
    Aug 17, 2013
    Messages:
    23
    This might be caused by something i fixed but never uploaded ...
    I attached a newer version, the older would only work if you drive through the sectors in the right order.
     

    Attached Files:

  19. reginald

    reginald
    Expand Collapse

    Joined:
    Aug 23, 2013
    Messages:
    29
    There we go! Great thanks. Amazed this thread has not had more response. Thanks again.
     
  20. reginald

    reginald
    Expand Collapse

    Joined:
    Aug 23, 2013
    Messages:
    29
    is it possible to implement this lua within the map folder? ..to avoid the script being deleted with beam updates?
     
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice