# SynCity: training-free 3D world generation, tile by tile

> SynCity assembles a navigable 3D scene from a text prompt by generating a grid of 2D tiles with Flux, turning each tile into geometry with TRELLIS, and blending the results, with no training or optimization step. The catch is hardware: a single NVIDIA GPU with 48GB of memory, Blender, and a gated Flux checkpoint.

**paulengstler/syncity** — SynCity: Training-Free Generation of 3D Worlds

- Repository: https://github.com/paulengstler/syncity
- Stars: 679 · Forks: 58
- Language: Jupyter Notebook
- License: BSD-3-Clause
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/paulengstler-syncity

## SynCity builds a scene incrementally on a grid instead of in one shot

SynCity is a research codebase from the Visual Geometry Group at the University of Oxford that produces 3D worlds from text prompts without any training or optimization run. The core idea is incremental construction. Rather than asking a single generative model for a whole environment, the pipeline lays out a grid of tiles and fills it one cell at a time. Each cell starts life as a 2D image, and the images that already exist around it act as context so the new tile stays visually consistent with its neighbours. Once the picture exists, it is converted into a 3D model, and the finished tiles are blended at their boundaries so the result can be walked through as one continuous space.

That ordering is the whole point of the project. Text-to-3D systems that render the entire scene in a single pass tend to produce objects that do not connect, repeated furniture, and lighting that changes as you turn. SynCity sidesteps that by controlling coherence locally, one shared edge at a time. The cost is time and hardware rather than model training, since the pretrained Flux image generator and the pretrained TRELLIS 3D generator are used as they ship.

## Flux handles the picture, TRELLIS handles the geometry

Two pretrained models do the heavy lifting and SynCity adds the orchestration. Flux, the 2D image generator, is there for artistic diversity and contextual coherence: it renders the appearance of each tile, and the inpainting server inside the repository lets the pipeline repaint the overlapping border of a new tile so it continues the one already there. TRELLIS, the 3D generator, is the part that produces accurate geometry from the 2D picture. The repository carries TRELLIS as a submodule, so the 3D stage is versioned alongside the rest of the pipeline rather than pulled in at runtime.

The inpainting server is a separate process, not a library call. It is started on its own, it advertises a local URL such as http://127.0.0.1:7860, and that URL is then handed to both the tile generation script and the blending script as the gradio_url argument. This split has a practical consequence: the server has to be up before either stage runs, and if it dies mid-run the pipeline has no way to reach the model. The repository layout also shows helper modules such as tile_cutting.py, blender_script.py and profile.pkl, which points to a pipeline that cuts tiles, profiles the scene, and drives Blender as an external step rather than doing everything inside one Python process.

## The setup needs 48GB of VRAM, Blender and a gated model licence

The prerequisites are the first thing to check, because they rule out most laptops and most cloud instances with a single consumer card. The README states the code was tested on Ubuntu 22.04, that an NVIDIA GPU with at least 48GB of memory is required, and that A40 and A6000 GPUs were used. CUDA 11.8 and 12.4 are the tested toolkit versions, the CUDA Toolkit is needed to compile certain submodules, and Conda creates the environment with Python 3.10. Blender 3.6.19 is required as part of the pipeline.

The installation itself is a short sequence. Clone with submodules so the TRELLIS and other submodules land correctly, then let the setup script build the environment:

```bash
git clone --recurse-submodules https://github.com/paulengstler/syncity.git
cd syncity
```

```bash
source ./setup.sh --new-env --basic --xformers --diffoctreerast --spconv --mipgaussian --kaolin --nvdiffrast
```

The CUDA_HOME environment variable must point at the CUDA Toolkit installation before that setup script runs, and the README points readers to the TRELLIS installation README if the script misbehaves. Next the inpainting server is installed and Blender is downloaded:

```bash
./inpainting_server.sh --install
```

Blender 3.6.19 is extracted into the root of the project, and the binary at blender-3.6.19-linux-x64/blender must be executable. Finally you need a HuggingFace account, you must agree to the terms of black-forest-labs/FLUX.1-dev, and you must run huggingface-cli login. That last step is not optional decoration: without an accepted licence on the gated checkpoint the image stage cannot produce a tile.

## run_pipeline.py generates the tiles, one prompt per cell

Generating a world takes two commands. The first stage reads an instruction file that holds one prompt per tile and produces the 2D images and their 3D conversions. The instruction files are plain JSON, and the repository ships examples in the instructions folder, including a 3x3 set named solarpunk. A generation run looks like this:

```bash
python run_pipeline.py --instructions instructions/3x3/solarpunk.json --prefix scenes/solarpunk --gradio_url=http://127.0.0.1:7860
```

The prefix argument decides where the output is written, so the same command against a different instruction file and prefix yields a different scene without touching the code. Tile generation is parallelised where possible, and the script will use multiple GPUs if they are visible. The README is unusually candid about what to do when that parallel path stalls: if the script hangs for more than a minute, run the generation synchronously with --parallel=False. If one tile keeps being regenerated, interrupt the run, replace that tile's prompt, and restart with --skip_existing=True so the tiles you already accepted are not overwritten. There is also an Advanced Usage section covering the tile rejection criteria, which is where the acceptance thresholds for a generated tile are adjusted.

## blend_gaussians.py stitches the grid into a single ply

The second stage does the geometry work that turns a set of separate tiles into a scene. It creates smooth transitions between neighbouring tiles and refines the boundary regions where the independently generated cells meet:

```bash
python blend_gaussians.py --compute_rescaled --stitch_images --stitch_slats --gradio_url=http://127.0.0.1:7860 --prefix scenes/solarpunk
```

Note that the prefix matches the one used during generation, which is how the two stages refer to the same scene directory. The output is a .ply file holding the Gaussians of the entire grid, plus a video rendering of the result. The presence of --stitch_images and --stitch_slats as separate switches means the two stitching passes are individually controllable, and --compute_rescaled recomputes the rescaled representation before stitching. The pipeline also relies on Blender for part of its work, and blender_script.py plus the extensions directory sit at the top level of the repository, so Blender is a runtime dependency and not merely an optional visualizer.

## Open-space prompts and flat worlds: what actually produces usable tiles

The README closes with a set of practical tips that read like hard-won results rather than documentation boilerplate. Prompts describing free-standing buildings and objects are preferred over room-like prompts, because room prompts tend to push walls onto the edges of a tile, which is exactly where the blending step has to stitch to a neighbour. A restaurant with generous outdoor seating is given as a prompt that works, while a large room inside a restaurant with a long table in the center is given as one that does not. The authors also recommend designing flat worlds: elevation can vary inside a single tile, but carrying a change in elevation across tiles is something the method may struggle with.

Instruction files can be written by hand, since they are simple JSON, or generated by a large language model. The paper results used OpenAI's ChatGPT o3-mini-high, and the initial task prompt is in instructions/prompt.txt, with the expectation that other modern reasoning models work equally well. Each tile also uses a different seed, so repeating the same prompt gives a different result. Those two tools, rewriting a prompt and changing the seed, are the practical workaround for a stubborn tile when restarting the pipeline is not worth the time.

## No releases, no homepage, and a pipeline with several fragile seams

SynCity ships as research code rather than a packaged product. The repository has no GitHub releases, so there is no versioned artefact to install and no upgrade path beyond tracking the main branch, and the last push was on 2026-07-07. The project page is hosted separately from the repository and the repository itself carries no homepage field.

The failure modes follow the architecture. A 48GB GPU requirement means a single RTX-class consumer card is not enough, and the README does not document a CPU or low-memory fallback. The inpainting server is a separate process whose local URL has to be threaded into two different commands, so a server restart mid-session means re-reading that URL. Blender must be extracted into the repository root with the exact directory layout the script expects, and the instructions remain silent on what happens when the path differs. The README also does not document a rollback procedure, headless rendering instructions beyond the pipeline calls, or a documented way to adjust the 48GB memory floor.

On licensing, the repository is BSD-3-Clause, which is permissive and imposes obligations on redistribution rather than on use, while the FLUX.1-dev checkpoint you must accept carries its own separate terms on the HuggingFace side. Those are two distinct licensing layers, and a team planning to ship generated worlds as a product needs to read both before assuming the code licence answers everything.

## Conclusion

SynCity suits research groups with a 48GB NVIDIA GPU, a Linux workstation and time to iterate on tile prompts, and it is the wrong tool for a team that needs a stable asset pipeline on a single consumer card. Before adopting it, verify that your driver and CUDA version match the tested ones, that the Blender binary path resolves inside the repository root, that you can accept the FLUX.1-dev terms, and that you are willing to hand-edit instruction JSON when a tile keeps getting regenerated.

## FAQ

### What hardware does SynCity need to generate a 3D world?

The README states that an NVIDIA GPU with at least 48GB of memory is required, and that A40 and A6000 GPUs were used. The code was tested on Ubuntu 22.04 with CUDA 11.8 and 12.4. No lower-memory option is documented.

### How do I run SynCity for the first time?

Clone the repository with --recurse-submodules, source setup.sh with the listed flags, install the inpainting server with ./inpainting_server.sh --install, place Blender 3.6.19 in the repository root, then start the server with ./inpainting_server.sh --run and pass its local URL to run_pipeline.py.

### Do I need a HuggingFace account to use SynCity?

Yes. The README asks you to create a HuggingFace account, agree to the terms and conditions of black-forest-labs/FLUX.1-dev, and run huggingface-cli login, because the Flux image generator is a gated checkpoint.

### What does SynCity produce as output files?

The blending stage creates a .ply file containing the Gaussians of the entire grid, along with a video rendering of the scene. Tiles and their 3D versions are written under the directory given by the --prefix argument.

### Why does one tile keep being regenerated during SynCity runs?

The README treats this as a prompt problem rather than a crash. It suggests interrupting the script, replacing the offending tile's prompt, and restarting with --skip_existing=True so the accepted tiles are preserved. The tile rejection criteria can also be adjusted in the Advanced Usage section.

## Sources

- [Issues](https://github.com/paulengstler/syncity/issues)
- [License: BSD-3-Clause](https://github.com/paulengstler/syncity/blob/main/LICENSE)
- [paulengstler/syncity on GitHub](https://github.com/paulengstler/syncity)
- [README](https://github.com/paulengstler/syncity/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/paulengstler-syncity
