@textscene/tscn 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +32 -2
- package/THIRD-PARTY-NOTICES.md +53 -0
- package/dist/index.d.ts +241 -0
- package/dist/index.js +12123 -0
- package/package.json +59 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vortiago
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @textscene/tscn
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@textscene/tscn` parses Godot `.tscn` scenes. It is the parser of the
|
|
4
|
+
[TextScene Inspector](https://github.com/Vortiago/textscene-inspector), bundled into one ES module
|
|
5
|
+
with no dependency, no peer dependency, no React and no three.js. It runs in Node and in a browser.
|
|
6
|
+
|
|
7
|
+
The parser reads the current `.tscn` format (`format=3`). The repository's
|
|
8
|
+
[glossary](https://github.com/Vortiago/textscene-inspector/blob/main/GLOSSARY.md) defines the format's terms,
|
|
9
|
+
and [REFERENCES.md](https://github.com/Vortiago/textscene-inspector/blob/main/REFERENCES.md) links Godot's
|
|
10
|
+
format documentation.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @textscene/tscn
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Use
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { TscnParser } from '@textscene/tscn';
|
|
22
|
+
|
|
23
|
+
const scene = new TscnParser().parse(source);
|
|
24
|
+
console.log(scene.nodes[0]?.name);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The package exports `TscnParser` and the types of the scene it returns: `TscnScene`, `TscnNode`,
|
|
28
|
+
`RawNode`, `TscnExternalResource`, `TscnInternalResource` and `TscnMainResource`.
|
|
29
|
+
|
|
30
|
+
## Licence
|
|
31
|
+
|
|
32
|
+
MIT. The package ships `LICENSE` and `THIRD-PARTY-NOTICES.md`. The build writes the notices from the
|
|
33
|
+
modules it bundles: the Godot Engine MIT notice covers the Godot code in the parser.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
TextScene Inspector is MIT licensed (see `LICENSE`). It additionally contains, and
|
|
4
|
+
distributes, material from the third parties below.
|
|
5
|
+
|
|
6
|
+
Runtime npm dependencies are not enumerated here; each carries its own licence in its
|
|
7
|
+
published package. FastNoiseLite and the Brotli decoder are the exceptions, since their
|
|
8
|
+
packages keep the licence in a source comment that a bundler strips.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Godot Engine
|
|
13
|
+
|
|
14
|
+
<https://github.com/godotengine/godot>
|
|
15
|
+
|
|
16
|
+
TextScene Inspector reproduces Godot's rendering behaviour, and doing that faithfully means
|
|
17
|
+
transcribing engine code rather than approximating it. The files listed below are ports of
|
|
18
|
+
Godot Engine source, used under the MIT licence. Each carries the same notice inline.
|
|
19
|
+
|
|
20
|
+
### Bundled source
|
|
21
|
+
|
|
22
|
+
- `packages/textscene-core/src/godot/math/alignment.ts`
|
|
23
|
+
- `packages/textscene-core/src/godot/math/color.ts`
|
|
24
|
+
- `packages/textscene-core/src/godot/math/transform2d.ts`
|
|
25
|
+
- `packages/textscene-core/src/nodes/2d/ui/graphelement/parser.ts`
|
|
26
|
+
- `packages/textscene-core/src/nodes/2d/ui/graphnode/parser.ts`
|
|
27
|
+
- `packages/textscene-core/src/nodes/2d/ui/graphedit/connections.ts`
|
|
28
|
+
- `packages/textscene-core/src/nodes/2d/ui/graphedit/loadOrder.ts`
|
|
29
|
+
|
|
30
|
+
### Licence
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md).
|
|
34
|
+
Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.
|
|
35
|
+
|
|
36
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
37
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
38
|
+
in the Software without restriction, including without limitation the rights
|
|
39
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
40
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
41
|
+
furnished to do so, subject to the following conditions:
|
|
42
|
+
|
|
43
|
+
The above copyright notice and this permission notice shall be included in all
|
|
44
|
+
copies or substantial portions of the Software.
|
|
45
|
+
|
|
46
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
47
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
48
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
49
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
50
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
51
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
52
|
+
SOFTWARE.
|
|
53
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
interface Vector3 {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
z: number;
|
|
5
|
+
}
|
|
6
|
+
interface Transform3D {
|
|
7
|
+
basis_x: Vector3;
|
|
8
|
+
basis_y: Vector3;
|
|
9
|
+
basis_z: Vector3;
|
|
10
|
+
origin: Vector3;
|
|
11
|
+
}
|
|
12
|
+
interface Node3DProperties {
|
|
13
|
+
/** Node name */
|
|
14
|
+
name: string;
|
|
15
|
+
/** Parent node path ("." for root, "NodeName" for named parent) */
|
|
16
|
+
parent?: string;
|
|
17
|
+
/** Full transform matrix */
|
|
18
|
+
transform?: Transform3D;
|
|
19
|
+
/** Whether this is an instanced scene */
|
|
20
|
+
instance?: string;
|
|
21
|
+
/** Child index for editable instance overrides (for example parent="." index="0") */
|
|
22
|
+
index?: number;
|
|
23
|
+
/** Whether the node and its subtree are rendered. Defaults to true. */
|
|
24
|
+
visible?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the global transform skips the parent: `global = local` (`node_3d.cpp:656-660`).
|
|
27
|
+
* Visibility still climbs the parent (`:1132-1143`). Unset when the file omits it.
|
|
28
|
+
*/
|
|
29
|
+
top_level?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The `visibility_parent` path text, relative to this node. Unset when the file omits it or
|
|
32
|
+
* leaves it empty, where the node takes its Node3D parent's visibility parent.
|
|
33
|
+
*/
|
|
34
|
+
visibility_parent?: string;
|
|
35
|
+
}
|
|
36
|
+
type OwnerHandOff = symbol;
|
|
37
|
+
type InstanceOwnerFallback = Required<Pick<InstanceNameSetting, "ownerInInstance">> & Pick<InstanceNameSetting, "ownerContentTrail">;
|
|
38
|
+
interface InstanceNameSetting {
|
|
39
|
+
/**
|
|
40
|
+
* The node's path below the instance, ending in its name. A node outside the instance that an
|
|
41
|
+
* explicit `owner=` gives to it climbs out with `..`.
|
|
42
|
+
*/
|
|
43
|
+
readonly pathInInstance: string;
|
|
44
|
+
readonly isUnique: boolean;
|
|
45
|
+
/** An explicit `owner=` below the instance, `''` for the instance itself. Absent: the nearest owner. */
|
|
46
|
+
readonly ownerInInstance?: string;
|
|
47
|
+
/**
|
|
48
|
+
* The ids of an `owner_uid_path=` that continue inside the node `ownerInInstance` names, which the
|
|
49
|
+
* graft follows to the owner (`RawNode.ownerContentTrail`).
|
|
50
|
+
*/
|
|
51
|
+
readonly ownerContentTrail?: readonly number[];
|
|
52
|
+
/**
|
|
53
|
+
* The owner to take where the `ownerInInstance` walk finds nothing, from the heading's
|
|
54
|
+
* `owner_uid_path=`, in this instance. Absent where the trail names an owner in no instance.
|
|
55
|
+
*/
|
|
56
|
+
readonly ownerFallback?: InstanceOwnerFallback;
|
|
57
|
+
/**
|
|
58
|
+
* Set where the `owner_uid_path=` owner sits in another instance: where the `ownerInInstance` walk
|
|
59
|
+
* finds nothing, the graft hands this back, and the copy of the setting that awaits it lands there.
|
|
60
|
+
*/
|
|
61
|
+
readonly ownerHandOff?: OwnerHandOff;
|
|
62
|
+
/** Set on that copy: it lands only once the instance its `owner=` walk enters hands this off. */
|
|
63
|
+
readonly awaits?: OwnerHandOff;
|
|
64
|
+
/**
|
|
65
|
+
* How many of the instance node's children the file seats before the setting lands, its own
|
|
66
|
+
* heading included: a host child's `%Name` parent reads the table as of its heading.
|
|
67
|
+
*/
|
|
68
|
+
readonly hostChildrenBefore: number;
|
|
69
|
+
}
|
|
70
|
+
/** A parsed scene. `N` is the node the parser built: a `TscnNode`, or the strict parser's `RawNode`. */
|
|
71
|
+
export interface TscnScene<N extends RawNode = TscnNode> {
|
|
72
|
+
/** Root nodes in the scene tree. */
|
|
73
|
+
nodes: N[];
|
|
74
|
+
readonly externalResources: readonly TscnExternalResource[];
|
|
75
|
+
readonly internalResources: readonly TscnInternalResource[];
|
|
76
|
+
/**
|
|
77
|
+
* Whether Godot gives up on the scene before it re-roots anything, so the builder re-roots no
|
|
78
|
+
* orphan, and refuses every scene that instances it. True when the scene has no node, the root
|
|
79
|
+
* heading has a `parent=` or states no identifier, a heading spells `parent=""`, or a later
|
|
80
|
+
* heading has no `parent=`.
|
|
81
|
+
*/
|
|
82
|
+
refusesToInstantiate: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* A `.tres` file's `[gd_resource type=]`, the class the loader builds its `[resource]` body as
|
|
85
|
+
* (`resource_format_text.cpp:1166`, `:741`). Absent in a `.tscn`, and where the header names no type.
|
|
86
|
+
*/
|
|
87
|
+
resourceType?: string;
|
|
88
|
+
/**
|
|
89
|
+
* The simplified `path=` of each `[editable]` heading, in file order: the instance nodes whose
|
|
90
|
+
* content the editor lets the user edit (`resource_format_text.cpp:400`). Absent where none.
|
|
91
|
+
*/
|
|
92
|
+
editableInstances?: readonly string[];
|
|
93
|
+
/**
|
|
94
|
+
* A `.tres` file's own `[resource]` body. Absent in a `.tscn`, where the loader refuses the tag
|
|
95
|
+
* (`resource_format_text.cpp:723-728`).
|
|
96
|
+
*/
|
|
97
|
+
mainResource?: TscnMainResource;
|
|
98
|
+
}
|
|
99
|
+
interface OwnerRecovery {
|
|
100
|
+
readonly owner: string;
|
|
101
|
+
readonly ownerContentTrail?: readonly number[];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The **Raw view** of a node: `rawProperties`, the literals both parsers publish, and no
|
|
105
|
+
* typed `properties`. The strict parser builds this. A `TscnNode` is a `RawNode`, so a helper
|
|
106
|
+
* typed on it takes either tree.
|
|
107
|
+
*/
|
|
108
|
+
export interface RawNode {
|
|
109
|
+
name: string;
|
|
110
|
+
/** Godot class name, for example "Node3D". */
|
|
111
|
+
type: string;
|
|
112
|
+
/** Parent node path: "." for the root's children, "NodeName" for a named parent. */
|
|
113
|
+
parent?: string;
|
|
114
|
+
children: RawNode[];
|
|
115
|
+
/**
|
|
116
|
+
* Raw body properties as written, published by both parsers
|
|
117
|
+
* (`parser/rawPropertyParity.test.ts`), so read this from code the linter and the
|
|
118
|
+
* render path share. It also lets a type-less instance node's overrides be re-parsed
|
|
119
|
+
* against the instanced root's type.
|
|
120
|
+
*/
|
|
121
|
+
rawProperties: Record<string, string>;
|
|
122
|
+
/**
|
|
123
|
+
* Whether `rawProperties`' key order is one file's scan order (ADR-0035).
|
|
124
|
+
* `core/NodeRegistry.ts`'s `parseNodeWithRegistry` sets `true`.
|
|
125
|
+
* `resources/layerRawOverride.ts` sets `false`: a shared key keeps the base's
|
|
126
|
+
* position but the override's value.
|
|
127
|
+
*/
|
|
128
|
+
rawPropertiesOrderReliable?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Set when the authored `parent` path descends into instanced content (a `.tscn` or
|
|
131
|
+
* `.glb`) this file does not declare: the path below the nearest enclosing instance,
|
|
132
|
+
* which holds the node in the tree. Never the empty string. `parent` keeps the
|
|
133
|
+
* authored path, so the linter and `mergeInstanceRoot` still read what the file said.
|
|
134
|
+
*/
|
|
135
|
+
instanceSubPath?: string;
|
|
136
|
+
/**
|
|
137
|
+
* The name the heading wrote, set only on a tree node the builder re-rooted: its `name`
|
|
138
|
+
* is then Godot's rename for the vanished `parent` (`packed_scene.cpp:561-563`).
|
|
139
|
+
*/
|
|
140
|
+
authoredName?: string;
|
|
141
|
+
/**
|
|
142
|
+
* True on a tree node the builder seated under the heading its `parent_id_path=` landed on,
|
|
143
|
+
* because its `parent` path vanished (`packed_scene.cpp:161-163`). The node keeps its name.
|
|
144
|
+
*/
|
|
145
|
+
landedByIdTrail?: true;
|
|
146
|
+
/**
|
|
147
|
+
* On a node seated below the instance heading its `parent_id_path=` enters: the ids that continue in
|
|
148
|
+
* that instance's scene. Its graft follows them and places the node (`packed_scene.cpp:1947-2005`).
|
|
149
|
+
*/
|
|
150
|
+
parentContentTrail?: readonly number[];
|
|
151
|
+
/**
|
|
152
|
+
* On a node seated below an instance for a `parent=` path into its content, whose `parent_id_path=`
|
|
153
|
+
* names a heading of this file: where Godot seats the node should the content lack the path.
|
|
154
|
+
* `contentTrail` holds the ids that continue inside that heading, where it is an instance.
|
|
155
|
+
*/
|
|
156
|
+
parentTrailFallback?: {
|
|
157
|
+
readonly path: string;
|
|
158
|
+
readonly contentTrail?: readonly number[];
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* On a node whose `owner_uid_path=` enters an instance: the ids that continue in the scene the node
|
|
162
|
+
* at `owner` holds. Where it is set, `owner` names the instance heading, not the owner itself.
|
|
163
|
+
*/
|
|
164
|
+
ownerContentTrail?: readonly number[];
|
|
165
|
+
/**
|
|
166
|
+
* On a node whose `owner=` walk enters an instance's content, where it may find nothing, and whose
|
|
167
|
+
* `owner_uid_path=` names an owner: the owner Godot takes then (`packed_scene.cpp:159-163`).
|
|
168
|
+
*/
|
|
169
|
+
ownerTrailFallback?: OwnerRecovery;
|
|
170
|
+
/**
|
|
171
|
+
* True when the heading declared none of `type=`, `instance=` and
|
|
172
|
+
* `instance_placeholder=`: Godot's marker for overriding the node already at this
|
|
173
|
+
* path. See `isPropertyOverrideHeading`.
|
|
174
|
+
*/
|
|
175
|
+
overridesExistingNode?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* The heading's `index=`: where Godot moves the node among its parent's children once it adds
|
|
178
|
+
* it (`packed_scene.cpp:543-544`). Godot writes it only for a node whose parent comes from an
|
|
179
|
+
* instanced scene (`packed_scene.cpp:820-830`). Unset when the heading has none.
|
|
180
|
+
*/
|
|
181
|
+
index?: number;
|
|
182
|
+
/**
|
|
183
|
+
* The heading's `owner=` NodePath, root-relative. The loader sets the owner from it
|
|
184
|
+
* (resource_format_text.cpp:257-262), which decides the table a `%Name` registers on. Godot's own
|
|
185
|
+
* writer never emits it (packed_scene.cpp:1036-1044). A seated node holds it walked from the root
|
|
186
|
+
* (`resolvedOwner`): `.` for the root, and each `%Name` the file answers replaced by its claimant.
|
|
187
|
+
*/
|
|
188
|
+
owner?: string;
|
|
189
|
+
/** External scene instance reference, for example ExtResource("1_abc"). */
|
|
190
|
+
instance?: string;
|
|
191
|
+
/**
|
|
192
|
+
* Set by the seating on an instance node below the root, and on an inherited root: the
|
|
193
|
+
* `unique_name_in_owner` settings this file writes inside its content, in file order. The graft
|
|
194
|
+
* reads them, and a graft into an outer instance appends the ones it hands down.
|
|
195
|
+
*/
|
|
196
|
+
instanceNameSettings?: readonly InstanceNameSetting[];
|
|
197
|
+
}
|
|
198
|
+
/** A node from the lenient parser: the **Raw view** plus the typed values the renderer reads. */
|
|
199
|
+
export interface TscnNode extends RawNode {
|
|
200
|
+
children: TscnNode[];
|
|
201
|
+
/** Type-specific properties, for example Node3DProperties for a Node3D. */
|
|
202
|
+
properties: Node3DProperties | Record<string, unknown>;
|
|
203
|
+
}
|
|
204
|
+
export interface TscnExternalResource {
|
|
205
|
+
id: string;
|
|
206
|
+
path: string;
|
|
207
|
+
type: string;
|
|
208
|
+
/** The id its own file wrote, on a copy that override re-homing made. The parser never sets it. */
|
|
209
|
+
authoredId?: string;
|
|
210
|
+
}
|
|
211
|
+
export interface TscnInternalResource {
|
|
212
|
+
id: string;
|
|
213
|
+
type: string;
|
|
214
|
+
data: Record<string, string>;
|
|
215
|
+
/** The id its own file wrote, on a copy that override re-homing made. The parser never sets it. */
|
|
216
|
+
authoredId?: string;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* A `.tres` file's `[resource]` body. It has no id and no `type=`: its class is the header's,
|
|
220
|
+
* {@link TscnScene.resourceType}. `data` holds the raw values, keyed as the scan stores them.
|
|
221
|
+
*/
|
|
222
|
+
export interface TscnMainResource {
|
|
223
|
+
data: Record<string, string>;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Lenient TSCN parser used for rendering.
|
|
227
|
+
*
|
|
228
|
+
* Strategy: recover from minor errors, log warnings, and keep rendering
|
|
229
|
+
* whatever it can. For strict validation use `linter/StrictTscnParser`.
|
|
230
|
+
*/
|
|
231
|
+
export declare class TscnParser {
|
|
232
|
+
private core;
|
|
233
|
+
/**
|
|
234
|
+
* Parse TSCN content. Returns a scene with nodes whose `.properties`
|
|
235
|
+
* have been converted from raw snake_case strings to the strongly-typed
|
|
236
|
+
* shape declared by the relevant node-type module.
|
|
237
|
+
*/
|
|
238
|
+
parse(content: string): TscnScene;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export {};
|