+
+ ```
+ ../WorldStructure
+ ```
+
+ Generator files that define which biomes spawn together.
+
+
+
+ ```
+ ../Biomes
+ ```
+
+ Biome assets, with content configurations.
+
+
+
+ ```
+ ../Density
+ ```
+
+ Density assets that can be referenced by other generation assets.
+
+
+
+ ```
+ ../Assignments
+ ```
+
+ Prop assets that can be referenced by Biome assets.
+
+
+
+---
+
+### How to visit our worlds
+
+{/* [Video] */}
+
+{/* {% include "../.gitbook/includes/requirements.md" %} */}
+
+The generation assets define a set of generators but on their own you cannot visit these. Currently you require a "world Instance config" to be setup with a generator that will allow you to visit your work.
+
+```
+Server/Instances/..
+```
+
+Instances are separate worlds that players can join using the `/instances` command. Each instance has an `Instance.bson` configuration asset that specifies which generator to use, among other worldly settings.
+
+```json title="instance.bson"
+"WorldGen": {
+ "Type": "HytaleGenerator",
+ "WorldStructure": "Basic",
+ "playerSpawn" : {
+ "X" : 123,
+ "Y" : 480,
+ "Z" : 10000,
+ "Pitch" : 0,
+ "Yaw" : 0,
+ "Roll" : 0
+ }
+ }
+}
+```
+
+
+```
+
+The last option is to simply fly south, new chunks will generate with the changes made.
diff --git a/content/docs/af-ZA/official-documentation/worldgen/worldgen-tutorial/world-generation-concepts.mdx b/content/docs/af-ZA/official-documentation/worldgen/worldgen-tutorial/world-generation-concepts.mdx
new file mode 100644
index 00000000..7bf23597
--- /dev/null
+++ b/content/docs/af-ZA/official-documentation/worldgen/worldgen-tutorial/world-generation-concepts.mdx
@@ -0,0 +1,149 @@
+---
+title: World Generation Concepts
+description: Explores the basic concepts of world generation in the context of Hytale.
+icon: Globe
+authors:
+ - name: Hypixel Studios Canada Inc.
+ url: https://hytale.com
+---
+
+
+
+# World Generation Concepts
+
+### Generative **Noise**
+
+
+
+ Hytale's terrain generation is founded on this concept of Density fields,
+ essentially these are maps of decimal values that are used to define the
+ terrain's shape. Density fields can be built from sources of procedural
+ noise (such as [Simplex](https://en.wikipedia.org/wiki/Simplex_noise) and
+ Cellular), contextual data and processing nodes.
+
+
+
+ 
+
+
+
+### **Noise based terrain**
+
+A basic terrain shape can be created by combining a set of heights with a noise field, this formula creates most of the terrain in Hytale. This is an important concept to understand as its foundational to making terrain.
+
+
+
+ Terrain
3-dimensional terrain
+ output.
+
+
+
+ Simplex 2D
Generative
+ 2-dimensional noise field.
+
+
+
+ Y-Curve
2-dimensional curve drawn
+ between a height differential.
+
+
+
+
+
+#### Solidity
+
+Density generates a range of values, typically between 1 and -1. Some of these values will become our terrain and others will become the negative space, or air, around our terrain.
+
+
+
+ Density
+ Density values are calculated at each coordinate, you can imagine this is
+ like a cloud 
+
+
+
+ Solidity
+ Typically, we interpret positive values account for solid terrain, and
+ negative values the empty space 
+
+
+
+#### Function Nodes
+
+All of our Density fields can be manipulated with a range of function nodes provided in our node editor. These have a range of functionality that can be used to make interesting terrain shapes - a list of these can be found below.
+
+
+ Density is calculated from the sum, this can be thought of like a traditional
+ math equation `f(x) = z + y`
+
+
+Below we cover some basic examples that are important to understand when creating some of your first terrain.
+
+##### Absolute
+
+In this example, absolute makes all negative values positive. This makes a kind of ridged shape on a simplex noise field.
+
+
+
+##### Normalization
+
+Its important to understand how to manipulate a noise field into a new range. This is because some functions affect the range of your field.
+
+In this example we are normalizing our previous example so that half of the field is empty and half solid. This is done by moving our 0 value to -1, stretching the field to our new range.
+
+
+
+
+ Currently the Hytale Node Editor does not support noise visualization, but a
+ range of examples of function nodes can be found in
+ `HytaleGenerator/Biomes/Examples/`
+
+
+### Material Providers
+
+Materials use a number of logical function nodes to determine which block asset is used at which location. These can be run on both solid portions of the terrain field but also on negative portions to fill in a water level for example. Some examples of this can be found below.
+
+#### Solidity
+
+Splits into two Material Providers, one for all positive values which becomes solid, the other for negatives which become empty.
+
+#### Queue
+
+Creates a queue of materials with the top node coming highest in priority and the bottom the lowest priority.
+
+
+ The Hytale Node Editor currently sets node priority based on a node's position
+ in the editor, this is displayed as a number in the top right corner of the
+ node.
+
+
+### Props
+
+Props enable you to generate content in a specific limited region. Hytale has a range of different Prop types that you can use to build content that gets procedurally added to the world. You can define where the content places by using a combination of Positions fields, Scanners and Patterns.
+
+
+
+
+ Positions
+ Provides the locations to scan in.
+
+
+
+ Scanner
+ An area or column around each position to scan, finds the locations that
+ match the Pattern.
+
+
+
+ Pattern
+ The Pattern that defines what are valid positions based on the contents of
+ the world.
+
+
+
+ 
+
diff --git a/content/docs/af-ZA/publishing/builtbybit.mdx b/content/docs/af-ZA/publishing/builtbybit.mdx
new file mode 100644
index 00000000..3d5715a6
--- /dev/null
+++ b/content/docs/af-ZA/publishing/builtbybit.mdx
@@ -0,0 +1,91 @@
+---
+title: BuiltByBit
+description: Complete guide to publishing and selling your Hytale creations on BuiltByBit.
+---
+
+# Why BuiltByBit?
+
+BuiltByBit is the largest third-party marketplace for Minecraft and Roblox, and now Hytale. Unlike other platforms, BuiltByBit is primarily focused on premium content, allowing creators to monetize their work (though free resources are also welcome)!
+
+Within just days of Hytale's early access launch, creators on BuiltByBit have already earned thousands of dollars selling their Hytale creations.
+
+Key advantages:
+
+- Monetize your work - Set your own prices for premium content with no maximum limit
+- Fast approval times - Industry-leading review times averaging just 4 hours
+- More categories - The widest range of content types of any Hytale platform
+- Established marketplace - Join a proven ecosystem with hundreds of thousands of active buyers
+
+# Available Categories
+
+BuiltByBit supports the following categories:
+Plugins - Server-side plugins and modifications
+Data assets - Custom data packs, loot tables, and data-driven content
+Server setups - Complete server configurations and setups
+Builds - Prefabs, structures, and world builds
+Graphics - UI elements, icons, and visual assets
+Textures - Texture packs and reskins
+Models - Custom 3D models and animations
+Audio - Sound effects and music
+Other - Anything else that doesn't fit the above
+
+# Prerequisites
+
+Before you start, make sure you have:
+
+- A compiled `.jar` file (for plugins) or `.zip` file (for other content)
+- A description of your creation's features
+- A Tebex account for receiving payments (can be created during setup)
+
+We also recommend:
+
+- High-quality screenshots showcasing your creation
+- A clear logo or icon
+- Documentation of any dependencies or requirements
+
+# Step-by-Step Publishing Process
+
+## 1. Create Your Account
+
+Register for a BuiltByBit account at [builtbybit.com/login/register](https://builtbybit.com/login/register).
+
+## 2. Set Up Your Wallet
+
+Link your Tebex Wallet (or create one if you don't have one) at [builtbybit.com/resources/dashboard/wallet](https://builtbybit.com/resources/dashboard/wallet). This is where your earnings will be deposited.
+
+## 3. Add Your Resource
+
+Navigate to [builtbybit.com/resources/add](https://builtbybit.com/resources/add) and select the appropriate category for your content.
+
+## 4. Complete Your Listing
+
+Fill out all required fields:
+
+- Title - A clear, descriptive name for your creation
+- Description - Comprehensive details about features and usage
+- Tags - Relevant keywords to help buyers find your content
+- Pricing - Choose free or set a price (minimum $3.99 for paid content)
+- File Upload - Upload your .jar or .zip file
+
+## 5. Submit for Approval
+
+Click "Submit for approval" to send your resource to our moderation team.
+
+## 6. You're Done!
+
+Once approved, your resource will be live and accessible to buyers. With our review times averaging just 4 hours, you won't be waiting long.
+
+# Pricing & Fees
+
+- Minimum price: $3.99 for paid content (no maximum)
+- Platform fee: 9.9% per transaction
+- Gateway fee: Reduced rate charged per transaction
+
+The 9.9% platform fee allows us to continuously introduce new features and improvements. [Learn more about fees](https://builtbybit.com/resources/creators).
+
+# Getting Help
+
+- Creator Knowledge Base - [creators.builtbybit.com](https://creators.builtbybit.com) - Articles covering every feature
+- Discord Community - [discord.gg/builtbybit](https://discord.gg/builtbybit) - Dedicated channels for Hytale creators (sync your account to access)
+- Become a Creator - [builtbybit.com/resources/creators](https://builtbybit.com/resources/creators) - Overview of selling on BuiltByBit
+- Browse Hytale Resources - [builtbybit.com/resources/hytale](https://builtbybit.com/resources/hytale) - See what other creators are selling
diff --git a/content/docs/af-ZA/publishing/index.mdx b/content/docs/af-ZA/publishing/index.mdx
index 0545a04f..fb60fa35 100644
--- a/content/docs/af-ZA/publishing/index.mdx
+++ b/content/docs/af-ZA/publishing/index.mdx
@@ -3,12 +3,13 @@ title: Publishing Your Mod
description: Learn how to publish your mod to the community.
---
-Now that you've created your mod, it's time to share it with the world! There are many marketplaces that allow you to publish your mod, such as Modtale, CurseForge, etc.
+Now that you've created your mod, it's time to share it with the world! There are many marketplaces that allow you to publish your mod, such as Modtale, CurseForge, BuiltByBit, etc.
We have compiled guides to publish for each marketplace, so you can easily get your mod out there and into the hands of players, no matter the marketplace they use.
- [Publishing on Modtale](./publishing/modtale)
- [Publishing on CurseForge](./publishing/curseforge)
+- [Publishing on BuiltByBit](./publishing/builtbybit)
If you run a marketplace, please reach out to us via our email `neil@hytalemodding.dev` to get your marketplace listed in our documentation.
diff --git a/content/docs/ar-SA/guides/ecs/entity-component-system.mdx b/content/docs/ar-SA/guides/ecs/entity-component-system.mdx
new file mode 100644
index 00000000..391a276d
--- /dev/null
+++ b/content/docs/ar-SA/guides/ecs/entity-component-system.mdx
@@ -0,0 +1,72 @@
+---
+title: Entity Component System
+description: A basic introduction into ECS (Entity Component System)
+---
+
+
+ This guide requires basic understanding of OOP concepts such as inheritance.
+
+ Please make sure you have a good understanding of these concepts before reading this guide.
+
+
+
+ This guide is currently only on the theory of ECS and will not have code examples.
+
+ Code examples are intentionally omitted to avoid confusion about how Hytale’s ECS may be implemented.
+
+
+# Introduction
+
+An Entity Component System otherwise known as ECS is a design pattern in game development.
+
+ECS is made up of Entities, which reference Components and Systems that operates on Entities.
+
+It also focuses on composition over inheritance, eliminating rigid hierarchy, helps separate behavior and data and makes reusability easier.
+
+# Composition Over Inheritance
+
+Before getting into understanding what ECS is made of, lets understand what is the ECS philosophy.
+
+We can describe composition as "has X" and inheritance as "is X".
+When we inherit a class in Java, we inherit all of its attributes and methods.
+While in composition we can choose for each object what it references and what systems will work on it.
+
+# Entities, Components and Systems
+
+## Entities
+
+An Entity is just a unique identifier.
+
+- It contains no data.
+- It contains no logic
+
+Think of entities as nouns that can be described using components
+
+## Components
+
+Components are just plain data containers.
+
+- They store only data
+- They contain no behavior or logic
+- They describe traits or aspects of an entity
+
+Examples of components:
+
+- A 'Position' component that stores X, Y and Z coordinates
+- A 'Velocity' component that stores the speed along each axis
+- A 'Health' component that stores the current health of the entity
+
+Think of components as adjectives that describe an entity
+
+## Systems
+
+Systems contains the logic for your game (or in this case, a mod).
+
+- It Operates on all entities that have a specific set of components
+- It Does not store entity data itself
+- It Applies behavior by reading and modifying component data
+
+For example:
+
+- A "WinConditionSystem" may process every Entity that contains the components "Position" and "Velocity"
+- If an entity reaches the position `(0, 0, 0)`, the system will trigger a "You Won!" message.
diff --git a/content/docs/ar-SA/guides/ecs/example-ecs-plugin.mdx b/content/docs/ar-SA/guides/ecs/example-ecs-plugin.mdx
new file mode 100644
index 00000000..44743be5
--- /dev/null
+++ b/content/docs/ar-SA/guides/ecs/example-ecs-plugin.mdx
@@ -0,0 +1,204 @@
+---
+title: Example ECS Plugin
+description: In this guide you will learn how to create a simple poison system utilising all of the features you previously learned about Hytale's ECS system
+authors:
+ - name: oskarscot
+ url: https://oskar.scot
+---
+
+## Practical Example: Poison System
+
+Putting together everything you learned so far, here's a complete poison effect. When applied to any entity, it deals damage at a set interval until it expires and removes itself.
+
+```java
+package scot.oskar.hytaletemplate.components;
+
+import com.hypixel.hytale.component.Component;
+import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
+import javax.annotation.Nullable;
+
+public class PoisonComponent implements Component {
+
+ private float damagePerTick;
+ private float tickInterval;
+ private int remainingTicks;
+ private float elapsedTime;
+
+ public PoisonComponent() {
+ this(5f, 1.0f, 10);
+ }
+
+ public PoisonComponent(float damagePerTick, float tickInterval, int totalTicks) {
+ this.damagePerTick = damagePerTick;
+ this.tickInterval = tickInterval;
+ this.remainingTicks = totalTicks;
+ this.elapsedTime = 0f;
+ }
+
+ public PoisonComponent(PoisonComponent other) {
+ this.damagePerTick = other.damagePerTick;
+ this.tickInterval = other.tickInterval;
+ this.remainingTicks = other.remainingTicks;
+ this.elapsedTime = other.elapsedTime;
+ }
+
+ @Nullable
+ @Override
+ public Component clone() {
+ return new PoisonComponent(this);
+ }
+
+ public float getDamagePerTick() {
+ return damagePerTick;
+ }
+
+ public float getTickInterval() {
+ return tickInterval;
+ }
+
+ public int getRemainingTicks() {
+ return remainingTicks;
+ }
+
+ public float getElapsedTime() {
+ return elapsedTime;
+ }
+
+ public void addElapsedTime(float dt) {
+ this.elapsedTime += dt;
+ }
+
+ public void resetElapsedTime() {
+ this.elapsedTime = 0f;
+ }
+
+ public void decrementRemainingTicks() {
+ this.remainingTicks--;
+ }
+
+ public boolean isExpired() {
+ return this.remainingTicks <= 0;
+ }
+}
+```
+
+```java
+package scot.oskar.hytaletemplate.systems;
+
+import com.hypixel.hytale.component.ArchetypeChunk;
+import com.hypixel.hytale.component.CommandBuffer;
+import com.hypixel.hytale.component.ComponentType;
+import com.hypixel.hytale.component.Ref;
+import com.hypixel.hytale.component.Store;
+import com.hypixel.hytale.component.SystemGroup;
+import com.hypixel.hytale.component.query.Query;
+import com.hypixel.hytale.component.system.tick.EntityTickingSystem;
+import com.hypixel.hytale.server.core.modules.entity.damage.Damage;
+import com.hypixel.hytale.server.core.modules.entity.damage.DamageCause;
+import com.hypixel.hytale.server.core.modules.entity.damage.DamageModule;
+import com.hypixel.hytale.server.core.modules.entity.damage.DamageSystems;
+import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import scot.oskar.hytaletemplate.components.PoisonComponent;
+
+public class PoisonSystem extends EntityTickingSystem {
+
+ private final ComponentType poisonComponentType;
+
+ public PoisonSystem(ComponentType poisonComponentType) {
+ this.poisonComponentType = poisonComponentType;
+ }
+
+ @Override
+ public void tick(float dt, int index, @Nonnull ArchetypeChunk archetypeChunk,
+ @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+
+ PoisonComponent poison = archetypeChunk.getComponent(index, poisonComponentType);
+ Ref ref = archetypeChunk.getReferenceTo(index);
+
+ poison.addElapsedTime(dt);
+
+ if (poison.getElapsedTime() >= poison.getTickInterval()) {
+ poison.resetElapsedTime();
+
+ Damage damage = new Damage(Damage.NULL_SOURCE, DamageCause.OUT_OF_WORLD, poison.getDamagePerTick());
+ DamageSystems.executeDamage(ref, commandBuffer, damage);
+
+ poison.decrementRemainingTicks();
+ }
+
+ if (poison.isExpired()) {
+ commandBuffer.removeComponent(ref, poisonComponentType);
+ }
+ }
+
+ @Nullable
+ @Override
+ public SystemGroup getGroup() {
+ return DamageModule.get().getGatherDamageGroup();
+ }
+
+ @Nonnull
+ @Override
+ public Query getQuery() {
+ return Query.and(this.poisonComponentType);
+ }
+}
+```
+
+```java
+package scot.oskar.hytaletemplate.commands;
+
+public class ExampleCommand extends AbstractPlayerCommand {
+
+ public ExampleCommand() {
+ super("test", "Super test command!");
+ }
+
+ @Override
+ protected void execute(@Nonnull CommandContext commandContext, @Nonnull Store store,
+ @Nonnull Ref ref, @Nonnull PlayerRef playerRef, @Nonnull World world) {
+ Player player = store.getComponent(ref, Player.getComponentType());
+ PoisonComponent poison = new PoisonComponent(3f, 0.5f, 8);
+ store.addComponent(ref, ExamplePlugin.get().getPoisonComponentType(), poison);
+ player.sendMessage(Message.raw("You have been poisoned!").color(Color.GREEN).bold(true));
+ }
+}
+```
+
+```java
+package scot.oskar.hytaletemplate;
+
+public final class ExamplePlugin extends JavaPlugin {
+
+ private static ExamplePlugin instance;
+ private ComponentType poisonComponent;
+
+ public ExamplePlugin(@Nonnull JavaPluginInit init) {
+ super(init);
+ instance = this;
+ }
+
+ @Override
+ protected void setup() {
+ this.getCommandRegistry().registerCommand(new ExampleCommand());
+ this.getEventRegistry().registerGlobal(PlayerReadyEvent.class, ExampleEvent::onPlayerReady);
+ this.getEventRegistry().registerGlobal(PlayerChatEvent.class, ChatFormatter::onPlayerChat);
+
+ this.poisonComponent = this.getEntityStoreRegistry()
+ .registerComponent(PoisonComponent.class, PoisonComponent::new);
+ this.getEntityStoreRegistry().registerSystem(new PoisonSystem(this.poisonComponent));
+ }
+
+ public ComponentType getPoisonComponentType() {
+ return poisonComponent;
+ }
+
+ public static ExamplePlugin get() {
+ return instance;
+ }
+}
+```
+
+The query uses only `poisonComponentType` which means the system will process any entity with a `PoisonComponent`, not just players. This makes it flexible for poisoning NPCs, mobs, or any living entity. The system places itself in the `GatherDamageGroup` so the damage it creates flows through the full damage pipeline including armor reduction and invulnerability checks.
diff --git a/content/docs/ar-SA/guides/ecs/hytale-ecs-theory.mdx b/content/docs/ar-SA/guides/ecs/hytale-ecs-theory.mdx
new file mode 100644
index 00000000..50b44be2
--- /dev/null
+++ b/content/docs/ar-SA/guides/ecs/hytale-ecs-theory.mdx
@@ -0,0 +1,162 @@
+---
+title: Hytale ECS Theory
+description: In this guide you will learn about the basics of Hytale's powerful ECS system as well as create your own component, a system, and work together with other systems to create gameplay logic.
+authors:
+ - name: oskarscot
+ url: https://oskar.scot
+ - name: musava_ribica
+ url: https://forum.hytalemodding.dev/u/musava_ribica
+---
+
+## Store
+
+The `Store` class is the core of Hytale's ECS system, it's responsible for storing entities, if you ever need to access an entity, you need access to the store. It utilises a concept called Archetypes where data is grouped together in chunks. For example if we have 100 Trorks, they will be chunked together along with their components so that they're closely packed together and faster to retrieve.
+
+## EntityStore
+
+When looking through Hytale's server code you will find that most of the time `Store` will be of type `EntityStore`. This name can be misleading as it might suggest that it's a `Store` for entities.
+But didn't we just say that the base `Store` already stores entities? The `EntityStore` class implements `WorldProvider` meaning that `EntityStore` is responsible for accessing a specific Hytale `World`. It maintains internal maps `entitiesByUuid` and `networkIdToRef`, allowing you to find a specific entity by its persistent ID or its networking ID.
+
+Every Entity has a `UUIDComponent` as well as a `NetworkId` which are used by the `EntityStore` to lookup entities inside of the `Store`.
+
+## ChunkStore
+
+Another type of `Store` that you might come across is the `ChunkStore`, it is responsible for storing all the components, related to blocks inside of the `World`. You can retrieve `WorldChunk`s which are your general chunk Components.
+A `WorldChunk` component contains an `EntityChunk` which holds all the Entities that are inside of the chunk as well as their reference to the EntityStore. It also holds the `BlockChunk` which consists of `BlockSection`s. There are more components making up the overall world and chunk systems but
+for now this is the basic understanding for the `ChunkStore`. You can use it to retrieve data about chunks and their blocks as well as entities on a given chunk and create block and chunk systems.
+
+## Holder
+
+A Holder is essentially a blueprint for an entity. Before an entity exists in the Store (and thus in the world), is exists as a `Holder`. It collects and holds all the necessary components (data). You can compare it analogous to shopping cart. You grab all components you need and once you have everything, check out at the store which will take your cart and create a valid entity ID and hand you back a receipt (a Ref).
+
+Let's take a look at an example: initializing players. In `Universe`, the `addPlayer` method demonstrates it perfectly.
+When a player connects, we don't immediately throw them into the ECS. We first construct their data in a Holder.
+Notice that `PlayerStorage#load` method, which loads player data from disk, returns a `CompletableFuture>`.
+What it means is that the method is async and the future will contain a Holder for something in the `EntityStore`.
+Just open the `Universe `class, find the `addPlayer` method and read it start to end. Trust me, it will help you a lot when you see the actual process how an entity is constructed, what it has to pass through. In the end, `Universe` calls `world#addPlayer`, which (after dispatching an event) calls the delightful
+
+```java
+Ref ref = playerRefComponent.addToStore(store);
+```
+
+and `PlayerRef#addToStore` has this:
+
+```java
+store.addEntity(this.holder, AddReason.LOAD);
+```
+
+## Ref (Reference)
+
+For those familiar with languages like C++, you probably already can guess what this class is purely by the name of it. However, a Ref is a safe "handle" or pointer to an entity. You should **NEVER** store a direct reference to an entity object, you use a Ref instead. It tracks whether an entity is still alive. If you call `validate()` on a Ref for an entity that has been deleted, it throws an exception.
+
+## Player Components
+
+In Hytale, a "Player" is not just one object. It is a single entity composed of multiple specialized components. Understanding the difference between `Player` and `PlayerRef` is crucial for modding.
+
+### PlayerRef
+
+Despite its name, PlayerRef is a Component, not a handle. It represents the player's connection and identity. It's a special component which stays active as long as the player is connected to the server, even if the player switches worlds. The key data that it stores are the player's username, UUID, language as well as the packet handler.
+
+### Player
+
+The `Player` component represents the player's physical presence. It only exists when the player is actually spawned in a world. Providing access to gameplay specific data, this component differs per world.
+
+To interact with an entity, you use the `Store` to retrieve its components via their `ComponentType`. Because Hytale uses a decoupled system, you don't call `entity.getHealth()`. Instead, you ask the `Store` for the health data associated with that entity's `Ref`.
+
+```java
+@Override
+protected void execute(@Nonnull CommandContext commandContext, @Nonnull Store store,
+ @Nonnull Ref ref, @Nonnull PlayerRef playerRef, @Nonnull World world) {
+ Player player = store.getComponent(ref, Player.getComponentType());
+ UUIDComponent component = store.getComponent(ref, UUIDComponent.getComponentType());
+ TransformComponent transform = store.getComponent(ref, TransformComponent.getComponentType());
+ player.sendMessage(Message.raw("UUIDComponent : " + component.getUuid()));
+ player.sendMessage(Message.raw("Transform : " + transform.getPosition()));
+}
+```
+
+In here we use the `Store` to access the `Player` component using the `Ref`. We can do the same for other components like the `UUIDComponent` or the `TransformComponent` to retrieve the entity Transform containing the position and rotation.
+
+## Components
+
+Components are pure data containers. They hold state but contain no logic. In Hytale, components must implement `Component` and provide a clone method for the ECS to copy them when needed.
+
+```java
+public class PoisonComponent implements Component {
+
+ private float damagePerTick;
+ private float tickInterval;
+ private int remainingTicks;
+ private float elapsedTime;
+
+ public PoisonComponent() {
+ this(5f, 1.0f, 10);
+ }
+
+ public PoisonComponent(float damagePerTick, float tickInterval, int totalTicks) {
+ this.damagePerTick = damagePerTick;
+ this.tickInterval = tickInterval;
+ this.remainingTicks = totalTicks;
+ this.elapsedTime = 0f;
+ }
+
+ public PoisonComponent(PoisonComponent other) {
+ this.damagePerTick = other.damagePerTick;
+ this.tickInterval = other.tickInterval;
+ this.remainingTicks = other.remainingTicks;
+ this.elapsedTime = other.elapsedTime;
+ }
+
+ @Nullable
+ @Override
+ public Component clone() {
+ return new PoisonComponent(this);
+ }
+
+ public float getDamagePerTick() {
+ return damagePerTick;
+ }
+
+ public float getTickInterval() {
+ return tickInterval;
+ }
+
+ public int getRemainingTicks() {
+ return remainingTicks;
+ }
+
+ public float getElapsedTime() {
+ return elapsedTime;
+ }
+
+ public void addElapsedTime(float dt) {
+ this.elapsedTime += dt;
+ }
+
+ public void resetElapsedTime() {
+ this.elapsedTime = 0f;
+ }
+
+ public void decrementRemainingTicks() {
+ this.remainingTicks--;
+ }
+
+ public boolean isExpired() {
+ return this.remainingTicks <= 0;
+ }
+}
+```
+
+The default constructor is required for the registration factory. The copy constructor is used by `clone()` which the ECS calls internally when it needs to duplicate component data.
+
+## CommandBuffer
+
+The `CommandBuffer` queues changes to entities. Use it instead of modifying the store directly to ensure thread safety and proper ordering. You'll use it to add components, remove components, and execute damage.
+
+```java
+commandBuffer.addComponent(ref, componentType, new MyComponent());
+
+commandBuffer.removeComponent(ref, componentType);
+
+MyComponent comp = commandBuffer.getComponent(ref, componentType);
+```
diff --git a/content/docs/ar-SA/guides/ecs/systems.mdx b/content/docs/ar-SA/guides/ecs/systems.mdx
new file mode 100644
index 00000000..eec8e494
--- /dev/null
+++ b/content/docs/ar-SA/guides/ecs/systems.mdx
@@ -0,0 +1,230 @@
+---
+title: Systems
+description: In this guide you will learn about how systems work inside of Hytale.
+authors:
+ - name: oskarscot
+ url: https://oskar.scot
+---
+
+Systems are where the logic lives. While components are pure data containers, systems operate on entities that match specific component queries. The ECS scheduler runs systems each tick, passing in only the entities that have the components the system cares about.
+
+### EntityTickingSystem
+
+The most common system type. It runs every tick and processes each entity matching its query individually.
+
+```java
+public class PoisonSystem extends EntityTickingSystem {
+
+ private final ComponentType poisonComponentType;
+
+ public PoisonSystem(ComponentType poisonComponentType) {
+ this.poisonComponentType = poisonComponentType;
+ }
+
+ @Override
+ public void tick(float dt, int index, @Nonnull ArchetypeChunk archetypeChunk,
+ @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+
+ PoisonComponent poison = archetypeChunk.getComponent(index, poisonComponentType);
+ Ref ref = archetypeChunk.getReferenceTo(index);
+
+ poison.addElapsedTime(dt);
+
+ if (poison.getElapsedTime() >= poison.getTickInterval()) {
+ poison.resetElapsedTime();
+
+ Damage damage = new Damage(Damage.NULL_SOURCE, DamageCause.OUT_OF_WORLD, poison.getDamagePerTick());
+ DamageSystems.executeDamage(ref, commandBuffer, damage);
+
+ poison.decrementRemainingTicks();
+ }
+
+ if (poison.isExpired()) {
+ commandBuffer.removeComponent(ref, poisonComponentType);
+ }
+ }
+
+ @Nullable
+ @Override
+ public SystemGroup getGroup() {
+ return DamageModule.get().getGatherDamageGroup();
+ }
+
+ @Nonnull
+ @Override
+ public Query getQuery() {
+ return Query.and(this.poisonComponentType);
+ }
+}
+```
+
+The `tick` method receives `dt` which is delta time since the last tick. This lets you accumulate time for interval-based logic rather than counting ticks. The `ArchetypeChunk` gives you access to the entity's components via the index, and `getReferenceTo` returns the `Ref` you need for issuing commands.
+
+### TickingSystem
+
+Runs once per tick globally, not per-entity. Use this for world-wide updates or logic that doesn't target specific entities.
+
+```java
+public class GlobalUpdateSystem extends TickingSystem {
+
+ @Override
+ public void tick(float dt, int index, Store store) {
+ World world = store.getExternalData().getWorld();
+ }
+}
+```
+
+### DelayedEntitySystem
+
+Like `EntityTickingSystem` but with a built-in delay. The constructor takes a float representing seconds between executions.
+
+```java
+public class HealthRegenSystem extends DelayedEntitySystem {
+
+ public HealthRegenSystem() {
+ super(1.0f);
+ }
+
+ @Override
+ public void tick(float dt, int index, @Nonnull ArchetypeChunk archetypeChunk,
+ @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+ // Runs every 1 second per matching entity
+ }
+
+ @Nonnull
+ @Override
+ public Query getQuery() {
+ return Query.and(Player.getComponentType());
+ }
+}
+```
+
+### RefSystem
+
+We can also create systems to listen for changes on entities themselves. This is done through a `RefSystem`, for example let's say we want to perform an action whenever we add a component to an entity, update it or remove it.
+This can be done via the `RefChangeSystem`. Let's break down the example below:
+
+```java
+public class PermissionAttachmentSystem extends RefChangeSystem {
+
+ private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
+
+ @Nonnull
+ @Override
+ public ComponentType componentType() {
+ return EntityStoreRegistry.get().getPermissionAttachmentComponentType();
+ }
+
+ @Override
+ public void onComponentAdded(@Nonnull Ref ref, @Nonnull PermissionAttachment permissionAttachment, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+ UUIDComponent component = store.getComponent(ref, UUIDComponent.getComponentType());
+ UUID playerUuid = component.getUuid();
+
+ // PermissionAttachment component was added to a new entity
+ }
+
+ @Override
+ public void onComponentSet(@Nonnull Ref ref, @Nullable PermissionAttachment oldAttachment, @Nonnull PermissionAttachment newAttachment, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+ UUIDComponent component = store.getComponent(ref, UUIDComponent.getComponentType());
+ UUID playerUuid = component.getUuid();
+
+ // PermissionAttachment component was updated using replaceComponent or putComponent
+ }
+
+ @Override
+ public void onComponentRemoved(@Nonnull Ref ref, @Nonnull PermissionAttachment permissionAttachment, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+ UUIDComponent component = store.getComponent(ref, UUIDComponent.getComponentType());
+ UUID playerUuid = component.getUuid();
+
+ // PermissionAttachment component was removed from an entity
+ }
+
+ @Nullable
+ @Override
+ public Query getQuery() {
+ return EntityStoreRegistry.get().getPermissionAttachmentComponentType();
+ }
+}
+```
+
+In this system we listen for changes on the `PermissionAttachment` component inside of the `EntityStore`. This gives us access to `onComponentAdded`, `onComponentSet` and `onComponentRemoved` which in this example caches and persists permission data
+which is stored on a player inside of a custom `PermissionAttachment` component.
+
+## Queries
+
+Queries filter which entities a system processes. The ECS only passes entities to your system's `tick` method if they have all the components specified in the query.
+
+```java
+// Single component - any entity with PoisonComponent
+Query.and(poisonComponentType)
+
+// Multiple components - entities with both
+Query.and(poisonComponentType, Player.getComponentType())
+
+// Exclusion - players that aren't dead
+Query.and(Player.getComponentType(), Query.not(DeathComponent.getComponentType()))
+```
+
+## SystemGroups and Dependencies
+
+Systems can declare which group they belong to and what dependencies they have. This controls execution order which is critical for systems that interact.
+
+```java
+@Nullable
+@Override
+public SystemGroup getGroup() {
+ return DamageModule.get().getGatherDamageGroup();
+}
+```
+
+For more complex ordering you can override `getDependencies`:
+
+```java
+@Nonnull
+public Set> getDependencies() {
+ return Set.of(
+ new SystemGroupDependency(Order.AFTER, DamageModule.get().getFilterDamageGroup()),
+ new SystemDependency(Order.BEFORE, PlayerSystems.ProcessPlayerInput.class)
+ );
+}
+```
+
+The damage system is a good example of why ordering matters. Hytale's damage pipeline has four stages: GatherDamageGroup collects damage sources, FilterDamageGroup applies reductions and cancellations, then damage is applied to health, and finally InspectDamageGroup handles side effects like particles and sounds. If these ran in the wrong order you'd play death animations before the entity dies or apply armor reduction after health is already subtracted.
+
+## Registering Components and Systems
+
+Components and systems must be registered during plugin setup. The `EntityStoreRegistry` handles this.
+
+```java
+public final class ExamplePlugin extends JavaPlugin {
+
+ private static ExamplePlugin instance;
+ private ComponentType poisonComponent;
+
+ public ExamplePlugin(@Nonnull JavaPluginInit init) {
+ super(init);
+ instance = this;
+ }
+
+ @Override
+ protected void setup() {
+ this.getCommandRegistry().registerCommand(new ExampleCommand());
+ this.getEventRegistry().registerGlobal(PlayerReadyEvent.class, ExampleEvent::onPlayerReady);
+ this.getEventRegistry().registerGlobal(PlayerChatEvent.class, ChatFormatter::onPlayerChat);
+
+ this.poisonComponent = this.getEntityStoreRegistry()
+ .registerComponent(PoisonComponent.class, PoisonComponent::new);
+ this.getEntityStoreRegistry().registerSystem(new PoisonSystem(this.poisonComponent));
+ }
+
+ public ComponentType getPoisonComponentType() {
+ return poisonComponent;
+ }
+
+ public static ExamplePlugin get() {
+ return instance;
+ }
+}
+```
+
+The `registerComponent` method returns a `ComponentType` which acts as a key for accessing that component type throughout your plugin. Store it as a field and pass it to any systems that need it. The second argument is a factory for creating default instances.
diff --git a/content/docs/ar-SA/guides/java-basics/00-introduction.mdx b/content/docs/ar-SA/guides/java-basics/00-introduction.mdx
index 5f55d5d4..a03ad638 100644
--- a/content/docs/ar-SA/guides/java-basics/00-introduction.mdx
+++ b/content/docs/ar-SA/guides/java-basics/00-introduction.mdx
@@ -25,9 +25,9 @@ Before we dive into programming, you'll need some essentials, you need to instal
### Java Development Kit (JDK)
-Downlaod and install JDK 25 or above from the [official Oracle website](https://www.oracle.com/java/technologies/javase-jdk25-downloads.html) or use an open-source alternative like [AdoptOpenJDK](https://adoptopenjdk.net/).
+Download and install JDK 25 or above from the [official Oracle website](https://www.oracle.com/java/technologies/javase-jdk25-downloads.html) or use an open-source alternative like [AdoptOpenJDK](https://adoptopenjdk.net/).
-### Intergrated Development Environment (IDE)
+### Integrated Development Environment (IDE)
An IDE is a software application that provides comprehensive facilities to programmers for software development. Popular choices for Java include:
diff --git a/content/docs/ar-SA/guides/java-basics/06-methods-functions.mdx b/content/docs/ar-SA/guides/java-basics/06-methods-functions.mdx
index 43692e91..e8e60761 100644
--- a/content/docs/ar-SA/guides/java-basics/06-methods-functions.mdx
+++ b/content/docs/ar-SA/guides/java-basics/06-methods-functions.mdx
@@ -376,6 +376,23 @@ public static String getHealthStatus(int health, int maxHealth) {
* Contains at least one number
* Returns true if valid, false otherwise
+
+ When writing a password validator, you may be in need of a way to compare array's values. For example:
+
+ ```java
+ String[] array1 = {"Apple", "Banana"};
+ String[] array2 = {"Apple", "Banana"};
+
+ //Wrong:
+ array1[0] == array2[0] // false - Java compares objects not by their location in Java's memory.
+
+ //Instead use .equals() method - it compares objects by their values:
+ array1[0].equals(array2[0]); // true
+
+ //This although does not affect primitive data types.
+ ```
+
+
## Common Mistakes
```java
diff --git a/content/docs/ar-SA/guides/plugin/block-components.mdx b/content/docs/ar-SA/guides/plugin/block-components.mdx
new file mode 100644
index 00000000..eec4aedf
--- /dev/null
+++ b/content/docs/ar-SA/guides/plugin/block-components.mdx
@@ -0,0 +1,253 @@
+---
+title: Block Components
+description: Learn how to use the block components.
+authors:
+ - name: Bird
+ link: https://discord.com/users/495709580068651009
+---
+
+# Overview
+
+In this guide, you'll learn how to use block components to create a ticking block.
+
+
+ For a more complete reference, you may also want to review FarmingSystems.Ticking, as much of the underlying logic is based on its implementation.
+
+
+## Steps
+
+### 1. ExampleBlock - holds block behavior
+
+```java
+public class ExampleBlock implements Component {
+
+ public static final BuilderCodec CODEC;
+
+ public ExampleBlock() {
+
+ }
+
+ public static ComponentType getComponentType() {
+ return ExamplePlugin.get().getExampleBlockComponentType();
+ }
+
+ public void runBlockAction(int x, int y, int z, World world) {
+ world.execute(() -> {
+ world.setBlock(x + 1, y, z, "Rock_Ice");
+ });
+ }
+
+ @Nullable
+ public Component clone() {
+ return new ExampleBlock();
+ }
+
+ static {
+ CODEC = BuilderCodec.builder(ExampleBlock.class, ExampleBlock::new).build();
+ }
+}
+```
+
+ExampleBlock is a custom component that stores the behavior and data for your ticking block. Here, it simply places an Ice Block at x + 1 relative to its current position when it ticks.
+
+---
+
+### 2. ExampleInitializer - marks blocks as ticking when placed
+
+```java
+public class ExampleInitializer extends RefSystem {
+
+ @Override
+ public void onEntityAdded(@Nonnull Ref ref, @Nonnull AddReason reason, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+ BlockModule.BlockStateInfo info = (BlockModule.BlockStateInfo) commandBuffer.getComponent(ref, BlockModule.BlockStateInfo.getComponentType());
+ if (info == null) return;
+
+ ExampleBlock generator = (ExampleBlock) commandBuffer.getComponent(ref, ExamplePlugin.get().getExampleBlockComponentType());
+ if (generator != null) {
+ int x = ChunkUtil.xFromBlockInColumn(info.getIndex());
+ int y = ChunkUtil.yFromBlockInColumn(info.getIndex());
+ int z = ChunkUtil.zFromBlockInColumn(info.getIndex());
+
+ WorldChunk worldChunk = (WorldChunk) commandBuffer.getComponent(info.getChunkRef(), WorldChunk.getComponentType());
+ if (worldChunk != null) {
+ worldChunk.setTicking(x, y, z, true);
+ }
+ }
+ }
+
+ @Override
+ public void onEntityRemove(@Nonnull Ref ref, @Nonnull RemoveReason reason, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+ }
+
+ @Override
+ public Query getQuery() {
+ return Query.and(BlockModule.BlockStateInfo.getComponentType(), ExamplePlugin.get().getExampleBlockComponentType());
+ }
+}
+```
+
+ExampleSystemInitializer is a RefSystem that reacts when block entities with the ExampleBlock component are added or removed. This is crucial for marking blocks as ticking when they're first placed.
+
+**Key Points:**
+
+- Tells the game that this block should tick, allowing `ExampleSystem` to process it.
+
+```java
+worldChunk.setTicking(x, y, z, true);
+```
+
+---
+
+### 3. ExampleSystem - handles ticking
+
+```java
+public class ExampleSystem extends EntityTickingSystem {
+ private static final Query QUERY = Query.and(BlockSection.getComponentType(), ChunkSection.getComponentType());
+
+ public void tick(float dt, int index, @Nonnull ArchetypeChunk archetypeChunk, @Nonnull Store store, @Nonnull CommandBuffer commandBuffer) {
+ BlockSection blocks = (BlockSection) archetypeChunk.getComponent(index, BlockSection.getComponentType());
+
+ assert blocks != null;
+
+ if (blocks.getTickingBlocksCountCopy() != 0) {
+ ChunkSection section = (ChunkSection) archetypeChunk.getComponent(index, ChunkSection.getComponentType());
+
+ assert section != null;
+
+ BlockComponentChunk blockComponentChunk = (BlockComponentChunk) commandBuffer.getComponent(section.getChunkColumnReference(), BlockComponentChunk.getComponentType());
+
+ assert blockComponentChunk != null;
+
+ blocks.forEachTicking(blockComponentChunk, commandBuffer, section.getY(), (blockComponentChunk1, commandBuffer1, localX, localY, localZ, blockId) ->
+ {
+ Ref blockRef = blockComponentChunk1.getEntityReference(ChunkUtil.indexBlockInColumn(localX, localY, localZ));
+ if (blockRef == null) {
+ return BlockTickStrategy.IGNORED;
+ } else {
+ ExampleBlock exampleBlock = (ExampleBlock) commandBuffer1.getComponent(blockRef, ExampleBlock.getComponentType());
+ if (exampleBlock != null) {
+ WorldChunk worldChunk = (WorldChunk) commandBuffer.getComponent(section.getChunkColumnReference(), WorldChunk.getComponentType());
+
+ int globalX = localX + (worldChunk.getX() * 32);
+ int globalZ = localZ + (worldChunk.getZ() * 32);
+
+ exampleBlock.runBlockAction(globalX, localY, globalZ, worldChunk.getWorld());
+
+ return BlockTickStrategy.CONTINUE;
+
+ } else {
+ return BlockTickStrategy.IGNORED;
+ }
+ }
+ });
+ }
+ }
+
+ @Nullable
+ public Query getQuery() {
+ return QUERY;
+ }
+}
+```
+
+ExampleSystem is an EntityTickingSystem that runs every tick to execute the logic for all ticking blocks with the ExampleBlock component.
+
+**Key Points:**
+
+- **Get the block component**
+
+```java
+ExampleBlock exampleBlock = (ExampleBlock) commandBuffer1.getComponent(blockRef, ExampleBlock.getComponentType());
+```
+
+- **Convert local chunk coordinates to world coordinates**
+
+```java
+int globalX = localX + (worldChunk.getX() * 32);
+int globalZ = localZ + (worldChunk.getZ() * 32);
+```
+
+- **Run the block logic**
+
+```java
+exampleBlock.runBlockAction(globalX, localY, globalZ, worldChunk.getWorld());
+```
+
+- **Keep the block ticking in the next tick**
+
+```java
+return BlockTickStrategy.CONTINUE;
+```
+
+---
+
+### 4. ExamplePlugin - registers components and systems
+
+```java
+public class ExamplePlugin extends JavaPlugin {
+ protected static ExamplePlugin instance;
+ private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
+ private ComponentType exampleBlockComponentType;
+
+ public static ExamplePlugin get() {
+ return instance;
+ }
+
+ public ExamplePlugin(@Nonnull JavaPluginInit init) {
+ super(init);
+ LOGGER.atInfo().log("Hello from " + this.getName() + " version " + this.getManifest().getVersion().toString());
+ }
+
+ @Override
+ protected void setup() {
+ instance = this;
+ LOGGER.atInfo().log("Setting up plugin " + this.getName());
+ this.exampleBlockComponentType = this.getChunkStoreRegistry().registerComponent(ExampleBlock.class, "ExampleBlock", ExampleBlock.CODEC);
+ }
+
+ @Override
+ protected void start() {
+ this.getChunkStoreRegistry().registerSystem(new ExampleSystem());
+ this.getChunkStoreRegistry().registerSystem(new ExampleSystemInitializer());
+ }
+
+ public ComponentType getExampleBlockComponentType() {
+ return this.exampleBlockComponentType;
+ }
+}
+```
+
+---
+
+### 5. Configure In-Game
+
+
+
+
+
+With this logic, the block will now continuously place an Ice Block at the coordinates x + 1 relative to its current position every time it ticks.
+
+---
+
+## Common Issues
+
+### NullPointerException on Startup
+
+**Error message:**
+
+```java
+java.lang.NullPointerException: Cannot invoke "com.hypixel.hytale.component.query.Query.validateRegistry(com.hypixel.hytale.component.ComponentRegistry)" because "query" is null
+```
+
+**Cause:**
+This error occurs when your module is loaded **before** the required Hytale modules.
+
+**Fix:**
+Add `EntityModule` and `BlockModule` as dependencies in your `manifest.json` to ensure proper load order.
+
+```json
+"Dependencies": {
+ "Hytale:EntityModule": "*",
+ "Hytale:BlockModule": "*"
+}
+```
diff --git a/content/docs/ar-SA/guides/plugin/browsing-serverjar.mdx b/content/docs/ar-SA/guides/plugin/browsing-serverjar.mdx
index 6f730b2c..240ed19a 100644
--- a/content/docs/ar-SA/guides/plugin/browsing-serverjar.mdx
+++ b/content/docs/ar-SA/guides/plugin/browsing-serverjar.mdx
@@ -1,13 +1,28 @@
---
title: Browsing the server.jar code
-description: Learn how to patch the server.jar and browse the source code.
+description: Learn how to decompile the HytaleServer.jar and browse the source code.
+authors:
+ - name: musava_ribica
+ url: https://github.com/IamMusavaRibica
---
-The ~~patcher~~ allows you to more easily prepare an environment for exploring the Hytale Server without publishing the decompiled code.
+Our [patcher](https://github.com/HytaleModding/patcher) tool allows you to easily prepare an environment for exploring the Hytale Server.
-## Setup
+## Why?
-- Clone the patcher `git clone https://github.com/HytaleModding/patcher.git`, and enter the directory. `cd patcher`
+When you add a compiled jar as a library, IntelliJ only decompiles class by class and doesn't let you search it. For example, you cannot right click some class and then Find Usages. This script will give you a ready to use Hytale server code as a project where you can explore anything you want.
+
+If anything goes wrong, please ping the author in [this post](https://discord.com/channels/1440173445039132724/1460707397189238785) in the Hytale Modding discord server
+
+## Instructions
+
+If you prefer watching over reading, check out the awesome video walkthrough made by Hyphen45. Note that the written instructions have since been improved, but the process remains the same.
+
+