feat: add NPC name generator and broadcast names in entity state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { World } from '../ecs/World.js';
|
||||
import type { GameMap } from '../map/GameMap.js';
|
||||
import { generateRandomAppearance } from '../spawner/appearanceGenerator.js';
|
||||
import { generateName } from '../spawner/nameGenerator.js';
|
||||
import type { EntityId, Position, Needs, Movement, NPCBrain, Appearance } from '@dflike/shared';
|
||||
|
||||
export function spawnNPC(world: World, map: GameMap): EntityId {
|
||||
@@ -24,6 +25,7 @@ export function spawnNPC(world: World, map: GameMap): EntityId {
|
||||
goalQueue: [],
|
||||
});
|
||||
world.addComponent<Appearance>(entity, 'appearance', generateRandomAppearance());
|
||||
world.addComponent<string>(entity, 'name', generateName());
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ export function serializeEntity(world: World, entityId: number): EntityState {
|
||||
needs: world.getComponent<Needs>(entityId, 'needs'),
|
||||
npcBrain: world.getComponent<NPCBrain>(entityId, 'npcBrain'),
|
||||
playerControlled: world.getComponent<PlayerControlled>(entityId, 'playerControlled'),
|
||||
name: world.getComponent<string>(entityId, 'name'),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { generateName } from '../nameGenerator.js';
|
||||
|
||||
describe('generateName', () => {
|
||||
it('returns a non-empty string', () => {
|
||||
const name = generateName();
|
||||
expect(name).toBeTruthy();
|
||||
expect(typeof name).toBe('string');
|
||||
expect(name.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('generates varied names over many calls', () => {
|
||||
const names = new Set<string>();
|
||||
for (let i = 0; i < 30; i++) {
|
||||
names.add(generateName());
|
||||
}
|
||||
expect(names.size).toBeGreaterThan(5);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
const PREFIXES = [
|
||||
'Urist', 'Kor', 'Bel', 'Thar', 'Grim', 'Hed', 'Mog', 'Zan',
|
||||
'Dur', 'Fal', 'Nor', 'Vim', 'Erd', 'Sig', 'Bor', 'Tul',
|
||||
'Arn', 'Hild', 'Dag', 'Sven', 'Brun', 'Kel', 'Ral', 'Tor',
|
||||
];
|
||||
|
||||
const SUFFIXES = [
|
||||
'mund', 'rik', 'mir', 'gard', 'sten', 'vald', 'dak', 'fen',
|
||||
'grim', 'lok', 'nar', 'thas', 'borg', 'din', 'run', 'vik',
|
||||
'gar', 'horn', 'mar', 'wulf', 'ban', 'dor', 'kel', 'ton',
|
||||
];
|
||||
|
||||
function pick<T>(arr: T[]): T {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
export function generateName(): string {
|
||||
return pick(PREFIXES) + pick(SUFFIXES);
|
||||
}
|
||||
@@ -55,6 +55,7 @@ export interface EntityState {
|
||||
needs?: Needs;
|
||||
npcBrain?: NPCBrain;
|
||||
playerControlled?: PlayerControlled;
|
||||
name?: string; // NPC display name
|
||||
}
|
||||
|
||||
export interface WorldState {
|
||||
|
||||
Reference in New Issue
Block a user