Player Data & Scoreboards

I came to do a scoreboard and had to think about how to network shit. You can’t just list through the players and get the scores and names from them to build the board… because they might not be being networked to you, they might be on the other side of the world.

So here’s what I got. On the player object you define properties like this.

		/// <summary>
		/// Number of deaths. We use the PlayerInfo system to store these variables because
		/// we want them to be available to all clients - not just the ones that can see us right now.
		/// </summary>
		public virtual int Deaths
		{
			get => GetPlayerInfo<int>( "deaths" );
			set => SetPlayerInfo( "deaths", value );
		}

		/// <summary>
		/// Number of kills. We use the PlayerInfo system to store these variables because
		/// we want them to be available to all clients - not just the ones that can see us right now.
		/// </summary>
		public virtual int Kills
		{
			get => GetPlayerInfo<int>( "kills" );
			set => SetPlayerInfo( "kills", value );
		}

This is calling Get/SetPlayerInfo. The backend automatically collates this info and networks it. I’m probably going to add an [attribute] to do this in the future, to make things a bit simpler.

Then in your scoreboard, you’d do something like this.

public Scoreboard()
{
	StyleSheet = StyleSheet.FromFile( "/ui/scoreboard/Scoreboard.scss" );
	AddClass( "scoreboard" );

	AddHeader();

	Canvas = Add.PanelWithClass( "canvas" );

	PlayerInfo.OnPlayerAdded += AddPlayer;
	PlayerInfo.OnPlayerUpdated += UpdatePlayer;
	PlayerInfo.OnPlayerRemoved += RemovePlayer;

	foreach ( var player in PlayerInfo.All )
	{
		AddPlayer( player );
	}
}

Then in your AddPlayer shit, you can create a new panel that has a function like this…

public virtual void UpdateFrom( PlayerInfo.Entry entry )
{
	Entry = entry;

	PlayerName.Text = entry.GetString( "name" );
	Kills.Text = entry.Get<int>( "kills", 0 ).ToString();
	Deaths.Text = entry.Get<int>( "deaths", 0 ).ToString();
	Ping.Text = entry.Get<int>( "ping", 12 ).ToString();
}

Throw in some css and you’re all done

.scoreboard
{
	width: 400px;
	position: absolute;
	top: 100px;
	left: 100px;
	z-index: 100;
	flex-direction: column;
	font-family: Poppins;
	font-size: 13px;
	font-weight: 500;
	color: white;

	.name
	{
		flex-grow: 1;
	}

	.deaths, .kills, .ping
	{
		width: 70px;
		text-align: right;
	}

	.header
	{
		font-weight: 200;
		opacity: 0.3;
		border-bottom: 2px solid rgba( white, 0.6 );
	}

	.canvas
	{
		flex-direction: column;

		.entry
		{
			margin-bottom: 2px;
			padding: 4px;
		}
	}
}
20 Likes

image

Get the pictures right next time!

Why is the variable Entry = entry; not used again in the code? Is it a global variable?

1 Like

I can’t wait to use CSS for UI, I hope it will be much better than on Gmod. Great work! :ok_hand:

Looks nice! pls tab to open/close scoreboard tho :weary:

1 Like

I really like the look of the console

1 Like

i can’t believe garry killed the simpsons… when will his reign of terror end!!!

2 Likes

I had to watch the video twice cause I didn’t see it the first time (I was waiting the whole time for a big translucent window to appear).

It’s a field/prop of the class which has the UpdateFrom method, it gets written to the object and probably gets used in some other method.

Looks nice, as you already said, with some [NetVar] attribute it’ll look super nice and simple!

UPD:
Also, the console message tracing feature is a killer, I dreamed about having something like that in gmod for years.

2 Likes

Hmm. Is this possible to center the scoreboard through flex?

Yes, this is obviously a quick mock-up / proof of concept. Garry has said he will make sure flex is available.