Skip to content
Back to skills

Action Forms

ASecurity

A dialog that asks the player something and hands an answer back is an action form: `openForm(Form, input)` from anywhere, awaited, null when the player walks away. An NPC is one folder under `src/overworld/npcs`: `createNpc` in its `index.ts` and the script it loads, which talks through a conversation of forms. Applies when adding a question dialog, an NPC, or changing what an NPC does.

  • 5 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 5, 2026
businessgoaws

Works with

  • cli

Security analysis

A100/100

Scanned October 5, 2026

npx -y skills add lxsmnsyc/overwander --skill action-forms --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Action Forms?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Action Forms
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lxsmnsyc-action-forms/badge)](https://www.skillsdirectory.com/skills/lxsmnsyc-action-forms)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: action-forms
description: >
  A dialog that asks the player something and hands an answer back is an
  action form: `openForm(Form, input)` from anywhere, awaited, null when the
  player walks away. An NPC is one folder under `src/overworld/npcs`: `createNpc` in its
  `index.ts` and the script it loads, which talks through a conversation of
  forms. Applies when adding a question dialog, an NPC, or changing what an
  NPC does.
---

A question is a promise. `src/components/forms` holds the forms, the stack they
open on and the one `FormHost` the app draws them in.

## Forms

- A form is `defineForm({ title, prompt, view })`. The view draws only its own
  content and its `DialogActions`; the frame (nameplate, the line under it) is
  whoever opened it. It ends with `submit(answer)` or `cancel()`, and its way
  out says `leave`.
- `openForm(Form, input)` opens it over whatever is up and resolves with the
  answer, or null. Only the top frame shows, so a form opened from inside
  another dialog's flow never fights it for the closing click.
- A form that needs a record declares the resource and reads it in a child
  under its own `Suspense` with a fallback, so a conversation's line stays up
  while it loads.
- Reach for the generic ones before writing a new one: `choose`/`choiceForm`,
  `PickCatchForm`, `PickItemForm`, `PickMoveForm`, `PickBoxForm`,
  `TeachMoveForm`.

## NPCs

- One folder per role under `src/overworld/npcs`. `index.ts` is
  `createNpc(Npc.X, { name, description, quote, spent, sprites, visit, wanders,
  shop, interact: () => import('./interact') })`, and `interact.tsx` beside it
  is the script. Add the folder to the `Record` in `src/overworld/npcs/index.ts`.
- `interact` stays a loader. The server and world generation read the
  definitions, and a static import would hand them every form and picker the
  script asks through.
- `wanders` puts a role in the wandering roll, which is world generation: a
  new wanderer moves who stands on every existing cell, so it is a deliberate
  change with its test updated.
- A script is `(visit) => Promise<void>`. It talks through `visit.say`,
  `visit.ask` and `visit.form`, reads the purse and bag through
  `visit.gold`/`bag`/`carrying`, and reports arrivals with `visit.notify`.
  Roles that share one script (the shops) point `interact` at it.
- A null from a step is the player declining; the script decides whether that
  ends it or steps back. A player who walks away ends the script where it
  stands, so no step needs to check.
- A once-a-window NPC (`visit` in its definition) says its `spent` line instead
  of running the script when the server has already served the player.
- The script is presentation. Everything it changes goes through a server
  function that derives the NPC again from the cell and refuses on its own.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…