feat(api/runtime): java-style assets and localization sync
@@ -195,8 +195,8 @@ public class ExampleMod : IMod
|
||||
.Hardness(3.0f)
|
||||
.Resistance(15f)
|
||||
.Sound(SoundType.Stone)
|
||||
.Icon("examplemod:ruby_ore") // From assets/blocks/ruby_ore.png
|
||||
.Name("Ruby Ore")
|
||||
.Icon("examplemod:block/ruby_ore")
|
||||
.Name(Text.Translatable("block.examplemod.ruby_ore"))
|
||||
.RequiredHarvestLevel(2)
|
||||
.RequiredTool(ToolType.Pickaxe)
|
||||
.InCreativeTab(CreativeTab.BuildingBlocks));
|
||||
@@ -207,8 +207,8 @@ public class ExampleMod : IMod
|
||||
.Hardness(1.5f)
|
||||
.Resistance(10f)
|
||||
.Sound(SoundType.Stone)
|
||||
.Icon("examplemod:ruby_stone")
|
||||
.Name("Ruby Stone")
|
||||
.Icon("examplemod:block/ruby_stone")
|
||||
.Name(Text.Translatable("block.examplemod.ruby_stone"))
|
||||
.RequiredHarvestLevel(1)
|
||||
.RequiredTool(ToolType.Pickaxe)
|
||||
.InCreativeTab(CreativeTab.BuildingBlocks));
|
||||
@@ -219,8 +219,8 @@ public class ExampleMod : IMod
|
||||
.Hardness(2.0f)
|
||||
.Resistance(5f)
|
||||
.Sound(SoundType.Wood)
|
||||
.Icon("examplemod:ruby_wood_planks")
|
||||
.Name("Ruby Wood Planks")
|
||||
.Icon("examplemod:block/ruby_wood_planks")
|
||||
.Name(Text.Translatable("block.examplemod.ruby_wood_planks"))
|
||||
.InCreativeTab(CreativeTab.BuildingBlocks));
|
||||
|
||||
RubySand = Registry.Block.Register("examplemod:ruby_sand",
|
||||
@@ -230,8 +230,8 @@ public class ExampleMod : IMod
|
||||
.Hardness(0.5f)
|
||||
.Resistance(2.5f)
|
||||
.Sound(SoundType.Sand)
|
||||
.Icon("examplemod:ruby_sand")
|
||||
.Name("Ruby Sand")
|
||||
.Icon("examplemod:block/ruby_sand")
|
||||
.Name(Text.Translatable("block.examplemod.ruby_sand"))
|
||||
.RequiredTool(ToolType.Shovel)
|
||||
.InCreativeTab(CreativeTab.BuildingBlocks));
|
||||
|
||||
@@ -242,8 +242,8 @@ public class ExampleMod : IMod
|
||||
.Hardness(1.5f)
|
||||
.Resistance(10f)
|
||||
.Sound(SoundType.Stone)
|
||||
.Icon("examplemod:ruby_stone")
|
||||
.Name("Ruby Stone Slab")
|
||||
.Icon("examplemod:block/ruby_stone")
|
||||
.Name(Text.Translatable("block.examplemod.ruby_stone_slab"))
|
||||
.RequiredHarvestLevel(1)
|
||||
.RequiredTool(ToolType.Pickaxe)
|
||||
.InCreativeTab(CreativeTab.BuildingBlocks));
|
||||
@@ -255,8 +255,8 @@ public class ExampleMod : IMod
|
||||
.Hardness(2.0f)
|
||||
.Resistance(5f)
|
||||
.Sound(SoundType.Wood)
|
||||
.Icon("examplemod:ruby_wood_planks")
|
||||
.Name("Ruby Wood Slab")
|
||||
.Icon("examplemod:block/ruby_wood_planks")
|
||||
.Name(Text.Translatable("block.examplemod.ruby_wood_slab"))
|
||||
.InCreativeTab(CreativeTab.BuildingBlocks));
|
||||
|
||||
RubyLamp = Registry.Block.Register("examplemod:ruby_lamp", new RubyLampBlock(false),
|
||||
@@ -265,8 +265,8 @@ public class ExampleMod : IMod
|
||||
.Hardness(0.3f)
|
||||
.Resistance(1.5f)
|
||||
.Sound(SoundType.Glass)
|
||||
.Icon("examplemod:ruby_lamp")
|
||||
.Name("Ruby Lamp")
|
||||
.Icon("examplemod:block/ruby_lamp")
|
||||
.Name(Text.Translatable("block.examplemod.ruby_lamp"))
|
||||
.RequiredHarvestLevel(0)
|
||||
.RequiredTool(ToolType.Pickaxe)
|
||||
.AcceptsRedstonePower()
|
||||
@@ -283,9 +283,9 @@ public class ExampleMod : IMod
|
||||
.Hardness(0.3f)
|
||||
.Resistance(1.5f)
|
||||
.Sound(SoundType.Glass)
|
||||
.Icon("examplemod:ruby_lamp_on")
|
||||
.Icon("examplemod:block/ruby_lamp_on")
|
||||
.LightLevel(1.0f)
|
||||
.Name("Ruby Lamp")
|
||||
.Name(Text.Translatable("block.examplemod.ruby_lamp_lit"))
|
||||
.RequiredHarvestLevel(0)
|
||||
.RequiredTool(ToolType.Pickaxe)
|
||||
.AcceptsRedstonePower());
|
||||
@@ -296,8 +296,8 @@ public class ExampleMod : IMod
|
||||
.Hardness(5.0f)
|
||||
.Resistance(30f)
|
||||
.Sound(SoundType.Metal)
|
||||
.Icon("examplemod:orichalcum_ore") // From assets/blocks/orichalcum.png
|
||||
.Name("Orichalcum Ore")
|
||||
.Icon("examplemod:block/orichalcum_ore")
|
||||
.Name(Text.Translatable("block.examplemod.orichalcum_ore"))
|
||||
.RequiredHarvestLevel(4)
|
||||
.RequiredTool(ToolType.Pickaxe)
|
||||
.InCreativeTab(CreativeTab.BuildingBlocks));
|
||||
@@ -305,8 +305,8 @@ public class ExampleMod : IMod
|
||||
Ruby = Registry.Item.Register("examplemod:ruby",
|
||||
new ItemProperties()
|
||||
.MaxStackSize(64)
|
||||
.Icon("examplemod:ruby") // From assets/items/ruby.png
|
||||
.Name("Ruby")
|
||||
.Icon("examplemod:item/ruby")
|
||||
.Name(Text.Translatable("item.examplemod.ruby"))
|
||||
.InCreativeTab(CreativeTab.Materials));
|
||||
|
||||
Registry.Item.RegisterToolMaterial("examplemod:ruby_material",
|
||||
@@ -320,8 +320,8 @@ public class ExampleMod : IMod
|
||||
.MaxStackSize(1)
|
||||
.MaxDamage(512)
|
||||
.AttackDamage(8.0f)
|
||||
.Icon("examplemod:ruby_sword")
|
||||
.Name("Ruby Sword")
|
||||
.Icon("examplemod:item/ruby_sword")
|
||||
.Name(Text.Translatable("item.examplemod.ruby_sword"))
|
||||
.InCreativeTab(CreativeTab.ToolsAndWeapons));
|
||||
|
||||
RubyShovelItem = Registry.Item.Register("examplemod:ruby_shovel", new RubyShovel { CustomMaterialId = "examplemod:ruby_material" },
|
||||
@@ -329,8 +329,8 @@ public class ExampleMod : IMod
|
||||
.MaxStackSize(1)
|
||||
.MaxDamage(512)
|
||||
.AttackDamage(4.5f)
|
||||
.Icon("examplemod:ruby_shovel")
|
||||
.Name("Ruby Shovel")
|
||||
.Icon("examplemod:item/ruby_shovel")
|
||||
.Name(Text.Translatable("item.examplemod.ruby_shovel"))
|
||||
.InCreativeTab(CreativeTab.ToolsAndWeapons));
|
||||
|
||||
RubyPickaxeItem = Registry.Item.Register("examplemod:ruby_pickaxe", new RubyPickaxe { CustomMaterialId = "examplemod:ruby_material" },
|
||||
@@ -338,8 +338,8 @@ public class ExampleMod : IMod
|
||||
.MaxStackSize(1)
|
||||
.MaxDamage(512)
|
||||
.AttackDamage(5.0f)
|
||||
.Icon("examplemod:ruby_pickaxe") // From assets/items/ruby_pickaxe.png
|
||||
.Name("Ruby Pickaxe")
|
||||
.Icon("examplemod:item/ruby_pickaxe")
|
||||
.Name(Text.Translatable("item.examplemod.ruby_pickaxe"))
|
||||
.InCreativeTab(CreativeTab.ToolsAndWeapons));
|
||||
|
||||
RubyAxeItem = Registry.Item.Register("examplemod:ruby_axe", new RubyAxe { CustomMaterialId = "examplemod:ruby_material" },
|
||||
@@ -347,8 +347,8 @@ public class ExampleMod : IMod
|
||||
.MaxStackSize(1)
|
||||
.MaxDamage(512)
|
||||
.AttackDamage(7.0f)
|
||||
.Icon("examplemod:ruby_axe")
|
||||
.Name("Ruby Axe")
|
||||
.Icon("examplemod:item/ruby_axe")
|
||||
.Name(Text.Translatable("item.examplemod.ruby_axe"))
|
||||
.InCreativeTab(CreativeTab.ToolsAndWeapons));
|
||||
|
||||
RubyHoeItem = Registry.Item.Register("examplemod:ruby_hoe", new RubyHoe { CustomMaterialId = "examplemod:ruby_material" },
|
||||
@@ -356,15 +356,15 @@ public class ExampleMod : IMod
|
||||
.MaxStackSize(1)
|
||||
.MaxDamage(512)
|
||||
.AttackDamage(1.0f)
|
||||
.Icon("examplemod:ruby_hoe")
|
||||
.Name("Ruby Hoe")
|
||||
.Icon("examplemod:item/ruby_hoe")
|
||||
.Name(Text.Translatable("item.examplemod.ruby_hoe"))
|
||||
.InCreativeTab(CreativeTab.ToolsAndWeapons));
|
||||
|
||||
RubyWandItem = Registry.Item.Register("examplemod:ruby_wand", new RubyWand(),
|
||||
new ItemProperties()
|
||||
.MaxStackSize(1)
|
||||
.Icon("examplemod:ruby_wand") // From assets/items/ruby_wand.png
|
||||
.Name("Ruby Wand")
|
||||
.Icon("examplemod:item/ruby_wand")
|
||||
.Name(Text.Translatable("item.examplemod.ruby_wand"))
|
||||
.InCreativeTab(CreativeTab.ToolsAndWeapons));
|
||||
|
||||
Registry.Recipe.AddFurnace("examplemod:ruby_ore", "examplemod:ruby", 1.0f);
|
||||
|
||||
@@ -2,24 +2,40 @@
|
||||
|
||||
## Language files
|
||||
|
||||
Language files live in `assets/lang/` with the format `{locale}.lang` (e.g. `en-GB.lang`, `de-DE.lang`).
|
||||
Language files live in `assets/examplemod/lang/` with the format `{locale}.lang` (e.g. `en-GB.lang`, `de-DE.lang`).
|
||||
|
||||
**Current API:** Use `BlockProperties.Name()` and `ItemProperties.Name()` when registering blocks and items. These set the display name shown in-game. The ModLoader hooks into the game's string lookup so your names appear correctly.
|
||||
Use `Text.Translatable()` with `BlockProperties.Name()` / `ItemProperties.Name()` to pull localized strings
|
||||
from these `.lang` files. Format: `key=value` per line, with `#` for comments.
|
||||
|
||||
**Future:** Multi-locale support may load from these `.lang` files. Format: `key=value` per line, with `#` for comments.
|
||||
Example:
|
||||
|
||||
```csharp
|
||||
.Name(Text.Translatable("item.examplemod.ruby"))
|
||||
.Name(Text.Literal("Ruby")) // literal fallback if you don't want localization
|
||||
```
|
||||
|
||||
## Textures
|
||||
|
||||
Mod textures are supported via the dynamic atlas system. Place PNG files in:
|
||||
Mod textures use Java-style asset paths. Place PNG files in:
|
||||
|
||||
- **Blocks:** `assets/blocks/{name}.png` → icon `{modid}:{name}` (e.g. `ruby_ore.png` → `examplemod:ruby_ore`)
|
||||
- **Items:** `assets/items/{name}.png` → icon `{modid}:{name}` (e.g. `ruby.png` → `examplemod:ruby`)
|
||||
- **Blocks:** `assets/examplemod/textures/block/{name}.png` → icon `examplemod:block/{name}`
|
||||
- **Items:** `assets/examplemod/textures/item/{name}.png` → icon `examplemod:item/{name}`
|
||||
|
||||
The mod ID is derived from the mod folder name (lowercase, hyphens removed). Use the namespaced icon in `BlockProperties.Icon()` and `ItemProperties.Icon()`:
|
||||
Use the Java-style icon in `BlockProperties.Icon()` and `ItemProperties.Icon()`:
|
||||
|
||||
```csharp
|
||||
.Icon("examplemod:ruby_ore") // block from assets/blocks/ruby_ore.png
|
||||
.Icon("examplemod:ruby") // item from assets/items/ruby.png
|
||||
.Icon("examplemod:block/ruby_ore") // block from assets/examplemod/textures/block/ruby_ore.png
|
||||
.Icon("examplemod:item/ruby") // item from assets/examplemod/textures/item/ruby.png
|
||||
```
|
||||
|
||||
Textures must be 16×16 pixels (or any size; they are scaled). For vanilla icons, use names like `gold_ore`, `diamond`, etc.
|
||||
Textures must be 16×16 pixels (or any size; they are scaled).
|
||||
|
||||
## Models (Java-style)
|
||||
|
||||
Block and item models are supported using Java-style JSON assets:
|
||||
|
||||
- **Blocks:** `assets/examplemod/models/block/{name}.json`
|
||||
- **Items:** `assets/examplemod/models/item/{name}.json`
|
||||
- **Entities (future):** `assets/examplemod/models/entity/{name}.json`
|
||||
|
||||
The `examplemod` namespace should match your mod ID (lowercase).
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
# ExampleMod language file (en-GB)
|
||||
# Display names for blocks and items.
|
||||
# In the current API, use BlockProperties.Name() and ItemProperties.Name() instead.
|
||||
# This file documents the expected format for future multi-locale support.
|
||||
|
||||
block.examplemod.ruby_ore=Ruby Ore
|
||||
block.examplemod.ruby_stone=Ruby Stone
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -1,5 +0,0 @@
|
||||
# ExampleMod language file (de-DE)
|
||||
# German translations for ExampleMod content.
|
||||
|
||||
block.examplemod.ruby_ore=Rubinerz
|
||||
item.examplemod.ruby=Rubin
|
||||