channeldorg / channeld-ue-plugin

Enables distributed simulation with Unreal Engine's dedicated servers. 为虚幻引擎专用服务器提供分布式模拟能力的开源插件.
Apache License 2.0
132 stars 38 forks source link

property memory offset caculation error #45

Closed laughxing closed 1 month ago

laughxing commented 1 year ago

there's some code like this:

// Character.h
#if WITH_EDITORONLY_DATA
    /** Component shown in the editor only to indicate character facing */
    UPROPERTY()
    TObjectPtr<UArrowComponent> ArrowComponent;
#endif

some property is replicated using pointer to their memory location. when we package the game, the memory offset will be different.

indiest commented 1 year ago

Does this only happen to the properties of the TObjectPtr type? We have a similar issue: #26

laughxing commented 1 year ago

lack of description, I don't fully understand what #26 is about. In our case, it's cause by different memory layout between editor and packaged game/server binary.

currently we generate replication code using the reflection info generated in editor. for example

#if WITH_EDITORONLY_DATA
int PropA;
#endif
int PropB;

so the memory offset of PropB would be sizeof(int), which is used in some replication code.

// init
PropA_ptr = (uint8*)ContainerAddress + 0;
PropB_ptr =  (uint8*)ContainerAddress + 4;
//set state
*PropA_ptr = state->prop_propA()
*PropB_ptr = state->prop_propB()

When we package the game, with WITH_EDITORONLY_DATA leaved out , the actual memory offset of PropB will be 0 in both Client/Server binary. but the replication code is not updated(only generated in editor), which will lead to some undefined behaviors.

Augkit commented 1 year ago

There are two ways to support conditional compilation properties:

  1. Borrowing from UBT, compile the entire project in another process and then generate replication code.
  2. Add a custom metadata that requires developers to add this metadata to conditional compilation properties that wrapped with WITH_EDITORONLY_DATA. The first approach has the strongest compatibility but is inefficient and complex to implement. The second approach requires developers to do more work, such as manually adding metadata to the source code of conditional compilation attributes when introducing a new plugin, but the benefit is that the time spent generating code is no different from now.