|
| 1 | +# Frequently Asked Questions |
| 2 | + |
| 3 | +This page covers some questions that many users may run into. |
| 4 | + |
| 5 | +If you are not yet familiar with *netfox*, it is recommended to explore the |
| 6 | +rest of the docs first. Doing so will provide the context for the answers |
| 7 | +below. |
| 8 | + |
| 9 | +Note that some questions may overlap, and their answers may refer to eachother. |
| 10 | +This is intentional, to make it easier to find answers to your specific issue. |
| 11 | + |
| 12 | +!!!question "Movement is glitchy, what do I do?" |
| 13 | + Make sure you're synchronizing every property used by `_rollback_tick()`, |
| 14 | + and that the same logic runs on the server and each client. Branching logic |
| 15 | + taking different paths may also be a cause. |
| 16 | + |
| 17 | + Glitchy movement happens when the client and server disagree on game state. |
| 18 | + The client in this case predicts the wrong position for an object, which then |
| 19 | + gets corrected by the server. This is seen as the object snapping into place. |
| 20 | + |
| 21 | + By applying the above suggestions, you're ensuring that your game code |
| 22 | + produces the same state, both as ground truth on the server, and as predicted |
| 23 | + by the clients. |
| 24 | + |
| 25 | +!!!question "I've read about a feature in the docs, but it's not there in the addon!" |
| 26 | + Compare the docs version with the addon's version. |
| 27 | + |
| 28 | + You can select which version to read about in the docs, on the top left |
| 29 | + corner of the page. Using *"latest"* means you're reading about the latest |
| 30 | + features present in the repository. Some of these features may not yet be |
| 31 | + released. |
| 32 | + |
| 33 | +!!!question "Help, something is not working!" |
| 34 | + Check if the issue is still present in the latest release, or in the latest |
| 35 | + main. If so, please let us know! |
| 36 | + |
| 37 | + The *latest release* refers to the version available on the [asset |
| 38 | + library], and in the [releases]. The *latest main* refers to the latest version |
| 39 | + available in the [repository]. The *latest release* is stable, but may contain |
| 40 | + some bugs that are already fixed on *latest main*. The *latest main* is the |
| 41 | + bleeding edge, meaning that it can be unstable. |
| 42 | + |
| 43 | + If the issue is still present, please let us know on [Discord], or by |
| 44 | + filing an [issue]! |
| 45 | + |
| 46 | +[asset library]: https://godotengine.org/asset-library/asset?filter=netfox&category=&godot_version=&cost=&sort=updated |
| 47 | +[releases]: https://github.com/foxssake/netfox/releases |
| 48 | +[repository]: https://github.com/foxssake/netfox |
| 49 | +[Discord]: https://discord.gg/xWGh4GskG5 |
| 50 | +[issue]: https://github.com/foxssake/netfox/issues |
| 51 | + |
| 52 | +!!!question "What properties should I synchronize with RollbackSynchronizer?" |
| 53 | + Synchronize every property representing player input as Input properties. |
| 54 | + |
| 55 | + Synchronize every property read by, or written to in `_rollback_tick()` as |
| 56 | + State properties. |
| 57 | + |
| 58 | + The key concept to keep in mind, is that both server and client need to |
| 59 | + produce the same resulting game state as part of `_rollback_tick()`. Also keep |
| 60 | + in mind, that the game may rewind to an earlier state and resimulate from |
| 61 | + there. |
| 62 | + |
| 63 | + This means that any data used by your game logic needs to be synchronized, |
| 64 | + otherwise it might differ between peers, leading to differing outcomes, |
| 65 | + ultimately result in glitches. The most surefire way is to synchronize each |
| 66 | + piece of data used by the simulation. |
| 67 | + |
| 68 | +!!!question "What kind of data can netfox synchronize?" |
| 69 | + Data that is safe to use as RPC parameters is also safe with netfox. Other |
| 70 | + data types may work with [custom schemas]. Values passed by reference are best |
| 71 | + avoided. |
| 72 | + |
| 73 | + Types passed by value are safe to synchronize - e.g. `int`, `float`, |
| 74 | + `String`, `Transform3D`, etc. |
| 75 | + |
| 76 | + Values passed by reference are not recommended. Since *netfox* needs to |
| 77 | + keep a history, the value of the property is stored for every tick. For |
| 78 | + reference types, the history can only store a *reference* to the value, not the |
| 79 | + value itself. This means that the same reference may be stored for multiple |
| 80 | + ticks. This leads to values "leaking" between ticks, i.e. a modification set in |
| 81 | + a tick may show up in an earlier tick where it shouldn't have. |
| 82 | + |
| 83 | + These may be worked around either by duplicating the value for every tick |
| 84 | + in `_rollback_tick()`, or by writing a custom wrapper type that keeps a history |
| 85 | + for the value for every tick. These are only recommended for advanced users. |
| 86 | + |
| 87 | + The best approach, when available, is flattening the complex value into |
| 88 | + multiple, value-based properties. This approach also benefits more from |
| 89 | + diff states. |
| 90 | + |
| 91 | +[custom schemas]: ./netfox/guides/network-schemas.md#implementing-a-custom-serializer |
| 92 | + |
| 93 | +!!!question "When should I use RollbackSynchronizer vs. StateSynchronizer vs. MultiplayerSynchronizer?" |
| 94 | + Use `RollbackSynchronizer` for responsive behavior, e.g. player movement. |
| 95 | + Also use for objects that need to interact with other objects in rollback. |
| 96 | + |
| 97 | + Use `PredictiveSynchronizer` for objects that need to participate in |
| 98 | + rollback, but their state can be predicted by every peer on their own. For |
| 99 | + example, projectiles. |
| 100 | + |
| 101 | + Use `StateSynchronizer` for objects that don't need to respond instantly, |
| 102 | + but may still benefit from interpolation, diff states, schemas, or other netfox |
| 103 | + features. For example, NPCs with their positions interpolated. Often used |
| 104 | + for objects completely owned by the server. |
| 105 | + |
| 106 | + Use `MultiplayerSynchronizer` as a fallback, e.g. for data that doesn't |
| 107 | + need to be interpolated. |
| 108 | + |
| 109 | + Keep in mind that `MultiplayerSynchronizer` without a *Replication |
| 110 | + interval* or *Delta interval* will transmit data on every `_process()`, |
| 111 | + potentially increasing bandwidth. In contrast, *netfox* only transmits updates |
| 112 | + per network tick. |
| 113 | + |
| 114 | +!!!question "Can I use MultiplayerSpawner with netfox and rollback?" |
| 115 | + Yes. |
| 116 | + |
| 117 | + In general, *netfox* tries to build on top of Godot's multiplayer tooling, |
| 118 | + instead of replacing them. |
| 119 | + |
| 120 | +!!!question "Is netfox only usable for rollback?" |
| 121 | + <a id="is-netfox-only-usable-for-rollback"></a> |
| 122 | + No, rollback is one approach that *netfox* supports. |
| 123 | + |
| 124 | + For prototypes and certain game types, a client-authoritative approach |
| 125 | + works well. Many tools provided by *netfox* are useful here - time |
| 126 | + synchronization, interpolation, schemas, diff states, etc. |
| 127 | + |
| 128 | + The tools mentioned above are also useful regardless of networking |
| 129 | + approach, and can be reused for custom solutions. This includes |
| 130 | + productivity features, like auto-tiling windows, automatically setting up |
| 131 | + server and client connections on game start, and built-in latency simulation. |
| 132 | + |
| 133 | + In addition, support for other approaches are also planned for *netfox*. |
| 134 | + |
| 135 | +!!!question "What kind of games can I build with netfox?" |
| 136 | + In general, most games can be expressed with rollback netcode, with a few |
| 137 | + notable exceptions. Rollback is also [not the only approach |
| 138 | + available](#is-netfox-only-usable-for-rollback) with *netfox*. |
| 139 | + |
| 140 | + Rollback is most often used for fighting games, where it's important that |
| 141 | + every input is processed and applied in the correct chronological order. |
| 142 | + |
| 143 | + Racing games that need collisions are good candidates for use with netfox's |
| 144 | + [physics support]. |
| 145 | + |
| 146 | + FPS games are also doable with rollback, but favoring the shooter is not |
| 147 | + trivial to implement. |
| 148 | + |
| 149 | + RTS games specifically are not recommended with rollback. These games |
| 150 | + usually involve from dozens to possibly thousands of entities present in the |
| 151 | + game. Resimulating these entities requires lots of CPU time. Additionally, |
| 152 | + synchronizing all their properties through the network requires lots of |
| 153 | + bandwidth capacity. This makes rollback not a good fit for RTS games. |
| 154 | + |
| 155 | +[physics support]: ./netfox.extras/guides/physics.md |
| 156 | + |
| 157 | +!!!question "Can I use netfox with C#?" |
| 158 | + Yes, with [NetfoxSharp]. |
| 159 | + |
| 160 | +[NetfoxSharp]: https://github.com/CyFurStudios/NetfoxSharp/ |
| 161 | + |
| 162 | +!!!question "Is NetfoxSharp up to date?" |
| 163 | + NetfoxSharp keeps up to date with the latest netfox release. Unreleased |
| 164 | + features e.g. on latest `main` might not be available. |
| 165 | + |
| 166 | +!!!question "Does netfox support android / iOS / web / ENet / etc.?" |
| 167 | + Yes. |
| 168 | + |
| 169 | + In general, *netfox* builds on top of Godot's multiplayer API, instead of |
| 170 | + replacing it. This means that it does not rely on any platform-specific functionality. |
| 171 | + |
| 172 | + It also uses Godot's built-in functions to transmit data. As long as Godot |
| 173 | + can transmit data on the desired platform or networking protocol, netfox should |
| 174 | + work fine. |
| 175 | + |
| 176 | +!!!question "Can I use Resources in my game logic?" |
| 177 | + Yes. |
| 178 | + |
| 179 | + However, make sure to **not rely on shared resources** in your game logic |
| 180 | + implemented in `_rollback_tick()` or elsewhere if it doesn't make sense. |
| 181 | + |
| 182 | + For example, when implementing a crouching logic that modifies the player's |
| 183 | + `CollisionShape`, make sure that the `CollisionShape` **is not shared**, |
| 184 | + otherwise one player crouching will make every player crouch. |
| 185 | + |
0 commit comments