README приведён в соответствие с тем, что реально сделано

This commit is contained in:
sasheg dev
2026-10-19 01:03:19 +03:00
parent 966a144a64
commit 736ef36a44
+71 -13
View File
@@ -37,14 +37,22 @@ vanilla client-1.12.2.jar verified Mojang signature
-> merge with MCP CSVs 9991 fields, 18715 methods renamed -> merge with MCP CSVs 9991 fields, 18715 methods renamed
-> SpecialSource 3310 classes in MCP names -> SpecialSource 3310 classes in MCP names
-> FernFlower 2050 source files -> FernFlower 2050 source files
-> hand patches + rules 103 patches, one regex rule -> hand patches + rules 114 patches, one regex rule
-> javac 3261 classes, clean -> javac 3268 classes, clean
``` ```
`prepare-game.ps1` runs the whole thing and is idempotent. Hand fixes live in `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 `game-fork\patches\decompiler-fixes.txt` and are re-applied on every run, so
regenerating the tree never loses them. regenerating the tree never loses them.
Compiling clean proves nothing. Decompilation quietly breaks code that still
compiles, still has the right methods and still runs: an entity that compares
itself with itself never leaves the ground, a list indexed by entity id
removes the wrong player. Every patch here was checked against the original
bytecode with `javap`, and `tools\javap_diff.py` is the tool that makes that
comparison usable. The self-comparison finder and the remove-by-index finder
both came out of this class of bug.
The fork holds Mojang-derived code and is **not published**. What ships in the 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. open repository is the loader, the mod API and the build tools.
@@ -53,12 +61,12 @@ open repository is the loader, the mod API and the build tools.
Mods are jars with a descriptor at `META-INF/rsxmod.properties`: Mods are jars with a descriptor at `META-INF/rsxmod.properties`:
```properties ```properties
id=rsxm-lib id=rsxm-demo
name=RustNotMC Library name=RustNotMC Demo
version=1.0.0 version=1.1.0
env=CLIENT env=CLIENT
entrypoint=net.rustnotmc.lib.LibMod entrypoint=net.rustnotmc.demo.DemoMod
access=hud, text, world, player access=hud,commands,files
depends.core=>=1.0 depends.core=>=1.0
``` ```
@@ -66,34 +74,84 @@ depends.core=>=1.0
the field exists so a mod that targets both sides does not need a format the field exists so a mod that targets both sides does not need a format
change when the loader moves to the server. change when the loader moves to the server.
Each mod gets its own class loader. Mods declare the capabilities they need and Each mod gets its own class loader. Load order comes from the dependency graph,
the loader grants them; `reflection` is never granted without explicit operator not from filenames. Shutdown runs in reverse.
consent.
Load order comes from the dependency graph, not from filenames. Shutdown runs ### What a mod may touch
in reverse.
A client mod changes what the client shows. It never decides what is true about
the world: the server owns the world, the inventory, the player and the
network. Capabilities are only granted when something actually checks them.
| Capability | Grants | Checked |
|---|---|---|
| `CORE` | lifecycle, logging, own mod directory | always |
| `HUD` | draw overlays through the game's font | granted from descriptor |
| `INPUT` | read keyboard and mouse state | granted from descriptor |
| `COMMANDS` | register commands the player can type | granted from descriptor |
| `FILES` | a directory of its own under `run/mods/<id>` | granted from descriptor |
| `REFLECTION` | reach into game internals | never automatic, operator consent |
`WORLD`, `PLAYER`, `NETWORK`, `TEXT`, `INPUT` and `COMMAND` were removed: they
were advertised but not enforced, so a descriptor could claim them and receive
nothing. A capability that cannot be granted is worse than an absent one.
Commands carry a scope. `CLIENT` commands run on the client and are never sent
anywhere. `SERVER` and `BOTH` commands are registered but deliberately not
executed on the client, because the server is what has to see them and decide.
The client API contains no game types at all, which is what lets the loader
build and test with the game closed: the SPI is implemented on the game side
and the API never depends on it. `tick()` advances on the client's own tick,
not on frames, so a mod counts the same twenty steps a second at 60 fps and at
240.
## Building ## Building
```powershell ```powershell
rsx-client\scripts\build.ps1 # dist\rsx-loader.jar rsx-client\scripts\build.ps1 # dist\rsx-loader.jar
rsx-client\scripts\test.ps1 # self test, 96 checks rsx-client\scripts\test.ps1 # self test, 128 checks
game-fork\scripts\prepare-game.ps1 # rebuild the fork from the vanilla jar game-fork\scripts\prepare-game.ps1 # rebuild the fork from the vanilla jar
game-fork\scripts\compile-game.ps1 # compile only, fast iteration game-fork\scripts\compile-game.ps1 # compile only, fast iteration
rsx-client\scripts\run-game.ps1 # launch the client
``` ```
Only a JDK is required. No Gradle, no network once the mappings are cached. Only a JDK is required. No Gradle, no network once the mappings are cached.
### Assets
The client will not run without a real asset tree, and the launcher on this
machine keeps assets the modern way: `indexes/1.12.json` pointing at
`objects/<aa>/<sha1>`. A 1.12.2 client reads neither. It wants
`<assetsDir>/minecraft/<path>`.
Pointing `--assetsDir` straight at the object store does not look broken. Text
and textures come from the jar, so the game looks complete, but every sound has
been an asset since 1.7.3 and none of them are on disk: the sound engine
starts, `play()` is called, nothing is found, and paulscode says nothing.
`tools\materialize_assets.py` lays the tree out and `run-game.ps1` calls it on
every launch, so this cannot be forgotten again.
## Tools ## Tools
| Script | Purpose | | Script | Purpose |
|---|---| |---|---|
| `rsx-client\tools\merge_srg_mcp.py` | vanilla SRG plus MCP CSVs into one obf to MCP SRG | | `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\apply_patches.py` | re-applies the hand fixes, fails loudly if one misses |
| `rsx-client\tools\add_patch.py` | appends a reviewed patch to the fix file |
| `rsx-client\tools\fix_stale_locals.py` | FernFlower's stale local references, scoped per method | | `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_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\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 | | `rsx-client\tools\show_errors.py` | javac errors next to the source line that caused them |
| `rsx-client\tools\struct_diff.py` | class-by-class comparison against the reference, plus orphan analysis |
| `rsx-client\tools\javap_diff.py` | instruction-level comparison, normalising constant pool and offsets |
| `rsx-client\tools\find_self_comparisons.py` | finds `x == x`, the decompiler's signature bug |
| `rsx-client\tools\find_remove_index_bugs.py` | finds `List<Integer>.remove(int)` where an object was meant |
| `rsx-client\tools\find_callers.py` | who calls a field or method, via the constant pool |
| `rsx-client\tools\materialize_assets.py` | lays the asset tree out from the index and object store |
| `rsx-client\tools\ogg_duration.py` | real length of an ogg, to tell a short file from a cut-off one |
| `rsx-client\tools\stage_run.py` | writes the runtime classpath |
| `rsx-client\tools\fetch_missing.py` | pulls natives into the local run directory |
## Legal ## Legal