You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**Hytale uses a multi-threaded server model. Understanding this is MANDATORY before writing any plugin code.**
139
+
140
+
### Core Architecture
141
+
142
+
| Component | Description |
143
+
|-----------|-------------|
144
+
|**HytaleServer**| Singleton root; owns `SCHEDULED_EXECUTOR` for background tasks |
145
+
|**Universe**| Singleton container for all worlds; thread-safe player lookups via `ConcurrentHashMap`|
146
+
|**World**| Each world runs on its **own dedicated thread**|
147
+
148
+
**Key Benefit:** Lag in "World A" does NOT cause lag in "World B" - worlds run in parallel.
149
+
150
+
### The Thread-Bound Rule (CRITICAL)
151
+
152
+
**The `EntityStore` and ALL ECS operations (`getComponent`, `addComponent`, `removeComponent`) are THREAD-BOUND.**
153
+
154
+
They can ONLY be accessed from their specific world's thread. Hytale uses `assertThread()` internally - accessing from the wrong thread throws `IllegalStateException` immediately to prevent silent data corruption.
|**Tick Budget**| 33ms | Heavy logic (>33ms) lags the entire world |
262
+
|**Scaling**| Per-core | More CPU cores = more parallel worlds |
263
+
264
+
### Performance Best Practices
265
+
266
+
1.**Offload Heavy Work:** Move expensive operations (pathfinding, database I/O, HTTP requests) to `SCHEDULED_EXECUTOR` or `CompletableFuture.runAsync()`
267
+
2.**Avoid Object Creation in Ticks:** Reuse objects where possible to reduce GC pressure
268
+
3.**Use `world.execute()` Sparingly:** Queue minimal work back to world threads
269
+
270
+
### Local vs Global Events
271
+
272
+
| Event Type | Thread Context | Example |
273
+
|------------|---------------|---------|
274
+
|**Local Events**| Fires on the World Thread |`PlayerInteractEvent`, `BreakBlockEvent` - safe to touch ECS directly |
275
+
|**Global Events**| May fire on different thread | Server-wide events - must use `world.execute()` before touching entities |
276
+
277
+
### The Golden Rule
278
+
279
+
> **"Always assume you are on the wrong thread unless you are inside a standard World System or event handler. If you touch `store`, verify you are thread-bound or wrapped in `world.execute()`."**
280
+
281
+
### Debugging Thread Issues
282
+
283
+
If you see:
284
+
-`IllegalStateException: Assert not in thread!` → You're accessing ECS from wrong thread
285
+
-`IllegalStateException: Store is currently processing!` → You're modifying during iteration
286
+
- Random crashes or data corruption → Race condition, use atomic types
287
+
288
+
**First debug step:** "Is this code touching a Store/Component while running on an Executor thread?"
0 commit comments