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.**
164
+
165
+
### Core Architecture
166
+
167
+
| Component | Description |
168
+
|-----------|-------------|
169
+
|**HytaleServer**| Singleton root; owns `SCHEDULED_EXECUTOR` for background tasks |
170
+
|**Universe**| Singleton container for all worlds; thread-safe player lookups via `ConcurrentHashMap`|
171
+
|**World**| Each world runs on its **own dedicated thread**|
172
+
173
+
**Key Benefit:** Lag in "World A" does NOT cause lag in "World B" - worlds run in parallel.
174
+
175
+
### The Thread-Bound Rule (CRITICAL)
176
+
177
+
**The `EntityStore` and ALL ECS operations (`getComponent`, `addComponent`, `removeComponent`) are THREAD-BOUND.**
178
+
179
+
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 |
287
+
|**Scaling**| Per-core | More CPU cores = more parallel worlds |
288
+
289
+
### Performance Best Practices
290
+
291
+
1.**Offload Heavy Work:** Move expensive operations (pathfinding, database I/O, HTTP requests) to `SCHEDULED_EXECUTOR` or `CompletableFuture.runAsync()`
292
+
2.**Avoid Object Creation in Ticks:** Reuse objects where possible to reduce GC pressure
293
+
3.**Use `world.execute()` Sparingly:** Queue minimal work back to world threads
294
+
295
+
### Local vs Global Events
296
+
297
+
| Event Type | Thread Context | Example |
298
+
|------------|---------------|---------|
299
+
|**Local Events**| Fires on the World Thread |`PlayerInteractEvent`, `BreakBlockEvent` - safe to touch ECS directly |
300
+
|**Global Events**| May fire on different thread | Server-wide events - must use `world.execute()` before touching entities |
301
+
302
+
### The Golden Rule
303
+
304
+
> **"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()`."**
305
+
306
+
### Debugging Thread Issues
307
+
308
+
If you see:
309
+
-`IllegalStateException: Assert not in thread!` → You're accessing ECS from wrong thread
310
+
-`IllegalStateException: Store is currently processing!` → You're modifying during iteration
311
+
- Random crashes or data corruption → Race condition, use atomic types
312
+
313
+
**First debug step:** "Is this code touching a Store/Component while running on an Executor thread?"
0 commit comments