Sim-eth-es Troubleshootings

Is there an easy way to limit/set the rate at which certain EntitySets are populated?
I have the scenario of a robotic arm which is moving. The Server/the Component knows the exact float value of the position, which is only partially predictable (e.g. if the power in the grid goes down, movement speed is decreased).

For this reason it’s acceptable to only send 2-5 updates per second (this obviously needs testing). Interpolation is already implemented in the client, but per default I receive 60 packets per second.

Do I need a separate channel, custom messages and a separate Thread? (or just a different component, which is updated by system every 3 frames or something, that’d be the poor mans solution probably)

In other words: How can I have separately and slower updated entitysets, for which the client listens for?

…hmmm… nothing sends anything at 60 packets per second. There are 60 updates per second from sim-ethereal for real time position synching… but those are sent 20 times a second as bundles.

For regular ES updates they only happen as often as the entity updater pushes them.

So are these regular component updates or real-time synched positions? If the latter, is it really important to save the 20 bytes or so for that frame? (I assume you have other things that really do need updating in real time?)

Edit: and actually, for sim-ethereal managed stuff, if you don’t push a position/rotation change then those are 1-bit each that frame. a “no change” only sends an ID plus three bits or so. Like, two bytes at most.

1 Like

Actually I was imprecise: I do extrapolate not interpolate.

^This. I was assuming the systems are updated 60 times per second and thus sent over the net every time.

And it’s not a position, so not using those mechanisms. The Problem comes when I’d have 100-1000 of those objects in the world, because then it’ll be hard on the Traffic.
EntityComponent Updates aren’t zoned by default I guess? (because that being visualization only would help).

So would I need a separate EntityUpdater or maybe an EntityDataHostedService which filters by component and thus holds back updates?

Edit: Actually I think it would be the best to have a separate visual only component which is throttled by a system, because that way I can also leave out unnecessary information, which is only relevant for sim

There may be a fundamental misunderstanding. The only components sent to the clients are the ones that the client will actually use, ie: the ones that it queried… filtering included.

So if you have some component Foo.class that is only ever used on the server then these are never sent over the wire.

Maybe you are worrying about a problem that doesn’t actually exist?

No, the client requests them, but it’s the same Foo.class that the Server uses for simulation purposes and thus is precisely calculated every frame, which is not what the client needs to visualize (among containing other information the client doesn’t really need).

And actually I already have frame drops in the Local Server Scenario when looking around, not sure what that actually is, but I guess the MessageDebugger spamming the log takes part in that. For Internet Situations though, that’s intolerable to send so many unnecessary packets.

So I have two solutions: Throttle the sync of the simulated Foo.class, or create a FooVisual.class, which is populated by a system only run every 3rd frame or so.

When doing extrapolation, shouldn’t you have a FooServer.class and a FooClient.class ? One calculate and used entirely on the server, and on entirely on the client. The information should not go over the wire… I think I have a different view on what extrapolation is than you do.

Well, simply put it’s this:

@Override
    protected void controlUpdate(float tpf) {
        // Extrapolation
        if (speed > 0f) {
            if (forward) {
                pos = Math.min(1f, pos + tpf * speed);
            } else {
                pos = Math.max(0f, pos - tpf * speed);
            }
        }

        move(pos);
    }

// The last two params are needed for interpolation/extrapolation.
    public void moveIntoPosition(float pos, float speed, boolean forward) {
        this.pos = pos;
        this.speed = speed;
        this.forward = forward;
    }

So whenever a packet comes, moveIntoPosition is called to override a drift in pos.

Okay, so thats the next part after extrapolating - some form of bending to the updates coming from the server. Let me know what you figure out :smiley:

I guess maybe we need to talk more specifics than “Foo” because I’m not sure why the server is extrapolating…

Edit: meant “not” extrapolating.

Only things I know from this discussion:

  1. whatever is being tracked is not real time.
  2. it is predictable on some level… certainly enough that TCP-lag and even lower update rates are fine.

This tends to mean to me it’s something like “X will be at location Y in 5 seconds”… in which case the client and server could both be extrapolating and you only have to update the component when a new location or time is required.

Very common for things like time-based buffs, etc… where you don’t need to constantly send “you have this much buff remaining” because everyone knows the buff will run out at time T.

Edit 2: and by the way, if that’s the case then it’s not really ‘extrapolation’… it’s still just interpolation.

I thought it’s extrapolating, because it’s not between two given frames (but on the other hand it’s definitely between known states). Let’s just call it prediction.
The Server cannot predict the state, which is the problem with all of this.

It’s about a robotic gripping arm (is there a special word for this, inserter?). This arm moves items from A to B, like this: First it moves from A to B, at B it waits a given time and then puts the items into the target inventory, moves to A again, waits and removes items from A’s inventory.

The catch is the Power Grid: When there is more power consumed than produced, there is no fuse flying, but instead every building/arm moves relatively slower. This means, that the time it takes from A to B depends on the state of the Power Grid at every simulation timestep.

One could argument that I can build a logic into the system, so that it sends said grid load factor everytime it changes, but that does only help at a small scale, because for a big factory, you have many arms starting/stopping moving at any random time, and thus the load factor is ever changing.

This however means that my prediction fails when the power would be going down, but that’d be corrected every 200ms and isn’t a desired play state anyway. I don’t know if I can get away with that, but I guess so. I could build a system which only updates the load factor when it’s over 1, so packet flood only occurs when the energy system is overload, but I’d rather solve that on a general purpose level, because similar problems might occur for other things (especially conveyor belts, where individual items move and can get blocked etc)

Oh and: For the Wait time, only one packet is sent, so it’s definitely only the movement, where packets are flooded.

Extrapolating is when you have two given states and you project beyond your known states. You “extrapolate” based on unknown information.

On the other, if you only care about ES updates 5 times a second then only send updates five times a second.

I’d still argue that you aren’t taking advantage of the predictability of your system, though… or if it really is so unpredictable then you’d be better off with regular sim-ethereal synching that is already filtered to the local view, etc…

But I kind of feel like the ES changes are things like:
move grip here this fast
change power level of grip
etc.
And not update position, update position, update position… at different rates.

Even other state machine games (which is sounds like what this is) like Factorio, Rimworld, etc. have a sort of “turn” where things actually take affect. So even a loss of power at some location is an event predictable in advance.

Yes, but those games are 100% deterministic and every client is running the simulation and they take extra care to keep them in sync.

Yes, but for simplicity I think I don’t want simulation on the client. With regular sim-etheral syncing you mean using Position components though I guess? Because this local view filtering is desireable/required for my case as well.

Or could I extend the ZoneManager someway to do it for entities as well? (Sorry for the stupid questions, but the whole architecture is a massive blackbox to me)

Edit: The client doesn’t know anything about the power networks, e.g.
Unless the player uses some inspection tool and an UI Window pops up. THEN it would request Data on demand (which would be another use case for throtteling)