bdf0ae866a
Проект начинается с двух вещей: клиент, который мы действительно собрали, и загрузчик, который является его частью, а не чем-то рядом. Форк - prepare-game.ps1 пересобирает клиент целиком: ванильный jar, SRG и MCP, SpecialSource, FernFlower, патчи, автофиксеры, javac. Идемпотентен. - Свой код игры лежит в src-overlay, потому что src пересоздаётся при каждой сборке и всё написанное вручную там погибает. - 116 патчей в patches/decompiler-fixes.txt. Каждый сверялся с оригинальным байткодом через javap: компиляция не ловит ошибки декомпиляции. - struct_diff.py сравнивает исходный байткод с нашей сборкой по классам, интерфейсам, суперклассам, методам и полям, и отдельно проверяет, что пропавшие классы действительно никому не нужны. Загрузчик - Собирается и тестируется без игры: build.ps1 не использует classpath вообще, поэтому SelfTest из 128 проверок проходит без запущенного форка. - Клиентский API не содержит ни одного игрового типа, реализацию даёт игра. - Политика: мод меняет то, что клиент показывает, но никогда то, что истинно в мире. Мир, предметы, игроки и сеть принадлежат серверу. - Capability приведены в соответствие с этой политикой: осталось шесть, и за каждым стоит реальная проверка. Прежние WORLD, PLAYER, NETWORK, TEXT, INPUT и COMMAND выдавались, но ничего не проверяли. - Команды модов имеют область CLIENT, SERVER или BOTH. Серверные не выполняются на клиенте никогда. - Свой jar загрузчика лежит в classpath игры и сборки форка. Инструменты - add_patch.py, чтобы каждое исправление переживало передекомпиляцию - find_self_comparisons.py, find_remove_index_bugs.py, find_callers.py - stage_run.py и fetch_missing.py для запуска клиента
101 lines
3.7 KiB
Markdown
101 lines
3.7 KiB
Markdown
# RustNotMC
|
|
|
|
A survival game built on a Minecraft 1.12.2 client as the rendering platform,
|
|
with its own server, its own protocol and its own accounts.
|
|
|
|
## Repositories
|
|
|
|
| Repository | License | What lives there |
|
|
|---|---|---|
|
|
| `rsx-client` | MIT | Loader, mod API, client hooks, deobfuscation tools |
|
|
| `rsx-protocol` | MIT | Wire format, packet schemas, shared simulation library |
|
|
| `rsx-plugin-api` | MIT | Interfaces for server-side content |
|
|
| `rsx-server-core` | proprietary | Tick loop, world, entities, scaling |
|
|
| `rsx-auth` | proprietary | Accounts, tokens, revocation |
|
|
|
|
## Target
|
|
|
|
Base platform is Minecraft 1.12.2, forked into our own source tree so the game
|
|
is moddable from the start rather than patched from outside.
|
|
|
|
- game fork: Java 17, compiled by `game-fork\scripts\prepare-game.ps1`
|
|
- loader and mod API: Java 17
|
|
- mods: Java only
|
|
|
|
Capacity target is 200 players on 4 cores and 8 GB of RAM, scaling to 500 on
|
|
larger hardware.
|
|
|
|
## The fork
|
|
|
|
The client is not wrapped around the game jar. `game-fork` rebuilds it from the
|
|
verified vanilla jar into readable source, and the loader is an ordinary part
|
|
of that game rather than an agent injected into someone else's process.
|
|
|
|
```
|
|
vanilla client-1.12.2.jar verified Mojang signature
|
|
-> mcp-1.12.2-srg.zip 3344 classes, 20817 members
|
|
-> merge with MCP CSVs 9991 fields, 18715 methods renamed
|
|
-> SpecialSource 3310 classes in MCP names
|
|
-> FernFlower 2050 source files
|
|
-> hand patches + rules 103 patches, one regex rule
|
|
-> javac 3261 classes, clean
|
|
```
|
|
|
|
`prepare-game.ps1` runs the whole thing and is idempotent. Hand fixes live in
|
|
`game-fork\patches\decompiler-fixes.txt` and are re-applied on every run, so
|
|
regenerating the tree never loses them.
|
|
|
|
The fork holds Mojang-derived code and is **not published**. What ships in the
|
|
open repository is the loader, the mod API and the build tools.
|
|
|
|
## Modding
|
|
|
|
Mods are jars with a descriptor at `META-INF/rsxmod.properties`:
|
|
|
|
```properties
|
|
id=rsxm-lib
|
|
name=RustNotMC Library
|
|
version=1.0.0
|
|
env=CLIENT
|
|
entrypoint=net.rustnotmc.lib.LibMod
|
|
access=hud, text, world, player
|
|
depends.core=>=1.0
|
|
```
|
|
|
|
`env` is `CLIENT`, `SERVER` or `BOTH`. The loader runs on the client today;
|
|
the field exists so a mod that targets both sides does not need a format
|
|
change when the loader moves to the server.
|
|
|
|
Each mod gets its own class loader. Mods declare the capabilities they need and
|
|
the loader grants them; `reflection` is never granted without explicit operator
|
|
consent.
|
|
|
|
Load order comes from the dependency graph, not from filenames. Shutdown runs
|
|
in reverse.
|
|
|
|
## Building
|
|
|
|
```powershell
|
|
rsx-client\scripts\build.ps1 # dist\rsx-loader.jar
|
|
rsx-client\scripts\test.ps1 # self test, 96 checks
|
|
game-fork\scripts\prepare-game.ps1 # rebuild the fork from the vanilla jar
|
|
game-fork\scripts\compile-game.ps1 # compile only, fast iteration
|
|
```
|
|
|
|
Only a JDK is required. No Gradle, no network once the mappings are cached.
|
|
|
|
## Tools
|
|
|
|
| Script | Purpose |
|
|
|---|---|
|
|
| `rsx-client\tools\merge_srg_mcp.py` | vanilla SRG plus MCP CSVs into one obf to MCP SRG |
|
|
| `rsx-client\tools\apply_patches.py` | re-applies the hand fixes, fails loudly if one misses |
|
|
| `rsx-client\tools\fix_stale_locals.py` | FernFlower's stale local references, scoped per method |
|
|
| `rsx-client\tools\fix_generic_casts.py` | inserts the cast where a generic loses its type parameter |
|
|
| `rsx-client\tools\fix_decompiler_rules.py` | systematic rewrites that would be hundreds of patches |
|
|
| `rsx-client\tools\show_errors.py` | javac errors next to the source line that caused them |
|
|
|
|
## Legal
|
|
|
|
Minecraft is a trademark of Mojang Studios. This project is not affiliated with
|
|
or endorsed by Mojang or Microsoft. Game assets are not redistributed here. |