dotframe 0.1.7 → 0.1.8
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
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.8
|
|
4
|
+
|
|
5
|
+
From dogfood round 7 (Craft Ones on 0.1.7).
|
|
6
|
+
|
|
7
|
+
- `doctor` sim:math skips files marked `// dotframe-allow-math-file`, for render-only files the sim reaches because it builds the renderer.
|
|
8
|
+
- `deploy init` pins images: bun from `packageManager` (game or repo root, else the local bun) and the relay's dotframe from the version installed in the game.
|
|
9
|
+
- The vendor fix (doctor and native builds) names `DOTFRAME_VENDOR` for reusing an existing vendor dir.
|
|
10
|
+
|
|
3
11
|
## 0.1.7
|
|
4
12
|
|
|
5
13
|
From dogfood rounds 5 and 6 (Craft Ones on iOS, online, and on the VPS).
|
package/cli/commands/docker.ts
CHANGED
|
@@ -14,14 +14,38 @@ async function gitRoot(ctx: Ctx, root: string): Promise<string> {
|
|
|
14
14
|
return r.output.trim();
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
interface Versions {
|
|
18
|
+
bun: string;
|
|
19
|
+
dotframe: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Pinned versions, so an image built tomorrow is the image built today: bun from packageManager (the game's
|
|
23
|
+
// package.json, then the repo root's), else the bun running this CLI; dotframe as installed in the game.
|
|
24
|
+
function versions(gameRoot: string, repo: string): Versions {
|
|
25
|
+
let bun = Bun.version;
|
|
26
|
+
for (const dir of [gameRoot, repo]) {
|
|
27
|
+
const file = join(dir, "package.json");
|
|
28
|
+
if (!existsSync(file)) continue;
|
|
29
|
+
const manager = (JSON.parse(readFileSync(file, "utf8")) as { packageManager?: string }).packageManager ?? "";
|
|
30
|
+
const match = manager.match(/^bun@(\d+\.\d+\.\d+)/);
|
|
31
|
+
if (match) {
|
|
32
|
+
bun = match[1];
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const installed = join(gameRoot, "node_modules", "dotframe", "package.json");
|
|
37
|
+
const dotframe = existsSync(installed) ? (JSON.parse(readFileSync(installed, "utf8")) as { version: string }).version : pkg.version;
|
|
38
|
+
return { bun, dotframe };
|
|
39
|
+
}
|
|
40
|
+
|
|
17
41
|
// game: the game's path inside the repo ("" at the root); context: the repo root, relative to deploy/.
|
|
18
|
-
function files(config: Config, game: string, out: string, context: string): Record<string, string> {
|
|
42
|
+
function files(config: Config, game: string, out: string, context: string, v: Versions): Record<string, string> {
|
|
19
43
|
const requires = (config.requires ?? []).filter((t: string): boolean => t !== "bun");
|
|
20
44
|
const apt = requires.length > 0 ? `RUN apt-get update && apt-get install -y --no-install-recommends ${requires.join(" ")} && rm -rf /var/lib/apt/lists/*\n` : "";
|
|
21
45
|
const at = game === "" ? "." : game;
|
|
22
46
|
return {
|
|
23
47
|
"Dockerfile.web": `# Static web build of ${config.name}, served by nginx. Generated by dotframe deploy init; edit freely.
|
|
24
|
-
FROM oven/bun
|
|
48
|
+
FROM oven/bun:${v.bun} AS build
|
|
25
49
|
${apt}WORKDIR /app
|
|
26
50
|
COPY . .
|
|
27
51
|
RUN cd ${at} && bun install --frozen-lockfile && bun node_modules/dotframe/cli/main.ts build web
|
|
@@ -32,9 +56,10 @@ COPY --from=build ${join("/app", at, out)} /usr/share/nginx/html
|
|
|
32
56
|
EXPOSE 80
|
|
33
57
|
`,
|
|
34
58
|
"Dockerfile.relay": `# Netplay relay for ${config.name}: dotframe relay serve. Generated by dotframe deploy init.
|
|
35
|
-
FROM oven/bun
|
|
59
|
+
FROM oven/bun:${v.bun}-alpine
|
|
36
60
|
WORKDIR /app
|
|
37
|
-
|
|
61
|
+
# The dotframe version the game has installed; bump it together with the game's.
|
|
62
|
+
RUN bun add dotframe@${v.dotframe}
|
|
38
63
|
ENV PORT=8787
|
|
39
64
|
EXPOSE 8787
|
|
40
65
|
CMD ["bun", "node_modules/dotframe/cli/main.ts", "relay", "serve"]
|
|
@@ -86,7 +111,7 @@ export async function deployInit(ctx: Ctx, name: string | undefined, provider: s
|
|
|
86
111
|
const repo = await gitRoot(ctx, config.root);
|
|
87
112
|
const game = relative(repo, config.root);
|
|
88
113
|
// compose.yaml sits in <game>/deploy; the web build context is the repo root, so workspace code is visible.
|
|
89
|
-
const generated = files(config, game, t.out, relative(join(config.root, DIR), repo) || ".");
|
|
114
|
+
const generated = files(config, game, t.out, relative(join(config.root, DIR), repo) || ".", versions(config.root, repo));
|
|
90
115
|
const dir = join(config.root, DIR);
|
|
91
116
|
const written = Object.keys(generated).map((f: string): string => join(DIR, f));
|
|
92
117
|
const existing = written.filter((f: string): boolean => existsSync(join(config.root, f)));
|
package/cli/commands/doctor.ts
CHANGED
|
@@ -147,8 +147,9 @@ async function renderCheck(sim: Sim, root: string): Promise<Check> {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
// Math.sin and friends differ in the last bits between engines and OSes, so simulation code that calls them drifts
|
|
150
|
-
// between netplay peers and breaks replays on another machine. Render code may use them
|
|
151
|
-
// `dotframe-allow-math
|
|
150
|
+
// between netplay peers and breaks replays on another machine. Render code may use them: mark a line with
|
|
151
|
+
// `dotframe-allow-math`, or a whole render-only file with `// dotframe-allow-math-file`. (The sim module builds the
|
|
152
|
+
// renderer for desync's purity check, so render files are reachable and a static scan cannot tell them apart.)
|
|
152
153
|
const NONDETERMINISTIC = /\bMath\.(sin|cos|tan|asin|acos|atan|atan2|sinh|cosh|tanh|asinh|acosh|atanh|exp|expm1|log|log1p|log2|log10|pow|cbrt|hypot)\b|[\w)\]]\s*\*\*\s*[\w(]/;
|
|
153
154
|
|
|
154
155
|
// The engine's own files (draw2d's arcs, raster2d) are render code, however the game imports them: a vendored
|
|
@@ -173,7 +174,9 @@ function mathCheck(simFile: string): Check {
|
|
|
173
174
|
const engine = new Map<string, boolean>();
|
|
174
175
|
for (const file of importGraph(simFile).files) {
|
|
175
176
|
if (!/\.tsx?$/.test(file) || file.includes(`${sep}node_modules${sep}`) || engineFile(file, engine)) continue;
|
|
176
|
-
readFileSync(file, "utf8")
|
|
177
|
+
const text = readFileSync(file, "utf8");
|
|
178
|
+
if (text.includes("dotframe-allow-math-file")) continue;
|
|
179
|
+
text
|
|
177
180
|
.split("\n")
|
|
178
181
|
.forEach((line: string, i: number): void => {
|
|
179
182
|
const code = line.replace(/\/\/.*$/, "");
|
|
@@ -187,6 +190,6 @@ function mathCheck(simFile: string): Check {
|
|
|
187
190
|
ok: false,
|
|
188
191
|
warn: true,
|
|
189
192
|
detail: `${hits.length} platform-dependent math call(s) in code the sim reaches: ${shown}`,
|
|
190
|
-
fix: "use dotframe/src/detmath (dsin, dcos, datan2, dexp, dpow, ...) in simulation code; mark render-only lines with // dotframe-allow-math",
|
|
193
|
+
fix: "use dotframe/src/detmath (dsin, dcos, datan2, dexp, dpow, ...) in simulation code; mark render-only lines with // dotframe-allow-math, or a render-only file with // dotframe-allow-math-file",
|
|
191
194
|
};
|
|
192
195
|
}
|
package/cli/native.ts
CHANGED
|
@@ -46,7 +46,7 @@ export function sdlLibrary(platform: NativePlatform): string {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export function vendorFix(platform: NativePlatform): string {
|
|
49
|
-
return `dotframe vendor ${platform}
|
|
49
|
+
return `dotframe vendor ${platform} (builds into ~/.dotframe/vendor), or point DOTFRAME_VENDOR at an existing vendor dir such as a dotframe checkout's vendor/`;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
const SPECIFIER = /(?:from\s+|import\s*\(\s*|import\s+)(["'])([^"']+)\1/g;
|
package/package.json
CHANGED
|
@@ -29,6 +29,7 @@ dotframe config set targets.web.deploy.compose '"<compose id>"' # vps compose
|
|
|
29
29
|
dotframe deploy web --dry-run && dotframe deploy web --yes
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
- Images are pinned: bun from `packageManager` (game or repo root, else the local bun) and the relay's dotframe from the version installed in the game. Rerun `deploy init --yes` after bumping either.
|
|
32
33
|
- The web image installs the tools in `requires` (dotframe.json, for example `["ffmpeg"]`) and builds with dotframe; the relay image runs `dotframe relay serve`. The build context is the repo root, so monorepo ports see workspace code.
|
|
33
34
|
- In Dokploy, route the domain's `/` to service `web` (port 80) and `/relay` to service `relay` (port 8787). For Discord, map `/` and `/relay` to that host.
|
|
34
35
|
- Dokploy builds the pushed branch, not your working tree: deploy warns about unpushed or uncommitted work. On failure it returns the build log (through `vps compose logs`).
|
package/skill-data/ios/SKILL.md
CHANGED
|
@@ -6,6 +6,7 @@ description: Build and install the iOS target of a dotframe game. Use when build
|
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
dotframe vendor ios # once per machine: SDL3 (Xcode generator) and wgpu-native for iOS
|
|
9
|
+
# or reuse an existing vendor (a dotframe checkout's vendor/): export DOTFRAME_VENDOR=<path>
|
|
9
10
|
dotframe doctor # vendor:ios, ios-runtime (scriptc pack matching the compiler), team placeholder
|
|
10
11
|
dotframe build ios --json # dist/ios/<Scheme>.app
|
|
11
12
|
dotframe device install ios --dry-run
|
|
@@ -43,7 +43,7 @@ Run several seeds and a high latency (474 ms is what a transatlantic relay measu
|
|
|
43
43
|
|
|
44
44
|
## Rules
|
|
45
45
|
|
|
46
|
-
- Simulation code uses `dotframe/src/detmath` (dsin, dcos, datan2, dexp, dlog, dpow, ...), never `Math.sin` and friends or `**`: those differ in the last bits between engines and operating systems, so peers and replays drift (Craft Ones' replays diverged between macOS and Linux at frame 120). `dotframe doctor` warns about them (`sim:math`); mark render-only lines with `// dotframe-allow-math
|
|
46
|
+
- Simulation code uses `dotframe/src/detmath` (dsin, dcos, datan2, dexp, dlog, dpow, ...), never `Math.sin` and friends or `**`: those differ in the last bits between engines and operating systems, so peers and replays drift (Craft Ones' replays diverged between macOS and Linux at frame 120). `dotframe doctor` warns about them (`sim:math`); mark render-only lines with `// dotframe-allow-math`, or a whole render-only file with `// dotframe-allow-math-file` (the sim builds the renderer for desync, so render files count as reachable). A replay passing on one machine proves nothing about another: run CI on a second OS.
|
|
47
47
|
- `desync` reports `restoreMs` early vs late; it warns when late restores cost more than twice the early ones (a heuristic for restore that replays from an earlier frame, which passes desync but stalls real rollbacks late in a match).
|
|
48
48
|
- Build checksums from numbers in a fixed order, never from `JSON.stringify`: native builds can order keys differently from JavaScript, so a web peer and a native peer would report false desyncs.
|
|
49
49
|
|