Ejemplo n.º 1
0
void call_window_script(augs::lua_state_raii& lua, game_window& window, const std::string& filename) {
	lua.global_ptr("global_gl_window", &window.window);
	lua.dofile_and_report_errors(filename);

	window.window.gl.initialize();
	window.window.gl.initialize_fbos(window.get_screen_size());
}
Ejemplo n.º 2
0
void client_setup::init(const config_lua_table& cfg, game_window& window, const std::string recording_filename, const bool use_alternative_port) {
	const vec2i screen_size = vec2i(window.get_screen_size());

	scene_managers::networked_testbed_client().populate_world_with_entities(initial_hypersomnia);

	session.systems_audiovisual.get<interpolation_system>().interpolation_speed = cfg.interpolation_speed;

	detailed_step_log = cfg.tickrate <= 2;

	if (!hypersomnia.load_from_file("save.state")) {
		hypersomnia.set_fixed_delta(cfg.tickrate);
		scene.populate_world_with_entities(hypersomnia);
	}

	if (cfg.get_input_recording_mode() != input_recording_type::DISABLED) {
		if (player.try_to_load_or_save_new_session("sessions/", recording_filename)) {
			timer.set_stepping_speed_multiplier(cfg.recording_replay_speed);
		}
	}

	session.camera.configure_size(screen_size);
	session.set_master_gain(cfg.sound_effects_volume);

	session.configure_input();

	receiver.jitter_buffer.set_lower_limit(static_cast<unsigned>(cfg.jitter_buffer_ms / hypersomnia.get_fixed_delta().in_milliseconds()));
	receiver.misprediction_smoothing_multiplier = cfg.misprediction_smoothing_multiplier;

	const bool is_replaying = player.is_replaying();
	LOG("Is client replaying: %x", is_replaying);
	const auto port = use_alternative_port ? cfg.alternative_port : cfg.connect_port;

	const std::string readable_ip = typesafe_sprintf("%x:%x", cfg.connect_address, port);

	LOG("Connecting to: %x", readable_ip);

	if (is_replaying || client.connect(cfg.connect_address, port, 15000)) {
		LOG("Connected successfully to %x", readable_ip);
		
		augs::stream welcome;
		augs::write_object(welcome, network_command::CLIENT_WELCOME_MESSAGE);
		augs::write_object(welcome, use_alternative_port ? cfg.debug_second_nickname : cfg.nickname);

		client.post_redundant(welcome);

		timer.reset_timer();
	}
	else {
		LOG("Connection failed.");
	}

	session.reserve_caches_for_entities(3000);
}
Ejemplo n.º 3
0
void client_setup::process(const config_lua_table& cfg, game_window& window) {
	init(cfg, window);

	while (!should_quit) {
		session.local_entropy_profiler.new_measurement();
		auto precollected = window.collect_entropy(!cfg.debug_disable_cursor_clipping);
		session.local_entropy_profiler.end_measurement();

		if (process_exit_key(precollected))
			break;

		process_once(window, precollected);
	}
}
Ejemplo n.º 4
0
void director_setup::process(const config_lua_table& cfg, game_window& window) {
	const vec2i screen_size = vec2i(window.get_screen_size());

	cosmos hypersomnia(3000);

	augs::window::event::state events;
	augs::machine_entropy total_collected_entropy;
	augs::fixed_delta_timer timer = augs::fixed_delta_timer(5);

	scene_managers::testbed testbed;
	testbed.debug_var = cfg.debug_var;

	if (!hypersomnia.load_from_file("save.state")) {
		hypersomnia.set_fixed_delta(cfg.tickrate);
		testbed.populate_world_with_entities(hypersomnia, screen_size);
	}

	viewing_session session;
	session.reserve_caches_for_entities(3000);
	session.camera.configure_size(screen_size);
	session.systems_audiovisual.get<interpolation_system>().interpolation_speed = cfg.interpolation_speed;
	session.set_interpolation_enabled(false);
	session.set_master_gain(cfg.sound_effects_volume);

	testbed.configure_view(session);

	const std::string input_director_file = cfg.director_scenario_filename;
	const std::string output_director_file = cfg.director_scenario_filename;

	cosmic_movie_director director;
	director.load_recording_from_file(input_director_file);

	enum class director_state {
		PLAYING,
		RECORDING
	} current_director_state = director_state::PLAYING;

	timer.reset_timer();

	int advance_steps_forward = 0;

	float requested_playing_speed = 0.f;

	bool unsaved_changes_exist = false;

	enum class recording_replacement_type {
		ALL,
		ONLY_KEYS,
		ONLY_MOUSE,

		COUNT
	};

	auto recording_replacement_mode = recording_replacement_type::ALL;

	std::vector<cosmos> snapshots_for_rewinding;
	
	const auto initial_step_number = hypersomnia.get_total_steps_passed();

	const double seconds_between_snapshots = 3.0;
	const auto steps_between_snapshots = static_cast<unsigned>(seconds_between_snapshots / hypersomnia.get_fixed_delta().in_seconds());

	unsigned bookmarked_step = 0;

	const auto get_step_number = [initial_step_number](const cosmos& cosm) {
		ensure(initial_step_number <= cosm.get_total_steps_passed());

		return cosm.get_total_steps_passed() - initial_step_number;
	};

	LOG("Seconds between rewind snapshots: %x", seconds_between_snapshots);
	LOG("Steps between rewind snapshots: %x", steps_between_snapshots);

	while (!should_quit) {
		{
			augs::machine_entropy new_entropy;

			session.local_entropy_profiler.new_measurement();
			new_entropy.local = window.collect_entropy(!cfg.debug_disable_cursor_clipping);
			session.local_entropy_profiler.end_measurement();
			
			session.control(new_entropy);

			process_exit_key(new_entropy.local);

			if (current_director_state == director_state::RECORDING) {
				total_collected_entropy += new_entropy;
			}

			for (const auto& raw_input : new_entropy.local) {
				events.apply(raw_input);

				if (raw_input.was_any_key_pressed()) {
					if (raw_input.key == key::F2) {
						current_director_state = director_state::PLAYING;
					}
					if (raw_input.key == key::F3) {
						requested_playing_speed = 0.f;

						if (current_director_state == director_state::RECORDING) {
							recording_replacement_mode = 
								static_cast<recording_replacement_type>((static_cast<int>(recording_replacement_mode) + 1) % static_cast<int>(recording_replacement_type::COUNT));
						}
						else {
							recording_replacement_mode = recording_replacement_type::ALL;

							current_director_state = director_state::RECORDING;
							total_collected_entropy.clear();
						}
					}
					if (raw_input.key == key::F7) {
						director.save_recording_to_file(output_director_file);
						unsaved_changes_exist = false;
					}

					if (raw_input.key == key::_1) {
						advance_steps_forward = -1;

						if (events.is_set(key::LCTRL)) {
							advance_steps_forward *= 10;
						}
					}
					if (raw_input.key == key::_2) {
						advance_steps_forward = 1;

						if (events.is_set(key::LCTRL)) {
							advance_steps_forward *= 10;
						}
					}
					if (raw_input.key == key::_3) {
						requested_playing_speed = 0.f;
						total_collected_entropy.clear();
					}
					if (raw_input.key == key::_4) {
						requested_playing_speed = 0.1f;
						total_collected_entropy.clear();
					}
					if (raw_input.key == key::_5) {
						requested_playing_speed = 1.f;
						total_collected_entropy.clear();
					}
					if (raw_input.key == key::_6) {
						requested_playing_speed = 6.f;
						total_collected_entropy.clear();
					}
					if (raw_input.key == key::_9) {
						bookmarked_step = get_step_number(hypersomnia);
						total_collected_entropy.clear();
					}
					if (raw_input.key == key::_0) {
						advance_steps_forward = static_cast<long long>(bookmarked_step) - static_cast<long long>(get_step_number(hypersomnia));
						total_collected_entropy.clear();
					}
				}
			}

			testbed.control_character_selection(new_entropy.local);

			timer.set_stepping_speed_multiplier(requested_playing_speed);
		}

		if (advance_steps_forward < 0) {
			const auto current_step = get_step_number(hypersomnia);
			const auto rewound_step = static_cast<unsigned>(-advance_steps_forward) > current_step ? 0 : current_step + advance_steps_forward;

#if LOG_REWINDING
			LOG("Current step: %x\nRewound step: %x", current_step, rewound_step);
#endif

			if (rewound_step < current_step) {
				const size_t resimulated_cosmos_index = rewound_step / steps_between_snapshots;
				
#if LOG_REWINDING
				LOG_NVPS(snapshots_for_rewinding.size());
				LOG_NVPS(resimulated_cosmos_index);
#endif

				if (snapshots_for_rewinding.size() > 1 && resimulated_cosmos_index < snapshots_for_rewinding.size() - 1) {
					snapshots_for_rewinding.erase(snapshots_for_rewinding.begin() + resimulated_cosmos_index + 1, snapshots_for_rewinding.end());
				}

				hypersomnia = snapshots_for_rewinding.at(resimulated_cosmos_index);
				
#if LOG_REWINDING
				LOG("Resimulated hypersomnia step: %x", get_step_number(hypersomnia));
#endif

				while (get_step_number(hypersomnia) < rewound_step) {
					const guid_mapped_entropy replayed_entropy = director.get_entropy_for_step(get_step_number(hypersomnia));
					const cosmic_entropy cosmic_entropy_for_this_advancement = cosmic_entropy(replayed_entropy, hypersomnia);

					hypersomnia.advance_deterministic_schemata(cosmic_entropy_for_this_advancement, [](auto) {},
						[this, &session](const const_logic_step& step) {
							session.acquire_game_events_for_hud(step);
						}
					);
				}
			}

			advance_steps_forward = 0;
		}

		auto steps = timer.count_logic_steps_to_perform(hypersomnia.get_fixed_delta());
		
		steps += advance_steps_forward;
		advance_steps_forward = 0;

		const auto selected_character = hypersomnia[testbed.get_selected_character()];

		while (steps--) {
			cosmic_entropy cosmic_entropy_for_this_advancement;
			const auto current_step = get_step_number(hypersomnia);

			if (current_step % steps_between_snapshots == 0) {
				snapshots_for_rewinding.push_back(hypersomnia);
			}

			if (current_director_state == director_state::PLAYING) {
				guid_mapped_entropy replayed_entropy = director.get_entropy_for_step(current_step);

				cosmic_entropy_for_this_advancement = cosmic_entropy(replayed_entropy, hypersomnia);
			}
			else if (current_director_state == director_state::RECORDING) {
				guid_mapped_entropy& recorded_entropy = director.step_to_entropy[current_step];

				auto& target_intents_from_recording = recorded_entropy.entropy_per_entity[selected_character.get_guid()];
				auto new_intents = make_intents_for_entity(selected_character, total_collected_entropy.local, session.context);

				auto mouse_remover = [](const auto& k) { return k.uses_mouse_motion(); };
				auto key_remover = [](const auto& k) { return !k.uses_mouse_motion(); };

				if (recording_replacement_mode == recording_replacement_type::ALL) {
					target_intents_from_recording = new_intents;
				}
				else if (recording_replacement_mode == recording_replacement_type::ONLY_KEYS) {
					erase_remove(target_intents_from_recording, key_remover);
					erase_remove(new_intents, mouse_remover);
					
					concatenate(target_intents_from_recording, new_intents);
				}
				else if (recording_replacement_mode == recording_replacement_type::ONLY_MOUSE) {
					erase_remove(target_intents_from_recording, mouse_remover);
					erase_remove(new_intents, key_remover);

					concatenate(target_intents_from_recording, new_intents);
				}
				else {
					ensure(false);
				}
				
				cosmic_entropy_for_this_advancement = cosmic_entropy(recorded_entropy, hypersomnia);

				unsaved_changes_exist = true;
			}

			renderer::get_current().clear_logic_lines();

			hypersomnia.advance_deterministic_schemata(cosmic_entropy_for_this_advancement, [](auto) {},
					[this, &session](const const_logic_step& step) {
					session.acquire_game_events_for_hud(step);
				}
			);

			session.resample_state_for_audiovisuals(hypersomnia);
			
			total_collected_entropy.clear();
		}

		const auto vdt = session.frame_timer.extract_variable_delta(hypersomnia.get_fixed_delta(), timer);

		session.advance_audiovisual_systems(hypersomnia, testbed.get_selected_character(), vdt);

		using namespace augs::gui::text;

		const auto white_font = style(assets::font_id::GUI_FONT, white);

		auto director_text = format(L"Welcome to the director setup.", white_font);
		director_text += format(L"\nMode: ", white_font); 
		
		if (current_director_state == director_state::PLAYING) {
			director_text += format(L"Playing", white_font);
		}
		else {
			if (recording_replacement_mode == recording_replacement_type::ALL) {
				director_text += simple_bbcode(L"[color=red]Recording (replacing all)[/color]", white_font);
			}
			else if (recording_replacement_mode == recording_replacement_type::ONLY_KEYS) {
				director_text += simple_bbcode(L"[color=red]Recording (replacing keys)[/color]", white_font);
			}
			else if (recording_replacement_mode == recording_replacement_type::ONLY_MOUSE) {
				director_text += simple_bbcode(L"[color=red]Recording (replacing mouse)[/color]", white_font);
			}
			else {
				ensure(false);
			}
		}

		director_text += format(typesafe_sprintf(L"\nRequested playing speed: %x", requested_playing_speed), white_font);
		director_text += format(typesafe_sprintf(L"\nStep number: %x", get_step_number(hypersomnia)), white_font);
		director_text += format(typesafe_sprintf(L"\nTime: %x", get_step_number(hypersomnia)*hypersomnia.get_fixed_delta().in_seconds()), white_font);
		director_text += format(typesafe_sprintf(L"\nControlling entity %x of %x", testbed.current_character_index, testbed.characters.size()), white_font);

		if (bookmarked_step != 0) {
			director_text += format(typesafe_sprintf(L"\nBookmarked time: %x", bookmarked_step*hypersomnia.get_fixed_delta().in_seconds()), white_font);
		}

		if (unsaved_changes_exist) {
			director_text += simple_bbcode(L"\n[color=yellow]Press F7 to save pending changes.[/color]", white_font);
		}

		auto& renderer = augs::renderer::get_current();
		renderer.clear_current_fbo();

		session.view(renderer, hypersomnia, testbed.get_selected_character(), vdt, director_text);

		window.swap_buffers();
	}

	if (unsaved_changes_exist) {
		director.save_recording_to_file(output_director_file + ".unsaved.ent");
	}
}
Ejemplo n.º 5
0
void client_setup::process_once(game_window& window, const augs::machine_entropy::local_type& precollected, const bool swap_buffers) {
	auto step_pred = [this](const cosmic_entropy& entropy, cosmos& cosm) {
		cosm.advance_deterministic_schemata(entropy,
			[this](const logic_step) {},
			[this](const const_logic_step) {}
		);
	};

	auto step_pred_with_effects_response = [this](const cosmic_entropy& entropy, cosmos& cosm) {
		cosm.advance_deterministic_schemata(entropy,
			[this](const logic_step) {},
			[this](const const_logic_step step) {
			session.spread_past_infection(step);
			session.acquire_game_events_for_hud(step);
		}
		);
	};

	augs::machine_entropy new_entropy;

	new_entropy.local = precollected;
	session.remote_entropy_profiler.new_measurement();
	new_entropy.remote = client.collect_entropy();
	session.remote_entropy_profiler.end_measurement();

	const bool still_downloading = !complete_state_received || receiver.jitter_buffer.is_still_refilling();

	total_collected_entropy += new_entropy;

	auto steps = timer.count_logic_steps_to_perform(hypersomnia.get_fixed_delta());

	while (steps--) {
		session.unpack_local_steps_profiler.new_measurement();
		player.advance_player_and_biserialize(total_collected_entropy);
		session.unpack_local_steps_profiler.end_measurement();

		for (auto& net_event : total_collected_entropy.remote) {
			if (net_event.message_type == augs::network::message::type::RECEIVE) {
				auto& stream = net_event.payload;

				auto to_skip = net_event.messages_to_skip;

				while (stream.get_unread_bytes() > 0) {
					network_command command;
					augs::read_object(stream, command);

					const bool should_skip = to_skip > 0;

					if (should_skip) {
						--to_skip;
					}

					if (detailed_step_log && !should_skip) {
						LOG("Client received command: %x", int(stream.peek<unsigned char>()));
					}

					switch (command) {
					case network_command::COMPLETE_STATE:
						ensure(!should_skip);

						cosmic_delta::decode(initial_hypersomnia, stream);
						hypersomnia = initial_hypersomnia;
						extrapolated_hypersomnia = initial_hypersomnia;

						LOG("Decoded cosm at step: %x", hypersomnia.get_total_steps_passed());

						unsigned controlled_character_guid;
						augs::read_object(stream, controlled_character_guid);

						scene.select_character(hypersomnia.get_entity_by_guid(controlled_character_guid));

						complete_state_received = true;
						break;

					case network_command::PACKAGED_STEP: {
						step_packaged_for_network step;
						augs::read_object(stream, step);
						
						if (!should_skip) {
							receiver.acquire_next_packaged_step(step);
						}
					}
						break;

					default: LOG("Client received invalid command: %x", int(command)); stream = augs::stream(); break;

					}
				}
			}
		}

		if (!still_downloading) {
			session.sending_commands_and_predict_profiler.new_measurement();
			const auto local_cosmic_entropy_for_this_step = cosmic_entropy(hypersomnia[scene.get_selected_character()], total_collected_entropy.local, session.context);

			receiver.send_commands_and_predict(client, local_cosmic_entropy_for_this_step, extrapolated_hypersomnia, step_pred_with_effects_response);
			session.sending_commands_and_predict_profiler.end_measurement();

			// LOG("Predicting to step: %x; predicted steps: %x", extrapolated_hypersomnia.get_total_steps_passed(), receiver.predicted_steps.size());

			session.unpack_remote_steps_profiler.new_measurement();
			receiver.unpack_deterministic_steps(
				session.systems_audiovisual.get<interpolation_system>(),
				session.systems_audiovisual.get<past_infection_system>(),
				scene.get_selected_character(), 
				hypersomnia, 
				hypersomnia_last_snapshot, 
				extrapolated_hypersomnia, 
				step_pred);

			session.unpack_remote_steps_profiler.end_measurement();

			session.resample_state_for_audiovisuals(extrapolated_hypersomnia);
		}
		
		if (client.has_timed_out(hypersomnia.get_fixed_delta().in_milliseconds(), 2000)) {
			LOG("Connection to server timed out.");
			client.forceful_disconnect();
		}

		session.sending_packets_profiler.new_measurement();
		client.send_pending_redundant();
		session.sending_packets_profiler.end_measurement();

		total_collected_entropy.clear();
	}

	if (!still_downloading) {
		const auto vdt = session.frame_timer.extract_variable_delta(extrapolated_hypersomnia.get_fixed_delta(), timer);

		session.advance_audiovisual_systems(extrapolated_hypersomnia, scene.get_selected_character(), vdt);

		auto& renderer = augs::renderer::get_current();
		
		if (swap_buffers) {
			renderer.clear_current_fbo();
		}

		session.view(renderer, extrapolated_hypersomnia, scene.get_selected_character(), vdt, client);

		if (swap_buffers) {
			window.swap_buffers();
		}
	}
}
Ejemplo n.º 6
0
void determinism_test_setup::process(const config_lua_table& cfg, game_window& window) {
	const vec2i screen_size = vec2i(window.get_screen_size());

	const unsigned cosmoi_count = 1 + cfg.determinism_test_cloned_cosmoi_count;
	std::vector<cosmos> hypersomnias(cosmoi_count, cosmos(3000));

	augs::machine_entropy total_collected_entropy;
	augs::machine_entropy_player player;
	augs::fixed_delta_timer timer = augs::fixed_delta_timer(5);
	std::vector<scene_managers::testbed> testbeds(cosmoi_count);

	if (augs::file_exists("save.state")) {
		for (auto& h : hypersomnias) {
			ensure(h.load_from_file("save.state"));
		}
	}
	else {
		for (size_t i = 0; i < cosmoi_count; ++i) {
			hypersomnias[i].set_fixed_delta(cfg.tickrate);
			testbeds[i].populate_world_with_entities(hypersomnias[i], vec2i(1920, 1080));
		}
	}

	for (auto& h : hypersomnias) {
		ensure(h == hypersomnias[0]);
	}

	if (cfg.get_input_recording_mode() != input_recording_type::DISABLED) {
		if (player.try_to_load_or_save_new_session("sessions/", "recorded.inputs")) {
			timer.set_stepping_speed_multiplier(cfg.recording_replay_speed);
		}
	}

	viewing_session session;
	session.reserve_caches_for_entities(3000);
	session.camera.configure_size(screen_size);
	session.set_interpolation_enabled(false);
	session.set_master_gain(cfg.sound_effects_volume);

	for (size_t i = 0; i < cosmoi_count; ++i) {
		testbeds[i].configure_view(session);
	}

	unsigned currently_viewn_cosmos = 0;
	bool divergence_detected = false;
	unsigned which_divergent = 0;

	timer.reset_timer();

	while (!should_quit) {
		augs::machine_entropy new_entropy;

		new_entropy.local = window.collect_entropy(!cfg.debug_disable_cursor_clipping);
		
		if (process_exit_key(new_entropy.local))
			break;

		for (auto& n : new_entropy.local) {
			if (n.was_any_key_pressed()) {
				if (n.key == augs::window::event::keys::key::F3) {
					++currently_viewn_cosmos;
					currently_viewn_cosmos %= cosmoi_count;
				}
			}
		}

		total_collected_entropy += new_entropy;

		auto steps = timer.count_logic_steps_to_perform(hypersomnias[0].get_fixed_delta());

		while (steps--) {
			if (divergence_detected) {
				break;
			}

			player.advance_player_and_biserialize(total_collected_entropy);

			for (size_t i = 0; i < cosmoi_count; ++i) {
				auto& h = hypersomnias[i];
				if (i + 1 < cosmoi_count)
					hypersomnias[i] = hypersomnias[i + 1];

				testbeds[i].control_character_selection(total_collected_entropy.local);

				auto cosmic_entropy_for_this_step = cosmic_entropy(h[testbeds[i].get_selected_character()], total_collected_entropy.local, session.context);

				renderer::get_current().clear_logic_lines();

				h.advance_deterministic_schemata(cosmic_entropy_for_this_step, [](auto) {},
					[this, &session](const const_logic_step& step) {
						session.spread_past_infection(step);
					}
				);
			}

			session.resample_state_for_audiovisuals(hypersomnias[0]);

			auto& first_cosm = hypersomnias[0].reserved_memory_for_serialization;

			augs::output_stream_reserver first_cosm_reserver;
			augs::write_object(first_cosm_reserver, hypersomnias[0].significant);
			first_cosm.reserve(first_cosm_reserver.get_write_pos());
			first_cosm.reset_write_pos();
			augs::write_object(first_cosm, hypersomnias[0].significant);

			for (unsigned i = 1; i < cosmoi_count; ++i) {
				auto& second_cosm = hypersomnias[i].reserved_memory_for_serialization;

				augs::output_stream_reserver second_cosm_reserver;
				augs::write_object(second_cosm_reserver, hypersomnias[i].significant);
				second_cosm.reserve(second_cosm_reserver.get_write_pos());
				second_cosm.reset_write_pos();
				augs::write_object(second_cosm, hypersomnias[i].significant);

				if (!(first_cosm == second_cosm)) {
					divergence_detected = true;
					which_divergent = i;
					break;
				}
			}

			total_collected_entropy.clear();
		}

		std::string logged;

		if (divergence_detected) {
			logged += typesafe_sprintf("Divergence detected in cosmos: %x (step: %x)\n", which_divergent, hypersomnias[0].get_total_steps_passed());
		}

		logged += typesafe_sprintf("Currently viewn cosmos: %x (F3 to switch)\n", currently_viewn_cosmos);

		auto& renderer = augs::renderer::get_current();
		renderer.clear_current_fbo();

		session.view(renderer, hypersomnias[currently_viewn_cosmos], testbeds[currently_viewn_cosmos].get_selected_character(), session.frame_timer.extract_variable_delta(hypersomnias[currently_viewn_cosmos].get_fixed_delta(), timer));
	
		window.swap_buffers();
	}
}