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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Support
url: https://github.com/ViTeXFTW/ZeroSyntaxV2/blob/main/SUPPORT.md
url: https://github.com/ViTeXFTW/ZeroSyntaxV2/blob/dev/SUPPORT.md
about: Read where to ask support questions before opening an issue.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ editors/vscode/out
editors/vscode/out-test
editors/vscode/*.vsix
editors/vscode/server
editors/vscode/icon/

# Reference game source (large, external)
/GeneralsCode
Expand Down
10 changes: 5 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,14 @@ take `absent = true` to pin that a diagnostic is *not* emitted.
### Editor client

`editors/vscode/` is a thin reference LSP client (claims the `generals-ini`
language id). The server speaks stdio LSP, so Neovim/Helix/Zed configs are in
the README. `GeneralsCode/` is the engine source the schema is modeled on (a
reference for hand-authoring `schema.json`) — it is not part of any crate.
language id). The server speaks stdio LSP; client setup is documented in
`docs/language-server.md`. `GeneralsCode/` is the engine source the schema is
modeled on (a reference for hand-authoring `schema.json`) — it is not part of
any crate.

## Conventions

- License is **GPL-3.0-or-later** (matches the engine source the schema
derives from); keep crate headers consistent.
- License is **MIT**.
- `schema.json` is hand-written — edit the JSON directly, modeling new entries
on the engine's `FieldParse` tables in `GeneralsCode/`. Keep `value_type`s
faithful and fall back to `Unknown { parse_fn }` when a type is unclear.
Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ cargo clippy --locked --all-targets --all-features -- -D warnings

cd editors/vscode
npm ci
npm run compile
npm test
```

The optional real-game corpus is not committed. Fetch it only when you need the
Expand Down Expand Up @@ -43,4 +43,5 @@ describe the workflow the feature should improve.

## Releases

Maintainers release from tags. See [docs/release.md](docs/release.md).
Maintainers release from the `dev` and `prod` branches. See the
[release process](docs/release.md).
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resolver = "2"
members = ["crates/schema", "crates/syntax", "crates/analysis", "crates/server"]

[workspace.package]
version = "1.0.5"
version = "1.1.0"
edition = "2021"
license = "MIT"
repository = "https://github.com/ViTeXFTW/ZeroSyntaxV2"
Expand Down
234 changes: 59 additions & 175 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,204 +1,88 @@
# ZeroSyntax v2

<p align="center">
<img src="icon/ZeroSyntaxLogo256.png" alt="ZeroSyntax logo">
</p>

[![CI](https://github.com/ViTeXFTW/ZeroSyntaxV2/actions/workflows/ci.yml/badge.svg)](https://github.com/ViTeXFTW/ZeroSyntaxV2/actions/workflows/ci.yml)
[![Release](https://github.com/ViTeXFTW/ZeroSyntaxV2/actions/workflows/release.yml/badge.svg)](https://github.com/ViTeXFTW/ZeroSyntaxV2/actions/workflows/release.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

ZeroSyntax v2 is a language server and VS Code extension for the INI files used by
*Command & Conquer: Generals - Zero Hour*. It gives modders and map authors
editor support for the game's object, weapon, upgrade, FX, audio, module, and
map override definitions.
ZeroSyntax v2 brings modern editor support to the INI scripting files used by
*Command & Conquer: Generals – Zero Hour*. It helps modders and map authors find
mistakes early and navigate large game or mod workspaces.

The project includes the IDE-independent `zerosyntax-lsp` language server and a
VS Code extension with the server bundled.

The project is built around an IDE-agnostic Language Server Protocol (LSP)
binary, `zerosyntax-lsp`, plus a reference VS Code extension. The analyzer uses a
hand-maintained schema modeled on the game's INI parsing tables, so diagnostics
and completions follow the structure the engine actually expects instead of
treating the files as generic INI.
## What you get

## Features
- Schema-aware diagnostics and quick fixes for blocks, fields, modules, values,
references, module tags, and missing `End` statements.
- Context-aware completion for INI keywords, enum values, flags, and definitions
in your workspace.
- Hover information, go to definition, find references, rename, workspace and
document symbols, and folding.
- Semantic highlighting for Generals INI files.
- Optional indentation formatting, disabled by default so existing files are
never reformatted without your consent.
- Base-game and mod indexing for `map.ini` and `solo.ini`, including W3D model
and bone checks.

- Diagnostics for unknown blocks, fields, modules, invalid values,
unterminated blocks, unresolved references, duplicate module tags, and
unreachable upgrade-conditioned sets.
- Context-aware completions for block names, field names, module slots, module
types, enum values, bitflags, and workspace definitions.
- Hover, go to definition, find references, rename, workspace symbol search,
document symbols, and folding ranges.
- Semantic highlighting for Generals INI syntax and schema-aware tokens.
- Quick fixes for common issues such as missing `End` statements, misspelled
enum values, unresolved references, and suppressing diagnostics.
- Optional formatter for indentation normalization.
- Incremental document updates and cached diagnostics for large game files.
- Reference VS Code extension with bundled syntax highlighting and LSP client
integration.
## Install the VS Code extension

## Supported platforms
ZeroSyntax supports Windows x64 and Linux x64 release builds.

Release assets are built for Windows x64 and Linux x64. Other platforms can
build from source with Rust and Node.js.
1. Download the `.vsix` for your platform from the
[latest GitHub release](https://github.com/ViTeXFTW/ZeroSyntaxV2/releases/latest).
2. In VS Code, open **Extensions**, choose **Views and More Actions …**,
select **Install from VSIX…**, and open the downloaded file.
3. Open your mod or map folder, then open an `.ini` file.

## Getting Started
The extension treats `.ini` files as **Generals INI**. If a workspace also
contains unrelated INI files, use VS Code's `files.associations` setting to
limit that language association to the appropriate folders.

Install the latest platform-specific VS Code extension package from
[GitHub Releases](https://github.com/ViTeXFTW/ZeroSyntaxV2/releases), then open a
Zero Hour `.ini` file. The extension activates for the `generals-ini` language
and starts the bundled language server automatically.
See the [VS Code extension guide](editors/vscode/README.md) for settings and
troubleshooting.

Formatting is off by default. Enable it with `zerosyntax.format.enable` when you
want the server to advertise document formatting to VS Code.
## Use the standalone language server

For map/solo.ini diagnostics and W3D model/bone completions, set
`zerosyntax.baseIniRoots` to game or mod directories and/or `.big` archives.
INI definitions are treated as already loaded before the map file; W3D assets
are indexed for model and bone checks.
Download the `zerosyntax-lsp` archive for your platform from the
[latest release](https://github.com/ViTeXFTW/ZeroSyntaxV2/releases/latest),
extract it, and configure your editor to run the binary over stdio.

### Standalone language server
See the [language server guide](docs/language-server.md) for initialization
options and editor integration details.

Release assets also include the standalone `zerosyntax-lsp` binary. Any editor
with generic LSP support can run that binary over stdio for `.ini` files. Pass
these initialization options if you want formatting or base INI roots:
## Configure map and model checks

For complete `map.ini` and `solo.ini` diagnostics, set
`zerosyntax.baseIniRoots` in VS Code to the base game or mod directories and/or
`.big` archives that load before the map. The same setting also enables W3D
model and bone completion and validation.

```json
{
"format": { "enable": true },
"baseIniRoots": ["C:/Games/Zero Hour", "C:/Mods/MyMod/Data/INI", "C:/Mods/MyMod.big"]
"zerosyntax.baseIniRoots": [
"C:/Games/Zero Hour",
"C:/Mods/MyMod/Data/INI",
"C:/Mods/MyMod.big"
]
}
```

## Development

```sh
cargo test --locked
cargo fmt --all --check
cargo clippy --locked --all-targets --all-features -- -D warnings

cd editors/vscode
npm ci
npm run compile
```

The optional `GeneralsCode/`, `corpus/`, and `examples/` directories are local
inputs only and are intentionally not committed. Generated binaries,
`node_modules`, compiled extension output, and `.vsix` packages are also ignored.

See [CONTRIBUTING.md](CONTRIBUTING.md) for pull request guidance and
[docs/release.md](docs/release.md) for the release process.

## Common Editor Setup

### Neovim

```lua
local configs = require("lspconfig.configs")
local lspconfig = require("lspconfig")

if not configs.zerosyntax then
configs.zerosyntax = {
default_config = {
cmd = { "zerosyntax-lsp" },
filetypes = { "generals_ini" },
root_dir = lspconfig.util.root_pattern(".git", "*.ini"),
single_file_support = true,
init_options = {
format = { enable = false },
baseIniRoots = { "C:/Games/Zero Hour" },
},
},
}
end

lspconfig.zerosyntax.setup({})
```

## Diagnostic Suppression

Suppress a diagnostic for one file with a file-scope comment:

```ini
; zerosyntax-disable: unresolved-reference, unreachable-set
```

Use the diagnostic code shown by your editor. Multiple codes can be separated by
spaces or commas, and multiple pragma lines accumulate. Unknown suppression codes
are reported so typos do not silently hide problems. The old
`; zerosyntax-disable:` spelling remains supported for existing files.

## Feature Showcase

### Diagnostic codes

ZeroSyntax v2 reports stable diagnostic codes so warnings can be searched,
suppressed, or tracked consistently:

| Code | Meaning |
| --- | --- |
| `syntax` | The file cannot be parsed cleanly, such as a missing `End`. |
| `stray-field` | A field appears outside a valid block or module. |
| `unknown-block` | A top-level block name is not known to the Generals INI schema. |
| `overrides` | A map override redefines an existing object-style definition. |
| `duplicate-definition` | The same definition is declared more than once. |
| `unreachable-set` | A `WeaponSet` or `ArmorSet` uses upgrade conditions without the trigger module needed to activate it. |
| `unknown-field` | A field is not valid in the current block or module. |
| `missing-module-tag` | A module is missing its required `ModuleTag_*` name. |
| `unknown-module` | A module type is not known for the current module slot. |
| `missing-condition` | A conditional state block is missing its condition token. |
| `missing-value` | A field requires a value but none was provided. |
| `bad-bool` | A boolean field is not `Yes` or `No`. |
| `non-positive` | A value must be greater than zero. |
| `bad-percent` | A percentage value is malformed or out of range. |
| `bad-color` | A color value is malformed. |
| `bad-coord` | A coordinate value is malformed. |
| `bad-number` | A numeric field does not contain a valid number. |
| `bad-enum` | A value is not a member of the expected enum set. |
| `bad-flag` | A bitflag value is not a member of the expected flag set. |
| `unresolved-reference` | A field references a definition that is not found in the workspace. |
| `unknown-suppression` | A `zerosyntax-disable` comment names a code that does not exist. |
| `module-wrong-slot` | A module type is used under the wrong slot. |
| `duplicate-module-tag` | Two modules in the same object use the same module tag. |
| `editor-default-module` | A placeholder/default module value should be replaced before shipping. |

### Quick fixes

Supported quick fixes appear in the editor's lightbulb/code action menu:

| Quick fix | When it appears |
| --- | --- |
| Insert missing `End` | A block or module is unterminated. |
| Replace with `<value>` | An enum or bitflag value is close to a known valid value. |
| Create stub `<Block> <Name>` | A reference points to a missing definition that can be scaffolded safely. |
| Remove unreachable `WeaponSet` / `ArmorSet` | An upgrade-conditioned set can never activate. |
| Insert `WeaponSetUpgrade` / `ArmorUpgrade` trigger module | An object has an unreachable upgrade-conditioned set and needs a trigger module. |
| Suppress `<code>` in this file | A warning or hint is intentional for the current file. |

### Example

```ini
; zerosyntax-disable: unresolved-reference

Weapon DemoCannon
PrimaryDamage = lots ; bad-number
DeathType = EXPLODDED ; quick fix: Replace with `EXPLODED`
FireFX = DemoMissingFX ; suppressed unresolved-reference
End

Object DemoTank
Behavior = PhysicsBehavior ModuleTag_01
End

WeaponSet
Conditions = PLAYER_UPGRADE
Weapon = PRIMARY DemoCannon
End ; unreachable-set
End
```
## Documentation

In this example, ZeroSyntax v2 can flag the invalid number, suggest the corrected
death flag, suppress the intentionally missing FX reference, and offer either to
remove the unreachable `WeaponSet` or insert the matching trigger module.
- [Diagnostics, suppression, and quick fixes](docs/diagnostics.md)
- [Standalone language server setup](docs/language-server.md)
- [Contributing](CONTRIBUTING.md)
- [Support](SUPPORT.md)
- [Security policy](SECURITY.md)

## License
## License and trademarks

ZeroSyntax v2 is licensed under the MIT License. See [LICENSE](LICENSE).
ZeroSyntax v2 is available under the [MIT License](LICENSE).

ZeroSyntax v2 is an unofficial community project and is not affiliated with,
endorsed by, or sponsored by Electronic Arts. Command & Conquer and related
Expand Down
6 changes: 3 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Security fixes target the latest released version of ZeroSyntax v2.

## Reporting a vulnerability

Please do not open a public issue for vulnerabilities. Report security issues by
emailing the maintainer listed on the GitHub repository profile, or by using
GitHub private vulnerability reporting if it is enabled for the repository.
Please do not open a public issue for vulnerabilities. Use
[GitHub private vulnerability reporting](https://github.com/ViTeXFTW/ZeroSyntaxV2/security/advisories/new)
or email the maintainer listed on the GitHub repository profile.

Include:

Expand Down
4 changes: 3 additions & 1 deletion SUPPORT.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Support

Use GitHub issues for reproducible bugs and focused feature requests. Or write a message in the discord server [ZeroSyntax](https://discord.gg/FShKq5s2hH)
Use [GitHub Issues](https://github.com/ViTeXFTW/ZeroSyntaxV2/issues) for
reproducible bugs and focused feature requests. For questions, join the
[ZeroSyntax Discord server](https://discord.gg/FShKq5s2hH).

Before opening an issue:

Expand Down
Loading
Loading