1
0
Fork 0

feat(npcs): add game-npcs collection for vendors

Developer-gated collection for NPC characters, including the vendor
fields (enabled, priceModifier, sells[]) used by the marketplace to
attribute auto-generated listings to background merchants.
This commit is contained in:
Jason Fraley 2026-08-10 16:03:52 -04:00
parent 9c15117b9b
commit 3a46d4e5be
2 changed files with 116 additions and 0 deletions

View file

@ -0,0 +1,114 @@
import { CollectionConfig } from "payload";
import { isDeveloper } from "@/utils/access-control/isRole";
export const GameNpcs: CollectionConfig = {
slug: "game-npcs",
admin: {
group: "Game",
useAsTitle: "name",
defaultColumns: ["name", "occupation", "location", "faction", "isGenerated", "isInGame"],
listSearchableFields: ["name", "occupation", "bio"],
pagination: { defaultLimit: 50 },
},
access: {
read: ({ req }) => !!req.user,
create: isDeveloper,
update: isDeveloper,
delete: isDeveloper,
},
fields: [
{
name: "name",
type: "text",
required: true,
admin: {
description: "The NPC's name as shown in-game and on the frontend.",
},
},
{
name: "occupation",
type: "text",
admin: {
description: "What this NPC does (e.g. 'Weapons Dealer', 'Field Medic').",
},
},
{
name: "location",
type: "relationship",
relationTo: "game-structures",
admin: {
description: "Where this NPC is stationed in-game.",
},
},
{
name: "faction",
type: "relationship",
relationTo: "factions",
admin: {
description: "The faction this NPC belongs to, if any.",
},
},
{
name: "bio",
type: "textarea",
admin: {
description: "A short background/profile for this NPC.",
},
},
{
name: "isGenerated",
type: "checkbox",
defaultValue: false,
admin: {
description:
"True for NPCs auto-created by the market tick to cover unstocked goods. They are placeholders until included in the game.",
},
},
{
name: "isInGame",
type: "checkbox",
defaultValue: true,
admin: {
description:
"Whether this NPC is officially part of the game. Generated NPCs start off; flip this on to include them.",
},
},
{
name: "vendor",
label: "Vendor",
type: "group",
fields: [
{
name: "enabled",
type: "checkbox",
defaultValue: false,
admin: {
description:
"Whether this NPC runs a market stall. Auto-generated vendor stock is attributed to them.",
},
},
{
name: "priceModifier",
type: "number",
defaultValue: 1,
min: 0.25,
max: 5,
admin: {
description:
"Multiplies the auto-generated price for this NPC's stock (1 = base market price).",
},
},
{
name: "sells",
type: "relationship",
relationTo: "assets",
hasMany: true,
admin: {
description:
"The goods this NPC sells. The market tick prefers these NPCs when stocking those assets.",
},
},
],
},
],
};

View file

@ -31,6 +31,7 @@ import { GameStructures } from "@/collections/game/GameStructures";
import { GameHardResources } from "@/collections/game/GameHardResources";
import { GameEventLogs } from "@/collections/game/GameEventLogs";
import { GameVehicles } from "@/collections/game/GameVehicles";
import { GameNpcs } from "@/collections/game/GameNpcs";
import { Experience } from "@/collections/users/Experience";
import { BankAccounts } from "@/collections/banking/BankAccounts";
import { BankTransactions } from "@/collections/banking/BankTransactions";
@ -78,6 +79,7 @@ export default buildConfig({
GameHardResources,
GameStructures,
GameVehicles,
GameNpcs,
GameEventLogs,
// Users