1. Do you need support for Assetto Corsa Competizione? Please use the proper forum below and ALWAYS zip and attach the WHOLE "Logs" folder in your c:\users\*youruser*\AppData\Local\AC2\Saved. The "AppData" folder is hidden by default, check "Hidden items" in your Windows view properties. If you report a crash, ALWAYS zip and attach the WHOLE "Crashes" folder in the same directory.
  2. FOR ASSETTO CORSA COMPETIZIONE: If you report issues with saved games, please always zip and attach your entire User/Documents/Assetto Corsa Competizione/Savegame folder!
  3. If your game executable is missing, please add your entire Steam directory to the exceptions in your antivirus software, then run a Steam integrity check or reinstall the game altogether.

Let's talk about broadcasting (programmer's thread)

Discussion in 'ACC General Discussions' started by Minolin, Dec 12, 2018.

  1. Brado23

    Brado23 Racer

    We aren't asking for updates/fixes for the test example test client though. We are asking for fixes to how the some types of data are being sent from the game via the broadcast API, which currently aren't working at all in some cases. As a result we cant use these things in our own clients.

    I'm sure Minolin is extremely busy with everything that has been going on at Kunos. From what I can work out he is the only one at Kunos that can help us with these issues. I'm just hoping that some of his time frees up soon and he can get some of these issues fixed for us sometime soon.
     
    Doug Duthie, Zeraxx and RadstaR like this.
  2. Doug Duthie

    Doug Duthie Racer

    @Minolin - I asked this over on the shared memory blog but it probably wasn't the best place. Any chance of getting the Broadcast car model enum/type and the shared memory "Kunos ID" of the GT4 cars early? It would give me a chance to get my app ready for next week

    Thanks
     
    Brado23 likes this.
  3. Toon Knapen

    Toon Knapen Gamer

    Question: LapTime of first lap ?

    How is the laptime of the first lap determined? When the green light comes on at the start of a race, the laptime of each car is already around 40 seconds or so. Isn't the green light the start of the first lap?
     
  4. Doug Duthie

    Doug Duthie Racer

    From what I've seen, it varies quite a lot - it can be up to 10 minutes and the start time seems to vary car to car. However, some tracks (eg Bathurst) it appears to just be the time for the lap. You could probably determine the real lap time by comparing sessionTime lap to lap (which IIRC starts at zero for the first car to cross the start line). I don't think it is worth using the crossed line event as that doesn't use the session time but the time since joining (or whatever that is). There's also a bit of a lag receiving crossed line events so if you use your own timer, it would be out. I tend to work out my own "crossed line" time when the spline goes from 1 to 0 (or thereabouts) and note the session time from there.
     
    Toon Knapen likes this.
  5. bartouze

    bartouze Gamer

    i managed to have atime stamp on my accident tracker adding
    Code:
      public TimeSpan SessionTime { get => Get<TimeSpan>(); private set => Set(value); }
            public string SessionTimeDisplay { get => Get<string>(); private set => Set(value); }
            private void MessageHandler_OnRealtimeUpdate(string sender, RealtimeUpdate update)
            {
                SessionTime = update.SessionTime;
                SessionTimeDisplay = SessionTime.ToString("hh\\:mm\\:ss");
            }
    
    to my broadcasting eventviewmodel

    and
    Code:
    <TextBlock Grid.Column="1" Text="{Binding SessionTime}" />
    in the broadcastingeventview.xaml

    but it return allways 00:00:00

    any clue of what going wrong ? :)
     
  6. Why isn't there any sector times (splits) for current lap? They get reported for last lap and best lap but not the current lap. Is it a bug, omission or intentional?
     
  7. Toon Knapen

    Toon Knapen Gamer

    Thanks. However my experience learns me that the SessionTime (in the RealTimUpdate) is not completely synced with the updates received in the RealTimeCarUpdate. To elaborate when a car is on lap 'n+1', the 'RealTimeUpdate.SessionTime - RealTimeCarUpdate.CurrentLap.LapTimeMs - RealTimeCarUpdate.LastLap.LapTimeMs' is not necessarily equal to following calculation while the car was in lap 'n': 'RealTimeUpdate.SessionTime - RealTimeCarUpdate.CurrentLap.LapTimeMs'.

    When calculating this in SP mode, both are always equal. However in MP mode, there is some jitter on this. My conclusion from that is that the SessionTime (in RealTimeUpdate) is the session-time for the local player. And the RealTimeCarUpdate of all remote cars is thus received over the network and thus has some latency. And due to small changes on latency, the 2 expressions above are not always equal.

    Hope I succeeded in explaining it a bit clearly :-/
     
  8. Doug Duthie

    Doug Duthie Racer

    You're probably correct about the latency - it is probably not going give accurate lap times. I haven't really looked into it to determine the variance of times (although come to think of it, I've got a history of the reported lap times and session times so I should be able to tell now)
     
  9. Brado23

    Brado23 Racer

    Sector times are only passed at the completion of each lap. I and many others would like to see sectors updated as they occur too rather than at the end of each lap, but Kunos need to make updates to the game / broadcast API to make this happen.
     
    GRFOCO and Toon Knapen like this.
  10. Brado23

    Brado23 Racer

    Hey guys. I'm trying to grab the state of cars immediately when the race starts but having some issues and wanted to know if any of you had found a way around it....

    If I try to pickup the Green Flag status at the start using "if (evt.Type == BroadcastingCarEventType.GreenFlag)" it doesn't seem to recognise (not sure if this is a bug?), and if I try to detect the start using a combination of "if ((SessType == RaceSessionType.Race) && (SessPhase == SessionPhase.Session))" it does work but unreliably. For some cars it will register as the session phase changes from FormationLap to Session, while others don't register until the completion of the first lap. I suspect it is tied in with your discussion above with how SessionTime/CurrentLap varies for different cars at the start of a race.

    Has anyone else found a way to achieve this reliably?

    Thanks,
    Brad
     
    Last edited: Jul 9, 2020
  11. Doug Duthie

    Doug Duthie Racer

    I cheat on this one - I detect the first car crossing the line (spline going from 1 to 0 on lap 0). Also, IIRC the session time stays at zero until the first car crosses the line. There might be some latency with that method though, but it is good enough for my purposes
     
    Toon Knapen and Brado23 like this.
  12. Brado23

    Brado23 Racer

    Thanks. I might do it the same way as I already have splineposition detection code for something else.
     
    Toon Knapen likes this.
  13. Toon Knapen

    Toon Knapen Gamer

    To calculate the time of the first lap, I calculate it from the moment I detect the car is in its second lap as follows: realTimeUpdate.sessionTime - realTimeCarUpdate.CurrentLap.LapTimeMs
     
    Brado23 likes this.
  14. Brado23

    Brado23 Racer

    I'm still having issues detecting the actual start of the race in real time. I can get SplinePostion, Lap Completed, Session Phase change and SessionTime all to work and allow me to gather car data at the completion of lap 1, but NONE of them work for me as the cars cross the line at the start of the race (lap 0). As mentioned previously, the broadcast for GreenFlag doesn't seem to work for me either.

    @Doug Duthie I'd be interested to know how you got SplinePosition to work on lap 0, as even if I just have a condition SplinePosition > 0 to try to pickup as soon as it starts getting recorded at the start of a race, it still only triggers after the first lap is complete. It is doing my head in .. lol
     
  15. Doug Duthie

    Doug Duthie Racer

    Ah yes...it completely did my head in too until I logged every single value received on the connection. When a session starts, the cars will be approaching spline=1 and flip to spline =0 when they cross line. Also, for fun, when I had a very small refresh interval, I would get some spline refreshes that appeared as though the cars were going backwards (maybe the updates weren't serialised).

    I check if the previous spline was approaching 1 and the new spline is less than that (but greater than zero)...

    Code:
    // Invoked where message is InboundMessageTypes.REALTIME_CAR_UPDATE
            private void MessageHandler_OnRealtimeCarUpdate(int connectionId, RealtimeCarUpdate carUpdate)
            {
                if (connectionId == currentBroadcastConnectionId)
                {
                    var vm = Cars.FirstOrDefault(x => x.CarIndex == carUpdate.CarIndex);
                     if (vm == null)
                    {
                        // Oh, we don't have this car yet. In this implementation, the Network protocol will take care of this
                        // so hopefully we will display this car in the next cycles
                        return;
                    }
    
                    long lapStartTimestamp = -1;
    
                    if (vm.SplinePosition > carUpdate.SplinePosition && vm.SplinePosition > 0.8 && carUpdate.SplinePosition < 0.2)
                    {
                        // This is for the first car starting across the line
                        if (!SessionStarted && carUpdate.Laps == 0)
                        {
                            // This is a map just to record all car positions at lap zero (used for position deltas)
                            lapZeroPosition.Clear();
                            SessionStarted = true;
                            // Real time just for logging
                            SessionStartTime = DateTime.Now;
                            logger.broadcast($"Car {carUpdate.CarIndex} crossed start line at {SessionStartTime.ToString(Constants.DATE_FORMAT)} - Old spline = {vm.SplinePosition} new spline = {carUpdate.SplinePosition}");
                            carLapZeroTimestamp.Clear();
                        }
    
                        // Not ideal, but sessionCurrentTime is taken from the most recent RealTimeUpdate - Only accurate to refresh interval (plus any internal latency within ACC)
                        lapStartTimestamp = sessionCurrentTime;
    
                        // Sometimes we can get two or more crossed line events (where new spline < old spline)
                        // Ensure we just take first
                        int carPos = 0;
                        if (carUpdate.Laps == 0 && !lapZeroPosition.TryGetValue(carUpdate.CarIndex, out carPos))
                        {
                            logger.broadcast($"Car {carUpdate.CarIndex} crossed line at {Utils.getTimeFromMs(sessionCurrentTime)} on lap {carUpdate.Laps} - Old spline = {vm.SplinePosition} new spline = {carUpdate.SplinePosition}");
                            carLapZeroTimestamp.Add(carUpdate.CarIndex, lapStartTimestamp);
                            lapZeroPosition.Add(carUpdate.CarIndex, carUpdate.Position);
                        }
    
                        // Notify here that car crossed line
                        carCrossedLineEvent?.Invoke(carUpdate.CarIndex, carUpdate.Laps, sessionCurrentTime);
                    }
                    long initialTimestamp = 0;
    
                    vm.Update(carUpdate, lapStartTimestamp, initialTimestamp);
                }
                else
                {
                    logger.broadcast($"Ignoring real time car update for car {carUpdate.CarIndex} on lap {carUpdate.Laps}  on connection {connectionId} - current connection is {currentBroadcastConnectionId}");
                }
    
            }
    Just for completeness, there is a lap completed BroadcastEvent, but that doesn't get fired until the end of the lap, so won't be useful in this case
     
    Brado23 likes this.
  16. Brado23

    Brado23 Racer

    That's great info. Thank you very much for your help!

    I have a function inside CarViewModel that detects the SplinePosition change from 1 to 0 once the value is written there. Maybe that is where I'm going wrong as I notice you are doing comparisons between the value you are getting from the API and the value you have written to the class instance for the car (before it is updated).

    I'll see if I can get your way to work in mine. Thanks again.
     
    Doug Duthie likes this.
  17. Toon Knapen

    Toon Knapen Gamer

    Do you want to measure the exact time the cars cross the S/F to start the first lap or the time the green flag is wave for the start of the race? Because for the latter you can just watch just to see when RealTimeUpdate.SessionTime starts being non-zero anymore, no ?
     
  18. Brado23

    Brado23 Racer

    Yeah I just need to pick when the green flag is waved for the start of a race. I tried the (SessionTime > TimeSpan.Zero) way and it would only detect after lap one strangely as well (the same as SplinePosition detection crossing the SF line going from 1 to 0). I took Doug's good advice and logged the data that was coming in and found the issue. Haven't had time to look into why yet, but it appears that if the detection is run within CarViewModel like I was doing, it is only updated after lap 1. When I logged data from SessionInfoViewModel or BroadcastingViewModel it would log the data from during the formation lap and also detect crossing the line and SessionTime start on lap 0. I'm going to fix it to work in a similar way to Doug's in BroadcastingViewModel but haven't had time to do it yet.

    Check out these logs to see what I mean (Note the timestamps).....

    CarViewModel (first entries logged)....

    13/07/2020 6:42:46 PM - CarIndex: 0, Session Phase: Session, SessionTime: 00:02:01.0430000, Lap: 1, Position: 1, RaceStartPosition: 1, SplinePosition: 0.002134687
    13/07/2020 6:42:47 PM - CarIndex: 0, Session Phase: Session, SessionTime: 00:02:01.2950000, Lap: 1, Position: 1, RaceStartPosition: 1, SplinePosition: 0.004586115
    13/07/2020 6:42:47 PM - CarIndex: 0, Session Phase: Session, SessionTime: 00:02:01.5530000, Lap: 1, Position: 1, RaceStartPosition: 1, SplinePosition: 0.007147247
    13/07/2020 6:42:47 PM - CarIndex: 0, Session Phase: Session, SessionTime: 00:02:01.8170000, Lap: 1, Position: 1, RaceStartPosition: 1, SplinePosition: 0.009768054

    SessionInfoViewModel (many entries before what is listed below while on formationlap, and obviously many after).....

    13/07/2020 6:40:45 PM - Session Phase: PreSession, SessionTime: 00:00:00
    13/07/2020 6:40:45 PM - Session Phase: PreSession, SessionTime: 00:00:00
    13/07/2020 6:40:46 PM - Session Phase: Session, SessionTime: 00:00:00.2090000
    13/07/2020 6:40:46 PM - Session Phase: Session, SessionTime: 00:00:00.4700000
    13/07/2020 6:40:46 PM - Session Phase: Session, SessionTime: 00:00:00.7340000
    13/07/2020 6:40:46 PM - Session Phase: Session, SessionTime: 00:00:00.9950000
    13/07/2020 6:40:47 PM - Session Phase: Session, SessionTime: 00:00:01.2530000

    BroadcastingViewModel (many entries before and after but this shows when crossing line on lap 0. This ties in with SessionTime > TimeSpan.Zero in the logs above)....

    13/07/2020 6:40:45 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0.9963828
    13/07/2020 6:40:45 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0.9974021
    13/07/2020 6:40:46 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0.9983932
    13/07/2020 6:40:46 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0.9994112
    13/07/2020 6:40:46 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0
    13/07/2020 6:40:46 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0.001308345
    13/07/2020 6:40:47 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0.002600961
    13/07/2020 6:40:47 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0.003952236
    13/07/2020 6:40:47 PM - CarIndex: 0, Lap: 0, Position: 1, SplinePosition: 0.005327115

    I either need to find out why CarViewModel takes until lap 1 to be updated, or move the code to BroadcastingViewModel the same as Doug.

    Thanks for your help guys. It is very much appreciated.
     
    Toon Knapen and Doug Duthie like this.
  19. Doug Duthie

    Doug Duthie Racer

    Has anyone got a list of the IDs of the new GT4 cars. I’d like to get these coded while I’m away - I won’t be able to test with the DLC until the weekend
    Cheers
    Doug


    Sent from my iPhone using Tapatalk
     
  20. steevee

    steevee Racer

    @Doug Duthie these ?

    50 Alpine A1110 GT4
    51 Aston Martin Vantage GT4
    52 Audi R8 LMS GT4
    53 BMW M4 GT4
    55 Chevrolet Camaro GT4
    56 Ginetta G55 GT4
    57 KTM X-Bow GT4
    58 Maserati MC GT4
    59 McLaren 570S GT4
    60 Mercedes AMG GT4
    61 Porsche 718 Cayman GT4
     
    Brado23 and Toon Knapen like this.
Similar Threads
Forum Title Date
ACC PS4 - XB1 General Discussions Let's talk multiplayer/online servers Jul 11, 2020
Chit Chat Room Let's talk about Sim Dream modding Jun 20, 2020
ACC General Discussions Let's talk about broadcasting (user's thread) Dec 12, 2018
Console Lounge Let's talk vote to kick Mar 18, 2017
Console Lounge Quick race weekend (let's talk abou it Vol.1) Feb 24, 2017
Chit Chat Room Let's talk Lotus 98T Feb 17, 2017
Console Lounge Porsche Cayman GT4 - Let's talk gearing Jan 16, 2017
Console Lounge Let's talk about rage quitters... Dec 9, 2016
Chit Chat Room 935/78 - Let's talk setup and driving Oct 30, 2016
Console Lounge Let's talk about braking Oct 6, 2016
Suggestions Let's talk weather (I am not asking for rain). Aug 15, 2016
Chit Chat Room Let's talk wheels...again. why not? Aug 27, 2014
ACC PS4 - XB1 General Discussions Let's do something, this is going to get ugly...(Servers) Aug 3, 2020
ACC General Discussions Let's get acquainted? Nov 28, 2019
ACC General Discussions POLL! Let's buy this game again every year to support Assetto Corsa guys! Jul 20, 2019

Share This Page

  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