ReadStar
A mod adds configurable and more realistic stars.
Quick challenge
How far can you run before the mobs catch you?
Minecraft check
Confirm your run
Complete the quick check to get your code.
ReadStar
ReadStar — NeoForge 26.1 天文模组
基于真实天体力学与星表数据的 Minecraft 天象模组。支持行星轨道系统、恒星目录、三级光晕渲染、服务端同步的行星系统配置。
作者: FrozenStream
---
快速开始
```bash
构建
./gradlew build
运行客户端
./gradlew runClient
数据生成(图集配置)
./gradlew runData ```
模组加载后,通过资源包 `data/readstar/celestial/system.json` 定义天体系统,通过资源包 `assets/readstar/custom/stars/stars.json` 定义恒星目录。
修改配置文件后需重新构建,或 F3+T 重载资源包(仅资源包内容有效,数据包需重启或 `/reload`)。
---
数据包 — 天体系统配置
路径: `data/readstar/celestial/system.json`
数据包定义了天体层次结构与轨道参数。可放在 `saves/<世界>/datapacks/<你的数据包>/data/readstar/celestial/system.json` 下替换默认配置,或放在服务端的 `world/datapacks/` 下。
结构
```json { "System": { "<天体名称>": { "mass": <double>, // 质量(kg),0 则固定于原点 "radius": <double>, // 半径(m),影响渲染视大小 "luminance": <int>, // 自发光亮度(0~15),>0 被识别为恒星 "axis": [<x>, <y>, <z>], // 自转轴方向向量,全零则默认 (0,0,-1) "orbit": { "semiMajorAxis": <double>, // 半长轴(m),0 表示不公转 "eccentricity": <double>, // 偏心率(0=正圆) "inclination": <double>, // 轨道倾角(弧度) "argumentOfPeriapsis": <double>, // 近心点幅角(弧度) "longitudeOfAscendingNode": <double>, // 升交点经度(弧度) "initialMeanAnomaly": <double> // 初始平近点角(弧度) }, "children": { "<子天体名称>": { ... } // 递归同结构,嵌套深度不限 } } } } ```
参数说明
| 字段 | 说明 | |------|------| | `mass` | 轨道力学计算核心参数。设为 0 的天体固定在原点(父节点位置) | | `radius` | 渲染时的天体大小通过 `max(1.024, radius / distance × 2000)` 计算,距离越远越小 | | `luminance` | 自动影响渲染:`> 0` 的天体被识别为恒星,同系统内其他天体自动查找最近的发光祖先作为 `hostStar` | | `inclination`, `longitudeOfAscendingNode` | 共同决定轨道平面方向。`inclination=0` 时轨道在参考平面内 | | `eccentricity` | 偏心率 = 0 为纯圆轨道,> 0 为椭圆 | | `initialMeanAnomaly` | 决定 t=0 时刻天体在轨道上的起始位置 |
名称大小写不敏感(内部统一转为小写)。`children` 为空对象 `{}` 时表示无子天体。
完整示例
下例定义了一个三层天体系统:太阳(中心恒星)→ 地球 + 火星 → 月球(地球的卫星)。数值采自真实太阳系数据。
```json { "System": { "Sun": { "mass": 1.989e30, "radius": 6.957e8, "luminance": 15, "axis": [0.0, 0.0, 0.0], "orbit": { "semiMajorAxis": 0.0, "eccentricity": 0.0, "inclination": 0.0, "argumentOfPeriapsis": 0.0, "longitudeOfAscendingNode": 0.0, "initialMeanAnomaly": 0.0 }, "children": { "Earth": { "mass": 5.972e24, "radius": 6.371e6, "luminance": 0, "axis": [0.0, 0.0, 0.0], "orbit": { "semiMajorAxis": 1.496e11, "eccentricity": 0.0167, "inclination": 0.0, "argumentOfPeriapsis": 1.796, "longitudeOfAscendingNode": 0.0, "initialMeanAnomaly": 6.240 }, "children": { "Moon": { "mass": 7.342e22, "radius": 1.737e6, "luminance": 0, "axis": [0.0, 0.0, 0.5], "orbit": { "semiMajorAxis": 3.844e8, "eccentricity": 0.0549, "inclination": 0.0899, "argumentOfPeriapsis": 0.0, "longitudeOfAscendingNode": 0.0, "initialMeanAnomaly": 0.0 }, "children": {} } } }, "Mars": { "mass": 6.417e23, "radius": 3.390e6, "luminance": 0, "axis": [0.0, 0.0, 0.0], "orbit": { "semiMajorAxis": 2.279e11, "eccentricity": 0.0934, "inclination": 0.0323, "argumentOfPeriapsis": 0.0, "longitudeOfAscendingNode": 0.865, "initialMeanAnomaly": 0.0 }, "children": {} } } } } } ```
继承规则
- `hostStar` 自动向上递归查找最近的自发光天体 - 无自发光祖先的天体不会渲染对应的日照效果 - 位置计算:`position = parent.position + orbit(parent.mass, t)` - 根节点 `Root` 固定于 `(0,0,0)`
日/月相计算
``` gameTime → updatePositions(t) → 轨道公转 daylightTime → updateCurrentVec(t) → 自转天顶更新 ```
- `gameTime`: 自世界创建以来的总 tick 数。影响天体轨道位置 - `daylightTime`: 维度的日光周期时间(0~24000)。影响行星自转带来的天顶方向变化
月相由观测者-卫星-恒星的几何关系自动计算,完整映射 8 种月相(亏盈由轨道法线方向区分)。
---
资源包 — 恒星目录
路径: `assets/readstar/custom/stars/stars.json`
资源包定义了渲染到天空中的恒星列表。可通过资源包完全替换。
```json { "Stars": [ { "name": "Sirius", "position": [-0.188181, -0.169608, 0.967338], "type": 1, "Vmag": -1.46, "color": 4291815679 } ] } ```
| 字段 | 说明 | |------|------| | `name` | 标识符,无运行时作用 | | `position` | 单位球面上的方向向量 `[x,y,z]`,渲染时归一化并缩放到 100 单位 | | `type` | 0~11 的光谱分类,图集中精灵的颜色由此索引 | | `Vmag` | 视星等。`< 0.5` 高级光晕,`< 1.5` 中级光晕,`< 2.0` 低级光晕,`≥ 2.0` 仅核心 | | `color` | ARGB 颜色值,作为图集精灵生成的 key |
恒星亮度映射到顶点 Alpha 通道:`clamp((14 - Vmag) / 15, 0.4, 1.0) × 255`。
资源包 — 精灵与图集
星星图集
图集源通过 `RegisterSpriteSourcesEvent` 注册,类型 `readstar:star`,在 `assets/readstar/atlases/star.json` 声明:
```json { "sources": [ { "type": "readstar:star" } ] } ```
运行时从 `stars.json` 读取所有 `color` 值,读取以下底模纹理逐像素染色生成精灵:
| 底模文件 | 路径 | 作用 | |----------|------|------| | `star_base.png` | `textures/environment/star/` | 核心贴图底模(32×32,RGBA) | | `star_glow_low.png` | 同上 | 低级光晕底模 | | `star_glow_med.png` | 同上 | 中级光晕底模 | | `star_glow_high.png` | 同上 | 高级光晕底模 |
每种颜色生成 4 个子图:`color_{color}`、`glow_low_{color}`、`glow_med_{color}`、`glow_high_{color}`。
底模制作要求: - RGBA 32-bit PNG(不可用 8-bit 灰度,否则 `NativeImage.read()` 解析失败) - 32×32 像素 - 边缘纯黑 `rgb(0,0,0)` 以融入背景 - 光晕底模的核心亮度通过采样中心 8×8 区域 × 0.35 系数压制,确保远暗于核心
天体图集
由数据生成器(`runData`)生成,位于 `src/generated/resources/assets/readstar/atlases/celestial.json`。添加新天体纹理需修改 `CelestialSpriteSourceProvider` 后重新生成。
---
网络同步
天体系统数据由服务端通过 `data/readstar/celestial/*.json` 加载,通过自定义网络包 `readstar:planet_system` 广播到所有客户端。客户端 `CelestialBodyManager.initializeFromJson()` 在收到数据包后解析并构建天体树。
---
构建
```bash ./gradlew build # 构建 mod JAR ./gradlew runData # 数据生成(图集配置) ./gradlew runClient # 运行客户端 ./gradlew runServer # 运行服务端 ```
构建产物:`build/libs/readstar-*.jar`
故障排查
| 现象 | 检查点 | |------|--------| | 星星显示紫黑贴图 | `star_base.png` 是否为 32-bit RGBA | | 数据包未生效 | `/reload` 或重启服务端 | | 资源包未更新 | F3+T 重载资源包,或重新构建 |
---
© 2026 FrozenStream DeepSeek-V4-Flash. 基于 NeoForge 构建,遵循 MIT 许可证。
ReadStar — NeoForge 26.1 Astronomy Mod
A Minecraft sky mod driven by real celestial mechanics and star catalog data, featuring planetary orbital systems, star catalogs, three-tier glow rendering, and server-synchronized planetary system configuration.
Author: FrozenStream
---
Quick Start
```bash
Build
./gradlew build
Run client
./gradlew runClient
Data generation (atlas config)
./gradlew runData ```
The celestial system is defined via resource pack at `data/readstar/celestial/system.json`, and the star catalog is defined via resource pack at `assets/readstar/custom/stars/stars.json`.
After modifying config files, rebuild or use F3+T to reload resource packs (resource pack only; data packs require restart or `/reload`).
---
Data Pack — Celestial System Configuration
Path: `data/readstar/celestial/system.json`
Place your custom data pack at `saves/<world>/datapacks/<your-pack>/data/readstar/celestial/system.json`, or on the server at `world/datapacks/`.
Structure
```json { "System": { "<body name>": { "mass": <double>, // Mass (kg); 0 = fixed at origin "radius": <double>, // Radius (m); affects rendered size "luminance": <int>, // Self-luminosity (0~15); >0 marks as star "axis": [<x>, <y>, <z>], // Rotation axis; zero vector defaults to (0,0,-1) "orbit": { "semiMajorAxis": <double>, // Semi-major axis (m); 0 = no orbit "eccentricity": <double>, // Eccentricity (0 = circular) "inclination": <double>, // Orbital inclination (radians) "argumentOfPeriapsis": <double>, // Argument of periapsis (radians) "longitudeOfAscendingNode": <double>, // Longitude of ascending node (radians) "initialMeanAnomaly": <double> // Initial mean anomaly (radians) }, "children": { "<child name>": { ... } // Recursive; unlimited nesting depth } } } } ```
Complete Example
A three-layer system: Sun (central star) → Earth + Mars → Moon (Earth's satellite), using real solar system data.
```json { "System": { "Sun": { "mass": 1.989e30, "radius": 6.957e8, "luminance": 15, "axis": [0.0, 0.0, 0.0], "orbit": { "semiMajorAxis": 0.0, "eccentricity": 0.0, "inclination": 0.0, "argumentOfPeriapsis": 0.0, "longitudeOfAscendingNode": 0.0, "initialMeanAnomaly": 0.0 }, "children": { "Earth": { "mass": 5.972e24, "radius": 6.371e6, "luminance": 0, "axis": [0.0, 0.0, 0.0], "orbit": { "semiMajorAxis": 1.496e11, "eccentricity": 0.0167, "inclination": 0.0, "argumentOfPeriapsis": 1.796, "longitudeOfAscendingNode": 0.0, "initialMeanAnomaly": 6.240 }, "children": { "Moon": { "mass": 7.342e22, "radius": 1.737e6, "luminance": 0, "axis": [0.0, 0.0, 0.5], "orbit": { "semiMajorAxis": 3.844e8, "eccentricity": 0.0549, "inclination": 0.0899, "argumentOfPeriapsis": 0.0, "longitudeOfAscendingNode": 0.0, "initialMeanAnomaly": 0.0 }, "children": {} } } }, "Mars": { "mass": 6.417e23, "radius": 3.390e6, "luminance": 0, "axis": [0.0, 0.0, 0.0], "orbit": { "semiMajorAxis": 2.279e11, "eccentricity": 0.0934, "inclination": 0.0323, "argumentOfPeriapsis": 0.0, "longitudeOfAscendingNode": 0.865, "initialMeanAnomaly": 0.0 }, "children": {} } } } } } ```
Field Reference
| Field | Description | |-------|-------------| | `mass` | Core orbital mechanics parameter. A body with mass 0 is fixed at its parent's position | | `radius` | Rendered size: `max(1.024, radius / distance × 2000)`. Diminishes with distance | | `luminance` | Bodies with `luminance > 0` are recognized as stars; child bodies auto-assign the nearest luminous ancestor as `hostStar` | | `inclination`, `longitudeOfAscendingNode` | Together define the orbital plane. `inclination=0` means the orbit lies in the reference plane | | `eccentricity` | 0 = circular orbit, > 0 = elliptical | | `initialMeanAnomaly` | Determines the body's starting position on its orbit at t=0 |
Names are case-insensitive (internally converted to lowercase). Use `{}` for empty children.
Inheritance
- `hostStar` is resolved by recursively searching upward for the nearest body with `luminance > 0` - Bodies without a luminous ancestor skip rendered sun-light effects - Position: `position = parent.position + orbit(parent.mass, t)` - Root node `Root` is fixed at `(0, 0, 0)`
Daytime and Moon Phase
``` gameTime → updatePositions(t) → orbital revolution daylightTime → updateCurrentVec(t) → rotation/zenith update ```
- `gameTime`: total ticks since world creation. Controls orbital positions - `daylightTime`: dimension daylight cycle time (0~24000). Controls planet rotation and zenith direction
Moon phases are automatically computed from observer-satellite-star geometry, mapping a full orbit to all 8 phase types. Waxing vs. waning is determined by the sign of the observer-centric cross product against the orbital normal.
---
Resource Pack — Star Catalog
Path: `assets/readstar/custom/stars/stars.json`
```json { "Stars": [ { "name": "Sirius", "position": [-0.188181, -0.169608, 0.967338], "Vmag": -1.46, "color": 4291815679 } ] } ```
| Field | Description | |-------|-------------| | `name` | Identifier; no runtime effect | | `position` | Direction vector `[x,y,z]` on the unit sphere; normalized and scaled to 100 during rendering | | `Vmag` | Apparent magnitude. `< 0.5`: high glow; `< 1.5`: medium glow; `< 2.0`: low glow; `≥ 2.0`: core only | | `color` | ARGB color value; used as the key for atlas sprite generation |
Star brightness is mapped to vertex alpha: `clamp((14 - Vmag) / 15, 0.4, 1.0) × 255`.
---
Resource Pack — Sprites & Atlas
Star Atlas
The atlas source is registered via `RegisterSpriteSourcesEvent` with type `readstar:star`, declared in `assets/readstar/atlases/star.json`:
```json { "sources": [ { "type": "readstar:star" } ] } ```
At runtime, all `color` values from `stars.json` are read. The following base textures are used as stencils and tinted per-pixel:
| Stencil | Path | Purpose | |---------|------|---------| | `star_base.png` | `textures/environment/star/` | Core texture (32×32, RGBA) | | `star_glow_low.png` | same | Low glow stencil | | `star_glow_med.png` | same | Medium glow stencil | | `star_glow_high.png` | same | High glow stencil |
Each color produces 4 sprites: `color_{color}`, `glow_low_{color}`, `glow_med_{color}`, `glow_high_{color}`.
Stencil requirements: - RGBA 32-bit PNG (8-bit grayscale will fail `NativeImage.read()`) - 32×32 pixels - Pure black edges (`rgb(0,0,0)`) to blend into the background - Glow brightness is suppressed by a factor of 0.35 based on the center 8×8 region sample
Celestial Atlas
Generated by `runData`, output at `src/generated/resources/assets/readstar/atlases/celestial.json`. Add new celestial body textures by modifying `CelestialSpriteSourceProvider` and re-running data generation.
---
Network Sync
The celestial system data is loaded from `data/readstar/celestial/*.json` on the server side and broadcast to all clients via the custom packet `readstar:planet_system`. `CelestialBodyManager.initializeFromJson()` parses and builds the body tree on the client upon receipt.
---
Build
```bash ./gradlew build # Build mod JAR ./gradlew runData # Data generation (atlas config) ./gradlew runClient # Run client ./gradlew runServer # Run server ```
Output: `build/libs/readstar-*.jar`
Troubleshooting
| Symptom | Check | |---------|-------| | Purple/black star textures | Is `star_base.png` 32-bit RGBA? | | Sun/moon not visible | Is `Observer` properly assigned in `ExtractLevelRenderStateEvent`? | | Celestial bodies in wrong direction | Check `currentRotationVector` calculation and `frameQuat` basis vectors | | Data pack not applied | Run `/reload` or restart the server | | Resource pack not updating | Press F3+T or rebuild |
---
© 2026 FrozenStream. Licensed under MIT.