The entity model defines which properties are replicated and which remote methods are callable. Client code can observe or request only what the server contract exposes.

Primary ownershipEntity definitions and the server/client authority boundary
Readiness anchorEntity creation plus property or method delivery
Version sensitivityVerify private names per client build

Conceptual directions

Definition element Direction Meaning
Client property Server → client Replicated state available to the client entity
Client method Server → client A remote call delivered to client code
Server method Client → server A request the client is allowed to send
Base method Server-side routing Communication involving the server-side base entity
Replay property Recorder / playback State captured or restored for replay behavior

Authority

Changing a Python attribute locally does not change server-owned state. A method with a promising name is not necessarily exposed in the client-to-server direction. Confirm the entity definition and generated proxy before calling it.

Local is not authoritative

Use local mutation for presentation or test state only. Never describe a local visual change as a server-side gameplay change.

Property delivery

Replicated properties can arrive during entity construction and later updates. Setters or callbacks may run before appearance, GUI, or optional components are ready, so handlers must tolerate partial initialization.

Remote method safety

def _send_verified_request(avatar, payload):
    if avatar is None or getattr(avatar, 'arena', None) is None:
        return False
    proxy = getattr(avatar, 'cell', None)
    method = getattr(proxy, 'verifiedMethodName', None)
    if method is None:
        return False
    method(payload)
    return True

The example intentionally uses a placeholder method name. Replace it only after confirming the current definition, argument schema, permissions, and expected context.

Replay behavior

Some properties are recorded and restored; others depend on live services or server methods and cannot function during playback. Make replay behavior explicit instead of allowing accidental partial operation.

Definition and registration map

Trace an engine-facing type through every layer. Core or feature entities.xml/components.xml files establish engine registration; the complete .def establishes wire type, direction flags, detail level, replay exposure, methods, host entity, and dynamic key; Python supplies behavior. CGF decorators are a second registration system and do not replace the BigWorld definition.

  • ALL_CLIENTS still operates inside interest and detail-level rules.
  • Static components commonly use their class name in the entity component collection. Dynamic components use dynamicComponents and their declared default key.
  • Importing a class proves neither feature activation nor presence on a live entity.
  • Resolve aliases before comparing entity, database, arena, vehicle-type, and network IDs.

Property callbacks and readiness

For ordinary entity and dynamic-component properties, the engine stores the new value before calling set_property(previousValue). Nested and slice setters receive a change path plus the previous value. Read new state from the object and verify whether a base class adapts the contract.

Construction is earlier than readiness. Separate entity existence, in-world state, avatar readiness, appearance construction, visual start, and CGF attachment. Delayed component work must confirm that both host and component still exist.

Leave, destroy, respawn, and CGF

onLeaveWorld, final destruction, and vehicle respawn are different boundaries. A respawn can leave and re-enter the world on the same Python entity. Release old appearance-owned resources, preserve continuing entity state where appropriate, and make cleanup idempotent.

Current Vehicle and ArenaInfo tracking bridges dynamic BigWorld components into CGF. Creation observers run after tracker attachment; destruction observers run before tracker detachment. Replicable components can belong to a separately replicated GameObject, so inspect the .def interface and follow its network ID before changing CGF state.

Direct and networked CGF bridges

Without a game_object_network_id, the tracker attaches the Python component type to the host entity GameObject when that type is not already present. Components implementing the replicable interface follow the network ID through the native replication path and may belong to a separate GameObject. A registration decorator alone does not prove which path applies.

CGF activation and deactivation reactions form another lifecycle layer. A system can subscribe to a script component on activation and unsubscribe on deactivation independently of the component's own onDestroy. Verify both cleanup paths and their ordering.

Common mistakes

  • Calling a Python method because it exists without checking the remote direction.
  • Assuming local property mutation will persist or reach the server.
  • Trusting a decompiled method signature without checking the definition schema.
  • Performing UI work directly inside high-frequency property callbacks.
  • Failing the whole mod when one optional entity component is absent.

Verification trail

Read the entity definition, generated proxy or component contract, and both sender and receiver call sites. Confirm argument types, ownership, replay exposure, and behavior when the entity leaves the world.

Component readiness and graph teardown

The dynamic-component base can wait for Avatar world visibility, then recheck entity destruction and current component membership before initialization. That does not establish appearance or collision readiness. An equipment graph can start before the initial context error/stage events are forwarded, so a plan-start consumer cannot assume every projection has already arrived.

On teardown, cleanup can run while the context still owns its vehicle, followed by plan stop, context destruction and reference release. Preserve the concrete ordering. A subclass teardown with the same name does not prove the base readiness-listener cleanup was called; inspect delegation and the native owner lifecycle.

Keep entity membership, next-tick work and subscription ownership explicit. Reusing a private component requires checking its concrete lifecycle; the base class name does not guarantee identical startup or teardown behavior.