mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-02-01 20:33:46 +08:00
netplay work
This commit is contained in:
parent
205635d51f
commit
9192b4f50e
@ -3932,40 +3932,40 @@
|
||||
"assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450",
|
||||
"assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e",
|
||||
"assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f",
|
||||
"build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d1/cd/67331a44c2d6f296bf77f33ee306",
|
||||
"build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/0e/9ce47318a17ce9ae48c91c2da8d0",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6c/e6/7446860570852b068f72af2fb9fe",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/85/61/ce38df8bbb8ea1472a9669e4b6d7",
|
||||
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/61/83/1111ea2ea7fc3761acde2dc06292",
|
||||
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/88/9c/931d1c5f404fc66a5e458bb2f428",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/dc/52/6ad3df68aeaa90e9a43093f5b4d9",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6d/b8/1ecbd98f66ec260fcffeb64a9b37",
|
||||
"build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/67/78/2af711de47c5239ef26017aa30c5",
|
||||
"build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/13/94/db30b2bc3e2c1106a8fe83a079c6",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b5/88/4cf938c5876c74060ae87be8739f",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/fd/0e/c35f6920f03ef6b762948133b316",
|
||||
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/47/08/9bf4c023631178c59ae1bd272ca4",
|
||||
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/71/19/42f7719d481349cc1f5fe9a7d99d",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f5/57/af559c12b01375b3fcaf33481655",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/5a/9d/870578d93d2b3b2c1bcc784f55e7",
|
||||
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/f5/14/a1ccbdf25ba24d1d46bcde6ae015",
|
||||
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/4a/ea/967d2fe1adab321afadc6144c56c",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/cb/d1/c43570bda2cbb6e6f8e767c054b9",
|
||||
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/cc/15/803086f664162eb61aae4363ee76",
|
||||
"build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/bf/393694ea67f3d590dd2706c9955e",
|
||||
"build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/78/cb/bb9ae4f896f862074057c8e36e1d",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ae/bd/39d7b885f7f01e81d0e96f0f85ce",
|
||||
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/30/da/709e6b36f4f3158843d3a39032c6",
|
||||
"build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c0/9b/5d60f10dbe2e6f670b9e177bce16",
|
||||
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/d9/563a6949d2c4db5a915c54460fbc",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d0/6a/42fe8d2e34f95e1b3282e8422344",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/50/cf/bad44b07a4022aee3001002086b5",
|
||||
"build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/30/e6/1f20540e32ee690d548bbe78e038",
|
||||
"build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/8f/e8/4153e97345a2405df151702b8fc9",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ef/d5/76b650d50e50a839fda4e499c270",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b3/3d/38218c0f9a876513c854ed75e960",
|
||||
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7c/58/c16677ab8794b977e95671e007e1",
|
||||
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/2e/e5/d6af87158a6209d96b5c0ef797c0",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c4/11/2082e99d03f4454f10dda7e56e6d",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7f/0a/fe4b2c683075cf837b9f0c37fe87"
|
||||
"build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/fd/41/a1ef000678c7cb89f87133a8f570",
|
||||
"build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/f8/12/c69a75fae714824ad525e43876d9",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/13/c2/f88ae12e42b164cc7ca9ed61e230",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/05/01/9aca815693cfc9200fe937a2ae58",
|
||||
"build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d6/20/7061a88a9dbd5c51eea45fce76bf",
|
||||
"build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/90/cb/be6d4aa11eb87cef4716d7e31901",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/17/df/23215ac9d4dacaa44edfd2310b91",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/a7/ad/1ec53567ccbd6a83334516b1c29b",
|
||||
"build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/4c/f5/d4bb7ed9f5f8dd2e7a5efbdeb5fe",
|
||||
"build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d9/9c/0e65f40739f4023f2fd5c7c4fdf2",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ba/fd/ac27673e2a5d56edf1b01d88da67",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/39/4c/206eecc8816ba3d46c28030cb795",
|
||||
"build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/b5/b5/7b5e887b9f0223f4372b97bd3e70",
|
||||
"build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/fd/c0/388a49b4a8b2879c6924fade2cc6",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/55/9e/e4a8a4458b7582883873d473fb42",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b3/c6/8c6ef646c2aa04e218b8f4974dc2",
|
||||
"build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/65/73/6d3ed79e37a08f575df04145b43d",
|
||||
"build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e9/03/60abb7a8cd8850fe4e1da24ff5ec",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/e2/76/0d2133bb2cbde40f684dc33e0720",
|
||||
"build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/e0/0e/36917b6deb6a079b73da41af358d",
|
||||
"build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/11/a7/73334288aedb6a2f990ae204ada6",
|
||||
"build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/14/20/4225a2af6c3893b9ab8b6ebd3e23",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a9/62/6166bba0b039be543105d1d7b642",
|
||||
"build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/eb/93/9d28ef49f8848703dfc6b233f7c1",
|
||||
"build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4c/51/0461da41b8cd8c02ff9260035e61",
|
||||
"build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ad/fa/7e4876b066d04ddef7d0cb60f44c",
|
||||
"build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/54/e3/ebd341c2c759ce067db1a740238b",
|
||||
"build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ec/bf/eb162e4704b9d970537ffe210d8d",
|
||||
"build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/aa/3a/a9ab538fb7754ae31870703fb253",
|
||||
"build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/51/8b/0fed5e510cc87557a79814211a05",
|
||||
"build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c4/6c/5f22862278b52e6d1b63d1f28b94",
|
||||
"build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b5/1f/983902fc58ea15a69653678f53b0",
|
||||
"build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a0/90/0d1a8771ad1798153180a28e453b",
|
||||
"build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/be/69/9072e5c66d0eb21727212843be8c",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/64/20/ee2ab6fee781ee8f1e2532c00dc2",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/1e/7178ea47b9331addd638c8e81b55"
|
||||
}
|
||||
1
.idea/dictionaries/ericf.xml
generated
1
.idea/dictionaries/ericf.xml
generated
@ -871,6 +871,7 @@
|
||||
<w>getcurrency</w>
|
||||
<w>getcwd</w>
|
||||
<w>getdata</w>
|
||||
<w>gethostbyname</w>
|
||||
<w>getinputdevice</w>
|
||||
<w>getkillerplayer</w>
|
||||
<w>getlevel</w>
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
### 1.6.0 (20308)
|
||||
- Revamped netcode significantly. We still don't have client-prediction, but things should (hopefully) feel much lower latency now.
|
||||
- Added network debug graphs accessible by hitting F8.
|
||||
- Added private parties functionality (cloud hosted parties with associated codes making it easier to play with friends)
|
||||
- The meta subsystem now enables new plugins by default in headless builds.
|
||||
- Added option to save party in Manual tab
|
||||
|
||||
@ -372,6 +372,7 @@
|
||||
<w>getbitshigh</w>
|
||||
<w>getcollidemodel</w>
|
||||
<w>getdata</w>
|
||||
<w>gethostbyname</w>
|
||||
<w>getifaddrs</w>
|
||||
<w>getinputdevice</w>
|
||||
<w>getline</w>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!-- THIS FILE IS AUTO GENERATED; DO NOT EDIT BY HAND -->
|
||||
<h4><em>last updated on 2021-03-11 for Ballistica version 1.6.0 build 20323</em></h4>
|
||||
<h4><em>last updated on 2021-03-19 for Ballistica version 1.6.0 build 20324</em></h4>
|
||||
<p>This page documents the Python classes and functions in the 'ba' module,
|
||||
which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please <a href="mailto:support@froemling.net">let me know</a>. Happy modding!</p>
|
||||
<hr>
|
||||
|
||||
@ -66,14 +66,15 @@ class AppGlobals {
|
||||
std::string user_config_dir;
|
||||
bool started_suicide{};
|
||||
|
||||
// Netplay testing.
|
||||
int buffer_time{1000 / 30};
|
||||
// Maximum time in milliseconds to buffer game input/output before sending
|
||||
// it over the network.
|
||||
int buffer_time{0};
|
||||
|
||||
// How often we send dynamics sync packets.
|
||||
// How often we send dynamics resync messages.
|
||||
int dynamics_sync_time{500};
|
||||
|
||||
// How many steps we sample for each bucket.
|
||||
int delay_samples{20};
|
||||
int delay_bucket_samples{60};
|
||||
|
||||
bool vr_mode{g_buildconfig.vr_build()};
|
||||
// Temp dirty way to do some shutdown stuff (FIXME: move to an App method).
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't change here.
|
||||
const int kAppBuildNumber = 20323;
|
||||
const int kAppBuildNumber = 20325;
|
||||
const char* kAppVersion = "1.6.0";
|
||||
|
||||
// Our standalone globals.
|
||||
|
||||
@ -1117,7 +1117,7 @@ void Game::PushToggleManualCameraCall() {
|
||||
}
|
||||
|
||||
void Game::PushToggleDebugInfoDisplayCall() {
|
||||
PushCall([] { g_graphics->ToggleDebugInfoDisplay(); });
|
||||
PushCall([] { g_graphics->ToggleNetworkDebugDisplay(); });
|
||||
}
|
||||
|
||||
void Game::PushToggleCollisionGeometryDisplayCall() {
|
||||
|
||||
@ -21,20 +21,22 @@ class ClientSession : public Session {
|
||||
virtual auto GetActualTimeAdvance(int advance_in) -> int {
|
||||
return advance_in;
|
||||
}
|
||||
void Update(int time_advance) override;
|
||||
void Draw(FrameDef* f) override;
|
||||
virtual void HandleSessionMessage(const std::vector<uint8_t>& buffer);
|
||||
void Reset(bool rewind);
|
||||
auto Update(int time_advance) -> void override;
|
||||
auto Draw(FrameDef* f) -> void override;
|
||||
virtual auto HandleSessionMessage(const std::vector<uint8_t>& buffer) -> void;
|
||||
auto Reset(bool rewind) -> void;
|
||||
auto GetForegroundContext() -> Context override;
|
||||
auto DoesFillScreen() const -> bool override;
|
||||
void ScreenSizeChanged() override;
|
||||
void LanguageChanged() override;
|
||||
auto shutting_down() const -> bool { return shutting_down_; }
|
||||
void GetCorrectionMessages(bool blend,
|
||||
std::vector<std::vector<uint8_t> >* messages);
|
||||
auto ScreenSizeChanged() -> void override;
|
||||
auto LanguageChanged() -> void override;
|
||||
auto GetCorrectionMessages(bool blend,
|
||||
std::vector<std::vector<uint8_t> >* messages)
|
||||
-> void;
|
||||
|
||||
// Called when attempting to step without input data available.
|
||||
virtual void OnCommandBufferUnderrun() {}
|
||||
/// Called when attempting to step without input data available.
|
||||
virtual auto OnCommandBufferUnderrun() -> void {}
|
||||
|
||||
virtual auto OnBaseTimeStepAdded(int step) -> void {}
|
||||
|
||||
// Returns existing objects; throws exceptions if not available.
|
||||
auto GetScene(int id) const -> Scene*;
|
||||
@ -45,46 +47,83 @@ class ClientSession : public Session {
|
||||
auto GetMaterial(int id) const -> Material*;
|
||||
auto GetSound(int id) const -> Sound*;
|
||||
|
||||
protected:
|
||||
virtual void OnReset(bool rewind);
|
||||
virtual void FetchMessages() {}
|
||||
int steps_on_list_;
|
||||
std::list<std::vector<uint8_t> > commands_; // ready-to-go commands
|
||||
auto base_time_buffered() const { return base_time_buffered_; }
|
||||
auto consume_rate() const { return consume_rate_; }
|
||||
auto set_consume_rate(float val) { consume_rate_ = val; }
|
||||
auto target_base_time() const { return target_base_time_; }
|
||||
auto base_time() const { return base_time_; }
|
||||
auto shutting_down() const { return shutting_down_; }
|
||||
|
||||
auto scenes() const -> const std::vector<Object::Ref<Scene> >& {
|
||||
return scenes_;
|
||||
}
|
||||
auto nodes() const -> const std::vector<Object::WeakRef<Node> >& {
|
||||
return nodes_;
|
||||
}
|
||||
auto textures() const -> const std::vector<Object::Ref<Texture> >& {
|
||||
return textures_;
|
||||
}
|
||||
auto models() const -> const std::vector<Object::Ref<Model> >& {
|
||||
return models_;
|
||||
}
|
||||
auto sounds() const -> const std::vector<Object::Ref<Sound> >& {
|
||||
return sounds_;
|
||||
}
|
||||
auto collide_models() const
|
||||
-> const std::vector<Object::Ref<CollideModel> >& {
|
||||
return collide_models_;
|
||||
}
|
||||
auto materials() const -> const std::vector<Object::Ref<Material> >& {
|
||||
return materials_;
|
||||
}
|
||||
auto commands() const -> const std::list<std::vector<uint8_t> >& {
|
||||
return commands_;
|
||||
}
|
||||
auto add_end_of_file_command() {
|
||||
commands_.emplace_back(1, static_cast<uint8_t>(SessionCommand::kEndOfFile));
|
||||
}
|
||||
virtual auto OnReset(bool rewind) -> void;
|
||||
virtual auto FetchMessages() -> void {}
|
||||
virtual void Error(const std::string& description);
|
||||
void End();
|
||||
millisecs_t base_time_;
|
||||
double target_base_time_ = 0.0f;
|
||||
bool shutting_down_;
|
||||
std::vector<int> least_buffered_count_list_; // move this to net-client?..
|
||||
std::vector<int> most_buffered_count_list_;
|
||||
int buffer_count_list_index_;
|
||||
int adjust_counter_;
|
||||
float correction_ = 1.0f;
|
||||
float largest_spike_smoothed_ = 0.0f;
|
||||
float low_pass_smoothed_ = 0.0f;
|
||||
void DumpFullState(GameStream* out) override;
|
||||
|
||||
/// Reset target base time to equal current. This can be used during command
|
||||
/// buffer underruns to cause playback to pause momentarily instead of
|
||||
/// skipping ahead to catch up. Generally desired for replays but not for
|
||||
/// net-play.
|
||||
auto ResetTargetBaseTime() -> void { target_base_time_ = base_time_; }
|
||||
|
||||
private:
|
||||
void ClearSessionObjs();
|
||||
void AddCommand(const std::vector<uint8_t>& command);
|
||||
|
||||
// commands being built up for the next time step
|
||||
// (we want to be able to run *everything* for a given timestep at once
|
||||
// to avoid drawing things in half-changed states, etc)
|
||||
std::list<std::vector<uint8_t> > commands_pending_; // commands for the next
|
||||
std::vector<uint8_t> current_cmd_;
|
||||
uint8_t* current_cmd_ptr_;
|
||||
auto ReadByte() -> uint8_t;
|
||||
auto ReadInt32() -> int32_t;
|
||||
void ReadInt32_2(int32_t* vals);
|
||||
void ReadInt32_3(int32_t* vals);
|
||||
void ReadInt32_4(int32_t* vals);
|
||||
auto ReadInt32_2(int32_t* vals) -> void;
|
||||
auto ReadInt32_3(int32_t* vals) -> void;
|
||||
auto ReadInt32_4(int32_t* vals) -> void;
|
||||
auto ReadString() -> std::string;
|
||||
auto ReadFloat() -> float;
|
||||
void ReadFloats(int count, float* vals);
|
||||
void ReadInt32s(int count, int32_t* vals);
|
||||
void ReadChars(int count, char* vals);
|
||||
auto ReadFloats(int count, float* vals) -> void;
|
||||
auto ReadInt32s(int count, int32_t* vals) -> void;
|
||||
auto ReadChars(int count, char* vals) -> void;
|
||||
|
||||
// Ready-to-go commands.
|
||||
std::list<std::vector<uint8_t> > commands_;
|
||||
|
||||
// Commands being built up for the next time step (we need to ship timesteps
|
||||
// as a whole).
|
||||
std::list<std::vector<uint8_t> > commands_pending_;
|
||||
std::vector<uint8_t> current_cmd_;
|
||||
uint8_t* current_cmd_ptr_{};
|
||||
int base_time_buffered_{};
|
||||
bool shutting_down_{};
|
||||
|
||||
millisecs_t base_time_{};
|
||||
double target_base_time_{};
|
||||
float consume_rate_{1.0f};
|
||||
|
||||
protected:
|
||||
std::vector<Object::Ref<Scene> > scenes_;
|
||||
std::vector<Object::WeakRef<Node> > nodes_;
|
||||
std::vector<Object::Ref<Texture> > textures_;
|
||||
|
||||
@ -17,17 +17,44 @@ class NetClientSession : public ClientSession {
|
||||
auto connection_to_host() const -> ConnectionToHost* {
|
||||
return connection_to_host_.get();
|
||||
}
|
||||
void SetConnectionToHost(ConnectionToHost* c);
|
||||
void HandleSessionMessage(const std::vector<uint8_t>& buffer) override;
|
||||
void OnCommandBufferUnderrun() override;
|
||||
|
||||
protected:
|
||||
void Update(int time_advance) override;
|
||||
auto SetConnectionToHost(ConnectionToHost* c) -> void;
|
||||
auto HandleSessionMessage(const std::vector<uint8_t>& buffer)
|
||||
-> void override;
|
||||
auto OnCommandBufferUnderrun() -> void override;
|
||||
auto Update(int time_advance) -> void override;
|
||||
auto OnReset(bool rewind) -> void override;
|
||||
auto OnBaseTimeStepAdded(int step) -> void override;
|
||||
|
||||
private:
|
||||
void UpdateBuffering();
|
||||
bool writing_replay_ = false;
|
||||
struct SampleBucket {
|
||||
// int least_buffered_count{};
|
||||
// int most_buffered_count{};
|
||||
int max_delay_from_projection{};
|
||||
};
|
||||
|
||||
auto ProjectedBaseTime(millisecs_t now) const -> millisecs_t {
|
||||
return leading_base_time_received_
|
||||
+ (now - leading_base_time_receive_time_);
|
||||
}
|
||||
auto UpdateBuffering() -> void;
|
||||
auto GetBucketNum() -> int;
|
||||
|
||||
bool writing_replay_{};
|
||||
millisecs_t base_time_received_{};
|
||||
millisecs_t last_base_time_receive_time_{};
|
||||
millisecs_t leading_base_time_received_{};
|
||||
millisecs_t leading_base_time_receive_time_{};
|
||||
Object::WeakRef<ConnectionToHost> connection_to_host_;
|
||||
std::vector<SampleBucket> buckets_{5};
|
||||
|
||||
// float bucket_max_smoothed_{};
|
||||
// float bucket_min_smoothed_{};
|
||||
float max_delay_smoothed_{};
|
||||
float last_bucket_max_delay_{};
|
||||
float current_delay_{};
|
||||
|
||||
int delay_sample_counter_{};
|
||||
int adjust_counter_{};
|
||||
};
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -17,25 +17,24 @@ class ReplayClientSession : public ClientSession,
|
||||
public:
|
||||
explicit ReplayClientSession(std::string filename);
|
||||
~ReplayClientSession() override;
|
||||
void OnReset(bool rewind) override;
|
||||
auto OnReset(bool rewind) -> void override;
|
||||
|
||||
// Our ClientControllerInterface implementation.
|
||||
auto GetActualTimeAdvance(int advance_in) -> int override;
|
||||
void OnClientConnected(ConnectionToClient* c) override;
|
||||
void OnClientDisconnected(ConnectionToClient* c) override;
|
||||
void DumpFullState(GameStream* out) override;
|
||||
auto OnClientConnected(ConnectionToClient* c) -> void override;
|
||||
auto OnClientDisconnected(ConnectionToClient* c) -> void override;
|
||||
auto OnCommandBufferUnderrun() -> void override;
|
||||
|
||||
protected:
|
||||
void Error(const std::string& description) override;
|
||||
void FetchMessages() override;
|
||||
auto Error(const std::string& description) -> void override;
|
||||
auto FetchMessages() -> void override;
|
||||
|
||||
private:
|
||||
uint32_t message_fetch_num_;
|
||||
bool have_sent_client_message_;
|
||||
uint32_t message_fetch_num_{};
|
||||
bool have_sent_client_message_{};
|
||||
std::vector<ConnectionToClient*> connections_to_clients_;
|
||||
std::vector<ConnectionToClient*> connections_to_clients_ignored_;
|
||||
std::string file_name_;
|
||||
FILE* file_;
|
||||
FILE* file_{};
|
||||
};
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -386,16 +386,22 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
}
|
||||
}
|
||||
|
||||
// Draw debug graphs.
|
||||
if (explicit_bool(false)) {
|
||||
if (!debug_graph_1_.exists()) {
|
||||
debug_graph_1_ = Object::New<NetGraph>();
|
||||
// Draw any debug graphs.
|
||||
{
|
||||
float debug_graph_y = 50.0;
|
||||
auto now = GetRealTime();
|
||||
for (auto it = debug_graphs_.begin(); it != debug_graphs_.end();) {
|
||||
assert(it->second.exists());
|
||||
if (now - it->second->LastUsedTime() > 1000) {
|
||||
it = debug_graphs_.erase(it);
|
||||
} else {
|
||||
it->second->Draw(pass, GetRealTime(), 50.0f, debug_graph_y, 500.0f,
|
||||
100.0f);
|
||||
debug_graph_y += 110.0f;
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
debug_graph_1_->Draw(pass, GetRealTime(), 50.0f, 50.0f, 500.0f, 100.0f);
|
||||
if (!debug_graph_2_.exists()) {
|
||||
debug_graph_2_ = Object::New<NetGraph>();
|
||||
}
|
||||
debug_graph_2_->Draw(pass, GetRealTime(), 50.0f, 160.0f, 500.0f, 100.0f);
|
||||
}
|
||||
|
||||
// Screen messages (bottom).
|
||||
@ -736,6 +742,18 @@ void Graphics::DrawMiscOverlays(RenderPass* pass) {
|
||||
}
|
||||
}
|
||||
|
||||
auto Graphics::GetDebugGraph(const std::string& name, bool smoothed)
|
||||
-> NetGraph* {
|
||||
auto out = debug_graphs_.find(name);
|
||||
if (out == debug_graphs_.end()) {
|
||||
debug_graphs_[name] = Object::New<NetGraph>();
|
||||
debug_graphs_[name]->SetLabel(name);
|
||||
debug_graphs_[name]->SetSmoothed(smoothed);
|
||||
}
|
||||
debug_graphs_[name]->SetLastUsedTime(GetRealTime());
|
||||
return debug_graphs_[name].get();
|
||||
}
|
||||
|
||||
void Graphics::GetSafeColor(float* red, float* green, float* blue,
|
||||
float target_intensity) {
|
||||
assert(red && green && blue);
|
||||
@ -1462,13 +1480,13 @@ void Graphics::LocalCameraShake(float mag) {
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::ToggleDebugInfoDisplay() {
|
||||
void Graphics::ToggleNetworkDebugDisplay() {
|
||||
assert(InGameThread());
|
||||
debug_info_display_ = !debug_info_display_;
|
||||
if (debug_info_display_) {
|
||||
ScreenMessage("debug info on\n");
|
||||
network_debug_display_enabled_ = !network_debug_display_enabled_;
|
||||
if (network_debug_display_enabled_) {
|
||||
ScreenMessage("Network Debug Display Enabled");
|
||||
} else {
|
||||
ScreenMessage("debug info off\n");
|
||||
ScreenMessage("Network Debug Display Disabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -129,8 +129,10 @@ class Graphics {
|
||||
auto ToggleManualCamera() -> void;
|
||||
auto LocalCameraShake(float intensity) -> void;
|
||||
auto ToggleDebugDraw() -> void;
|
||||
auto debug_info_display() const -> bool { return debug_info_display_; }
|
||||
auto ToggleDebugInfoDisplay() -> void;
|
||||
auto network_debug_info_display_enabled() const -> bool {
|
||||
return network_debug_display_enabled_;
|
||||
}
|
||||
auto ToggleNetworkDebugDisplay() -> void;
|
||||
auto SetGyroEnabled(bool enable) -> void;
|
||||
auto floor_reflection() const -> bool {
|
||||
assert(InGameThread());
|
||||
@ -265,8 +267,7 @@ class Graphics {
|
||||
auto set_gyro_vals(const Vector3f& vals) -> void { gyro_vals_ = vals; }
|
||||
auto show_net_info() const -> bool { return show_net_info_; }
|
||||
auto set_show_net_info(bool val) -> void { show_net_info_ = val; }
|
||||
auto debug_graph_1() const -> NetGraph* { return debug_graph_1_.get(); }
|
||||
auto debug_graph_2() const -> NetGraph* { return debug_graph_2_.get(); }
|
||||
auto GetDebugGraph(const std::string& name, bool smoothed) -> NetGraph*;
|
||||
|
||||
// Used by meshes.
|
||||
auto AddMeshDataCreate(MeshData* d) -> void;
|
||||
@ -372,12 +373,11 @@ class Graphics {
|
||||
bool show_net_info_{};
|
||||
bool tv_border_{};
|
||||
bool floor_reflection_{};
|
||||
Object::Ref<NetGraph> debug_graph_1_;
|
||||
Object::Ref<NetGraph> debug_graph_2_;
|
||||
std::map<std::string, Object::Ref<NetGraph> > debug_graphs_;
|
||||
std::mutex frame_def_delete_list_mutex_;
|
||||
std::vector<FrameDef*> frame_def_delete_list_;
|
||||
bool debug_draw_{};
|
||||
bool debug_info_display_{};
|
||||
bool network_debug_display_enabled_{};
|
||||
Object::Ref<Camera> camera_;
|
||||
millisecs_t next_stat_update_time_{};
|
||||
int last_total_frames_rendered_{};
|
||||
|
||||
@ -14,16 +14,30 @@ class NetGraph::Impl {
|
||||
std::list<std::pair<double, float>> samples;
|
||||
double duration = 2000.0;
|
||||
double v_max_smoothed = 1.0;
|
||||
double v_smoothed = 0.0;
|
||||
bool smoothed = false;
|
||||
std::string label;
|
||||
ImageMesh bg_mesh;
|
||||
MeshIndexedSimpleFull value_mesh;
|
||||
TextGroup max_vel_text;
|
||||
millisecs_t last_used_time{};
|
||||
};
|
||||
|
||||
NetGraph::NetGraph() : impl_(new NetGraph::Impl()) {}
|
||||
|
||||
NetGraph::~NetGraph() = default;
|
||||
|
||||
void NetGraph::AddSample(double time, double value) {
|
||||
auto NetGraph::SetLabel(const std::string& label) -> void {
|
||||
impl_->label = label;
|
||||
}
|
||||
auto NetGraph::SetSmoothed(bool val) -> void { impl_->smoothed = val; }
|
||||
|
||||
auto NetGraph::SetLastUsedTime(millisecs_t real_time) -> void {
|
||||
impl_->last_used_time = real_time;
|
||||
}
|
||||
auto NetGraph::LastUsedTime() -> millisecs_t { return impl_->last_used_time; }
|
||||
|
||||
auto NetGraph::AddSample(double time, double value) -> void {
|
||||
impl_->samples.emplace_back(time, value);
|
||||
double cutoffTime = time - impl_->duration;
|
||||
|
||||
@ -49,6 +63,8 @@ void NetGraph::Draw(RenderPass* pass, double time, double x, double y, double w,
|
||||
|
||||
int num_samples = static_cast<int>(impl_->samples.size());
|
||||
|
||||
double val = 0.0;
|
||||
|
||||
// Draw values (provided we have at least 2 samples)
|
||||
bool draw_values = (num_samples >= 2);
|
||||
if (draw_values) {
|
||||
@ -66,8 +82,10 @@ void NetGraph::Draw(RenderPass* pass, double time, double x, double y, double w,
|
||||
}
|
||||
}
|
||||
double smoothing = 0.95;
|
||||
val = impl_->samples.back().second;
|
||||
impl_->v_max_smoothed =
|
||||
smoothing * impl_->v_max_smoothed + (1.0 - smoothing) * v_max * 1.1;
|
||||
impl_->v_smoothed = smoothing * impl_->v_smoothed + (1.0 - smoothing) * val;
|
||||
|
||||
double v_top = impl_->v_max_smoothed;
|
||||
double v_height = v_top - v_bottom;
|
||||
@ -129,7 +147,14 @@ void NetGraph::Draw(RenderPass* pass, double time, double x, double y, double w,
|
||||
c.Submit();
|
||||
|
||||
char val_str[32];
|
||||
snprintf(val_str, sizeof(val_str), "%.2f", impl_->v_max_smoothed);
|
||||
if (!impl_->label.empty()) {
|
||||
snprintf(val_str, sizeof(val_str), "%s %.3f", impl_->label.c_str(),
|
||||
impl_->smoothed ? impl_->v_smoothed : val);
|
||||
|
||||
} else {
|
||||
snprintf(val_str, sizeof(val_str), "%.3f",
|
||||
impl_->smoothed ? impl_->v_smoothed : val);
|
||||
}
|
||||
impl_->max_vel_text.SetText(val_str, TextMesh::HAlign::kLeft,
|
||||
TextMesh::VAlign::kTop);
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#define BALLISTICA_GRAPHICS_NET_GRAPH_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "ballistica/core/object.h"
|
||||
|
||||
@ -13,9 +14,13 @@ class NetGraph : public Object {
|
||||
public:
|
||||
NetGraph();
|
||||
~NetGraph() override;
|
||||
void AddSample(double time, double value);
|
||||
void Draw(RenderPass* pass, double time, double x, double y, double w,
|
||||
double h);
|
||||
auto AddSample(double time, double value) -> void;
|
||||
auto SetLabel(const std::string& label) -> void;
|
||||
auto SetLastUsedTime(millisecs_t real_time) -> void;
|
||||
auto LastUsedTime() -> millisecs_t;
|
||||
auto SetSmoothed(bool smoothed) -> void;
|
||||
auto Draw(RenderPass* pass, double time, double x, double y, double w,
|
||||
double h) -> void;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
|
||||
@ -248,10 +248,11 @@ void InputDevice::ShipBufferIfFull() {
|
||||
|
||||
// Ship the buffer once it gets big enough or once enough time has passed.
|
||||
millisecs_t real_time = GetRealTime();
|
||||
|
||||
size_t size = remote_input_commands_buffer_.size();
|
||||
if (size > 2
|
||||
&& (static_cast<int>(real_time - last_remote_input_commands_send_time_)
|
||||
> g_app_globals->buffer_time
|
||||
>= g_app_globals->buffer_time
|
||||
|| size > 400)) {
|
||||
last_remote_input_commands_send_time_ = real_time;
|
||||
hc->SendReliableMessage(remote_input_commands_buffer_);
|
||||
|
||||
@ -281,13 +281,14 @@ auto PyValueTest(PyObject* self, PyObject* args, PyObject* keywds)
|
||||
return_val = g_app_globals->buffer_time;
|
||||
} else if (!strcmp(arg, "delaySampling")) {
|
||||
if (have_change) {
|
||||
g_app_globals->delay_samples += static_cast<int>(change);
|
||||
g_app_globals->delay_bucket_samples += static_cast<int>(change);
|
||||
}
|
||||
if (have_absolute) {
|
||||
g_app_globals->buffer_time = static_cast<int>(absolute);
|
||||
}
|
||||
g_app_globals->delay_samples = std::max(1, g_app_globals->delay_samples);
|
||||
return_val = g_app_globals->delay_samples;
|
||||
g_app_globals->delay_bucket_samples =
|
||||
std::max(1, g_app_globals->delay_bucket_samples);
|
||||
return_val = g_app_globals->delay_bucket_samples;
|
||||
} else if (!strcmp(arg, "dynamicsSyncTime")) {
|
||||
if (have_change) {
|
||||
g_app_globals->dynamics_sync_time += static_cast<int>(change);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user