Skip to content

lucaspoffo/tkr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TK Rollback

TKR is P2P rollback network library for Odin.

Rollback Network requires the game to be deterministic, but this allows to only send inputs between peers. Also, to predict remote players inputs so we can keep simulating gameplay without waiting, when receiving the correct input we can rollback and re-simulate the game if necessary.

Features:

  • Supports UDP or Steam NetworkMessages transport layer, you can also write a custom transport if needed
  • Automatic input delay based on ping, you can customize or disabled this
  • Desync detection, players will disconnect when their game state diverges
  • Detection when the client frame is too far ahead or behind so you can slowdown/speedup the fixed update rate
    • Check the example to see how to do this
example.mp4

Code sample using UDP

For a complete usage check the example folder.

FPS :: 60.0

game: Game
local_input: Input

p2p: tkr.P2P_Session(Game, Input)
udp_transport: tkr.UDP_Transport

tkr.p2p_init(&p2p, num_players, FPS, serialize_input, deserialize_input)

// Players information usually come from a Lobby System or Matchmaking
local_player_index: u64 = 0
local_endpoint := net.Endpoint { net.IP4_Loopback, 5000 } 

remote_player_index: u64 = 1
remote_client_id: u64 = 123
remote_endpoint := net.Endpoint { net.IP4_Loopback, 5001 } 

tkr.p2p_add_local_player(&p2p, local_player_index)
tkr.p2p_add_remote_player(&p2p, remote_player_index, remote_client_id)

tkr.udp_transport_init(&udp_transport, local_endpoint)
tkr.udp_transport_add_client(&udp_transport, remote_client_id, remote_endpoint)

for game_running {
	messages_to_send := tkr.p2p_update(&p2p)
	tkr.udp_transport_send_messages(&udp_transport, &p2p, messages_to_send)
	tkr.udp_transport_poll(&udp_transport, &p2p)

	// Add local input to the simulation
	tkr.p2p_add_local_input(&p2p, client_index, local_input)

	requests, messages_to_send := tkr.p2p_advance_frame(&p2p)
	tkr.udp_transport_send_messages(&udp_transport, &p2p, messages_to_send)

	// Must handle this requests in order.
	for request in requests {
		switch &r in request {
		case tkr.Save_Game(Game):
			// Store the current game state in the given ptr
			r.game_rollback_state.state = game
			r.game_rollback_state.checksum = hash.crc32(mem.ptr_to_bytes(&game))
		case tkr.Load_Game(Game):
			// Load given game state to the global game variable
			game = r.game_rollback_state.state
		case tkr.Advance_Frame(Input):
			// Run gameplay code
			game_update(r.inputs, r.status)
		case tkr.Skip_Frames:
			// We cannot simulate more (reached the maximum Prediction Window)
			// Do nothing
		}
	}
}

game_update :: proc(inputs: [tkr.MAX_NUM_PLAYERS]Input, status: [tkr.MAX_NUM_PLAYERS]tkr.Input_Status) {
	// ... gameplay code
}

Full Example

In the example folder you can check simple game example with Steam or UDP transport.

UDP

odin build example

Commands to run a 2 player game, run each client with:

.\example.exe 0 127.0.0.1:5000 127.0.0.1:5001
.\example.exe 1 127.0.0.1:5000 127.0.0.1:5001

Steam

When running the steam example, each client instance MUST have a different steam account. To do this you need 2 computers (or VMs) each running different steam accounts.

odin build example -define:STEAM_ENABLED=true

Commands to run a 2 player game, run each client with (replace STEAM_IDs with your owns):

.\example.exe 0 <STEAM_ID_1> <STEAM_ID_2>
.\example.exe 1 <STEAM_ID_1> <STEAM_ID_2>

Some resources about rollback netcode

About

P2P Rollback Network library for Odin

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages