Table of Contents

Creation Law — Shops

You know classic Diku shop tables / sedit. Neo has no sedit. A shop is a workspace prototype keyed by an existing mobile VID, edited with @shop …, reviewed with @examine shop, then committed with @save shop.

Hub: Creation Law. Build the keeper mobile first: Mobiles. Place it: Zones. Player-facing buy/list/auction flow: Shopkeepers.

Why a shop is not the mobile

The mobile is the body players talk to. The shop row (H2 table shopkeeper) is the trade config: home room, produce list, item types traded, hours, and keeper messages. When a mobile has Acts.SHOPKEEPER, runtime looks up ShopkeeperDB.at(mobile.vid()).

So the build order is: mobile (with SHOPKEEPER)shop workspace on that same VIDzone placezone reset. Creating @new shop before the mobile exists fails. Forgetting the Acts flag leaves a shop row that never handles list / buy.

Prerequisites

Step-by-step: first shop

1. Confirm the mobile (build it if needed — Mobiles):

> @load npc_stats 1210
Okay.
> @npc_stats flags acts shopkeeper
Okay.
> @npc_stats flags acts sentinel
Okay.
> @examine npc_stats
> @save npc_stats
Okay.
>

2. Open the shop draft — VID is the mobile VID (must be in your mobile range; mobile must exist; no second shop draft while one is open):

> @new shop 1210
Okay.
>

Echoes you will see on failure (exact Immortality strings):

3. Home room (why: Shopkeeper.check refuses @save when room is 0 — the room VID must already exist in RoomDB):

> @shop room 1200
Okay.
>

4. What the keeper trades (ItemType flags via @shop trades; prefix ! to clear when the modifier supports it). At least one type is required to save:

> @shop trades weapon
Okay.
> @shop trades armor
Okay.
>

Bare @shop trades reprints @shop trades (!)<flag> plus the ItemType list from code.

5. Produce list (optional but usual — stock the keeper lists / sells at a fixed cost). Positions 1–10 (Shopkeeper.MAX_PRODUCES). Cost must be ≥ 1 gold for any filled slot or @save returns producing vid:… for 0gc:

> @shop produces 1 3100 500
Okay.
> @shop produces 2 3101 50
Okay.
>

Syntax: @shop produces <pos> <item-vid> <cost>. The produce setter does not verify the item prototype exists at edit time — @examine shows ItemDB.proper when the item is known.

6. Hourshours1 is required to save (open1 must be non-zero). Both start and finish for hours1 must be positive integers, and start must be strictly less than finish. hours2 is optional and may only be set after hours1:

> @shop hours1 8 12
Okay.
> @shop hours2 14 20
Okay.
>

7. Keeper messages (one-line writers — all six are required by Shopkeeper.check before @save):

> @shop keeper_no_item_msg
I do not have that item.
> @shop customer_no_item_msg
You do not seem to have that.
> @shop customer_no_cash_msg
You cannot afford that.
> @shop keeper_no_buy_msg
I do not buy that sort of thing.
> @shop keeper_buy_msg
That will be %d coins.
> @shop keeper_sell_msg
Sold.
>

keeper_buy_msg is passed through String.format(…, price) on several buy paths — include a %d where you want the gold amount echoed (same idea as the default string in S.keeperBuyMsg).

8. Review and commit:

> @examine shop
--- Shop ---
MOBILE  : 1210
ROOM    : 1200
HOURS1  : 8 to 12
HOURS2  : 14 to 20
--- produces ---
...
--- trades ---
...
--- keeper has no item ---
...
> @save shop
Okay.
>

If @save returns a short error from Shopkeeper.check, fix the field and save again — the draft stays open until save succeeds or you @clear shop. Exact check strings include: no room is set; no item types are set; no customerNoItemMsg set (also returned when keeper_no_item_msg is missing — code quirk); no customerNoCashMsg set; no keeperNoBuyMsg set; no keeperBuyMsg set; no keeperSellMsg set; open time must be set; producing vid:<n> for 0gc.

Place the keeper via a zone

Why: the shop row alone does not spawn the mobile. Zone reset loads the npc into a room; players then use list / buy / auction / … against that keeper (Shopkeepers).

> @load zone 1299
Okay.
> @zone npc 1210 1200
Okay.
> @examine zone
> @save zone
Okay.
> zone reset
Okay.
>

''@shop'' field commands

From ModifySocial.cmdCrShop (real subcommands only):

Workspace companions (same pattern as rooms/items): @new shop, @examine shop, @clear shop, @save shop, @load shop <vid>, @destroy shop <vid>.

Edit an existing shop

> @load shop 1210
Okay.
> @shop produces 1 3100 450
Okay.
> @examine shop
> @save shop
Okay.
>

Vs classic shop OLC

You never enter a numbered shop editor. There is no sedit. You open a shop workspace on a mobile VID, set fields with @shop, @examine, @save. Trade behavior also needs Acts.SHOPKEEPER on the mobile and a zone placement.

Common mistakes

Code notes / gaps

Documented as facts from the Java tree (not guesses):