Skip to content

Commit 1b81917

Browse files
committed
feat: initial commit
0 parents  commit 1b81917

17 files changed

Lines changed: 1565 additions & 0 deletions

File tree

.github/workflows/docker.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
tags: ['v*']
7+
pull_request:
8+
branches: [main, master]
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
IMAGE_NAME: ${{ github.repository }}
13+
14+
jobs:
15+
build:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
packages: write
20+
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
- name: Set up Docker Buildx
26+
uses: docker/setup-buildx-action@v3
27+
28+
- name: Log in to GHCR
29+
if: github.event_name != 'pull_request'
30+
uses: docker/login-action@v3
31+
with:
32+
registry: ${{ env.REGISTRY }}
33+
username: ${{ github.actor }}
34+
password: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Extract metadata
37+
id: meta
38+
uses: docker/metadata-action@v5
39+
with:
40+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
41+
tags: |
42+
type=ref,event=branch
43+
type=semver,pattern={{version}}
44+
type=semver,pattern={{major}}.{{minor}}
45+
type=sha,prefix=
46+
47+
- name: Build and push
48+
uses: docker/build-push-action@v6
49+
with:
50+
context: .
51+
push: ${{ github.event_name != 'pull_request' }}
52+
tags: ${{ steps.meta.outputs.tags }}
53+
labels: ${{ steps.meta.outputs.labels }}
54+
cache-from: type=gha
55+
cache-to: type=gha,mode=max

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
assets/
2+
data/
3+
old/
4+
5+
# Go binaries
6+
blockymerge
7+
extract-assets
8+
*.exe
9+
*.exe~
10+
*.dll
11+
*.so
12+
*.dylib
13+
14+
# AI slop
15+
.claude
16+
.sisyphus
17+
18+
# Hytale assets archive
19+
Assets.zip

CLAUDE.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Build & Run Commands
6+
7+
```bash
8+
# Build
9+
go build -o blockyserver.exe .
10+
11+
# Run (default port 8080)
12+
./blockyserver.exe
13+
./blockyserver.exe -port 3000
14+
15+
# Dependencies
16+
go mod tidy
17+
```
18+
19+
## Architecture
20+
21+
BlockyServer is an HTTP API for rendering Hytale character models. It wraps the `github.com/hytale-tools/blockymodel-merger` library to provide web endpoints.
22+
23+
### Request Flow
24+
25+
```
26+
HTTP Request → api.Handlers → service.MergeService → blockymodel-merger pkg
27+
28+
render.RenderPNG/GIF (for image endpoints)
29+
30+
HTTP Response (GLB/PNG/GIF)
31+
```
32+
33+
### Package Structure
34+
35+
- **main.go** - Entry point, flag parsing, server startup
36+
- **internal/api/** - HTTP layer (chi router, handlers, OpenAPI spec)
37+
- **internal/service/** - Business logic wrapping blockymodel-merger
38+
- **internal/render/** - Software 3D rendering using fauxgl (GLB→PNG/GIF)
39+
40+
### Key Dependencies
41+
42+
- `github.com/hytale-tools/blockymodel-merger` - Core model merging, texture atlas, GLB export
43+
- `github.com/fogleman/fauxgl` - Software 3D renderer for PNG/GIF output
44+
- `github.com/go-chi/chi/v5` - HTTP router
45+
46+
### Runtime Data
47+
48+
Server requires these directories at runtime (relative to working directory):
49+
- `assets/` - Character models (.blockymodel), textures
50+
- `data/` - JSON registry files (accessories, colors, gradients)
51+
52+
### API Endpoints
53+
54+
| Endpoint | Method | Description |
55+
|----------|--------|-------------|
56+
| `/render/glb` | POST | Character JSON → GLB binary |
57+
| `/render/png` | POST | Character JSON + options → PNG image |
58+
| `/render/gif` | POST | Character JSON + options → Animated GIF |
59+
| `/docs` | GET | Swagger UI |
60+
| `/openapi.json` | GET | OpenAPI spec |
61+
| `/health` | GET | Health check |
62+
63+
### Character JSON Format
64+
65+
Accessory format: `"AccessoryId.Color.Variant"` (e.g., `"Scavenger_Hair.PitchBlack"`)
66+
67+
Key fields: `bodyCharacteristic`, `haircut`, `eyes`, `pants`, `undertop`, `overtop`, `shoes`

Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FROM golang:1.25-alpine AS builder
2+
3+
WORKDIR /app
4+
5+
COPY go.mod go.sum ./
6+
RUN go mod download
7+
8+
COPY . .
9+
RUN CGO_ENABLED=0 GOOS=linux go build -o blockyserver .
10+
11+
FROM alpine:latest
12+
13+
WORKDIR /app
14+
15+
COPY --from=builder /app/blockyserver .
16+
17+
EXPOSE 8080
18+
19+
ENTRYPOINT ["./blockyserver"]
20+
CMD ["-port", "8080"]

README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# BlockyServer
2+
3+
> [!WARNING]
4+
> Not affiliated with Hypixel Studios.
5+
> All trademarks and assets are property of their respective owners.
6+
7+
HTTP API for rendering Hytale character models as GLB, PNG, or animated GIF.
8+
9+
Built on top of [blockymodel-merger](https://github.com/hytale-tools/blockymodel-merger) by [JackGamesFTW](https://github.com/JackGamesFTW), special thanks to him!
10+
11+
## Features
12+
13+
- Merge character accessories into a single model
14+
- Export as GLB (glTF binary)
15+
- Render to PNG with configurable rotation and background
16+
- Render to animated rotating GIF
17+
- Swagger UI documentation
18+
19+
## Requirements
20+
21+
- Go 1.21+
22+
- `assets/` directory with character models and textures
23+
- `data/` directory with JSON registry files
24+
25+
## Obtaining Assets
26+
27+
> [!NOTE]
28+
> You must purchase [Hytale](https://store.hytale.com) to obtain assets. Use code `jack` in the Hytale Store to support Jack's projects.
29+
30+
Download `assets.zip` from the [Hytale Server Manual](https://support.hytale.com/hc/en-us/articles/45326769420827-Hytale-Server-Manual#server-setup).
31+
32+
**Important:** Use the server version, not the client version. The server package includes the `data/` directory with registry JSON files.
33+
34+
### Using extract-assets tool
35+
36+
Clone and build the extraction tool from blockymodel-merger:
37+
38+
```bash
39+
git clone https://github.com/hytale-tools/blockymodel-merger.git
40+
cd blockymodel-merger
41+
go build -o extract-assets ./cmd/extract-assets
42+
./extract-assets /path/to/assets.zip
43+
```
44+
45+
This extracts files into the required structure:
46+
- `Common/Characters``assets/Characters/`
47+
- `Common/Cosmetics``assets/Cosmetics/`
48+
- `Common/TintGradients``assets/TintGradients/`
49+
- `Cosmetics/CharacterCreator``data/`
50+
51+
Copy the resulting `assets/` and `data/` directories to your blockyserver folder.
52+
53+
## Installation
54+
55+
```bash
56+
git clone https://github.com/yourusername/blockyserver.git
57+
cd blockyserver
58+
go mod tidy
59+
go build -o blockyserver.exe .
60+
```
61+
62+
## Usage
63+
64+
```bash
65+
# Start server on default port 8080
66+
./blockyserver.exe
67+
68+
# Start on custom port
69+
./blockyserver.exe -port 3000
70+
```
71+
72+
## Docker
73+
74+
### Using Docker Compose (recommended)
75+
76+
```bash
77+
docker compose up -d
78+
```
79+
80+
This mounts `assets/` and `data/` directories as read-only volumes.
81+
82+
### Using Docker directly
83+
84+
```bash
85+
# Build image
86+
docker build -t blockyserver .
87+
88+
# Run container
89+
docker run -d -p 8080:8080 \
90+
-v $(pwd)/assets:/app/assets:ro \
91+
-v $(pwd)/data:/app/data:ro \
92+
blockyserver
93+
```
94+
95+
## API Endpoints
96+
97+
| Endpoint | Method | Description |
98+
|----------|--------|-------------|
99+
| `/render/glb` | POST | Returns GLB binary |
100+
| `/render/png` | POST | Returns PNG image |
101+
| `/render/gif` | POST | Returns animated GIF |
102+
| `/docs` | GET | Swagger UI |
103+
| `/openapi.json` | GET | OpenAPI specification |
104+
| `/health` | GET | Health check |
105+
106+
## Example Request
107+
108+
### Render PNG
109+
110+
```bash
111+
curl -X POST http://localhost:8080/render/png \
112+
-H "Content-Type: application/json" \
113+
-d '{
114+
"character": {
115+
"bodyCharacteristic": "Default.02",
116+
"haircut": "Scavenger_Hair.PitchBlack",
117+
"eyes": "Large_Eyes.Pink",
118+
"pants": "Pants_A.Blue",
119+
"undertop": "Shirt_A.White"
120+
},
121+
"rotation": 45,
122+
"background": "transparent",
123+
"width": 512,
124+
"height": 512
125+
}' --output character.png
126+
```

docker-compose.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
blockyserver:
3+
build: .
4+
ports:
5+
- "8080:8080"
6+
volumes:
7+
- ./assets:/app/assets:ro
8+
- ./data:/app/data:ro
9+
restart: unless-stopped

go.mod

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module blockyserver
2+
3+
go 1.21
4+
5+
require (
6+
github.com/fogleman/fauxgl v0.0.0-20200818143847-27cddc103802
7+
github.com/go-chi/chi/v5 v5.0.12
8+
github.com/qmuntal/gltf v0.28.0
9+
)
10+
11+
require (
12+
github.com/fogleman/simplify v0.0.0-20170216171241-d32f302d5046 // indirect
13+
github.com/hytale-tools/blockymodel-merger v0.3.0
14+
)

go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
github.com/fogleman/fauxgl v0.0.0-20200818143847-27cddc103802 h1:5vdq0jOnV15v1NdZbAcU+dIJ22rFgwaieiFewPvnKCA=
2+
github.com/fogleman/fauxgl v0.0.0-20200818143847-27cddc103802/go.mod h1:7f7F8EvO8MWvDx9sIoloOfZBCKzlWuZV/h3TjpXOO3k=
3+
github.com/fogleman/simplify v0.0.0-20170216171241-d32f302d5046 h1:n3RPbpwXSFT0G8FYslzMUBDO09Ix8/dlqzvUkcJm4Jk=
4+
github.com/fogleman/simplify v0.0.0-20170216171241-d32f302d5046/go.mod h1:KDwyDqFmVUxUmo7tmqXtyaaJMdGon06y8BD2jmh84CQ=
5+
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
6+
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
7+
github.com/go-test/deep v1.0.1 h1:UQhStjbkDClarlmv0am7OXXO4/GaPdCGiUiMTvi28sg=
8+
github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
9+
github.com/hytale-tools/blockymodel-merger v0.3.0 h1:3nsPl8zilJHwckD3S2X8AiMTmPAZc1Kjy/gHAjAmHU4=
10+
github.com/hytale-tools/blockymodel-merger v0.3.0/go.mod h1:T4jzkIZbtC9uSA9kpRx2Lclyc50/kWw2WQLtwRyn4m4=
11+
github.com/qmuntal/gltf v0.28.0 h1:C4A1temWMPtcI2+qNfpfRq8FEJxoBGUN3ZZM8BCc+xU=
12+
github.com/qmuntal/gltf v0.28.0/go.mod h1:YoXZOt0Nc0kIfSKOLZIRoV4FycdC+GzE+3JgiAGYoMs=

0 commit comments

Comments
 (0)