Skip to content

Instantly share code, notes, and snippets.

@Birch-san
Created May 17, 2026 11:13
Show Gist options
  • Select an option

  • Save Birch-san/a9ec6c1cd3e73f55a6feb38e2dc9e95f to your computer and use it in GitHub Desktop.

Select an option

Save Birch-san/a9ec6c1cd3e73f55a6feb38e2dc9e95f to your computer and use it in GitHub Desktop.
Infinite Craft NAIScript JSX
/*---
compatibilityVersion: naiscript-1.0
id: e30350cc-876f-46e5-ba3a-b0f37c642935
name: Infinite Craft
createdAt: 1775407865919
updatedAt: 1779012871584
version: 1.0.0
author: Unknown
memoryLimit: 8
---*/
export default {}
interface Elem {
emoji: string
name: string
}
interface World {
elemList: string[]
elemDict: Record<string, Elem>
selectedElems: Set<string>
generating: boolean
dupeElem: Elem | undefined
newElem: Elem | undefined
precursors: Elem[] | undefined
craftParseFailure: string | undefined
generationError: string | undefined
}
const getInitialWorld = (): World => {
type ElemTup = [emoji: string, name: string]
const elems: ElemTup[] = [
['💧', 'Water'],
['🔥', 'Fire'],
['🌬️', 'Wind'],
['🌍', 'Earth'],
// ['💨', 'Steam'],
]
return {
elemList: elems.map(([_, name]) => name),
elemDict: Object.fromEntries(elems.map((([emoji, name]) => [name, {
emoji, name
} satisfies Elem]))),
selectedElems: new Set<string>(),
generating: false,
dupeElem: undefined,
newElem: undefined,
precursors: undefined,
craftParseFailure: undefined,
generationError: undefined,
}
}
const fmtElem = ({ emoji, name }: Elem): string =>
`<elem>${emoji} ${name}</elem>`;
const fmtEquation = (left: Elem, right: Elem): string =>
`${fmtElem(left)} + ${fmtElem(right)} = `;
const fewShot: Message[] = [
{
role: "user",
content: fmtEquation(
{emoji: '💧', name: 'Water'},
{emoji: '🔥', name: 'Fire'},
),
},
{
role: "assistant",
content: fmtElem({emoji: '💨', name: 'Steam'}),
},
{
role: "user",
content: fmtEquation(
{emoji: '💧', name: 'Water'},
{emoji: '🌬️', name: 'Wind'},
),
},
{
role: "assistant",
content: fmtElem({emoji: '🌧️', name: 'Rain'}),
},
{
role: "user",
content: fmtEquation(
{emoji: '🔥', name: 'Fire'},
{emoji: '🌍', name: 'Earth'},
),
},
{
role: "assistant",
content: fmtElem({emoji: 'Lava', name: '🌋'}),
},
]
type Reducer<State, Action> = (state: State, action: Action) => State
enum WorldActionType {
PickElem = "PickElem",
AddElem = "AddElem",
SetDupeElem = "SetDupeElem",
Generating = "Generating",
ClearSelections = "ClearSelections",
SetCraftParseFailure = "SetCraftParseFailure",
SetGenerationError = "SetGenerationError"
}
interface AbstractReduceWorldAction<T extends WorldActionType> {
type: T
}
interface PickElemAction extends AbstractReduceWorldAction<WorldActionType.PickElem> {
name: string
}
interface AddElemAction extends AbstractReduceWorldAction<WorldActionType.AddElem> {
elem: Elem
precursors: Elem[]
}
interface SetDupeElemAction extends AbstractReduceWorldAction<WorldActionType.SetDupeElem> {
elem: Elem
precursors: Elem[]
}
interface GeneratingAction extends AbstractReduceWorldAction<WorldActionType.Generating> {
generating: boolean
}
interface SetCraftParseFailureAction extends AbstractReduceWorldAction<WorldActionType.SetCraftParseFailure> {
message: string
}
interface SetGenerationErrorAction extends AbstractReduceWorldAction<WorldActionType.SetGenerationError> {
message: string
}
type ClearSelectionsAction = AbstractReduceWorldAction<WorldActionType.ClearSelections>
type ReduceWorldAction = PickElemAction | GeneratingAction | AddElemAction | ClearSelectionsAction | SetCraftParseFailureAction | SetGenerationErrorAction | SetDupeElemAction
type ElemsReducer<T extends ReduceWorldAction> = Reducer<World, T>
type ReduceElemStrategyMap = {
[K in WorldActionType]: ElemsReducer<Extract<ReduceWorldAction, {type: K}>>;
};
const pickElemReducer: ElemsReducer<PickElemAction> = (state: World, { name }: PickElemAction): World => {
const selectedElems: Set<string> = new Set(state.selectedElems)
if (selectedElems.has(name)) {
selectedElems.delete(name)
} else{
selectedElems.add(name)
}
return {
...state,
selectedElems,
dupeElem: undefined,
newElem: undefined,
precursors: undefined,
craftParseFailure: undefined,
generationError: undefined,
}
}
const addElemReducer: ElemsReducer<AddElemAction> = (state: World, { elem, precursors }: AddElemAction): World => {
const { name } = elem
const { elemList, elemDict } = state
return {
...state,
elemList: [...elemList, name],
elemDict: {
...elemDict,
[name]: elem,
},
newElem: elem,
precursors,
}
}
const setDupeElemReducer: ElemsReducer<SetDupeElemAction> = (state: World, { elem: dupeElem, precursors }: SetDupeElemAction): World => ({
...state,
dupeElem,
precursors,
})
const clearSelectionsReducer: ElemsReducer<ClearSelectionsAction> = (state: World, _: ClearSelectionsAction): World => ({
...state,
selectedElems: new Set<string>(),
})
const generatingReducer: ElemsReducer<GeneratingAction> = (state: World, { generating }: GeneratingAction): World => ({
...state,
generating,
})
const setCraftParseFailureReducer: ElemsReducer<SetCraftParseFailureAction> = (state: World, { message: craftParseFailure }: SetCraftParseFailureAction): World => ({
...state,
craftParseFailure,
})
const setGenerationErrorReducer: ElemsReducer<SetGenerationErrorAction> = (state: World, { message: generationError }: SetGenerationErrorAction): World => ({
...state,
generationError,
})
const worldReducers: ReduceElemStrategyMap = {
[WorldActionType.PickElem]: pickElemReducer,
[WorldActionType.AddElem]: addElemReducer,
[WorldActionType.SetDupeElem]: setDupeElemReducer,
[WorldActionType.ClearSelections]: clearSelectionsReducer,
[WorldActionType.Generating]: generatingReducer,
[WorldActionType.SetCraftParseFailure]: setCraftParseFailureReducer,
[WorldActionType.SetGenerationError]: setGenerationErrorReducer,
}
const applyStrategy = <
State,
Action extends { type: K },
K extends string
>(
strategies: { [T in K]: Reducer<State, Extract<Action, { type: T }>> },
state: State,
action: Action
): State => {
const k = action.type as K
const strategy = strategies[k] as Reducer<State, Action>
return strategy(state, action)
}
const worldReducer = (state: World, action: ReduceWorldAction): World =>
applyStrategy(worldReducers, state, action)
const createStore = <S, A>(reducer: (s: S, a: A) => S, initial: S) => {
let state = initial;
const listeners = new Set<() => void>();
return {
getState: () => state,
dispatch: (action: A) => {
state = reducer(state, action);
listeners.forEach((l) => l());
},
subscribe: (listener: () => void) => {
listeners.add(listener);
return () => listeners.delete(listener);
},
};
}
const worldStore = createStore(worldReducer, getInitialWorld());
enum CraftOutcomeType {
NewElement = "NewElement",
Duplicate = "Duplicate",
ParseError = "ParseError",
GenerateError = "GenerateError"
}
interface AbstractCraftOutcome<T extends CraftOutcomeType> {
type: T
}
interface NewElementCraftOutcome extends AbstractCraftOutcome<CraftOutcomeType.NewElement> {
elem: Elem
}
interface DuplicateCraftOutcome extends AbstractCraftOutcome<CraftOutcomeType.Duplicate> {
elem: Elem
}
interface ParseErrorCraftOutcome extends AbstractCraftOutcome<CraftOutcomeType.ParseError> {
message: string
}
interface GenerateErrorCraftOutcome extends AbstractCraftOutcome<CraftOutcomeType.GenerateError> {
message: string
}
type CraftOutcome = NewElementCraftOutcome | DuplicateCraftOutcome | ParseErrorCraftOutcome | GenerateErrorCraftOutcome
// matches '<elem>🌫️ Dust</elem>'
const matcher = /^<elem>(\p{Emoji_Presentation}|\p{Emoji}\ufe0f)\s+(\P{Emoji_Presentation}+)<\/elem>$/u
// matches '<elem>Dust 🌪️</elem>'
const altMatcher = /^<elem>(\P{Emoji_Presentation}+)\s+(\p{Emoji_Presentation}|\p{Emoji}\ufe0f)<\/elem>$/u
async function craftElements(left: Elem, right: Elem, knownElems: Set<string>): Promise<CraftOutcome> {
const prompt = fmtEquation(left, right)
const cancellationSignal: CancellationSignal = await api.v1.createCancellationSignal()
const cbk = (choices: GenerationChoice[], final: boolean): void | string => {
// api.v1.log(choices, final);
const total = choices.map(({text}) => text).join('')
const match = matcher.exec(total)
if (match) {
cancellationSignal.cancel()
}
// it can get confused and generate it in reverse
const altMatch = altMatcher.exec(total)
if (altMatch) {
cancellationSignal.cancel()
}
}
const resp: GenerationResponse = await api.v1.generate(
[
...fewShot,
{
role: "user",
content: prompt,
},
] satisfies Message[],
{
model: "glm-4-6",
max_tokens: 50,
temperature: 0.8,
} satisfies GenerationParams,
cbk,
"blocking",
cancellationSignal,
)
const total = resp.choices.map(({text}) => text).join('')
api.v1.log(`Response: ${total}`)
const getMatch = (str: string): Elem | undefined => {
const match = matcher.exec(str)
if (match) {
const [_, emoji, name] = match
return { emoji, name }
}
const altMatch = altMatcher.exec(str)
if (altMatch) {
const [_, name, emoji] = altMatch
return { emoji, name }
}
return undefined
}
const elem: Elem | undefined = getMatch(total)
if (elem) {
const { name } = elem
const again = knownElems.has(name)
api.v1.log(`Crafted ${name} ${again ? "again" : "for the first time!"}`)
if (again) {
return { type: CraftOutcomeType.Duplicate, elem } satisfies DuplicateCraftOutcome
}
return { type: CraftOutcomeType.NewElement, elem } satisfies NewElementCraftOutcome
}
return { type: CraftOutcomeType.ParseError, message: total } satisfies ParseErrorCraftOutcome
}
const assertNever = (value: never): never => {
throw new Error(`Unhandled value: ${value}`);
}
worldStore.subscribe(async () => {
const { selectedElems, generating, elemDict } = worldStore.getState();
// Guard: only trigger when exactly 2 are selected and not already generating
if (selectedElems.size !== 2 || generating) return;
const [elemAName, elemBName] = Array.from(selectedElems);
worldStore.dispatch({ type: WorldActionType.Generating, generating: true } satisfies GeneratingAction);
try {
const elemA = elemDict[elemAName]
const elemB = elemDict[elemBName]
const outcome: CraftOutcome = await craftElements(elemA, elemB, new Set<string>(Object.keys(elemDict)))
switch (outcome.type) {
case CraftOutcomeType.Duplicate:
{
const { elem } = outcome
const precursors: Elem[] = [elemA, elemB]
worldStore.dispatch({ type: WorldActionType.SetDupeElem, elem, precursors } satisfies SetDupeElemAction);
break;
}
case CraftOutcomeType.NewElement:
{
const { elem } = outcome
const precursors: Elem[] = [elemA, elemB]
worldStore.dispatch({ type: WorldActionType.AddElem, elem, precursors } satisfies AddElemAction);
break;
}
case CraftOutcomeType.GenerateError:
{
const { message } = outcome
api.v1.error(`Failed to generate. Error was: ${message}`)
worldStore.dispatch({ type: WorldActionType.SetGenerationError, message } satisfies SetGenerationErrorAction);
}
case CraftOutcomeType.ParseError:
{
const { message } = outcome
api.v1.log(`Failed to parse craft. Response was: ${message}`)
worldStore.dispatch({ type: WorldActionType.SetCraftParseFailure, message } satisfies SetCraftParseFailureAction);
break;
}
default:
return assertNever(outcome)
}
} catch (err) {
worldStore.dispatch({ type: WorldActionType.SetGenerationError, message: JSON.stringify(err, null, 2) } satisfies SetGenerationErrorAction);
}
worldStore.dispatch({ type: WorldActionType.ClearSelections } satisfies ClearSelectionsAction);
worldStore.dispatch({ type: WorldActionType.Generating, generating: false } satisfies GeneratingAction);
});
const useWorldSelector = <T,>(selector: (s: World) => T): T =>
useSyncExternalStore<T>(
worldStore.subscribe,
() => selector(worldStore.getState())
)
const disabledButtonStyles = { cursor: 'not-allowed', pointerEvents: 'none' } as const
const selectedButtonStyles = { color: 'rgb(19, 21, 44)', backgroundColor: '#f4f3c6' } as const
const ElemComponent = ({elem: {emoji, name}}: {elem: Elem}): JSX.Element => {
const isSelected = useWorldSelector(({ selectedElems }: World) => selectedElems.has(name))
const isDisabled = useWorldSelector(({ generating }: World) => generating)
const style = useMemo(() => ({
...(isSelected && selectedButtonStyles),
...(isDisabled && disabledButtonStyles),
}), [isSelected, isDisabled])
const handleClick = useCallback(() => {
worldStore.dispatch({ type: WorldActionType.PickElem, name } satisfies PickElemAction)
}, []);
const onMouseEnter = useCallback(({ target }) => {
api.v1.log("onMouseEnter")
}, [isSelected]);
const onMouseLeave = useCallback(({ target }) => {
api.v1.log("onMouseLeave")
}, [isSelected]);
return <li>
<button
style={style} onClick={handleClick} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}
>{emoji} {name}</button>
</li>
}
const CraftPanel = (): JSX.Element => {
const elemList = useWorldSelector(({ elemList }: World) => elemList)
const elemDict = useWorldSelector(({ elemDict }: World) => elemDict)
const craftParseFailure = useWorldSelector(({ craftParseFailure }: World) => craftParseFailure)
const generationError = useWorldSelector(({ generationError }: World) => generationError)
const generating = useWorldSelector(({ generating }: World) => generating)
const dupeElem = useWorldSelector(({ dupeElem }: World) => dupeElem)
const newElem = useWorldSelector(({ newElem }: World) => newElem)
const precursors = useWorldSelector(({ precursors }: World) => precursors)
return <div>
<h1>Infinite Craft</h1>
<ul style={{ display: 'flex', listStyle: 'none', gap: '0.5em', flexWrap: 'wrap' }}>
{
elemList.map((elemName: string): JSX.Element => {
const elem: Elem = elemDict[elemName]
return <ElemComponent key={`elem-${elemName}`} elem={elem}/>
})
}
</ul>
{generating && <><div>Crafting...</div><div>&nbsp;</div></>}
{dupeElem && <div>You crafted <span>{dupeElem.emoji} {dupeElem.name}</span> again.</div>}
{newElem && <div>You just crafted <span>{newElem.emoji} {newElem.name}</span>!</div>}
{precursors && <div>From: {precursors.map(({emoji, name}: Elem, ix: number) => <><span key={`precursor-${name}`}>{emoji} {name}</span>{ix < precursors.length-1 && ', '}</>)}</div>}
{craftParseFailure && <div>Failed to parse craft output. Response was:
<pre>{craftParseFailure}</pre>
</div>}
{generationError && <div>Failed to generate. Error was:
<pre>{generationError}</pre>
</div>}
{/* stop layout jumping up and down */}
{(!generating && !dupeElem && !newElem && !craftParseFailure && !generating) && <><div>&nbsp;</div><div>&nbsp;</div></>}
</div>
}
await api.v1.ui.register([{
type: "scriptPanel",
id: "craftPanel",
name: "Craft",
iconId: "tool",
content: [{
type: "jsx",
id: "craft-jsx-root",
onMount: (elem: any) => render(<CraftPanel />, elem),
style: { height: "100%" },
} satisfies UIPartJSX],
}]);
api.v1.log("Craft panel initialized successfully!");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment