@neocompose/cli 0.34.2 → 0.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/dist/neo.mjs +627 -181
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +5 -4
- package/skills/neocompose-cli/references/animation-and-world-authoring.md +16 -5
- package/skills/neocompose-cli/references/cli-development.md +1 -1
- package/skills/neocompose-cli/references/neoscript.md +44 -0
- package/skills/neocompose-cli/references/values-identities-and-references.md +3 -4
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
`@neocompose/cli` or `node cli/bin/neo.mjs` in the neo-compose repository.
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
<!-- reviewed-through-cli: 0.
|
|
12
|
+
<!-- reviewed-through-cli: 0.35.1 -->
|
|
13
13
|
|
|
14
14
|
# Neo Compose CLI
|
|
15
15
|
|
|
@@ -47,9 +47,8 @@ Treat pull followed immediately by status or dry-run as a semantic no-op. If it
|
|
|
47
47
|
reports project changes, stop and report a round-trip bug instead of pushing.
|
|
48
48
|
|
|
49
49
|
The compiler reports file:line:column diagnostics and fails closed. Unknown
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
value is exactly JSON `null` is treated as absent.
|
|
50
|
+
authorable server fields require a CLI contract update; never preserve them as
|
|
51
|
+
opaque JSON or guessed syntax.
|
|
53
52
|
|
|
54
53
|
## Honor hard authoring invariants
|
|
55
54
|
|
|
@@ -198,6 +197,8 @@ AudioClipRegistry AudioClips = new() {
|
|
|
198
197
|
Use `Images.Sword.Slice(0)` for a sprite and `AudioClips.SwordHit` for audio.
|
|
199
198
|
Renaming the registry symbol, moving the local presentation, or replacing bytes
|
|
200
199
|
retains the file ID.
|
|
200
|
+
Omitting `@settings(template: ...)` uses the complete built-in Unity import
|
|
201
|
+
defaults for that file kind.
|
|
201
202
|
|
|
202
203
|
## Resolve conflicts by identity
|
|
203
204
|
|
|
@@ -45,9 +45,17 @@ NeoVariant<ExampleObject> Down = new(
|
|
|
45
45
|
required: it is the only way to construct through the variant.
|
|
46
46
|
- `apply` takes exactly one parameter of the target class and is void. Omit it
|
|
47
47
|
for a variant that is only ever constructed.
|
|
48
|
-
- Both are ordinary delegate closures: parenthesized parameter list,
|
|
49
|
-
body
|
|
50
|
-
|
|
48
|
+
- Both are ordinary delegate closures: parenthesized parameter list, then
|
|
49
|
+
either a block body or an expression body. `initialize` returns, so
|
|
50
|
+
`() => new ExampleObject(.Down)` works; `apply` is void, so its expression
|
|
51
|
+
body must be a call or an assignment, as in
|
|
52
|
+
`(source) => source.FacingDir = .Down`. The server compiles them, so authored
|
|
53
|
+
source carries only the code. Each closure has its own lexical scope, so
|
|
54
|
+
local names may be reused between `initialize` and `apply`.
|
|
55
|
+
- `overrides` and each child override's `overrides` value are `Partial<T>`
|
|
56
|
+
deltas over existing instances. They may use inferred `new { ... }` or
|
|
57
|
+
explicit `new Partial<T> { ... }`, and never pass arguments to or invoke
|
|
58
|
+
`T`'s constructor—even when `T` has a required constructor.
|
|
51
59
|
|
|
52
60
|
Folders are records too, declared as their own globals and assigned per
|
|
53
61
|
variant. Nesting is spelled in the path with `/`; intermediate segments are
|
|
@@ -346,8 +354,11 @@ node bindings scoped to their node/children. Give each persisted condition use,
|
|
|
346
354
|
action invocation, mutation, pause, option, and node its own owner-scoped ID.
|
|
347
355
|
|
|
348
356
|
Use `=> Next` or a trailing block with `return Next;`; do not author a `to:`
|
|
349
|
-
argument.
|
|
350
|
-
|
|
357
|
+
argument. A destination arrow always follows an `=` initializer, as in
|
|
358
|
+
`= new(...) => Welcome;`; an arrow that instead follows a member name or a
|
|
359
|
+
parameter list's `)` is a NeoScript expression body, so the two never collide.
|
|
360
|
+
Require destinations for triggers, options, and outcomes. Permit terminal
|
|
361
|
+
text/actions to fall through. Keep all statements for
|
|
351
362
|
`Actions Empty = new();` inside its body.
|
|
352
363
|
|
|
353
364
|
After editing, run `neo dialogue dryrun <dialogue-ref>`. Exit 1 means the graph
|
|
@@ -83,7 +83,7 @@ wrappers.
|
|
|
83
83
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
84
84
|
|
|
85
85
|
```html
|
|
86
|
-
<!-- reviewed-through-cli: 0.
|
|
86
|
+
<!-- reviewed-through-cli: 0.35.1 -->
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -25,6 +25,41 @@ Declare a setter's value type explicitly with the canonical form
|
|
|
25
25
|
`set(int value) { ... }`. Project analysis, candidate materialization, and
|
|
26
26
|
focused script commands all use the same accessor extraction.
|
|
27
27
|
|
|
28
|
+
A body whose whole point is one expression may be written as an expression
|
|
29
|
+
body, `=> expr;`. It is pure sugar for the block form — same compiled
|
|
30
|
+
instructions, same diagnostics, same stored source — and is available on
|
|
31
|
+
getter-only properties, individual accessors, and functions:
|
|
32
|
+
|
|
33
|
+
```neo
|
|
34
|
+
public bool HasVisited => this.VisitCount > 0;
|
|
35
|
+
|
|
36
|
+
public int Clamped {
|
|
37
|
+
get => Math.Clamp(this.Raw, 0, 10);
|
|
38
|
+
set(int value) { this.Raw = value; }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public bool Unlocked(int level) => this.Level >= level;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The `=>` is only an expression body where it directly follows the member name
|
|
45
|
+
or the parameter list's `)`. An arrow after an `=` initializer is always a
|
|
46
|
+
NeoFlow destination, so `override Trigger Trigger = new(...) => Welcome;`
|
|
47
|
+
keeps its meaning.
|
|
48
|
+
|
|
49
|
+
In a void context — a `void` function, a setter, or a void delegate — `=> expr`
|
|
50
|
+
is an expression statement rather than a return, so the expression must do
|
|
51
|
+
something: a call such as `void Ping() => this.OnChanged();`, or an assignment
|
|
52
|
+
such as `set(int value) => this.Raw = value;`. An expression whose value would
|
|
53
|
+
simply be discarded is rejected with a diagnostic that names the block body as
|
|
54
|
+
the fix.
|
|
55
|
+
|
|
56
|
+
`neo push` and `neo pull` canonicalize a stored body to the shorthand when its
|
|
57
|
+
authored spelling is exactly one `return` statement that fits on one line;
|
|
58
|
+
anything else re-emits as a block. Setters always re-emit as blocks. A push
|
|
59
|
+
preserves the form you authored for members it did not otherwise rewrite, so
|
|
60
|
+
choosing longhand for a one-line getter is stable; a fresh `neo pull` writes
|
|
61
|
+
the canonical shorthand.
|
|
62
|
+
|
|
28
63
|
Declare a bodyless NeoScript contract with `abstract`, for example
|
|
29
64
|
`public abstract bool Equals(Item other);`. Reserve `native` for host-provided
|
|
30
65
|
functions; concrete NeoScript overrides inherit the abstract signature.
|
|
@@ -55,6 +90,15 @@ so later changes to the outer binding do not alter the closure. Explicit lambda
|
|
|
55
90
|
parameter annotations accept the same type grammar as declarations, including
|
|
56
91
|
`decimal`, generic parameters, collections, arrays, and nullable types.
|
|
57
92
|
|
|
93
|
+
A lambda may use an expression body too: `(x) => x * 2` is the block body
|
|
94
|
+
`(x) => { return x * 2; }`. In a void delegate the expression is a statement,
|
|
95
|
+
so it must call or assign. A dictionary-literal body needs parentheses,
|
|
96
|
+
`() => ({ "a": 1 })`, because a bare `{` after the arrow always opens a block.
|
|
97
|
+
|
|
98
|
+
```neo
|
|
99
|
+
List<Item> ready = this.Items.Where((item) => item.Count > 0);
|
|
100
|
+
```
|
|
101
|
+
|
|
58
102
|
Calling `Equals(other)` on a non-null generic value dynamically uses the
|
|
59
103
|
runtime Class's one-argument `Equals` Function or NSFunction when it returns
|
|
60
104
|
`bool`, including the effective override. Values without that member fall back
|
|
@@ -39,9 +39,7 @@ class Assets {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
@id("home-getter-id")
|
|
42
|
-
static Outpost Home
|
|
43
|
-
get { return Assets.Capitol; }
|
|
44
|
-
}
|
|
42
|
+
static Outpost Home => Assets.Capitol;
|
|
45
43
|
}
|
|
46
44
|
```
|
|
47
45
|
|
|
@@ -172,7 +170,8 @@ diff, and dry-run do not rewrite its registry. A successful push creates the
|
|
|
172
170
|
record, uploads verified bytes, and materializes its declaration and ID.
|
|
173
171
|
|
|
174
172
|
Edit the typed registry declaration directly when an explicit symbol or
|
|
175
|
-
non-default template is needed before push.
|
|
173
|
+
non-default template is needed before push. With no template annotation, the
|
|
174
|
+
CLI persists the complete built-in Unity defaults for the file kind.
|
|
176
175
|
|
|
177
176
|
Pull/push compare server-verified SHA-256, not storage ETags. A divergent
|
|
178
177
|
binary keeps local bytes and writes the verified remote side under
|