feat(content): translate seeded items, locations, and reputation faction to English

Converts all German player-facing content in the API's seed files to
English per the English Game Content Foundation glossary: item
name/description, monster name, location name/description, all
local-location POI/action content, and the border-guard reputation
faction. Technical keys are unchanged.
This commit is contained in:
Bastian Wagner
2026-08-21 20:00:04 +02:00
parent 74fc89dfe5
commit b8ee56ca1a
5 changed files with 101 additions and 101 deletions

View File

@@ -63,8 +63,8 @@ function item(
export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
item(
'worn-short-sword',
'Abgenutztes Kurzschwert',
'Die Klinge eines Rekruten, öfter geschliffen als geführt.',
'Worn Shortsword',
"A recruit's blade, sharpened more often than it's been swung.",
ItemType.EQUIPMENT,
EquipmentSlot.WEAPON,
ItemRarity.COMMON,
@@ -72,8 +72,8 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'bandit-blade',
'Räuberklinge',
'Eine grob gezahnte Klinge, geschmiedet für schnelle Überfälle.',
'Bandit Blade',
'A roughly serrated blade, forged for quick raids.',
ItemType.EQUIPMENT,
EquipmentSlot.WEAPON,
ItemRarity.COMMON,
@@ -81,8 +81,8 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'ash-blade',
'Aschenklinge',
'In der Glut der Aschenfelder gehärtet; die Schneide glimmt noch.',
'Ashen Blade',
'Tempered in the embers of the Ashen Fields; the edge still glows faintly.',
ItemType.EQUIPMENT,
EquipmentSlot.WEAPON,
ItemRarity.RARE,
@@ -90,8 +90,8 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'bandit-hood',
'Räuberhaube',
'Vernarbtes Leder, das Gesicht und Absicht des Trägers verbirgt.',
'Bandit Hood',
"Scarred leather that hides both the wearer's face and their intent.",
ItemType.EQUIPMENT,
EquipmentSlot.HEAD,
ItemRarity.COMMON,
@@ -99,8 +99,8 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'reinforced-leather-jacket',
'Verstärkte Lederjacke',
'Mit Eisenplatten benähtes Leder, schwer und verlässlich.',
'Reinforced Leather Jacket',
'Leather sewn with iron plates, heavy and dependable.',
ItemType.EQUIPMENT,
EquipmentSlot.CHEST,
ItemRarity.RARE,
@@ -108,8 +108,8 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'raider-gloves',
'Plündererhandschuhe',
'Beschlagene Handschuhe, abgegriffen von fremdem Gut.',
'Plunderer Gloves',
"Studded gloves, worn smooth from handling other people's belongings.",
ItemType.EQUIPMENT,
EquipmentSlot.HANDS,
ItemRarity.COMMON,
@@ -117,8 +117,8 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'guardsman-legs',
'Wachmannsbeinkleid',
'Beinzeug der Grenzwacht, an den Knien geflickt.',
"Watchman's Leggings",
'Leg armor of the Border Watch, patched at the knees.',
ItemType.EQUIPMENT,
EquipmentSlot.LEGS,
ItemRarity.RARE,
@@ -126,8 +126,8 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'ash-boots',
'Aschenstiefel',
'Stiefel, die durch glimmende Felder getragen wurden und blieben.',
'Ashen Boots',
'Boots that walked through smoldering fields and never quite left them behind.',
ItemType.EQUIPMENT,
EquipmentSlot.FEET,
ItemRarity.RARE,
@@ -135,8 +135,8 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'borderwatch-sigil',
'Zeichen der Grenzwacht',
'Das Wappen eines Turms, den es nicht mehr gibt.',
'Mark of the Border Watch',
'The crest of a watchtower that no longer stands.',
ItemType.EQUIPMENT,
EquipmentSlot.AMULET,
ItemRarity.RARE,
@@ -144,37 +144,37 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
),
item(
'burned-captain-pendant',
'Anhänger des verbrannten Hauptmanns',
'Ein Schädel aus Schlacke, in dem die Glut nie erlosch.',
"Charred Captain's Pendant",
'A skull cast in slag, its embers never quite gone out.',
ItemType.EQUIPMENT,
EquipmentSlot.AMULET,
ItemRarity.EPIC,
{ bonusAttack: 3, bonusHp: 15, bonusArmor: 2 },
),
// Seeded as content only. Slice 0.4 implements no consumable use, and the
// Straßenräuber loot entry for it is deliberately deferred (spec §16).
// Road Bandit loot entry for it is deliberately deferred (spec §16).
item(
'small-healing-potion',
'Kleiner Heiltrank',
'Ein bitterer Sud, der Wunden für einen Atemzug vergessen lässt.',
'Small Healing Potion',
'A bitter draught that makes wounds forgettable, if only for a breath.',
ItemType.CONSUMABLE,
null,
ItemRarity.COMMON,
),
// A Trade Good (spec §17): turned in to the Grenzwacht for Silver and
// A Trade Good (spec §17): turned in to the Border Watch for Silver and
// reputation rather than crafted with.
item(
'ash-pelt',
'Aschenfell',
'Versengtes Fell, zäh wie Leder und grau von Ascheflug.',
'Ash Pelt',
'Singed pelt, tough as leather and grey with drifting ash.',
ItemType.TRADE_GOOD,
null,
ItemRarity.COMMON,
),
item(
'bandit-insignia',
'Räuberabzeichen',
'Ein grob geprägtes Zeichen, das einen Straßenräuber als Mitglied seiner Bande auswies.',
'Bandit Insignia',
'A roughly stamped token marking a road bandit as one of their band.',
ItemType.TROPHY,
null,
ItemRarity.COMMON,
@@ -182,11 +182,11 @@ export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
];
export const LOOT_TABLES = [
{ id: ASH_RAT_LOOT_TABLE_ID, key: 'ash-rat-loot', name: 'Aschenratte Beute' },
{ id: ASH_RAT_LOOT_TABLE_ID, key: 'ash-rat-loot', name: 'Ash Rat Loot' },
{
id: ROAD_BANDIT_LOOT_TABLE_ID,
key: 'road-bandit-loot',
name: 'Straßenräuber Beute',
name: 'Road Bandit Loot',
},
];

View File

@@ -25,11 +25,11 @@ export interface LocalLocationContent {
}
export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = {
regionName: 'Aschenfelder',
regionTierLabel: 'Gebiet 1',
regionName: 'Ashen Fields',
regionTierLabel: 'Tier 1',
locationType: 'HUNTING_GROUND',
localDescription:
'Ein alter Handelsweg, der durch Feuer und Krieg in Asche gelegt wurde. Verbrannte Karren, zerbrochene Waffen und verstummte Schreie säumen den Pfad in die Aschenfelder.',
'An old trade road, burned to ash by fire and war. Charred carts, broken weapons, and silenced cries line the path into the Ashen Fields.',
localArtworkPath: '/images/backgrounds/Aschestrasse.png',
// Anchored to painted detail in `Aschestrasse.png`: the burning horizon down
// the road, the standing gravestone on the left verge, the cracked stones in
@@ -37,8 +37,8 @@ export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = {
localPointsOfInterest: [
{
key: 'hunt-area',
title: 'Jagdgebiet',
actionLabel: 'Jagd beginnen',
title: 'Hunting Ground',
actionLabel: 'Begin Hunt',
type: 'HUNT',
iconKey: 'hunt',
xPercent: 57,
@@ -47,57 +47,57 @@ export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = {
},
{
key: 'inspect-tracks',
title: 'Verdächtige Spuren',
actionLabel: 'Untersuchen',
title: 'Suspicious Tracks',
actionLabel: 'Investigate',
type: 'INVESTIGATE',
iconKey: 'investigate',
xPercent: 40,
yPercent: 82,
enabled: true,
resultTitle: 'Verdächtige Spuren',
resultTitle: 'Suspicious Tracks',
resultText:
'Zwischen Asche und zerbrochenen Steinen erkennst du mehrere frische Stiefelabdrücke. Sie führen nach Osten, in Richtung des verlassenen Wachtpostens.',
'Among the ash and broken stones you make out several fresh bootprints. They lead east, toward the abandoned watchpost.',
},
{
key: 'search-abandoned-wagon',
title: 'Verlassener Wagen',
actionLabel: 'Durchsuchen',
title: 'Abandoned Wagon',
actionLabel: 'Search',
type: 'SEARCH',
iconKey: 'search',
xPercent: 86,
yPercent: 70,
enabled: true,
resultTitle: 'Verlassener Wagen',
resultTitle: 'Abandoned Wagon',
resultText:
'Der Wagen wurde gründlich geplündert. Zwischen verbrannten Brettern findest du nur leere Kisten und Spuren eines hastigen Aufbruchs.',
'The wagon has been thoroughly looted. Among the charred planks you find only empty crates and signs of a hasty departure.',
},
{
key: 'wounded-scout',
title: 'Verwundeter Kundschafter',
actionLabel: 'Sprechen',
title: 'Wounded Scout',
actionLabel: 'Talk',
type: 'NPC',
iconKey: 'speak',
xPercent: 17,
yPercent: 62,
enabled: true,
resultTitle: 'Verwundeter Kundschafter',
resultTitle: 'Wounded Scout',
resultText:
'„Die Straße ist nicht mehr sicher. Die Plünderer kommen aus Richtung des alten Wachtpostens. Wenn du weitergehst, halte die Augen offen."',
'"The road isn\'t safe anymore. The raiders are coming from the direction of the old watchpost. If you keep going, keep your eyes open."',
},
],
localPrimaryActions: [
{
key: 'start-hunt',
label: 'Jagd beginnen',
description: 'Im Gebiet jagen',
label: 'Begin Hunt',
description: 'Hunt in this area',
type: 'HUNT',
iconKey: 'hunt',
enabled: true,
},
{
key: 'investigate-tracks',
label: 'Spuren untersuchen',
description: 'Hinweise finden',
label: 'Investigate tracks',
description: 'Find clues',
type: 'INVESTIGATE',
iconKey: 'investigate',
enabled: true,
@@ -105,8 +105,8 @@ export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = {
},
{
key: 'search-surroundings',
label: 'Umgebung durchsuchen',
description: 'Beute finden',
label: 'Search surroundings',
description: 'Find loot',
type: 'SEARCH',
iconKey: 'search',
enabled: true,
@@ -114,8 +114,8 @@ export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = {
},
{
key: 'open-map',
label: 'Zur Karte',
description: 'Gebiet wechseln',
label: 'To Map',
description: 'Change area',
type: 'MAP',
iconKey: 'map',
enabled: true,
@@ -132,49 +132,49 @@ export const BURNED_ROAD_LOCAL_CONTENT: LocalLocationContent = {
// so a kill here yields neither. Silver reaches the player through turn-ins
// instead. Leaving either entry in place would break this list's own rule.
localRewardPreview: [
{ key: 'equipment', label: 'Ausrüstung', iconKey: 'equipment' },
{ key: 'equipment', label: 'Equipment', iconKey: 'equipment' },
{ key: 'material', label: 'Material', iconKey: 'material' },
],
};
export const SOUTH_GATE_LOCAL_CONTENT: LocalLocationContent = {
regionName: 'Aschenfelder',
regionTierLabel: 'Gebiet 1',
regionName: 'Ashen Fields',
regionTierLabel: 'Tier 1',
locationType: 'TRANSITION',
localDescription:
'Am schwarzen Südtor endet der Schutz Graufurts. Hinter den Wachtfeuern beginnt die stille Weite der Aschenfelder.',
"At the black South Gate, Graufurt's protection ends. Beyond the watch-fires begins the silent expanse of the Ashen Fields.",
localArtworkPath: '/images/backgrounds/Suedtor.png',
localPointsOfInterest: [
{
key: 'gate-notice',
title: 'Aushangtafel',
actionLabel: 'Lesen',
title: 'Notice Board',
actionLabel: 'Read',
type: 'INVESTIGATE',
iconKey: 'investigate',
xPercent: 22,
yPercent: 42,
enabled: true,
resultTitle: 'Aushangtafel',
resultTitle: 'Notice Board',
resultText:
'Verwitterte Anschläge flattern im Wind. Ein frischer Zettel warnt vor Plünderern auf der Verbrannten Straße und verspricht Silber für jeden erlegten Räuber.',
'Weathered notices flutter in the wind. A fresh one warns of raiders on the Burned Road and promises silver for every bandit killed.',
},
{
key: 'gate-watch',
title: 'Torwache',
actionLabel: 'Sprechen',
title: 'Gate Watch',
actionLabel: 'Talk',
type: 'NPC',
iconKey: 'speak',
xPercent: 45,
yPercent: 52,
enabled: true,
resultTitle: 'Torwache',
resultTitle: 'Gate Watch',
resultText:
'„Hinter dem Tor endet Graufurts Schutz. Wer nach Süden geht, geht auf eigene Gefahrund kommt selten so zurück, wie er gegangen ist."',
'"Beyond the gate, Graufurt\'s protection ends. Whoever heads south does so at their own riskand rarely comes back the way they left."',
},
{
key: 'south-road',
title: 'Straße nach Süden',
actionLabel: 'Zur Karte',
title: 'Road South',
actionLabel: 'To Map',
type: 'MAP',
iconKey: 'map',
xPercent: 66,
@@ -185,8 +185,8 @@ export const SOUTH_GATE_LOCAL_CONTENT: LocalLocationContent = {
localPrimaryActions: [
{
key: 'talk-to-watch',
label: 'Wache ansprechen',
description: 'Lage erfragen',
label: 'Talk to the watch',
description: 'Ask about the situation',
type: 'NPC',
iconKey: 'speak',
enabled: true,
@@ -194,8 +194,8 @@ export const SOUTH_GATE_LOCAL_CONTENT: LocalLocationContent = {
},
{
key: 'read-notice',
label: 'Aushang lesen',
description: 'Hinweise finden',
label: 'Read the notice',
description: 'Find clues',
type: 'INVESTIGATE',
iconKey: 'investigate',
enabled: true,
@@ -203,8 +203,8 @@ export const SOUTH_GATE_LOCAL_CONTENT: LocalLocationContent = {
},
{
key: 'open-map',
label: 'Zur Karte',
description: 'Gebiet wechseln',
label: 'To Map',
description: 'Change area',
type: 'MAP',
iconKey: 'map',
enabled: true,

View File

@@ -16,9 +16,9 @@ export const REPUTATION_FACTIONS: SeedReputationFaction[] = [
{
id: BORDER_GUARD_FACTION_ID,
key: 'border-guard',
name: 'Grenzwacht',
name: 'Border Watch',
description:
'Die letzten organisierten Wächter der Aschenfelder, die verbliebene Handelsrouten und Außenposten schützen.',
'The last organized watch of the Ashen Fields, guarding what remains of the trade routes and outposts.',
regionKey: 'ashen-fields',
enabled: true,
},

View File

@@ -181,7 +181,7 @@ describe('seedVisibleVerticalSlice', () => {
expect.arrayContaining([
expect.objectContaining({
key: 'ash-rat',
name: 'Aschenratte',
name: 'Ash Rat',
level: 1,
maxHp: 45,
attack: 5,
@@ -192,7 +192,7 @@ describe('seedVisibleVerticalSlice', () => {
}),
expect.objectContaining({
key: 'road-bandit',
name: 'Straßenräuber',
name: 'Road Bandit',
level: 2,
maxHp: 75,
attack: 9,
@@ -203,7 +203,7 @@ describe('seedVisibleVerticalSlice', () => {
}),
expect.objectContaining({
key: 'wild-road-dog',
name: 'Verwilderter Straßenhund',
name: 'Feral Road Hound',
level: 1,
silverMin: 0,
silverMax: 0,
@@ -212,7 +212,7 @@ describe('seedVisibleVerticalSlice', () => {
}),
expect.objectContaining({
key: 'charred-looter',
name: 'Verkohlter Plünderer',
name: 'Charred Raider',
level: 2,
silverMin: 0,
silverMax: 0,
@@ -268,14 +268,14 @@ describe('seedVisibleVerticalSlice', () => {
expect(burnedRoad).toEqual(
expect.objectContaining({
regionName: 'Aschenfelder',
regionTierLabel: 'Gebiet 1',
regionName: 'Ashen Fields',
regionTierLabel: 'Tier 1',
locationType: 'HUNTING_GROUND',
localArtworkPath: '/images/backgrounds/Aschestrasse.png',
}),
);
expect(burnedRoad.localDescription).toContain(
'Ein alter Handelsweg, der durch Feuer und Krieg in Asche gelegt wurde.',
'An old trade road, burned to ash by fire and war.',
);
const pointsOfInterest = burnedRoad.localPointsOfInterest as {
@@ -299,10 +299,10 @@ describe('seedVisibleVerticalSlice', () => {
label: string;
}[];
expect(primaryActions.map((action) => action.label)).toEqual([
'Jagd beginnen',
'Spuren untersuchen',
'Umgebung durchsuchen',
'Zur Karte',
'Begin Hunt',
'Investigate tracks',
'Search surroundings',
'To Map',
]);
});
@@ -364,7 +364,7 @@ describe('seedVisibleVerticalSlice', () => {
expect.objectContaining({
id: persistedSouthGateId,
key: 'south-gate',
name: 'Südtor von Graufurt',
name: 'Graufurt South Gate',
}),
expect.objectContaining({
id: BURNED_ROAD_ID,
@@ -420,7 +420,7 @@ describe('seedVisibleVerticalSlice', () => {
expect.arrayContaining([
expect.objectContaining({
key: 'bandit-blade',
name: 'Räuberklinge',
name: 'Bandit Blade',
type: 'EQUIPMENT',
equipmentSlot: 'WEAPON',
rarity: 'COMMON',
@@ -431,13 +431,13 @@ describe('seedVisibleVerticalSlice', () => {
}),
expect.objectContaining({
key: 'ash-pelt',
name: 'Aschenfell',
name: 'Ash Pelt',
type: 'TRADE_GOOD',
equipmentSlot: null,
}),
expect.objectContaining({
key: 'bandit-insignia',
name: 'Räuberabzeichen',
name: 'Bandit Insignia',
type: 'TROPHY',
equipmentSlot: null,
}),
@@ -628,7 +628,7 @@ describe('seedVisibleVerticalSlice', () => {
.getRepository(ReputationFaction)
.findOneBy({ key: 'border-guard' });
expect(faction).toMatchObject({ name: 'Grenzwacht', enabled: true });
expect(faction).toMatchObject({ name: 'Border Watch', enabled: true });
});
it('seeds both turn-in definitions', async () => {

View File

@@ -62,9 +62,9 @@ export async function seedVisibleVerticalSlice(
{
id: SOUTH_GATE_ID,
key: 'south-gate',
name: 'Südtor von Graufurt',
name: 'Graufurt South Gate',
description:
'Am schwarzen Südtor endet der Schutz Graufurts. Hinter den Wachtfeuern beginnt die stille Weite der Aschenfelder.',
"At the black South Gate, Graufurt's protection ends. Beyond the watch-fires begins the silent expanse of the Ashen Fields.",
regionKey: 'ashen-fields',
minRecommendedLevel: 1,
maxRecommendedLevel: 1,
@@ -77,9 +77,9 @@ export async function seedVisibleVerticalSlice(
{
id: BURNED_ROAD_ID,
key: 'burned-road',
name: 'Verbrannte Straße',
name: 'Burned Road',
description:
'Die alte Handelsstraße führt durch verkohlte Felder. Zwischen Asche und zerbrochenen Wagen warten die ersten Gefahren.',
'The old trade road cuts through charred fields. Among the ash and broken wagons, the first dangers wait.',
regionKey: 'ashen-fields',
minRecommendedLevel: 1,
maxRecommendedLevel: 2,
@@ -143,7 +143,7 @@ export async function seedVisibleVerticalSlice(
{
id: ASH_RAT_MONSTER_ID,
key: 'ash-rat',
name: 'Aschenratte',
name: 'Ash Rat',
level: 1,
maxHp: 45,
attack: 5,
@@ -157,7 +157,7 @@ export async function seedVisibleVerticalSlice(
{
id: WILD_ROAD_DOG_MONSTER_ID,
key: 'wild-road-dog',
name: 'Verwilderter Straßenhund',
name: 'Feral Road Hound',
level: 1,
maxHp: 55,
attack: 7,
@@ -173,7 +173,7 @@ export async function seedVisibleVerticalSlice(
{
id: ROAD_BANDIT_MONSTER_ID,
key: 'road-bandit',
name: 'Straßenräuber',
name: 'Road Bandit',
level: 2,
maxHp: 75,
attack: 9,
@@ -187,7 +187,7 @@ export async function seedVisibleVerticalSlice(
{
id: CHARRED_LOOTER_MONSTER_ID,
key: 'charred-looter',
name: 'Verkohlter Plünderer',
name: 'Charred Raider',
level: 2,
maxHp: 85,
attack: 11,