Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ pub fn build(b: *std.Build) void {
for (examples) |file| if (std.mem.endsWith(u8, file, ".luau")) scripts.append(b.allocator, file) catch @panic("out of memory");
example_scripts.addOption([]const []const u8, "scripts", scripts.items);
scripting.addOptions("example_scripts", example_scripts);
const source_parser = sourceParser(b, translate_c, lib, target, optimize);
// The parser is exported next to the library, for projects that build missions from their
// source as sltool does, such as the editor.
const source_parser = sourceParser(b, translate_c, lib, target, optimize, "source_parser");
// The definitions files, which its tests parse as luau-lsp reads them, and the guide to writing
// missions, whose missions its tests build and play.
source_parser.addAnonymousImport("openreliant.d.luau", .{ .root_source_file = b.path("docs/guide/openreliant.d.luau") });
Expand Down Expand Up @@ -183,7 +185,7 @@ pub fn build(b: *std.Build) void {
.target = b.graph.host,
.imports = &.{
.{ .name = "openreliant", .module = host_lib },
.{ .name = "source_parser", .module = sourceParser(b, translate_c, host_lib, b.graph.host, .debug) },
.{ .name = "source_parser", .module = sourceParser(b, translate_c, host_lib, b.graph.host, .debug, null) },
},
}),
});
Expand Down Expand Up @@ -359,10 +361,10 @@ fn addWindowsResources(b: *std.Build, program: *std.Build.Step.Compile, build_re

/// The module that reads mission source with Luau's own parser (`src/source_parser.zig`), for
/// `target`, on `lib`, the library built for it. It links the parser through a C++ shim, since the
/// parser has no C API.
fn sourceParser(b: *std.Build, translate_c: *std.Build.Dependency, lib: *std.Build.Module, target: std.Build.ResolvedTarget, optimize: std.lang.Optimize) *std.Build.Module {
/// parser has no C API. With a `name`, other packages can import the module by that name.
fn sourceParser(b: *std.Build, translate_c: *std.Build.Dependency, lib: *std.Build.Module, target: std.Build.ResolvedTarget, optimize: std.lang.Optimize, name: ?[]const u8) *std.Build.Module {
const luau_ast_library = b.dependency("luau", .{ .target = target, .optimize = .fast }).artifact("luau-ast");
const module = b.createModule(.{
const options: std.Build.Module.CreateOptions = .{
.root_source_file = b.path("src/source_parser.zig"),
.target = target,
.optimize = optimize,
Expand All @@ -371,7 +373,8 @@ fn sourceParser(b: *std.Build, translate_c: *std.Build.Dependency, lib: *std.Bui
.{ .name = "openreliant", .module = lib },
.{ .name = "luau_syntax", .module = translateHeader(translate_c, b.path("src/source_parser/luau.h"), luau_ast_library, target, optimize) },
},
});
};
const module = if (name) |exported| b.addModule(exported, options) else b.createModule(options);
module.linkLibrary(luau_ast_library);
module.addIncludePath(luau_ast_library.getEmittedIncludeTree());
module.addCSourceFile(.{ .file = b.path("src/source_parser/luau.cpp"), .flags = &.{ "-std=c++17", "-fno-sanitize=undefined" } });
Expand Down
5 changes: 5 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,16 @@
.hash = "rc-0.0.0-rMftL71EAAAxhe4swpM5rrfcmC9k_j7ApwJJPRssBiDL",
},
},
// The package holds what the build needs, so that other projects can use the library: the
// modules embed the guide's definitions and reference pages, and the scripting module's tests
// embed the example mods.
.paths = .{
"build.zig",
"build.zig.zon",
"src",
"deps",
"assets",
"docs/guide",
"examples/mods",
},
}
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ The [user guide](guide/README.md) covers installing, configuring and playing Ope
| [`engine/ion-cannon.md`](engine/ion-cannon.md) | The ion cannon: how the Dark Reign, the Boridin and the rogue base pick a ship, lock on, charge and fire. |
| [`engine/director.md`](engine/director.md) | The director's camera: the script's shots, the mission's curves they fly along, and the ships they hold. |
| [`engine/maneuvers.md`](engine/maneuvers.md) | Combat maneuvers: the scripts Fight runs, their language, and how it chooses them. |
| [`port/platform.md`](port/platform.md) | The platform: the `openreliant` executable on SDL3, how to build and run it on each system, the installer, and joysticks and gamepads. |
| [`port/platform.md`](port/platform.md) | The platform: the `openreliant` executable on SDL3, how to build and run it on each system, the installer, joysticks and gamepads, and using the library in another project. |
| [`port/renderer.md`](port/renderer.md) | The renderer: Surrender's pipeline and Direct3D driver as ported, improvements and what is not yet ported. |
| [`port/scripting.md`](port/scripting.md) | Scripting: mod scripts in Luau, the Luau state, the sandbox and limits, how scripts read and change the engine's values, and the records load scripts can change. |
| [`port/sound.md`](port/sound.md) | Sound: the stand-in for the Miles Sound System, and its output through SDL3. |
Expand Down
6 changes: 3 additions & 3 deletions docs/engine/editor-link.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,14 @@ needs that OpenReliant doesn't carry yet:
([#1057](https://github.com/OpenReliant/openreliant/issues/1057));
- the live scene: the objects' places, orientations and orders, which the original's editor kept
from its own copy of the mission ([#1059](https://github.com/OpenReliant/openreliant/issues/1059));
- the mission format as a library, so that it reads and writes missions as OpenReliant does
([#1060](https://github.com/OpenReliant/openreliant/issues/1060));
- the other games' script dialects, which `Hello`'s `vm` names
([#1017](https://github.com/OpenReliant/openreliant/issues/1017)).

### Writing a client

A client works the way `openreliant debug` does:
A client in Zig can read and write missions exactly as OpenReliant does by importing its library
([Using the library in another project](../port/platform.md#using-the-library-in-another-project)).
It works the way `openreliant debug` does:

1. Connect to 127.0.0.1 at the port, and read `Hello`.
2. On `Mission file`, which comes right after `Mission started`, send tag `0x09` with the script's
Expand Down
15 changes: 15 additions & 0 deletions docs/port/platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,21 @@ On Windows, both executables carry OpenReliant's icon ([The icon](#the-icon)), a

release-please opens its pull request with the workflow's own token, which needs "Allow GitHub Actions to create and approve pull requests" turned on in the repository's Actions settings. GitHub does not run workflows for pull requests opened with that token, so the release pull request never gets its checks, and an admin merges it past the branch protection.

## Using the library in another project

Another Zig project, such as [OpenReliant Editor](https://github.com/OpenReliant/openreliant-editor), can add OpenReliant to its `build.zig.zon` with `zig fetch --save` and import two of its modules:

- `openreliant`, the library: the readers and writers of the game's files, the engine and its tables;
- `source_parser`, which parses mission source and builds it into a mission file, as `sltool dte build` does ([Mission source](../formats/mission-source.md)).

```zig
const openreliant = b.dependency("openreliant", .{ .target = target, .optimize = optimize });
module.addImport("openreliant", openreliant.module("openreliant"));
module.addImport("source_parser", openreliant.module("source_parser"));
```

Besides the source, the package holds the guide's definitions and reference pages, which the modules embed, and the example mods, which the scripting module's tests embed. The project fetches every library the game builds on too, not only the ones these modules use ([#1204](https://github.com/OpenReliant/openreliant/issues/1204)).

## The icon

OpenReliant's icon is the letters OR in Newtown on the website's dark sky ([`assets/icon`](../../assets/icon/README.md)). On Windows, the executables carry it, and SDL gives the window the executable's icon. On macOS and Linux, the game gives its window the icon as PNGs at 256 and 512 pixels, which SDL decodes (`Window.setIcon`), and macOS shows it in the Dock. A Wayland compositor without the protocol for a window's icon shows its own. `make icon` makes the icon's PNG, ICO and ICNS files from its SVG.
Expand Down
Loading