Advertisement
Guest User

Untitled

a guest
May 23rd, 2021
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.09 KB | None | 0 0
  1. void loadframe(int fr) {
  2. List<game_obj> gos = new List<game_obj>();
  3. foreach(game_obj go in p1.active_game_objs) {
  4. gos.Add(go);
  5. }
  6. foreach(game_obj go in p2.active_game_objs) {
  7. gos.Add(go);
  8. }
  9. foreach(game_obj go in gos) {
  10. go.load_frame(fr);
  11. }
  12. p1.load_frame(fr);
  13. p2.load_frame(fr);
  14. }
  15. void new_savestate() {
  16. p1.sim_frame = local_frame;
  17. p2.sim_frame = local_frame;
  18. p1.save_state();
  19. p2.save_state();
  20. List<game_obj> goos = new List<game_obj>();
  21. foreach(game_obj go in p1.active_game_objs) {
  22. goos.Add(go);
  23. }
  24. foreach(game_obj go in p2.active_game_objs) {
  25. goos.Add(go);
  26. }
  27. foreach(game_obj go in goos) {
  28. go.sim_frame = local_frame;
  29. go.save_state();
  30. }
  31.  
  32. }
  33. void overwrite_savestate(int f) {
  34. p1.sim_frame = f;
  35. p2.sim_frame = f;
  36. p1.frame_save();
  37. p2.frame_save();
  38. List<game_obj> goos = new List<game_obj>();
  39. foreach(game_obj go in p1.active_game_objs) {
  40. goos.Add(go);
  41. }
  42. foreach(game_obj go in p2.active_game_objs) {
  43. goos.Add(go);
  44. }
  45. foreach(game_obj go in goos) {
  46. go.sim_frame = f;
  47. go.frame_save();
  48. }
  49.  
  50. }
  51. /*
  52.  
  53. Start Program:
  54. [Initialize Variables]
  55.  
  56. loop:
  57.  
  58. [Update Network]
  59. [Update Synchronization]
  60. if [Time Synced] then
  61. [Normal Update]
  62. goto loop
  63.  
  64. End Program
  65. */
  66. int MAX_ROLLBACK_FRAMES = 30;
  67. int FRAME_ADVANTAGE_LIMIT = 6;
  68. int INITAL_FRAME = 10;
  69.  
  70. int local_frame = 0;
  71. int remote_frame = 0;
  72. int sync_frame = 0;
  73. int remote_frame_advantage = 0;
  74.  
  75. byte last_remote_input = 0;
  76.  
  77. List<inputframe> inputframes = new List<inputframe>();
  78. /*
  79. MAX_ROLLBACK_FRAMES := Any Positive Integer # Specifies the maximum number of frames that can be resimulated
  80. FRAME_ADVANTAGE_LIMIT := Any Positive Integer # Specifies the number of frames the local client can progress ahead of the remote client before time synchronizing.
  81. INITAL_FRAME := Any Integer # Specifies the initial frame the game starts in. Cannot rollback before this frame.
  82.  
  83. [Initialize Variables]
  84. local_frame := INITAL_FRAME # Tracks the latest updates frame.
  85. remote_frame := INITAL_FRAME # Tracks the latest frame received from the remote client
  86. sync_frame := INITAL_FRAME # Tracks the last frame where we synchronized the game state with the remote client. Never rollback before this frame.
  87. remote_frame_advantage := 0 # Latest frame advantage received from the remote client.
  88.  
  89.  
  90. photonView.RPC("getInput", PhotonTargets.Others, i.my_input, i.myframe);
  91. PhotonNetwork.SendOutgoingCommands();
  92.  
  93. */
  94. void rlbk_update_input(inputframe i) {
  95. /*
  96. [Update Input]
  97. Predict the remote player's input if not available yet.
  98. Setup the local player and remote player's input for use in [Update Game]
  99. */
  100. if(i.remote_input == 0) {
  101. if(last_remote_input!=0) {
  102. i.predicted_input = last_remote_input;
  103. }
  104. else {
  105. i.predicted_input = 50;
  106. }
  107.  
  108. }
  109. give_inputs(localPlayer(),i.local_input);
  110.  
  111. if(i.remote_input != 0) {
  112. give_inputs(localPlayer().enemy,i.remote_input);
  113. }
  114. else {
  115. give_inputs(localPlayer().enemy,i.predicted_input);
  116. }
  117. }
  118.  
  119. void rlbk_execute_rollbacks() {
  120. /*
  121. [Execute Rollbacks]
  122. [Restore Game State]
  123. select inputs from (sync_frame + 1) through local_frame # Use all the inputs since the last sync frame until the current frame to simulate
  124. [Rollback Update]
  125. */
  126. loadframe(sync_frame);
  127.  
  128. for(int i = sync_frame+1; i <= local_frame; i++) {
  129. foreach(inputframe inp in inputframes) {
  130. if(inp.myframe == i) {
  131. /*
  132. [Update Input]
  133. [Update Game]
  134. [Store Game State]
  135. */
  136. rlbk_update_input(inp);
  137. rlbk_update_game(i);
  138. overwrite_savestate(i);
  139. }
  140. }
  141. }
  142.  
  143. }
  144.  
  145. void rlbk_update_game(int fr) {
  146. p1.sim_frame = fr;
  147. p2.sim_frame = fr;
  148. p1.frame_update(fr);
  149. p2.frame_update(fr);
  150. }
  151. bool rlbk_timesynced() {
  152. /*
  153. bool [Time Synced]
  154. Let local_frame_advantage = local_frame - remote_frame # How far the client is ahead of the last reported frame by the remote client
  155. Let frame_advantage_difference = local_frame_advantage - remote_frame_advantage # How different is the frame advantage reported by the remote client and this one.
  156. local_frame_advantage < MAX_ROLLBACK_FRAMES AND frame_advantage_difference <= FRAME_ADVANTAGE_LIMIT # Only allow the local client to get so far ahead of remote.
  157.  
  158. */
  159. int local_frame_advantage = local_frame - remote_frame;
  160. int frame_advantage_difference = local_frame_advantage - remote_frame_advantage;
  161.  
  162. return local_frame_advantage < MAX_ROLLBACK_FRAMES && frame_advantage_difference <= FRAME_ADVANTAGE_LIMIT;
  163. }
  164.  
  165. byte localbyteinput = 0;
  166.  
  167. void rlbk_normalupdate() {
  168. /*
  169. [Normal Update]
  170. Increment local_frame
  171. [Get Local Player Input]
  172. [Send input to remote client]
  173.  
  174. [Update Input]
  175. [Update Game]
  176. [Store Game State]
  177. */
  178. local_frame++;
  179. localbyteinput = byte_input(localPlayer());
  180. inputframe lfi = rlbk_get_local_player_input();
  181. rlbk_send_input_to_remote_client();
  182.  
  183. rlbk_update_input(lfi);
  184. rlbk_update_game(local_frame);
  185.  
  186. new_savestate();
  187.  
  188. }
  189.  
  190. void rlbk_send_input_to_remote_client() {
  191. // Send the input and the local_frame to the remote client so it arrives asap.
  192. photonView.RPC("getInput", PhotonTargets.Others, localbyteinput, local_frame);
  193. PhotonNetwork.SendOutgoingCommands();
  194. }
  195.  
  196. inputframe rlbk_get_local_player_input() {
  197. //Read the joystick/pad/keyboard for the local player and store it, associating it with local_frame
  198.  
  199. inputframe ii=null;
  200. foreach(inputframe i in inputframes) {
  201. if(i.myframe == local_frame) {
  202. ii = i;
  203. }
  204. }
  205. if(ii == null) {
  206. ii = new inputframe();
  207. inputframes.Add(ii);
  208. ii.predicted_input = last_remote_input;
  209. ii.myframe = local_frame;
  210. }
  211.  
  212. ii.local_input = localbyteinput;
  213. return ii;
  214.  
  215. }
  216.  
  217.  
  218.  
  219. bool rlbk_rollback_condition() {
  220. /*
  221. bool [Rollback Condition]
  222. local_frame > sync_frame AND remote_frame > sync_frame # No need to rollback if we don't have a frame after the previous sync frame to synchronize to.
  223. */
  224. return local_frame > sync_frame && remote_frame > sync_frame;
  225. }
  226. void rlbk_updatenetwork() {
  227. /* [Update Network]
  228. Let remote_frame = latest frame received from the remote client
  229. Let remote_frame_advantage = (local_frame - remote_frame) sent from the remote client
  230. */
  231. remote_frame = online_frame;
  232. remote_frame_advantage = (local_frame - remote_frame);
  233. }
  234. class inputframe {
  235. public int myframe=0;
  236. public byte local_input=0;
  237. public byte predicted_input=0;
  238. public byte remote_input = 0;
  239. }
  240. void rlbk_determinesyncframe() {
  241. /*
  242. [Determine the sync_frame]
  243. Let final_frame = remote_frame # We will only check inputs until the remote_frame, since we don't have inputs after.
  244. if remote_frame > local_frame then final_frame = local_frame # Incase the remote client is ahead of local, don't check past the local frame.
  245. select frames from (sync_frame + 1) through final_frame and find the first frame where predicted and remote inputs don't match
  246. if found then
  247. sync_frame = found frame - 1 # The found frame is the first frame where inputs don't match, so assume the previous frame is synchronized.
  248. else
  249. sync_frame = final_frame # All remote inputs matched the predicted inputs since the last synchronized frame.
  250. */
  251. int final_frame = remote_frame;
  252. if(remote_frame > local_frame) {
  253. final_frame = local_frame;
  254. }
  255.  
  256. inputframe oic = null; // find the oldest incorrect input frame
  257.  
  258. foreach(inputframe inp in inputframes) {
  259. if(inp.myframe >= sync_frame+1 && inp.myframe <= final_frame) {
  260. if(inp.remote_input != inp.predicted_input) {
  261. if(oic == null) {
  262. oic = inp;
  263. }
  264. else {
  265. if(inp.myframe < oic.myframe) {
  266. oic = inp;
  267. }
  268. }
  269. }
  270. }
  271. }
  272.  
  273. if(oic != null) {
  274. sync_frame = oic.myframe - 1;
  275. }
  276. else {
  277. sync_frame = final_frame;
  278. }
  279.  
  280.  
  281. }
  282. void rlbk_updatesync() {
  283. /*
  284. [Update Synchronization]
  285. [Determine the sync_frame]
  286. if [Rollback Condition] then
  287. [Execute Rollbacks]
  288. */
  289. rlbk_determinesyncframe();
  290. if(rlbk_rollback_condition() == true) {
  291. rlbk_execute_rollbacks();
  292. }
  293. }
  294.  
  295. void rlbk_init() {
  296. local_frame = INITAL_FRAME;
  297. remote_frame = INITAL_FRAME;
  298. sync_frame = INITAL_FRAME;
  299. remote_frame_advantage = 0;
  300. }
  301. void online_sendinput() {
  302.  
  303. /* if(playingonline==false) {
  304. photonView.RPC("startgame", PhotonTargets.Others);
  305. Debug.Log("nope " + local_frame);
  306. return;
  307. }*/
  308.  
  309. if(timer_synced==false) {
  310.  
  311. countups=0;
  312. syncTimers();
  313. rlbk_init();
  314.  
  315. }
  316. rlbk_updatenetwork();
  317. rlbk_updatesync();
  318.  
  319. if(rlbk_timesynced() == true) {
  320. rlbk_normalupdate();
  321. dotimer();
  322. List<inputframe> deads = new List<inputframe>();
  323. foreach(inputframe i in inputframes) {
  324. if(i.myframe < local_frame - MAX_ROLLBACK_FRAMES - 1) {
  325. deads.Add(i);
  326. }
  327. }
  328. foreach(inputframe d in deads) {
  329. inputframes.Remove(d);
  330. }
  331. }
  332.  
  333. gameui();
  334.  
  335. }
  336.  
  337. [PunRPC]
  338. void onlineready() {
  339. character_select_online();
  340.  
  341. }
  342. /*[PunRPC]
  343. void startgame() {
  344. playingonline=true;
  345. }*/
  346. [PunRPC]
  347. void closeroom() {
  348. if(PhotonNetwork.connected==true && in_game==true) {
  349. online_disconnect();
  350. gametomenu();
  351. reset_game();
  352. }
  353.  
  354. }
  355. [PunRPC]
  356. void pickchar(int gx, int gy) {
  357. localPlayer().enemy.myc.online_char_sel(gx,gy);
  358. }
  359.  
  360. int online_frame=0;
  361. [PunRPC]
  362. void getInput(byte input1, int theframe) {
  363. online_frame = theframe;
  364. last_remote_input = input1;
  365.  
  366. bool bb=false;
  367. foreach(inputframe i in inputframes) {
  368. if(i.myframe == theframe) {
  369. i.remote_input = input1;
  370. bb=true;
  371. }
  372. }
  373. if(bb == false) {
  374. inputframe i = new inputframe();
  375. inputframes.Add(i);
  376. i.myframe = theframe;
  377. i.remote_input = input1;
  378. i.predicted_input = input1;
  379. }
  380.  
  381. }
  382.  
  383.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement