Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge dev -> master to start the developer beta #46

Merged
merged 58 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
a78a2b4
Fix match starts
VirxEC Aug 9, 2024
a0dbfac
Re-add SetNullMatchSettings
VirxEC Aug 9, 2024
32c0275
Rename `looks_config` -> `loadout_config`
VirxEC Aug 9, 2024
ce3a338
New protocol
VirxEC Aug 9, 2024
0a8130b
Wait for inactive to end match
VirxEC Aug 10, 2024
260a96b
Ensure bots are only spawned once
VirxEC Aug 10, 2024
9fc9b4e
Give bots a chance to clearly shutdown after a match
VirxEC Aug 10, 2024
433cec6
Update spec
VirxEC Aug 10, 2024
13ecbe8
Add PerfMonitor
VirxEC Aug 10, 2024
30adfb6
RLBot perf monitoring
VirxEC Aug 11, 2024
345590c
Fix? Match starting
VirxEC Aug 11, 2024
0d0693a
Don't close connections when starting match
VirxEC Aug 11, 2024
d75b805
Fix error trace spam on unexpected match leave
VirxEC Aug 11, 2024
df88b17
Fix initial match start
VirxEC Aug 11, 2024
33c2f25
Fix Continue and Spawn
VirxEC Aug 11, 2024
7a23f61
Fix field info not being distributed
VirxEC Aug 11, 2024
fe27399
Add epic launching on Windows
VirxEC Aug 12, 2024
2c70a5b
Add `MatchEnded` to `Restart_If_Different`'s `shouldSpawnNewMap`
VirxEC Aug 12, 2024
ff3f61d
Add `()` to `doSpawning`
VirxEC Aug 12, 2024
18835e1
Filter out TeamOnly match comms
VirxEC Aug 13, 2024
69705e9
Fix AutoStartBots
VirxEC Aug 14, 2024
62afb75
Fix starting a match on the current map first thing
VirxEC Aug 14, 2024
384f0cf
Fix SkipReplays
VirxEC Aug 14, 2024
065b921
Prevent bot spawning before map loads
VirxEC Aug 14, 2024
034ee96
Don't kill new bots during match start
VirxEC Aug 14, 2024
4c0ea9f
Silence IOException when client disconnects
VirxEC Aug 14, 2024
08aaddb
Fix `_expectedConnections` counting
VirxEC Aug 14, 2024
3973eb0
Skip non-rlbots
VirxEC Aug 15, 2024
f27bfd7
Parse script names
VirxEC Aug 15, 2024
d960a94
Use command to clear all renders
VirxEC Aug 15, 2024
40758ea
Ensure all renders are cleared
VirxEC Aug 15, 2024
af2734b
Run bot/script commands in shell
VirxEC Aug 15, 2024
1c25e3b
Clear all renders (too many edge cases)
VirxEC Aug 15, 2024
7876aba
Construct GameTickPacket in Bridge instead of Server
VirxEC Aug 15, 2024
62d5569
Skip 1 tick max
VirxEC Aug 15, 2024
bbef438
Fix unit test
VirxEC Aug 15, 2024
1562470
Update `Bridge.dll`
VirxEC Aug 15, 2024
f42c454
Always continue and spawn
VirxEC Aug 16, 2024
ae2c341
Be more careful about emitting warning on Linux
VirxEC Aug 16, 2024
d86eae5
Print map name upon load
VirxEC Aug 16, 2024
4e6072d
Legendary launcher support
VirxEC Aug 16, 2024
d3487e5
Loadout generator support
VirxEC Aug 17, 2024
54b67e8
Update to new spec
VirxEC Aug 22, 2024
8296462
Update CI to be able to publish binary to a release on Github
VirxEC Aug 22, 2024
c42e369
`rocket_league_exe_path` -> `game_path`
VirxEC Aug 22, 2024
3b425d7
Update README
VirxEC Aug 22, 2024
89dbeee
Wait for spawn queuing to be complete
VirxEC Aug 27, 2024
ab06a7a
Properly de-deduplicate frames during play
VirxEC Aug 27, 2024
05638c6
Remove comment
VirxEC Aug 31, 2024
cb2ac1c
Silence additional error upon disconnect in BridgeHandler
VirxEC Sep 4, 2024
cb8faf4
Update `Bridge.dll`
VirxEC Sep 6, 2024
c1a96d2
Fix spawning a match with only a human
VirxEC Sep 6, 2024
e43b073
Fix state setting cars
VirxEC Sep 7, 2024
a1d36f4
Sort boost pads by Y then X
VirxEC Sep 9, 2024
970447c
Sort boost pads in GTP
VirxEC Sep 9, 2024
6e2420a
New test
VirxEC Sep 16, 2024
8abc0cb
Update `Bridge.dll`
VirxEC Sep 16, 2024
98f855b
Update to new spec
VirxEC Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
name: Build

on: [ workflow_dispatch, push ]
on:
push:
branches:
- "*"
tags:
- "v*.*.*"
pull_request:
workflow_dispatch:

jobs:
build-windows:
Expand Down Expand Up @@ -38,3 +45,23 @@ jobs:
with:
name: RLBotServer-ubuntu
path: ./**/publish/RLBotServer

release:
name: Release
runs-on: ubuntu-latest
if: "startsWith(github.ref, 'refs/tags/')"
needs: [build-linux, build-windows]
permissions:
contents: write

steps:
- uses: actions/download-artifact@v4
with:
merge-multiple: "true"
- name: Publish to GitHub Releases
uses: softprops/action-gh-release@v2
with:
files: ./**/publish/RLBotServer*
generate_release_notes: true
body: |
Pre-built binaries that allows bots to interface with Rocket League via the RLBot v5 spec
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ compiled binaries at `RLBotCS\bin\Release\net8.0`.

## Deployment

New deployment method is still TBD.
1. Ensure all changes are on the `master` branch
1. Create a new tag with the next version number - e.x. `git tag v0.1.0 -m "Core v0.1.0"`
- Preferably sign the tag too - `git tag -s v0.1.0 -m "Core v0.1.0"`
1. Push the tag - `git push --tags`
1. Wait for the Github Actions to build the release and upload it to the release page!

Further deployment steps for automatic updates are still in progress.

## Maintenance

Expand All @@ -35,11 +41,11 @@ This project uses the CSharpier formatter. You can run it with `dotnet csharpier
### Flatbuffers

The Core project uses flatbuffers, which involves generating C# code based on a specification
file called `rlbot.fbs`. Find this in `RLBotCS/FlatBuffer` after it's been generated.
file called `rlbot.fbs`. Find this in `./FlatBuffer` after it's been generated.

The [flatbuffers-schema](https://github.com/RLBot/flatbuffers-schema) submodule should be kept update to date:

- `cd RLBotCS/flatbuffers-schema`
- `cd flatbuffers-schema`
- `git checkout main`
- `git fetch`
- `git pull`
Expand All @@ -52,3 +58,10 @@ The `Bridge.dll` file in `RLBotCS/lib` is built from a _closed-source_ repositor
It is maintained by RLBot developers who have signed an agreement with Psyonix to keep it private.

The dll file is platform-independent and works for building the project on both Windows and Linux.

### rl_ball_sym

The native binaries that live in `RLBotCS/lib/rl_ball_sym` generate the ball prediction that core then distributes to bots & scripts that request it.
The `dll`/`so` are dynamically loaded at run time while developing core, and the `a`/`lib` files are statically linked during publishing.

All source code and releases for building the dlls can be found at <https://github.com/VirxEC/rl_ball_sym_dll> but the core of the code is a library that's published for anyone's use at <https://crates.io/crates/rl_ball_sym>.
39 changes: 39 additions & 0 deletions RLBotCS/Conversion/FlatToCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ private static string MapGameMode(GameMode gameMode) =>
GameMode.Rumble => "?game=TAGame.GameInfo_Items_TA",
GameMode.Heatseeker => "?game=TAGame.GameInfo_GodBall_TA",
GameMode.Gridiron => "?game=TAGame.GameInfo_Football_TA",
GameMode.Knockout => "?game=TAGame.GameInfo_KnockOut_TA",
_ => throw new ArgumentOutOfRangeException(nameof(gameMode), gameMode, null)
};

Expand Down Expand Up @@ -101,6 +102,8 @@ private static string MapBallType(BallTypeOption option) =>
BallTypeOption.Beachball => "Ball_BeachBall",
BallTypeOption.Anniversary => "Ball_Anniversary",
BallTypeOption.Haunted => "Ball_Haunted",
BallTypeOption.Ekin => "Ball_Ekin",
BallTypeOption.SpookyCube => "Ball_SpookyCube",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};

Expand All @@ -113,6 +116,7 @@ private static string MapBallWeight(BallWeightOption option) =>
BallWeightOption.Super_Light => "SuperLightBall",
BallWeightOption.Curve_Ball => "MagnusBall",
BallWeightOption.Beach_Ball_Curve => "MagnusBeachBall",
BallWeightOption.Magnus_FutBall => "MagnusFutBallTest",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};

Expand All @@ -121,6 +125,7 @@ private static string MapBallSize(BallSizeOption option) =>
{
BallSizeOption.Default => "",
BallSizeOption.Small => "SmallBall",
BallSizeOption.Medium => "MediumBall",
BallSizeOption.Large => "BigBall",
BallSizeOption.Gigantic => "GiantBall",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
Expand All @@ -133,6 +138,7 @@ private static string MapBallBounciness(BallBouncinessOption option) =>
BallBouncinessOption.Low => "LowBounciness",
BallBouncinessOption.High => "HighBounciness",
BallBouncinessOption.Super_High => "SuperBounciness",
BallBouncinessOption.LowishBounciness => "LowishBounciness",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};

Expand Down Expand Up @@ -160,6 +166,7 @@ private static string MapRumble(RumbleOption option) =>
RumbleOption.Spike_Rush => "ItemsModeRugby",
RumbleOption.Haunted_Ball_Beam => "ItemsModeHauntedBallBeam",
RumbleOption.Tactical => "ItemsModeSelection",
RumbleOption.BatmanRumble => "ItemsMode_BM",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};

Expand All @@ -169,6 +176,7 @@ private static string MapBoostStrength(BoostStrengthOption option) =>
BoostStrengthOption.One => "",
BoostStrengthOption.OneAndAHalf => "BoostMultiplier1_5x",
BoostStrengthOption.Two => "BoostMultiplier2x",
BoostStrengthOption.Five => "BoostMultiplier5x",
BoostStrengthOption.Ten => "BoostMultiplier10x",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};
Expand Down Expand Up @@ -205,6 +213,31 @@ private static string MapRespawnTime(RespawnTimeOption option) =>
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};

private static string MapMaxTime(MaxTimeOption option) =>
option switch
{
MaxTimeOption.Default => "",
MaxTimeOption.Eleven_Minutes => "MaxTime11Minutes",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};

private static string MapGameEvent(GameEventOption option) =>
option switch
{
GameEventOption.Default => "",
GameEventOption.Rugby => "RugbyGameEventRules",
GameEventOption.Haunted => "HauntedGameEventRules",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};

private static string MapAudio(AudioOption option) =>
option switch
{
AudioOption.Default => "",
AudioOption.Haunted => "HauntedAudio",
_ => throw new ArgumentOutOfRangeException(nameof(option), option, null)
};

private static string GetOption(string option)
{
if (option != "")
Expand Down Expand Up @@ -232,6 +265,9 @@ public static string MakeOpenCommand(MatchSettingsT matchSettings)
// Parse game mode
command += MapGameMode(matchSettings.GameMode);

if (matchSettings.SkipReplays)
command += "?noreplay";

// Whether to or not to skip the kickoff countdown
if (!matchSettings.InstantStart)
command += "?Playtest";
Expand Down Expand Up @@ -262,6 +298,9 @@ public static string MakeOpenCommand(MatchSettingsT matchSettings)
command += GetOption(MapGravity(mutatorSettings.GravityOption));
command += GetOption(MapDemolish(mutatorSettings.DemolishOption));
command += GetOption(MapRespawnTime(mutatorSettings.RespawnTimeOption));
command += GetOption(MapMaxTime(mutatorSettings.MaxTimeOption));
command += GetOption(MapGameEvent(mutatorSettings.GameEventOption));
command += GetOption(MapAudio(mutatorSettings.AudioOption));

return command;
}
Expand Down
38 changes: 17 additions & 21 deletions RLBotCS/Conversion/GameStateToFlat.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Bridge.Models.Message;
using Bridge.Packet;
using Bridge.State;
using rlbot.flat;
using CollisionShapeUnion = rlbot.flat.CollisionShapeUnion;
Expand Down Expand Up @@ -51,17 +52,6 @@ public static GameTickPacketT ToFlatBuffers(this GameState gameState)
AngularVelocity = ball.Physics.AngularVelocity.ToVector3T()
};

TouchT lastTouch =
new()
{
PlayerName = ball.LatestTouch.PlayerName,
PlayerIndex = ball.LatestTouch.PlayerIndex,
Team = ball.LatestTouch.Team,
GameSeconds = ball.LatestTouch.TimeSeconds,
Location = ball.LatestTouch.HitLocation.ToVector3T(),
Normal = ball.LatestTouch.HitNormal.ToVector3T()
};

CollisionShapeUnion collisionShape = ball.Shape switch
{
ICollisionShape.Box boxShape
Expand Down Expand Up @@ -91,14 +81,7 @@ ICollisionShape.Cylinder cylinderShape
)
};

balls.Add(
new()
{
Physics = ballPhysics,
LatestTouch = lastTouch,
Shape = collisionShape
}
);
balls.Add(new() { Physics = ballPhysics, Shape = collisionShape });
}

rlbot.flat.GameStateType gameStateType = gameState.GameStateType switch
Expand Down Expand Up @@ -134,7 +117,9 @@ ICollisionShape.Cylinder cylinderShape
];

List<BoostPadStateT> boostStates = gameState
.BoostPads.Values.Select(
.BoostPads.Values.OrderBy(boost => boost.SpawnPosition.Y)
.ThenBy(boost => boost.SpawnPosition.X)
.Select(
boost => new BoostPadStateT { IsActive = boost.IsActive, Timer = boost.Timer }
)
.ToList();
Expand All @@ -152,6 +137,16 @@ ICollisionShape.Cylinder cylinderShape
_ => AirState.OnGround
};

TouchT? lastTouch = null;
if (car.LastTouch is BallTouch touch)
lastTouch = new()
{
GameSeconds = touch.TimeSeconds,
Location = touch.HitLocation.ToVector3T(),
Normal = touch.HitNormal.ToVector3T(),
BallIndex = touch.BallIndex,
};

players.Add(
new()
{
Expand All @@ -162,6 +157,7 @@ ICollisionShape.Cylinder cylinderShape
Velocity = car.Physics.Velocity.ToVector3T(),
AngularVelocity = car.Physics.AngularVelocity.ToVector3T()
},
LastestTouch = lastTouch,
AirState = airState,
DodgeTimeout = car.DodgeTimeout,
DemolishedTimeout = car.DemolishedTimeout,
Expand Down Expand Up @@ -210,7 +206,7 @@ ICollisionShape.Cylinder cylinderShape
Balls = balls,
GameInfo = gameInfo,
Teams = teams,
BoostPadStates = boostStates,
BoostPads = boostStates,
Players = players
};
}
Expand Down
18 changes: 15 additions & 3 deletions RLBotCS/Conversion/PsyonixLoadouts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,30 @@ namespace RLBotCS.Conversion;
internal static class PsyonixLoadouts
{
private static Random _random = new();

/// Unused loadout names, used to avoid spawning multiple of the same Psyonix bot
private static List<string> Unused = new();

public static void Reset()
{
Unused.Clear();
}


public static PlayerLoadoutT? GetFromName(string name, int team)
{
int index = Unused.FindIndex(n => n.Contains(name));
if (index == -1)
return null;

var loadout = DefaultLoadouts[Unused[index]][team];
Unused.RemoveAt(index);
return loadout;
}

public static (string, PlayerLoadoutT) GetNext(int team)
{
if (Unused.Count == 0) Unused = DefaultLoadouts.Keys.OrderBy(_ => _random.Next()).ToList();
if (Unused.Count == 0)
Unused = DefaultLoadouts.Keys.OrderBy(_ => _random.Next()).ToList();
var fullName = Unused.Last();
Unused.RemoveAt(Unused.Count - 1);
var loadout = DefaultLoadouts[fullName][team];
Expand Down
3 changes: 2 additions & 1 deletion RLBotCS/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
if (rlbotSocketsPort < 0)
{
throw new FormatException();
} else if (rlbotSocketsPort > 65535)
}
else if (rlbotSocketsPort > 65535)
{
throw new OverflowException();
}
Expand Down
31 changes: 17 additions & 14 deletions RLBotCS/ManagerTools/BallPredictor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Runtime.InteropServices;
using Bridge.Packet;
using rlbot.flat;

namespace RLBotCS.ManagerTools;
Expand Down Expand Up @@ -62,7 +61,7 @@ public static partial class BallPredictor
[LibraryImport("rl_ball_sym", EntryPoint = "free_ball_slices")]
private static unsafe partial void FreeBallSlices(BallSlice* slices, ushort ticks);

private static Vec3 ToVec3(Bridge.Models.Phys.Vector3 vec) => new(vec.X, vec.Y, vec.Z);
private static Vec3 ToVec3(Vector3T vec) => new(vec.X, vec.Y, vec.Z);

private static Vector3T ToVector3T(Vec3 vec) =>
new()
Expand Down Expand Up @@ -111,7 +110,8 @@ public static PredictionMode GetMode(MatchSettingsT matchSettings)
public static BallPredictionT Generate(
PredictionMode mode,
float currentTime,
Ball currentBall
BallInfoT currentBall,
(TouchT, uint)? lastTouch
)
{
BallSlice ball =
Expand All @@ -131,20 +131,23 @@ Ball currentBall

if (mode == PredictionMode.Heatseeker)
{
if (currentBall.LatestTouch.TimeSeconds < float.Epsilon)
if (lastTouch is (TouchT, uint) lastestTouch)
{
// A goal happened, we're in kickoff
ResetHeatseekerTarget();
}
else if (currentTime - currentBall.LatestTouch.TimeSeconds < 0.1)
{
// Target goal is the opposite of the last touch
SetHeatseekerTarget(currentBall.LatestTouch.Team == 1 ? (byte)0 : (byte)1);
if (currentTime - lastestTouch.Item1.GameSeconds < 0.1)
{
// Target goal is the opposite of the last touch
SetHeatseekerTarget(lastestTouch.Item2 == 1 ? (byte)0 : (byte)1);
}
else if (GetHeatseekerTargetY() == 0 || MathF.Abs(ball.Location.Y) >= 4820)
{
// We're very likely to hit a wall that will redirect the ball towards the other goal
SetHeatseekerTarget(ball.LinearVelocity.Y < 0 ? (byte)1 : (byte)0);
}
}
else if (GetHeatseekerTargetY() == 0 || MathF.Abs(ball.Location.Y) >= 4820)
else
{
// We're very likely to hit a wall that will redirect the ball towards the other goal
SetHeatseekerTarget(ball.LinearVelocity.Y < 0 ? (byte)1 : (byte)0);
// A goal happened, we're in kickoff
ResetHeatseekerTarget();
}
}

Expand Down
Loading