Overwatch Script To Workshop

repository·master·Indexed 42 days ago

https://github.com/itsdeltin/overwatch-script-to-workshop

A toolchain and high-level programming language that allows developers to write custom scripts and convert them into Overwatch Workshop code. It features support for control flow, functions, classes, and an LSP implementation (OstwLangServer) providing syntax highlighting and autocompletion for .del, .ostw, and .workshop files.

Tokens
3.1K
Snippets
9
Records
13
Agent score
52%

What's inside OSTW

  1. Overview of Deltin's Script To Workshop

    master
    Deltin's Script To Workshop is a tool designed to allow developers to write scripts that are subsequently converted into Overwatch Workshop code. This enables a more programmatic approach to creating Overwatch game modes compared to using the in-game Workshop editor directly.
  2. Overview of OSTW features

    master

    OSTW is a high-level programming language designed for the Overwatch workshop. It provides several programming constructs and developer experience improvements, including:

    • Control Flow: if...else statements, switch cases, and loops (while, for, foreach).
    • Data & Logic: Easy string creation and easy operation trees.
    • Abstraction: Support for functions and classes.
    • IDE Support: Syntax highlighting and autocompletion.
  3. Build TextMate grammars with tmlanguage-generator

    master

    The tmlanguage-generator package provides a programmatic API to construct complex regular expression trees and convert them into TextMate language grammars. It uses a functional approach to compose RegexNode objects using logic, quantifiers, and symbols, which can then be used to generate TmLanguage structures via createTextmateGrammar.

    import { createTextmateGrammar, Or, Digit, Whitespace, Match } from 'overwatch-script-to-workshop/tmlanguage-generator';
    
    // Example of composing a regex pattern
    const pattern = Or(Digit(), Whitespace());
    
    // The actual grammar generation is handled by createTextmateGrammar (exported from TextmateGenerator)
    // using the patterns defined via this API.
  4. Initialize the OstwLangServer

    master

    The OstwLangServer class is the main entrypoint for the Language Server Protocol (LSP) implementation. It manages protocol handlers for various IDE features like completion, definition, hover, and more.

    To instantiate the server, you must provide a ITomlDiagnosticReporter, an IDocumentEvent handler, and optionally a logger and a file getter factory. The server uses a LanguageServerBuilder to coordinate the internal components.

    // Example instantiation pattern
    var server = new OstwLangServer(
        tomlDiagnosticsReporter,
        documentEventHandler,
        langLogger,
        createFileGetterFunc,
        settingsProvider
    );
  5. Custom LSP Requests in OstwLangServer

    master

    The OstwLangServer implements several custom LSP requests that extend standard functionality. These requests allow the client to interact with specialized features like pathmap editing and decompilation.

    Available Custom Requests

    Request NameParameter TypeReturn TypeDescription
    pathmapFromClipboardstringstringImports a pathmap from the system clipboard. Returns "success" or an error message.
    pathmapApplyJTokenJTokenSaves the current lastMap to a file path specified in the JSON object: {"path": "..."}.
    pathmapEditorPathmapDocumentPathmapEditorResultGenerates/edits a pathmap script. PathmapDocument contains Text and File fields.
    semanticTokensJTokenSemanticToken[]Returns semantic tokens for a specific file path provided in {"fsPath": "..."}.
    decompile.insertN/ADecompileResultDecompiles text from the clipboard and returns the result.
    decompile.fileDecompileFileArgsDecompileResultDecompiles workshop code and writes it to the file path provided in DecompileFileArgs.

    Data Structures

    DecompileFileArgs

    • file (string): The target file path to write the decompiled code to.

    PathmapDocument

    • Text (string): The content of the pathmap.
    • File (string): The file path.
  6. Compose regex patterns using logic and quantifiers

    master

    You can build complex regular expressions by composing simple building blocks using the following functional API:

    Logic

    • Or(...values: Regexable[]): Matches any of the provided patterns.
    • And(...values: Regexable[]): Matches a sequence of the provided patterns (Chain).
    • Group(options: GroupOptions): Creates a grouping node.
    • Match(value: Regexable, tmName: TmName): Creates a capturing group associated with a TextMate scope name.
    • NonCapturing(value: Regexable): Creates a non-capturing group.

    Quantifiers

    All quantifiers accept a lazy: boolean parameter (defaults to false).

    • Maybe(value: Regexable, lazy?: boolean): Zero or one.
    • ZeroOrMore(value: Regexable, lazy?: boolean): Zero or more.
    • OneOrMore(value: Regexable, lazy?: boolean): One or more.
    • Exactly(value: Regexable, count: number, lazy?: boolean): Exactly N times.
    • AtLeast(value: Regexable, count: number, lazy?: boolean): At least N times.
    • Between(value: Regexable, from: number, to: number, lazy?: boolean): Between N and M times.

    Lookarounds

    • PositiveLookahead(value: Regexable)
    • PositiveLookbehind(value: Regexable)
    • NegativeLookahead(value: Regexable)
    • NegativeLookbehind(value: Regexable)
    import { Or, OneOrMore, Digit, Match } from 'overwatch-script-to-workshop/tmlanguage-generator';
    
    // Matches one or more digits and assigns a TextMate scope
    const myPattern = OneOrMore(Digit());
    const scopedPattern = Match(myPattern, 'keyword.control.digit');
  7. Use the ostw export from the Deltinteger CLI

    master

    The ostw object is the primary entry point for interacting with the Overwatch Script To Workshop logic via the JavaScript bridge. It is exported from the main module and provides access to the underlying .NET assembly's functionality through a JavaScript interface. To use it, you must ensure the dotnet framework is initialized and the assembly exports are loaded.

    Note: This module is designed to run in an environment where the dotnet framework (provided by ./_framework/dotnet.js) is available, typically a browser-based WebAssembly environment.

    import { ostw } from './Deltinteger/Deltinteger/main.js';
    
    // Use ostw to interact with the workshop logic
    // ostw is an instance of OstwJavascript
    await ostw.someMethod();
  8. Access OstwLangServer Protocol Handlers

    master

    The OstwLangServer exposes several public properties that provide access to specific protocol handlers. These handlers manage the logic for standard LSP features:

    • DocumentHandler: Manages document lifecycle and changes.
    • CompletionHandler: Provides autocompletion.
    • SignatureHandler: Provides parameter information for function calls.
    • DefinitionHandler: Handles 'Go to Definition'.
    • HoverHandler: Provides hover information.
    • ReferenceHandler: Handles 'Find All References'.
    • CodeLensHandler: Manages code lens information.
    • RenameHandler: Handles symbol renaming.
    • ColorHandler: Provides color information.
    • SemanticTokenHandler: Manages semantic highlighting.
    • DocumentSymbolHandler: Provides document symbols (outline).
    • ConfigurationHandler: Manages server configuration.

    Other useful properties:

    • Builder: The LanguageServerBuilder instance.
    • ProjectUpdater: An IProjectUpdater for managing project-wide compilation state.
    • Workspace: The ServerWorkspace instance.
  9. Use regex symbols and character classes

    master

    The API provides shorthand functions for common regex symbols and character classes:

    Symbols

    • Digit(): \d
    • NotDigit(): \D
    • WordCharacter(): \w
    • NotWordCharacter(): \W
    • Whitespace(): \s
    • NotWhitespace(): \S
    • Any(): .

    Anchors

    • StartOfLine(): ^
    • EndOfLine(): $
    • WordBoundary(): \b
    • NotWordBoundary(): \B

    Character Classes and Literals

    • CharacterClass(text: string): Creates a character set (e.g., [a-z]).
    • Raw(value: string): Creates a TextNode with the exact string provided.
    • Literal(value: string): Creates a TextNode but automatically escapes regex reserved characters (like ., *, ?, etc.).
    import { Digit, Whitespace, WordBoundary, Literal } from 'overwatch-script-to-workshop/tmlanguage-generator';
    
    // Using shorthand symbols
    const pattern = Whitespace().ZeroOrMore().Digit();
    
    // Using Literal to safely escape characters
    const safePattern = Literal('hello.world'); // results in 'hello\.world'
  10. Convert various types to RegexNode with GetRegexNode

    master

    The GetRegexNode function is a utility that normalizes different input types into a single RegexNode. This allows you to pass a variety of types into the composition functions.

    Supported Regexable types:

    • string: Converted to a Literal node.
    • RegExp: Converted to an ExpressionGroup node.
    • RegexNode: Used directly.
    • RegexNode[]: Flattened into a ChainNode.
    • Regexable[]: Recursively processed and flattened.
    import { GetRegexNode } from 'overwatch-script-to-workshop/tmlanguage-generator';
    
    // These all result in valid RegexNodes
    const node1 = GetRegexNode('abc');
    const node2 = GetRegexNode(/abc/);
    const node3 = GetRegexNode(['abc', /def/]);
  11. Create a pattern repository with makeRepository

    master

    The makeRepository function provides a structured way to collect and name multiple Pattern objects into a single lookup object. It accepts a callback function that provides an add method to register patterns.

    Note: When registering a name, any # character is stripped from the resulting key in the repository object.

    import { makeRepository, Digit, OneOrMore } from 'overwatch-script-to-workshop/tmlanguage-generator';
    
    const myRepo = makeRepository((add) => {
        add('number#pattern', OneOrMore(Digit()));
        add('simple_text', Digit());
    });
    
    // myRepo will be: { 'numberpattern': Pattern, 'simple_text': Pattern }
    console.log(myRepo['numberpattern']);