PowerRules is a language designed to generate rules for DDNet (GitHub). Its goal is to simplify writing rules by providing a more user-friendly and powerful syntax.
You can use the online transpiler to convert PowerRules into DDNet rules. For more information on how to write PowerRules, check out the wiki.
Special thanks to Toom for significant technical help and advice with Scala, Ssor for support and ideas, and archimede67 for fixing bugs that almost led me to abandon the project!
Writing rules for the DDNet automapper is often tricky. It can be confusing because of its format which is neither readable nor intuitive. Moreover, writing rules is often about writing the same patterns: first making grass or freeze, then adding 2×2 or 3×3 shapes and finally finishing with some random variations.
That's why PowerRules was born. It enables anyone to make rules thanks to a simpler usage. Its goal is to make rules accessible to anyone instead of the "more developpers" ones.
It follows a linear structure like the original DDNet rules format. The patterns have been implemented into commands to improve both the readability and the ease.
Contributions are welcome! Whether it concerns the backend, the frontend, the wiki or the visual design, contributions are much appreciated. There is many ways to help this project so if you are motivated, feel free to contact @lomination on Discord.
Moreover, if you have any suggestions, feel free to reach out via GitHub issues or Discord.
- DDNet official wiki
- Forum post (possibly partially outdated)
- Forum post (possibly partially outdated)
This project is cross-compiled for both ScalaJVM and ScalaJS. The shared core is located in the shared/ directory, while platform-specific code resides in the js/ or jvm/ directories.
The compilation process follows several steps. All referenced classes are found in the shared/src/main/scala/lomination/powerrules directory:
- The configuration is parsed using
config.ConfigParser. - The macro section is tokenized with
lexing.Lexer. - Tokens are formatted using
formatting.Formatterto ease parsing. - The formatted tokens are parsed by
macros.MacroParser. - The rules section is tokenized using
lexing.Lexer. - Parsed macros are applied to the tokens in the rules section using
macros.MacroApplier. - The resulting tokens are formatted by
formatting.Formatter. - Tokens are parsed using
parsing.MainParser. - Finally, the parsed AST is written using the
writing.Writertype class.
The ScalaJVM part of the project allows you to convert a PowerRules file into a DDNet rules file. To use it, run the following command replacing <filename> by the name of your PowerRules file:
sbt "rootJVM/run <filename>"It will create a new .rules file in the current directory, containing the compiled rules.
The ScalaJS component enables building a web-based PowerRules to DDNet rules converter. You can try it here or build
All workflows are located in the default directory for GitHub workflows i.e. ./github/workflows/.
The build.yaml workflow builds the project and run the tests for both ScalaJVM and ScalaJS plateforms. The check-format.yaml workflow uses scalafmt and scalafix to check if the Scala source code is formatted according to the respective given configurations ./.scalafmt.conf and ./.scalafix.conf to improve code consistency. Finally, the coverage.yaml workflows runs code coverage thanks to sbt-scoverage plugin, then computes the line coverage and branch coverage and, if it is run on a commit on the main branch, update the GitHub Gists responsible for the badges at the begining of this file. These three workflows can be trigger on workflow call.
The on-push.yaml workflow is used only to call the three previously mentioned ones: build.yaml, check-format and coverage.yaml. As its name suggests, it is run on every pushed commit, regardless of the branch. Note that it first runs build.yaml and check-format workflows and then coverage.yaml only if the build and tests have succeeded.
The check-examples.yaml workflow ensures that each provided compiled PowerRules file in ./examples/*.rules corresponds exactly to its .powerrules file (i.e. it ensures that no change in the compiler has affected the result of the compilation of the examples). It is not automatically run but can be triggered using the GitHub interface thanks to the workflow_dispatch tag.
The release.yaml workflow creates a new release of the project. It can be triggered manually as the check-examples.yaml workflow. The release process includes:
- running
build.yaml,check-format.yamlandcoverage.yamlworkflows and ensuring they succeed, - changing the version to the new release in the
./build.sbtand./package.jsonfiles, - creating a git tag,
- building for ScalaJS using
npm run build, - deploying to GitHub pages,
- chaging the version to the future snapshot in the
./build.sbtand./package.jsonfiles, - updating the GitHub Gist responsible for the version badge at the begining of this file.