feat(api/runtime): java-style assets and localization sync

This commit is contained in:
Jacobwasbeast
2026-03-10 14:36:23 -05:00
parent 36094e0ea9
commit 70dbff3fac
38 changed files with 794 additions and 110 deletions

View File

@@ -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);

View File

@@ -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).

View File

@@ -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

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,5 +0,0 @@
# ExampleMod language file (de-DE)
# German translations for ExampleMod content.
block.examplemod.ruby_ore=Rubinerz
item.examplemod.ruby=Rubin