HyCodeYourTale

Assets

Assets

Dokumentace k práci s herními assety v Hytale.

Obsah

| Soubor | Popis |
|--------|-------|
| MODELS.md | Detailní dokumentace 3D modelů - Model, ModelAsset, ModelComponent, škálování, attachmenty |
| MARKERS.md | World map markery - WorldMapManager, MarkerProvider, MapMarker, vestavěné providery |

---

Struktura Assets

Assets/
├── Server/ # Server-side assety
│ ├── Entity/ # Entity definice
│ ├── NPC/ # NPC definice
│ ├── Item/ # Item definice
│ ├── Drops/ # Drop tabulky
│ └── World/ # World konfigurace

└── Common/ # Sdílené assety (client + server)
├── Blocks/ # Block definice
├── Items/ # Item assety
├── UI/ # UI definice
├── Sounds/ # Zvuky
└── VFX/ # Vizuální efekty

---

Asset Registry

Získání Assetu

// Model asset
ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset("ModelName");
if (modelAsset != null) {
Model model = Model.createUnitScaleModel(modelAsset);
}

// Kontrola existence
if (ModelAsset.getAssetMap().getAsset("MyModel") == null) {
throw new IllegalStateException("Model 'MyModel' not found");
}

LoadedAssetsEvent

Reagování na načtení/změnu assetů:

@Override
protected void setup() {
getEventRegistry().register(LoadedAssetsEvent.class, ModelAsset.class, event -> {
Map loadedModels = event.getLoadedAssets();

ModelAsset myModel = loadedModels.get("MyCustomModel");
if (myModel != null) {
// Model byl načten nebo změněn
this.cachedModel = Model.createUnitScaleModel(myModel);
}
});
}

---

Modely

Vytvoření Model Instance

// Z asset mapy
ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset("Warp");
if (modelAsset == null) {
throw new IllegalStateException("Warp model not found");
}

// Vytvoření modelu s jednotkovou škálou
Model model = Model.createUnitScaleModel(modelAsset);

// Bounding box
BoundingBox boundingBox = new BoundingBox(model.getBoundingBox());

Přidání Modelu k Entitě

public Holder createEntityWithModel(Model model, Vector3d position) {
Holder holder = EntityStore.REGISTRY.newHolder();

// Pozice
holder.addComponent(
TransformComponent.getComponentType(),
new TransformComponent(position, new Vector3f(0, 0, 0))
);

// Network ID
holder.addComponent(
NetworkId.getComponentType(),
new NetworkId(store.getExternalData().takeNextNetworkId())
);

// Model
holder.addComponent(
ModelComponent.getComponentType(),
new ModelComponent(model)
);

// Bounding box
holder.addComponent(
BoundingBox.getComponentType(),
new BoundingBox(model.getBoundingBox())
);

return holder;
}

---

Warp Entity Příklad

Z TeleportPlugin - vytvoření warp markeru:

@Nonnull
public Holder createWarp(@Nonnull Warp warp, @Nonnull Store store) {
Transform transform = warp.getTransform();
Holder holder = EntityStore.REGISTRY.newHolder();

// Pozice a rotace
holder.addComponent(
TransformComponent.getComponentType(),
new TransformComponent(transform.getPosition(), transform.getRotation())
);

// Network ID pro síťovou synchronizaci
holder.addComponent(
NetworkId.getComponentType(),
new NetworkId(store.getExternalData().takeNextNetworkId())
);

// Nelze s entitou interagovat
holder.ensureComponent(Intangible.getComponentType());

// Bounding box z modelu
holder.addComponent(
BoundingBox.getComponentType(),
new BoundingBox(this.warpModel.getBoundingBox())
);

// 3D model
holder.addComponent(
ModelComponent.getComponentType(),
new ModelComponent(this.warpModel)
);

// Jmenovka
holder.addComponent(
Nameplate.getComponentType(),
new Nameplate(warp.getId())
);

// Skrytá pro adventure hráče
holder.ensureComponent(HiddenFromAdventurePlayers.getComponentType());

// Neserializovat (neperzistovat)
holder.ensureComponent(EntityStore.REGISTRY.getNonSerializedComponentType());

// Vlastní komponenta
holder.addComponent(
this.warpComponentType,
new WarpComponent(warp)
);

return holder;
}

---

Spawn Entity do Světa

// Spawn entity při načtení chunku
private void onChunkPreLoadProcess(ChunkPreLoadProcessEvent event) {
WorldChunk chunk = event.getChunk();
BlockChunk blockChunk = chunk.getBlockChunk();

if (blockChunk == null) return;

int chunkX = blockChunk.getX();
int chunkZ = blockChunk.getZ();
World world = chunk.getWorld();

// Kontrola zda entita patří do tohoto chunku
Vector3d entityPos = getEntityPosition();
if (ChunkUtil.isInsideChunk(chunkX, chunkZ,
MathUtil.floor(entityPos.x),
MathUtil.floor(entityPos.z))) {

// Spawn na world threadu
world.execute(() -> {
Store store = world.getEntityStore().getStore();
Holder holder = createMyEntity(store);
store.addEntity(holder, AddReason.LOAD);
});
}
}

---

World Map Markery

MarkerProvider

public class MyMarkerProvider implements WorldMapManager.MarkerProvider {

public static final MyMarkerProvider INSTANCE = new MyMarkerProvider();

@Override
public void update(
@Nonnull World world,
@Nonnull GameplayConfig gameplayConfig,
@Nonnull WorldMapTracker tracker,
int chunkViewRadius,
int playerChunkX,
int playerChunkZ
) {
// Kontrola konfigurace
if (!gameplayConfig.getWorldMapConfig().isDisplayWarps()) {
return;
}

for (MyMarker marker : getMarkers()) {
if (!marker.getWorld().equals(world.getName())) {
continue;
}

tracker.trySendMarker(
chunkViewRadius,
playerChunkX,
playerChunkZ,
marker.getPosition(),
marker.getYaw(),
"Marker-" + marker.getId(),
"Marker: " + marker.getName(),
marker,
(id, name, m) -> new MapMarker(
id,
name,
"MarkerIcon.png",
PositionUtil.toTransformPacket(m.getTransform()),
null
)
);
}
}
}

Registrace Provideru

@Override
protected void setup() {
getEventRegistry().registerGlobal(AddWorldEvent.class, event -> {
World world = event.getWorld();
world.getWorldMapManager().addMarkerProvider("mymarkers", MyMarkerProvider.INSTANCE);
});
}

---

JSON Asset Konfigurace

Assety používají JSON s dědičností:

{
"Parent": "BaseEntity",
"Components": {
"Health": {
"MaxHealth": 100
},
"Movement": {
"Speed": 5.0
}
}
}

Dědičnost

{
"Inherits": "Common/Entities/BaseEnemy",
"Override": {
"Health": {
"MaxHealth": 200
}
}
}

---

Shrnutí

| Operace | Metoda |
|---------|--------|
| Získat model | ModelAsset.getAssetMap().getAsset(name) |
| Vytvořit model | Model.createUnitScaleModel(asset) |
| Reagovat na load | LoadedAssetsEvent |
| Spawn entity | store.addEntity(holder, AddReason.LOAD) |
| World marker | WorldMapManager.addMarkerProvider() |

| Komponenta | Účel |
|------------|------|
| TransformComponent | Pozice a rotace |
| ModelComponent | 3D model |
| BoundingBox | Kolizní box |
| NetworkId | Síťová synchronizace |
| Nameplate | Jmenovka |
| Intangible | Nelze interagovat |

Last updated: 20. ledna 2026