Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Feb 22, 2025. It is now read-only.

Fractural/FracturalRollbackNetcode

Repository files navigation

Warning

This repository is now deprecated.

Please use Godot Rollback Netcode Mono, a C# wrapper for SnopekGame's Godot Rollback Netcode addon instead!

Fractural Rollback Netcode πŸ”ƒ

This is a C# implementation of rollback netcode in Godot. This is based off of SnopekGames' Godot Rollback Netcode addon.

Usage

Getting Input

public class Game : Node2D
{
 public enum Scenes
 {
 Player
 }
 NetcodeManager _netcodeManager;
 DIContainer _diContainer;
 PackedScene _playerPrefab;
 Player _player;
 public void _Ready()
 {
 InitDIContainer();
 StartGame();
 }
 private void InitDIContainer()
 {
 _netcodeManager = new NetcodeManager();
 _diContainer = new DIContainer();
 AddChild(_diContainer);
 _diContainer.Bind<NetcodeManager>().To(_netcodeManager);
 }
 private void StartGame()
 {
 // Spawn automatically registers the instance to the
 // sync manager if it implements any of the INetwork
 // interfaces.
 _player = _netcodeManager.Spawn(this,
 (int)Scenes.Player,
 _playerPrefab);
 }
}
public class Explosion : Node2D, INetworkSpawnable, IInjectable
{
 public class SpawnData
 {
 public Vector2 position;
 }
 private NetworkTimer _despawnTimer;
 private NetcodeManager _netcodeManager;
 public void Construct(DIContainer container)
 {
 _netcodeManager = container.Resolve<NetcodeManager>();
 }
 public void _Ready()
 {
 _despawnTimer = GetNode<NetworkTimer>("ExplosionTimer");
 _despawnTimer.Timeout += OnDespawnTimerTimeout;
 }
 // ----- INetworkSpawnable ----- //
 public void NetworkSpawn(object data)
 {
 var typedData = data as SpawnData;
 GlobalPosition = typedData.position;
 _despawnTimer.Start();
 }
 public void NetworkDespawn() {}
 // ----- INetworkSpawnable ----- //
 public void OnDespawnTimerTimeout()
 {
 _netcodeManager.Despawn(this);
 }
}
public class Bomb : Node2D, INetworkSpawnable, IInjectable
{
 public enum Scenes
 {
 Explosion
 }
 public class SpawnData
 {
 public Vector2 position;
 }
 private NetworkTimer _explosionTimer;
 private NetcodeManager _netcodeManager;
 public void Construct(DIContainer container)
 {
 _netcodeManager = container.Resolve<NetcodeManager>();
 }
 public void _Ready()
 {
 _explosionTimer = GetNode<NetworkTimer>("ExplosionTimer");
 _explosionTimer.Timeout += OnExplosionTimerTimeout;
 }
 // ----- INetworkSpawnable ----- //
 public void NetworkSpawn(object data)
 {
 var typedData = data as SpawnData;
 GlobalPosition = typedData.position;
 _explosionTimer.Start();
 }
 public void NetworkDespawn() { }
 // ----- INetworkSpawnable ----- //
 public void OnExplosionTimerTimeout()
 {
 _netcodeManager.Spawn(this,
 (int)Scenes.Explosion,
 new Explosion.SpawnData() {
 position = GlobalPosition
 });
 _netcodeManager.Despawn(this);
 }
}
public class Player : Node2D, INetworkSerializable, INetworkInput, INetworkProcess, INetworkSpawner
{
 public enum Scenes
 {
 Bomb
 }
 public class Data
 {
 public Vector2 position;
 public Vector2 attackCooldown;
 }
 public class Input
 {
 public bool bombDropped;
 public Vector2 inputDirection;
 }
 public Data data;
 private NetcodeManager _netcodeManager;
 public void Construct(DIContainer container)
 {
 _netcodeManager = container.Resolve<NetcodeManager>();
 }
 // ----- INetworkSpawner ----- //
 public void SpawnwerSpawned(int id, Node scene)
 {
 if (id == (int) Scenes.Bomb)
 {
 scene.Exploded += OnBombExploded;
 }
 }
 public void SpawnwerDespawned(int id, Node scene)
 {
 if (id == (int) Scenes.Bomb)
 {
 scene.Exploded -= OnBombExploded;
 }
 }
 // ----- INetworkSpawner ----- //
 // ----- INetworkProcess ----- //
 private void NetworkProcess(object input)
 {
 if (input is Input typedInput)
 {
 if (typedInput.bombDropped)
 _netcodeManager.Spawn(this,
 (int)Scenes.Bomb,
 new Bomb.SpawnData() {
 position = GlobalPosition
 });
 }
 }
 // ----- INetworkProcess ----- //
 // ----- INetworkSerializable ----- //
 public object Save()
 {
 return Object.MemberwiseClone(data);
 }
 public void Load(object data)
 {
 data = Object.MemberwiseClone(data) as Data;
 }
 // ----- INetworkSerializable ----- //
 // ----- INetworkInput ----- //
 public object GetLocalInput()
 {
 return new Input()
 {
 inputDirection = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
 bombDropped = Input.IsActionJustPressed("ui_accept")
 };
 }
 public object PredictLocalInput(object input, int ticksSinceRealInput)
 {
 var input = Object.MemberwiseClone(input);
 if (input.bombDropped)
 input.bombDropped = false;
 return input;
 }
 // ----- INetworkInput ----- //
 private void OnBombExploded()
 {
 }
}

About

C# rollback netcode solution for Godot. Based on Snopek Game's godot-rollback-netcode addon. πŸ”™

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

Languages

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /