diff --git a/README.rst b/README.rst index 6bf8047..e46c711 100644 --- a/README.rst +++ b/README.rst @@ -3,63 +3,41 @@ Minecraft Overviewer ==================== By Andrew Brown and contributors (see CONTRIBUTORS.rst). -http://github.com/overviewer/Minecraft-Overviewer +Documentation: + http://docs.overviewer.org -Generates large resolution images of a Minecraft map. +Github code repository: + http://github.com/overviewer/Minecraft-Overviewer -In short, this program reads in Minecraft world files and renders very large -resolution images that can be viewed through a Google Maps interface. It -performs a similar function to the existing Minecraft Cartographer program but -with a slightly different goal in mind: to generate large resolution images -such that one can zoom in and see details. -See some examples here! -http://github.com/overviewer/Minecraft-Overviewer/wiki/Map-examples +The Minecraft Overviewer is a command-line tool for rendering high-resolution +maps of Minecraft worlds. It generates a set of static html and image files and +uses the Google Maps API to display a nice interactive map. -Further documentation may be found at -https://github.com/overviewer/Minecraft-Overviewer/wiki/Documentation +The Overviewer has been in active development for over a year and has many +features, including day and night lighting, cave rendering, mineral overlays, +and many plugins for even more features! It is written mostly in Python with +critical sections in C as an extension module. -To contact the developers and other users, go to the site at the top of this -README, or go to #overviewer on irc.freenode.net. +Getting Started +--------------- +All documentation has been consolidated at our documentation site. For +information on downloading, compiling, installing, and running The Overviewer, +visit the docs site. -Features -======== +http://docs.overviewer.org -* Renders large resolution images of your world, such that you can zoom in and - see details +A few helpful tips are below, but everyone is going to want to visit the +documentation site for the most up-to-date and complete set of instructions! -* Customizable textures! Pulls textures straight from your installed texture - pack! +Alternatively, the docs are also in the docs/ directory of the source download. +Look in there if you can't access the docs site. -* Outputs a Google Map powered interface that is memory efficient, both in - generating and viewing. +Examples +-------- +See examples of The Overviewer in action! -* Renders efficiently in parallel, using as many simultaneous processes as you - want! - -* Utilizes caching to speed up subsequent renderings of your world. - -* Throw the output directory up on a web server to share your Minecraft world - with everyone! - -Requirements -============ -This program requires: - -* Python 2.6 or 2.7 -* PIL (Python Imaging Library) -* Numpy -* Either the Minecraft client installed, or a terrain.png file. See the - `Textures`_ section below. -* A C compiler. - -If you download a binary package, then some or all of these may not be required. - -Using the Overviewer -==================== - -For a quick-start guide, see -https://github.com/overviewer/Minecraft-Overviewer/wiki/Quick-Start-Guide +https://github.com/overviewer/Minecraft-Overviewer/wiki/Map-examples Disclaimers ----------- @@ -78,204 +56,6 @@ directory and it will only update the tiles it needs to. There are probably some other minor glitches along the way, hopefully they will be fixed soon. See the `Bugs`_ section below. -Textures --------- -The Overviewer uses actual textures to render your world. However, I don't -include textures in the package. You will need to do one of two things before -you can use the Overviewer: - -* Make sure the Minecraft client is installed. The Overviewer will find the - installed minecraft.jar and extract the textures from it. - -* Install a texture file yourself. This file is called "terrain.png" and is - normally found in your minecraft.jar file (not "Minecraft.jar", the launcher, - but rather the file that's downloaded by the launcher and installed into a - hidden directory). You can also get this file from any of the third party - texture packs out there. - -Biome Tinting -------------- -With the Halloween update, biomes were added to Minecraft. In order to get -biome-accurate tinting, the Overviewer can use biome data produced by the -Minecraft Biome Extractor tool. This tool can be downloaded from: -http://www.minecraftforum.net/viewtopic.php?f=25&t=80902 - -If the "biomes" folder is present in the world directory, then the Overviewer -will use the biome data to tint grass and leaves automatically -- there is no -command line option to turn this feature on. If this folder does not exist, -then the Overviewer will use a static tinting for grass and leaves. - -Compiling the C Extension -------------------------- -The C Extension for Overviewer is no longer optional. In addition to -providing a higher quality image compositing function that looks better on -maps with lighting enabled, it now does the bulk of the rendering. - -If you downloaded Overviewer as a binary package, this extension will already -be compiled for you. - -If you have a C compiler and the Python development libraries set up, you can -compile this extension like this:: - - python setup.py build - -Note that you need the development headers for your version of Python installed, -look for a package named 'python-dev', 'python-devel' or similar. Also, some -Python distributions do not install "Imaging.h" and "ImPlatform.h" properly. If -you get errors complaining about them, you can get them from the PIL source, or -at . Just put them in -the same directory as "overviewer.py". - -For more detailed instructions, check the wiki: -https://github.com/overviewer/Minecraft-Overviewer/wiki/Build-Instructions - -Running -------- -To generate a set of Google Map tiles, use the overviewer.py script like this:: - - python overviewer.py [OPTIONS] - -The output directory will be created if it doesn't exist. This will generate a -set of image tiles for your world in the directory you choose. When it's done, -you will find an index.html file in the same directory that you can use to view -it. - - -Options -------- - --h, --help - Shows the list of options and exits - ---advanced-help - Display help - including advanced options - --p PROCS, --processes=PROCS - Adding the "-p" option will utilize more cores during processing. This - can speed up rendering quite a bit. The default is set to the same - number of cores in your computer, but you can adjust it. - - Example to run 5 worker processes in parallel:: - - python overviewer.py -p 5 - --d, --delete - This option changes the mode of execution. No tiles are rendered, and - instead, files are deleted. - - *Note*: Currently only the overviewer.dat file is deleted when you run with - this option - ---forcerender - Force re-rendering the entire map (or the given regionlist). This - is an easier way to completely re-render without deleting the map. - ---regionlist=regionlist - Use this option to specify manually a list of regions to consider for - updating. Without this option, every chunk in every region is checked for - update and if necessary, re-rendered. If this option points to a file - containing, 1 per line, the path to a region data file, then only those - in the list will be considered for update. - - It's up to you to build such a list. On Linux or Mac, try using the "find" - command. You could, for example, output all region files that are older than - a certain date. Or perhaps you can incrementally update your map by passing - in a subset of regions each time. It's up to you! - ---rendermodes=MODE1[,MODE2,...] - Use this option to specify which render mode to use, such as lighting or - night. Use --list-rendermodes to get a list of available rendermodes, and - a short description of each. If you provide more than one mode (separated - by commas), Overviewer will render all of them at once, and provide a - toggle on the resulting map to switch between them. - - If for some reason commas do not work for your shell (like if you're using - Powershell on Windows), you can also use a colon ':' or a forward slash '/' - to separate the modes. - ---list-rendermodes - List the available render modes, and a short description of each. - ---north-direction=NORTH_DIRECTION - Specifies which corner of the screen north will point to. - Valid options are: lower-left, upper-left, upper-right, lower-right. - If you do not specify this option, it will default to whatever direction - the existing map uses. For new maps, it defaults to lower-left for - historical reasons. - ---settings=PATH - Use this option to load settings from a file. The format of this file is - given below. - - -Settings --------- - -You can optionally store settings in a file named settings.py (or really, -anything you want). It is a regular python script, so you can use any python -functions or modules you want. To use a settings file, use the --settings -command line option. - -For a sample settings file, look at 'sample.settings.py'. Note that this file -is not meant to be used directly, but instead it should be used as a -collection of examples to guide writing your own. - -Here's a (possibly incomplete) list of available settings, which are available -in settings.py. Note that you can also set command-line options in a similar -way. - -imgformat=FORMAT - Set the output image format used for the tiles. The default is 'png', - but 'jpg' is also supported. - -zoom=ZOOM - The Overviewer by default will detect how many zoom levels are required - to show your entire map. This option sets it manually. - - *You do not normally need to set this option!* - - This is equivalent to setting the dimensions of the highest zoom level. It - does not actually change how the map is rendered, but rather *how much of - the map is rendered.* Setting this option too low *will crop your map.* - (Calling this option "zoom" may be a bit misleading, I know) - - To be precise, it sets the width and height of the highest zoom level, in - tiles. A zoom level of z means the highest zoom level of your map will be - 2^z by 2^z tiles. - - This option map be useful if you have some outlier chunks causing your map - to be too large, or you want to render a smaller portion of your map, - instead of rendering everything. - - Remember that each additional zoom level adds 4 times as many tiles as - the last. This can add up fast, zoom level 10 has over a million tiles. - Tiles with no content will not be rendered, but they still take a small - amount of time to process. - -web_assets_hook - This option lets you define a function to run after the web assets have - been copied into the output directory, but before any tile rendering takes - place. This is an ideal time to do any custom postprocessing for - markers.js or other web assets. - - This function should accept one argument: a QuadtreeGen object. - -web_assets_path - This option lets you provide alternative web assets to use when - rendering. The contents of this folder will be copied into the output folder - during render, and will overwrite any default files already copied by - Overviewer. See the web_assets folder included with Overviewer for the - default assets. - -textures_path - This is like web_assets_path, but instead it provides an alternative texture - source. Overviewer looks in here for terrain.png and other textures before - it looks anywhere else. - -north_direction - Specifies which corner of the screen north will point to. - Valid options are: lower-left, upper-left, upper-right, lower-right. - Viewing the Results ------------------- Within the output directory you will find two things: an index.html file, and a @@ -290,44 +70,12 @@ however, bound by the Google Maps API terms of service. http://code.google.com/apis/maps/terms.html -Crushing the Output Tiles -------------------------- -Image files taking too much disk space? Try using pngcrush. On Linux and -probably Mac, if you have pngcrush installed, this command will go and crush -all your images in the given destination. This took the total disk usage of the -render for my world from 85M to 67M. - -:: - - find /path/to/destination -name "*.png" -exec pngcrush {} {}.crush \; -exec mv {}.crush {} \; - -Or if you prefer a more parallel solution, try something like this:: - - find /path/to/destination -print0 | xargs -0 -n 1 -P sh -c 'pngcrush $0 temp.$$ && mv temp.$$ $0' - -If you're on Windows, I've gotten word that this command line snippet works -provided pngout is installed and on your path. Note that the % symbols will -need to be doubled up if this is in a batch file. - -:: - - FOR /R c:\path\to\tiles\folder %v IN (*.png) DO pngout %v /y - Bugs ==== -This program has bugs. They are mostly minor things, I wouldn't have released a -completely useless program. However, there are a number of things that I want -to fix or improve. For a current list of issues, visit -http://github.com/overviewer/Minecraft-Overviewer/issues +https://github.com/overviewer/Minecraft-Overviewer/issues Feel free to comment on issues, report new issues, and vote on issues that are -important to you, so I can prioritize accordingly. - -An incomplete list of things I want to do soon is: - -* Improve efficiency - -* Some kind of graphical interface. +important to you. diff --git a/contrib/clearOldCache.py b/contrib/clearOldCache.py index a7000e1..03650ce 100644 --- a/contrib/clearOldCache.py +++ b/contrib/clearOldCache.py @@ -18,7 +18,8 @@ import re import os.path # incantation to be able to import overviewer_core -sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) +if not hasattr(sys, "frozen"): + sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) from overviewer_core import world from overviewer import list_worlds diff --git a/contrib/findSigns.py b/contrib/findSigns.py index 2dbacd8..8961365 100644 --- a/contrib/findSigns.py +++ b/contrib/findSigns.py @@ -30,7 +30,8 @@ import os import cPickle # incantation to be able to import overviewer_core -sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) +if not hasattr(sys, "frozen"): + sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) from overviewer_core import nbt diff --git a/contrib/playerInspect.py b/contrib/playerInspect.py index cf12ee3..638e1b0 100644 --- a/contrib/playerInspect.py +++ b/contrib/playerInspect.py @@ -5,7 +5,8 @@ Very basic player.dat inspection script import sys, os # incantation to be able to import overviewer_core -sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) +if not hasattr(sys, "frozen"): + sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) from overviewer_core.nbt import load from overviewer_core import items diff --git a/contrib/rerenderBlocks.py b/contrib/rerenderBlocks.py index 7dde88d..56f6bcf 100644 --- a/contrib/rerenderBlocks.py +++ b/contrib/rerenderBlocks.py @@ -21,7 +21,8 @@ import sys,os import re # incantation to be able to import overviewer_core -sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) +if not hasattr(sys, "frozen"): + sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) from overviewer_core import nbt from overviewer_core import world diff --git a/contrib/validateRegionFile.py b/contrib/validateRegionFile.py index c723734..75b6a87 100644 --- a/contrib/validateRegionFile.py +++ b/contrib/validateRegionFile.py @@ -9,7 +9,8 @@ import os import sys # incantation to be able to import overviewer_core -sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) +if not hasattr(sys, "frozen"): + sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '..'))) from overviewer_core import nbt diff --git a/contribManager.py b/contribManager.py index 29737eb..00f3a09 100755 --- a/contribManager.py +++ b/contribManager.py @@ -8,7 +8,8 @@ import os.path import ast # incantation to be able to import overviewer_core -sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '.'))) +if not hasattr(sys, "frozen"): + sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0], '.'))) from overviewer_core import nbt diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..e1e0086 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,132 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +default: html + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Overviewer.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Overviewer.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Overviewer" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Overviewer" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + make -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/building.rst b/docs/building.rst new file mode 100644 index 0000000..21f4371 --- /dev/null +++ b/docs/building.rst @@ -0,0 +1,161 @@ +=================================== +Building the Overviewer from Source +=================================== + +These instructions are for building the C extension for Overviewer. Also note +that pre-built Windows and Debian executables are available in the `Downloads +`_ section. These +kits already contain the compiled extension and require no further setup (so you +can skip to the :doc:`Running ` section of the docs). + +Get The Source +============== +First step: download the source! Either clone with Git or download the most recent snapshot + +* URL to clone: ``git://github.com/overviewer/Minecraft-Overviewer.git`` +* `Download most recent tar archive `_ + +* `Download most recent zip archive `_ + +Build Instructions For Various Operating Systems +================================================ + +.. contents:: + :local: + +Windows Build Instructions +-------------------------- + +First, you'll need a compiler. You can either use Visual Studio, or +cygwin/mingw. The free `Visual Studio Express +`_ is okay. You will want the C++ +version (Microsoft® Visual C++® 2010 Express). Note that the Express version of +Visual Studio will only build 32-bit executables. We currently don't have a +recommended way of building Overviewer on 64-bit Windows using free tools. If you +have bought a copy of Visual Studio, you can use it for 64-bit builds. + + +Prerequisits +~~~~~~~~~~~~ + +You will need a copy of the `PIL sources `_. + +Building with Visual Studio +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Get the latest Overviewer source code as per above. +2. From the Start menu, navigate to the 'Microsoft Visual Studio 2010 Express' and open the 'Visual Studio Command Prompt (2010)' shortcut. +3. cd to the folder containing the Overviewer source code. +4. Copy Imaging.h and ImPlatform.h from your PIL installation into the current working directory. +5. First try a build:: + + c:\python26\python setup.py build + +If you encounter the following errors:: + + error: Unable to find vcvarsall.bat + +then try the following:: + + set DISTUTILS_USE_SDK=1 + set MSSdk=1 + c:\python26\python setup.py build + +If the build was successful, there should be a c_overviewer.pyd file in your current working directory. + +Building with mingw +~~~~~~~~~~~~~~~~~~~ + +1. Open a MinGW shell. +2. cd to the Overviewer directory. +3. Copy Imaging.h and ImPlatform.h from your PIL installation into the current working directory. +4. Build:: + + python setup.py build --compiler=mingw32 + + +Linux +----- + +You will need the gcc compiler and a working build environment. On Ubuntu and +Debian, this can be done by installing the ``build-essential`` package. For +CentOS machines, see the :ref:`centos` section below + +You will need the following packages (at least): + +* python-imaging (for PIL) +* python-dev +* python-numpy + +Then to build:: + + python setup.py build + +OSX +--- + +1. Download the source code for PIL from http://www.pythonware.com/products/pil/ +2. Compile the PIL code (``python ./setup.py build``) +3. Install PIL (``sudo python ./setup.py install``) +4. Find the path to libImaging in the PIL source tree +5. Build Minecraft Overviewer with the path from step 3 as the value for C_INCLUDE_PATH:: + + C_INCLUDE_PATH="path from step 3" python ./setup.py build + +The following script (copied into your MCO source directory) should handle everything for you: + +.. code-block:: bash + + #!/bin/bash + + # start with a clean place to work + python ./setup.py clean + + # get PIL + if [ ! -d "`pwd`/Imaging-1.1.7/libImaging" ]; then + /usr/bin/curl -o imaging.tgz http://effbot.org/media/downloads/Imaging-1.1.7.tar.gz + tar xzf imaging.tgz + rm imaging.tgz + fi + + # build MCO + C_INCLUDE_PATH="`pwd`/Imaging-1.1.7/libImaging" python ./setup.py build + +.. _centos: + +CentOS +------ +Since CentOS has an older version of Python (2.4), there are some difficulties +in getting the Overviewer to work. Follow these steps which have been reported +to work. + +Note: commands prefixed with a "#" mean to run as root, and "$" mean to run as a +regular user. + +1. Install the `EPEL repo `_. Go to step #2 if you already have the EPEL repo installed. + + 1. ``$ wget http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm`` + 2. ``# rpm -Uhv epel-release-5-4.noarch.rpm`` + +2. Install the python26 packages and build dependancies + + 1. ``# yum groupinstall -y 'Development Tools'`` + 2. ``# yum install -y python26{,-imaging,-numpy}{,-devel}`` + +3. Install and setup Overviewer + + 1. ``$ git clone git://github.com/overviewer/Minecraft-Overviewer.git`` + 2. ``$ cd Minecraft-Overviewer`` + 3. ``$ python26 setup.py build`` + 4. Change the first line of overviewer.py from ``#!/usr/bin/env python`` to ``#!/usr/bin/env python26`` so that the Python 2.6 interpreter is used instead of the default 2.4 + +4. Run Overviewer as usual + + 1. ``$ ./overviewer.py path/to/world/ path/to/output/`` or ``$ python26 path/to/overviewer.py path/to/world/ path/to/output/`` + 2. Proceed to the :doc:`Running ` instructions for more info. + + +Installing the Compiled Code +---------------------------- +You can run the ``overviewer.py`` script from the build directory just fine. If +you'd like to install, run ``python setup.py install`` diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..ba5b27e --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +# +# Overviewer documentation build configuration file, created by +# sphinx-quickstart on Thu Sep 22 10:19:03 2011. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('..')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Overviewer' +copyright = u'2010-2011 the Overviewer Team' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = "0.3" +# The full version, including alpha/beta/rc tags. +release = "0.3.0" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Overviewerdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'Overviewer.tex', u'Overviewer Documentation', + u'The Overviewer Team', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'overviewer', u'Overviewer Documentation', + [u'The Overviewer Team'], 1) +] diff --git a/docs/design/cube_parts.png b/docs/design/cube_parts.png new file mode 100644 index 0000000..d012e0e Binary files /dev/null and b/docs/design/cube_parts.png differ diff --git a/docs/design/cube_parts.svg b/docs/design/cube_parts.svg new file mode 100644 index 0000000..ab7eb8c --- /dev/null +++ b/docs/design/cube_parts.svg @@ -0,0 +1,433 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 24 + 24 + + + + + + + + + 25 + + + + + + diff --git a/docs/design/cube_sides.png b/docs/design/cube_sides.png new file mode 100644 index 0000000..d79c443 Binary files /dev/null and b/docs/design/cube_sides.png differ diff --git a/docs/design/cube_top.png b/docs/design/cube_top.png new file mode 100644 index 0000000..8e527e0 Binary files /dev/null and b/docs/design/cube_top.png differ diff --git a/docs/design/cubepositionimgs/cube_horizontal_offset.png b/docs/design/cubepositionimgs/cube_horizontal_offset.png new file mode 100644 index 0000000..74893d3 Binary files /dev/null and b/docs/design/cubepositionimgs/cube_horizontal_offset.png differ diff --git a/docs/design/cubepositionimgs/cube_horizontal_offset.svg b/docs/design/cubepositionimgs/cube_horizontal_offset.svg new file mode 100644 index 0000000..c3790fc --- /dev/null +++ b/docs/design/cubepositionimgs/cube_horizontal_offset.svg @@ -0,0 +1,286 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + 24 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 + + + + + + + + diff --git a/docs/design/cubepositionimgs/cube_measurements.png b/docs/design/cubepositionimgs/cube_measurements.png new file mode 100644 index 0000000..973a10e Binary files /dev/null and b/docs/design/cubepositionimgs/cube_measurements.png differ diff --git a/docs/design/cubepositionimgs/cube_measurements.svg b/docs/design/cubepositionimgs/cube_measurements.svg new file mode 100644 index 0000000..4c48fa1 --- /dev/null +++ b/docs/design/cubepositionimgs/cube_measurements.svg @@ -0,0 +1,418 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + 24 + 24 + + + + + + + + + 6 + 12 + 6 + + + + + + + + + + + + + + + + + + 12 + + + + + 12 + + + 12 + + + + + 12 + + + + diff --git a/docs/design/cubepositionimgs/cube_neighbors.png b/docs/design/cubepositionimgs/cube_neighbors.png new file mode 100644 index 0000000..fd69adf Binary files /dev/null and b/docs/design/cubepositionimgs/cube_neighbors.png differ diff --git a/docs/design/cubepositionimgs/cube_neighbors.svg b/docs/design/cubepositionimgs/cube_neighbors.svg new file mode 100644 index 0000000..e376fd5 --- /dev/null +++ b/docs/design/cubepositionimgs/cube_neighbors.svg @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + 12 + + 6 + + diff --git a/docs/design/cubepositionimgs/cube_stacking.png b/docs/design/cubepositionimgs/cube_stacking.png new file mode 100644 index 0000000..ae0fbaa Binary files /dev/null and b/docs/design/cubepositionimgs/cube_stacking.png differ diff --git a/docs/design/cubepositionimgs/cube_stacking.svg b/docs/design/cubepositionimgs/cube_stacking.svg new file mode 100644 index 0000000..2571a4d --- /dev/null +++ b/docs/design/cubepositionimgs/cube_stacking.svg @@ -0,0 +1,183 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/design/cuberenderimgs/chunk_height.png b/docs/design/cuberenderimgs/chunk_height.png new file mode 100644 index 0000000..8b4257d Binary files /dev/null and b/docs/design/cuberenderimgs/chunk_height.png differ diff --git a/docs/design/cuberenderimgs/chunk_height.svg b/docs/design/cuberenderimgs/chunk_height.svg new file mode 100644 index 0000000..532e06c --- /dev/null +++ b/docs/design/cuberenderimgs/chunk_height.svg @@ -0,0 +1,4240 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + 1524 + + 1704 + + + + + + 1728 + + diff --git a/docs/design/cuberenderimgs/chunk_perspective.png b/docs/design/cuberenderimgs/chunk_perspective.png new file mode 100644 index 0000000..8139928 Binary files /dev/null and b/docs/design/cuberenderimgs/chunk_perspective.png differ diff --git a/docs/design/cuberenderimgs/chunk_perspective.svg b/docs/design/cuberenderimgs/chunk_perspective.svg new file mode 100644 index 0000000..c6baf79 --- /dev/null +++ b/docs/design/cuberenderimgs/chunk_perspective.svg @@ -0,0 +1,2104 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/design/cuberenderimgs/chunk_topdown.png b/docs/design/cuberenderimgs/chunk_topdown.png new file mode 100644 index 0000000..33bb83f Binary files /dev/null and b/docs/design/cuberenderimgs/chunk_topdown.png differ diff --git a/docs/design/cuberenderimgs/chunk_topdown.svg b/docs/design/cuberenderimgs/chunk_topdown.svg new file mode 100644 index 0000000..e21cfe4 --- /dev/null +++ b/docs/design/cuberenderimgs/chunk_topdown.svg @@ -0,0 +1,1869 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/design/cuberenderimgs/chunk_width.png b/docs/design/cuberenderimgs/chunk_width.png new file mode 100644 index 0000000..e27bcc8 Binary files /dev/null and b/docs/design/cuberenderimgs/chunk_width.png differ diff --git a/docs/design/cuberenderimgs/chunk_width.svg b/docs/design/cuberenderimgs/chunk_width.svg new file mode 100644 index 0000000..5521ba1 --- /dev/null +++ b/docs/design/cuberenderimgs/chunk_width.svg @@ -0,0 +1,2210 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 24 + + + + + 24 + + + + 24*16=384 + + + + + + + + + + + + + + + + + + + + diff --git a/docs/design/cuberenderimgs/cube_stack128.png b/docs/design/cuberenderimgs/cube_stack128.png new file mode 100644 index 0000000..03c8c3a Binary files /dev/null and b/docs/design/cuberenderimgs/cube_stack128.png differ diff --git a/docs/design/cuberenderimgs/cube_stack128.svg b/docs/design/cuberenderimgs/cube_stack128.svg new file mode 100644 index 0000000..8624a16 --- /dev/null +++ b/docs/design/cuberenderimgs/cube_stack128.svg @@ -0,0 +1,490 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Y Offset + + 0 + 12 + 24 + Block # + + 0 + 1 + 2 + 127 + 126 + 125 + 1500 + 1512 + 1524 + 12*128=1536 + + + + + + diff --git a/docs/design/designdoc.rst b/docs/design/designdoc.rst new file mode 100644 index 0000000..e6a7ef7 --- /dev/null +++ b/docs/design/designdoc.rst @@ -0,0 +1,364 @@ +==================== +Design Documentation +==================== +So you'd like a technical overview of how The Overviewer works, huh? You've come +to the right place! + +This document's scope does not cover the details of the code. The code is fairly +well commented and not difficult to understand. Instead, this document is +intended to give an explanation to how the Overviewer was designed, why certain +decisions were made, and how all the pieces fit together. Think of this document +as commenting on how all the high level pieces of the code work. + +This document is probably a good read to anyone that wants to get involved in +Overviewer development. + +So let's get started! + +.. note:: + + This page is still under construction + +.. contents:: + +Background Info +=============== +The Overviewer's task is to take Minecraft worlds and render them into a set of tiles that can be displayed with a Google Maps interface. + +A Minecraft world extends indefinitely along the two horizontal axes, and are +exactly 128 units high. Minecraft worlds are made of cubes, where each slot in +the world's grid has a type that determines what it is (grass, stone, ...). +This makes worlds relatively uncomplicated to render, the Overviewer simply +determines what cubes to draw and where. Since everything in Minecraft is +aligned to a strict grid, placement and rendering decisions are completely +deterministic and can be performed in an iterative fashon. + +The coordinate system for Minecraft has three axes. The X and Z axes are the +horizontal axes. They extend indefinitely towards both positive and negative +infinity. (There are practical limits, but no theoretical limits). The Y axis +extends from 0 to 127, which corresponds with the world height limit. Each +block in Minecraft has a coordinate address, e.g. the block at 15,78,-35 refers +to 15 along the X axis, -35 along the Z axis, and 78 units up from bedrock. + +The world is divided up into *chunks*. A chunk is a 16 by 16 area of the world +that extends from bedrock to sky. In other words, a 16,128,16 "chunk" of the +world. Chunks also have an address, but in only 2 dimensions. To find the which +chunk a block is in, simply divide its X and Z coordinates by 16 and take the +floor. + +Minecraft worlds are generated on-the-fly by the chunk. This means not all +chunks will exist. There is no pattern to chunk generation, the game simply +generates them as needed. + +Chunks are stored on-disk in region files. A Minecraft region is a "region" of +32 by 32 chunks. Regions have their own address, and for a particular chunk one +can find its region by dividing its coordinates by 32 and taking the floor. A +region may contain all 1024 of its chunks, or only a subset of them, since not +all chunks may exist. The absence of a region file indicates none of its chunks +exist. + +About the Rendering +=================== + +Minecraft worlds are rendered in an approximated Isometric projection at an +oblique angle. In the original design, the projection acts as if your eye is +infinitely far away looking down at the world at a 45 degree angle in the +South-East direction (now, the world can be rendered at any of the 4 oblique +directions). + +.. image:: screenshot.png + :alt: A screenshot of Overviewer output + +In order to render a Minecraft world, there are a few steps that need to happen. +These steps are explained in detail in the next few sections. + +1. Render each block +2. Render the chunks from the blocks +3. Render the tiles of the map from the chunks +4. Shrink and combine the tiles for the other zoom levels + +Block Rendering +=============== +.. This section shows how each block is pre-rendered + +The first step is rendering the blocks from the textures. Each block is "built" +from its textures into an image of a cube and cached in global variables of the +:mod:`textures` module. + +Textures come in the size 16 by 16 (higher resolution textures are resized and +the process remains the same). In order to render a cube out of this, an `affine +transformation`_ is applied to the texture in order to transform it to the top, +left, and right faces of the cube. + +.. image:: texturecubing.png + :alt: A texture gets rendered into a cube + +.. _affine transformation: http://en.wikipedia.org/wiki/Affine_transformation + +The result is an image of a cube that is 24 by 24 pixels in size. This +particular size for the cubes was chosen for an important reason: 24 is +divisible by 2 and by 4. This makes placement much easier. E.g. in order to draw +two cubes that are next to each other in the world, one is drawn exactly 12 +pixels over and 6 pixels down from the other. All placements of the cubes happen +on exact pixel boundaries and no further resolution is lost beyond the initial +transformations. + +The transformation happens in two stages. First, the texture is transformed for +the top of the cube. Then the texture is transformed for the left side of the +cube, which is mirrored for the right side of the cube. + +Top Transformation +------------------ + +The transformation for the top face of the cube is a simple `affine +transformation`_ from the original square texture. It is actually several affine +transformations: a re-size, a rotation, and a scaling; but since multiple affine +transformations can be chained together simply by multiplying the transformation +matrices together, only one transformation is actually done. + +This can be seen in the function :func:`textures.transform_image`. It takes +these steps: + +1. The texture is re-sized to 17 by 17 pixels. This is done because the diagonal + of a square with sides 17 is approximately 24, which is the target size for + the bounding box of the cube image. So when it's rotated, it will be the + correct width. + +2. The image is rotated 45 degrees about its center. + +3. The image is scaled on the vertical axis by a factor of 1/2. + +This produces an image of size 24 by 12 as seen in the following sequence. + +.. image:: texturetopsteps.png + :alt: The 4 steps for transforming a texture square into the top of the cube. + +The final image, shown below, becomes the top of the cube. + +.. image:: cube_top.png + :alt: Top of the cube + +On the left is what will become the top of the block at actual size after the +transformation, the right is the same but blown up by a factor of 10 with no +interpolation to show the pixels. + +Side Transformation +------------------- + +The texture square is transformed for the sides of the cube in the +:func:`textures.transform_image_side` function. This is another `affine +transformation`_, but this time only two transformations are done: a re-size and +a shear. + +1. First the texture is re-sized to 12 by 12 pixels. This is half the width of + 24 so it will have the correct width after the shear. + +2. The 12 by 12 square is sheared by a factor of 1.5 in the Y direction, + producing an image that is bounded by a 12 by 18 pixel square. + +.. image:: texturesidesteps.png + :alt: Texture being sheared for the side of the cube. + +This image is simply flipped along the horizontal axis for the other visible +side of the cube. + +.. image:: cube_sides.png + :alt: The sides of the block + +Again, shown on the left are the two sides of the block at actual size, the +right is scaled with no interpolation by a factor of 10 to show the pixels. + +An Entire Cube +-------------- +These three images, the top and two sides, are pasted into a single 24 by 24 +pixel image to get the cube, as shown. + +However, notice from the middle of the three images in the sequence below that +the images as transformed don't fit together exactly. There is some overlap when +put in the 24 by 24 box in which they must fit. + +.. image:: cube_parts.png + :alt: How the cube parts fit together + +There is one more complication. The cubes don't tessellate perfectly. This +diagram illustrates when a cube is positioned next to another. The lower cubes +are 18 pixels lower and 12 pixels to either side, which is half the width and +3/4 the height respectively. + +.. image:: tessellation.png + :alt: Cubes don't tessellate perfectly + +The solution is to manually touch up those 6 pixels. 3 pixels are added on the +upper left of each cube, 3 on the lower right. Therefore, they all line up +perfectly! + +This is done at the end of :func:`textures._build_block` + +.. image:: pixelfix.png + :alt: The 6 pixels manually added to each cube. + +Other Cube Types +---------------- +Many block types are not rendered as cubes. Fences, rails, doors, torches, and +many other types of blocks have custom rendering routines. + +Chunk Rendering +=============== + +So now that each type of cube is rendered and cached in global variables within +the :mod:`textures` module, the next step is to use the data from a chunk of +the world to arrange these cubes on an image, rendering an entire chunk. + +How big is a chunk going to be? A chunk is 16 by 16 blocks across, 128 blocks +high. The diagonal of a 16 by 16 grid is 16 squares. Observe. + +This is the top-down view of a single chunk. It is essentially a 16 by 16 grid, +extending 128 units into the page. + +.. image:: cuberenderimgs/chunk_topdown.png + :alt: A 16x16 square grid + +Rendered at the appropriate perspective, we'll have something like this +(continued down for 128 layers). + +.. image:: cuberenderimgs/chunk_perspective.png + :alt: Perspective rendering of the two top layers of a chunk. + +Each of those cubes shown is where one of the pre-rendered cubes gets pasted. +This happens from back to front, bottom to top, so that the chunk gets drawn +correctly. Obviously if a cube in the back is pasted on the image after the +cubes in the front, it will be drawn on top of everything. + +Cube Positioning +---------------- +A single cube is drawn in a 24 by 24 square. Before we can construct a chunk out +of individual cubes, we must figure out how to position neighboring cubes. + +First, to review, these are the measurements of a cube: + +.. image:: cubepositionimgs/cube_measurements.png + :alt: The measurements of a cube + +* The cube is bounded by a 24 by 24 pixel square. + +* The side vertical edges are 12 pixels high. + +* The top (and bottom) face of the cube takes 12 vertical pixels (and 24 + horizontal pixels). + +* The edges of the top and bottom of the cube take up 6 vertical pixels and 12 + horizontal pixels each. + +Two cubes that are neighbors after projection to the image (diagonally +neighboring in the world) have a horizontal offset of 24 pixels from each other, +as shown below on the left. This is mostly trivial, since the images don't end +up overlapping at all. Two cubes in the same configuration but rotated 90 +degrees have some overlap in the image, and are only vertically offset by 12 +pixels, as shown on the right. + +.. image:: cubepositionimgs/cube_horizontal_offset.png + :alt: Two cubes horizontally positioned are offset by 24 pixels on the X axis. + +Now for something slightly less trivial: two cubes that are stacked on top of +each other in the world. One is rendered lower on the vertical axis of the +image, but by how much? + +.. image:: cubepositionimgs/cube_stacking.png + :alt: Two cubes stacked are offset in the image by 12 pixels. + +Interestingly enough, due to the projection, this is exactly the same offset as +the situation above for diagonally neighboring cubes. The cube outlined in green +is drawn 12 pixels below the other one. Only the order that the cubes are drawn +is different. + +And finally, what about cubes that are next to each other in the world --- +diagonally next to each other in the image? + +.. image:: cubepositionimgs/cube_neighbors.png + :alt: Cubes that are neighbors are offset by 12 on the X and 6 on the Y + +The cube outlined in green is offset on the horizontal axis by half the cube +width, or 12 pixels. It is offset on the vertical axis by half the width of the +cube's top, or 6 pixels. For the other 3 directions this could go, the +directions of the offsets are changed, but the amounts are the same. + +The size of a chunk +------------------- +Now that we know how to place cubes relative to each other, we can begin to +construct a chunk. + +Since the cube images are 24 by 24 pixels, and the diagonal of the 16 by 16 grid +is 16 squares, the width of one rendered chunk will be 384 pixels. Just +considering the top layer of the chunk: + +.. image:: cuberenderimgs/chunk_width.png + :alt: Illustrating the width of a single chunk + +Since cubes next to each other in the same "diagonal row" are offset by 24 +pixels, this is trivially calculated. + +The height is a bit more tricky to calculate. Let's start by calculating the +height of a single stack of 128 cubes. + +If the top of a stack of cubes is at Y value 0, the 128th cube down must be +drawn (128-1)*12=1524 pixels below. However, that's not the end of the story. +The bottom cube has a height of 24 pixels, so the height of a rendered stack of +128 cube is 1548 pixels. + +.. image:: cuberenderimgs/cube_stack128.png + :alt: A stack of 128 cubes takes 1560 vertical pixels to draw. + +You can also calculate this by looking at the sides of the cubes, which don't +overlap at all. They are 12 pixels each, times 128 cubes in the stack, gives +1536 pixels. Add in the 6 pixels for the top cube and the 6 pixels for the +bottom cube to get the total height of 1548 pixels. + +So what about the entire chunk? Let's take a look at the top and bottom few +layers of a chunk. + +.. image:: cuberenderimgs/chunk_height.png + :alt: The highest and lowest positioned cubes in a chunk + +Let's let the red cubes represent the stack from above. The one on the top we'll +define as position 0, with our vertical axis running positively downward (as is +the case in a lot of imaging library coordinate systems) Therefore, the bottom +red cube is at vertical offset 1524 below. + +The green cube at the bottom most tip is the cube with the lowest vertical +placement on the image, so its offset plus 24 pixels for its height will be the +chunk height. Since the green cubes each have an offset of 12 pixels, add 15*12 +pixels to get the offset of the lowest green cube: 1704. + +So the total size of a chunk in pixels is 384 wide by 1728 tall. That's pretty +tall! + +Tile Rendering +============== +.. Covers the placement of chunk images on a tile + +Reading the Data Files +====================== +.. + Covers how to extract the blocks of each chunk from the region files. Also + covers the nbt file stuff. + +Image Composition +================= +.. + Covers the issues I had with PIL's image composition and why we needed + something fancier. + +Multiprocessing +=============== +.. + Covers how the Overviewer utilizes multiple processors to render faster + +Caching +======= +.. How the overviewer determines what needs to be rendered and what doesn't + +Lighting +======== + +Cave Mode +========= diff --git a/docs/design/pixelfix.png b/docs/design/pixelfix.png new file mode 100644 index 0000000..34ee495 Binary files /dev/null and b/docs/design/pixelfix.png differ diff --git a/docs/design/pixelfix.svg b/docs/design/pixelfix.svg new file mode 100644 index 0000000..b61a06a --- /dev/null +++ b/docs/design/pixelfix.svg @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/docs/design/screenshot.png b/docs/design/screenshot.png new file mode 100644 index 0000000..953b50e Binary files /dev/null and b/docs/design/screenshot.png differ diff --git a/docs/design/tessellation.png b/docs/design/tessellation.png new file mode 100644 index 0000000..0e62d07 Binary files /dev/null and b/docs/design/tessellation.png differ diff --git a/docs/design/tessellation.svg b/docs/design/tessellation.svg new file mode 100644 index 0000000..7f31851 --- /dev/null +++ b/docs/design/tessellation.svg @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/design/texturecubing.png b/docs/design/texturecubing.png new file mode 100644 index 0000000..4e8f8fb Binary files /dev/null and b/docs/design/texturecubing.png differ diff --git a/docs/design/texturecubing.svg b/docs/design/texturecubing.svg new file mode 100644 index 0000000..5ab6e50 --- /dev/null +++ b/docs/design/texturecubing.svg @@ -0,0 +1,278 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + 16 + 16 + 24 + 24 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/design/texturesidesteps.png b/docs/design/texturesidesteps.png new file mode 100644 index 0000000..3658f0b Binary files /dev/null and b/docs/design/texturesidesteps.png differ diff --git a/docs/design/texturesidesteps.svg b/docs/design/texturesidesteps.svg new file mode 100644 index 0000000..d1bd219 --- /dev/null +++ b/docs/design/texturesidesteps.svg @@ -0,0 +1,418 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + 16 + + + + + + + + + + + + + + + + + 18 + + + + + + + + + 12 + 12 + + + + + + + + + + + + + + + + + + 12 + + + + + + + + + + + + diff --git a/docs/design/texturetopsteps.png b/docs/design/texturetopsteps.png new file mode 100644 index 0000000..d7427f4 Binary files /dev/null and b/docs/design/texturetopsteps.png differ diff --git a/docs/design/texturetopsteps.svg b/docs/design/texturetopsteps.svg new file mode 100644 index 0000000..39dcd3a --- /dev/null +++ b/docs/design/texturetopsteps.svg @@ -0,0 +1,524 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + 16 + + + + + + + + + + + + + + + + + + + 24 + + + + + + + + + 24 + + + + + + + + + 17 + 17 + + + + + + + + + + + + + + + + + + + + + + + + + 24 + + + + + 12 + + + + + + + + + + + + + + + diff --git a/docs/faq.rst b/docs/faq.rst new file mode 100644 index 0000000..f9790a1 --- /dev/null +++ b/docs/faq.rst @@ -0,0 +1,23 @@ +========================== +Frequently Asked Questions +========================== + +**The full map doesn't display even when fully zoomed out!** + Are you using the :option:`-z` or :option:`--zoom <-z>` option on your commandline or + in settings.py? If so, try removing it, or increasing the value you set. + It's quite likely you don't need it at all. See the documentation for the + :option:`zoom <-z>` option. + +**You've added a few feature, but it's not showing up on my map!** + Some new features will only show up in newly-rendered areas. Use the + :option:`--forcerender` option to update the entire map. + +**How do I use this on CentOS 5?** + CentOS 5 comes with Python 2.4, but the Overviewer needs 2.6 or higher. See + the special instructions at :ref:`centos` + +**The background color of the map is black, and I don't like it!** + You can change this by using the :option:`--bg-color` command line option, or + ``bg_color`` in settings.py. See the :doc:`options` page for more + details. + diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..57b1663 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,109 @@ +.. + Hey! You! Read these docs at http://docs.overviewer.org + Go there now! + +======================== +The Minecraft Overviewer +======================== + +Introduction +============ +The Minecraft Overviewer is a command-line tool for rendering high-resolution +maps of Minecraft worlds. It generates a set of static html and image files and +uses the Google Maps API to display a nice interactive map. + +The Overviewer has been in active development for over a year and has many +features, including day and night lighting, cave rendering, mineral overlays, +and many plugins for even more features! It is written mostly in Python with +critical sections in C as an extension module. + +For a simple example of what your renders will look like, head over to `The +"Exmaple" Map `_. For more user-contributed +examples, see `The Example Wiki Page `_. + +Features +======== + +* Renders large resolution images of your world, such that you can zoom in and + see details + +* Customizable textures! Pulls textures straight from your installed texture + pack! + +* Outputs a Google Map powered interface that is memory efficient, both in + generating and viewing. + +* Renders efficiently in parallel, using as many simultaneous processes as you + want! + +* Utilizes caching to speed up subsequent renderings of your world. + +* Throw the output directory up on a web server to share your Minecraft world + with everyone! + +Requirements +============ +This is a quick list of what's required to run The Overviewer. It runs on +Windows, Mac, and Linux as long as you have these software packages installed: + +* Python 2.6 or 2.7 + +* PIL (Python Imaging Library) + +* Numpy + +* Either a Minecraft Client installed or a terrain.png for the textures. + +There are additional requirements for compiling it. More details are available +in either the :doc:`Building ` or :doc:`Installing ` pages. + +Getting Started +=============== + +The Overviewer works with Linux, Mac, and Windows! We provide Windows and Debian +built executables for your convenience. Find them as well as the full sources on +our `Github Homepage`_. + +**If you are running Windows, Debian, or Ubuntu and would like the pre-built +packages and don't want to have to compile anything yourself**, head to the +:doc:`installing` page. + +**If you would like to build the Overviewer from source yourself (it's not that +bad)**, head to the :doc:`Building ` page. + +.. _Github Homepage: https://github.com/overviewer/Minecraft-Overviewer + +Help +==== + +**IF YOU NEED HELP COMPILING OR RUNNING THE OVERVIEWER** feel free to chat with +us live in IRC: #overviewer on Freenode. There's usually someone on there that +can help you out. Not familiar with IRC? `Use the web client +`_. + +If you think you've found a bug or other issue, file an issue on our `Issue +Tracker `_. Filing or +commenting on an issue sends a notice to our IRC channel, so the response time +is often very good! + +Documentation Contents +====================== + +.. toctree:: + :maxdepth: 2 + + building + installing + running + options + faq + design/designdoc + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/docs/installing.rst b/docs/installing.rst new file mode 100644 index 0000000..a9b5b4b --- /dev/null +++ b/docs/installing.rst @@ -0,0 +1,35 @@ +========== +Installing +========== + +This page is for installing the pre-compiled binary versions of the Overviewer. +If you have built the Overviewer from source yourself, head back to +:doc:`Building `. + + +Windows +======= +Running Windows and don't want to compile the Overviewer? You've come to the +right place! + +1. Head to the `Downloads `_ page and download the most recent Windows download for your architecture (32 or 64 bit). + +2. For 32 bit you may need to install the `VC++ 2008 `_ and `VC++ 2010 `_ redistributables. + + For 64 bit, you'll want these instead: `VC++ 2008 `_ and `VC++ 2010 `_ + +3. That's it! Proceed with instructions on :doc:`Running ` the + Overviewer. + +Debian / Ubuntu +=============== +We provide an APT repository with pre-built Overviewer packages for Debian and +Ubuntu users. To do this, add the following line to your +``/etc/apt/sources.list`` + +:: + + deb http://overviewer.org/debian ./ + +Then run ``apt-get update`` and ``apt-get install minecraft-overviewer`` and +you're all set! See you at the :doc:`running` page! diff --git a/docs/options.rst b/docs/options.rst new file mode 100644 index 0000000..a8f00a3 --- /dev/null +++ b/docs/options.rst @@ -0,0 +1,699 @@ +==================== +Settings and Options +==================== + +Overviewer settings can be set in two places, on the command line when you run +the overviewer, or in a settings file. You specify a settings file to use with +the :option:`--settings` command line option. + +.. note:: + Any command line option can optionally be set in the settings file. However, + there are some settings that can only be set in the settings file. + +.. note:: + Some options go by different names on the command line and the settings + file. Those are noted in bold below. + +The first section of this document covers command line options. The second part +covers the more advanced ways of customizing The Overviewer using settings +files. + +.. contents:: + :local: + +Command line options +==================== + +.. cmdoption:: -h, --help + + Shows the list of options and exits + +.. cmdoption:: --advanced-help + + Display help - including advanced options + +Useful Options +-------------- + +.. cmdoption:: --settings + + Use this option to load settings from a file. For more information see the + `Settings File`_ section below. + + **Not available in settings file (duh)** + +.. cmdoption:: --north-direction + + Specifies which corner of the screen north will point to. + Valid options are: lower-left, upper-left, upper-right, lower-right. + If you do not specify this option, it will default to whatever direction + the existing map uses. For new maps, it defaults to lower-left for + historical reasons. + + .. note:: + We define cardinal directions by the sun in game; the sun rises in the + East and sets in the West. + + **Settings file:** + Option name: ``north_direction`` + + Format: One of the above strings. + +.. cmdoption:: --rendermodes [,MODE2,...] + + Use this option to specify which render mode to use, such as lighting or + night. Use :option:`--list-rendermodes` to get a list of available + rendermodes, and a short description of each. If you provide more than one + mode (separated by commas), Overviewer will render all of them at once, and + provide a toggle on the resulting map to switch between them. + + If for some reason commas do not work for your shell (like if you're using + Powershell on Windows), you can also use a colon ':' or a forward slash '/' + to separate the modes. + + Incomplete list of common render-modes for your convenience: + + * normal + * lighting + * night + + Example:: + + ./overviewer.py --rendermodes=lighting,night /opt/server/world /opt/map + + **Settings file:** + Option name: ``rendermode`` **Note the lack of an s** + + Format: a list of strings. + + Default: only render the normal mode + + See the `Render Modes`_ section for more information. + +.. cmdoption:: --list-rendermodes + + List the available render modes, and a short description of each, and exit. + + **Not available in settings file** + +Less Useful Options +------------------- + +.. cmdoption:: --bg-color + + Configures the background color for the Google Map output. Specify in + #RRGGBB format. + + **Settings file:** + Option name: ``bg_color`` + + Format: A string in the above format. + + Default: "#1A1A1A" + +.. cmdoption:: --changelist + + Outputs a list of changed tiles to the named file. If the file doesn't + exist, it is created. If it does exist, its contents are overwritten. + + This could be useful for example in conjunction with a script to upload only + changed tiles to your web server. + + **Settings file:** + Option name: ``changelist`` + + Format: String (path plus filename) + + Default: Not specified (no changelist outputted) + +.. cmdoption:: --changelist-format + + Chooses absolute or relative paths for the output with the + :option:`--changelist` option. Valid values for format are "relative" or + "absolute". + + **Settings file:** + Option name: ``changelist_format`` + + Format: A string (one of the above) + + Default: "relative" + +.. cmdoption:: --check-terrain + + When this option appears on the command line, Overviewer prints the location + and hash of the terrain.png it will use, and then exits. + + This is useful for debugging terrain.png path problems, especially with + :option:`--textures-path`. Use this to see what terrain.png your current + setup has selected. + + See the :ref:`installing-textures` section for an example. + + **Not available in settings file** + +.. cmdoption:: --display-config + + Display the configuration parameters and exit. Doesn't render the map. This + is useful to help validate a configuration setup. + + **Not available in settings file** + +.. cmdoption:: --forcerender + + Force re-rendering the entire map (or the given regionlist). This + is an easier way to completely re-render without deleting the map. + + This is useful if you change texture packs and want to re-render everything + in the new textures, or if you're changing the :option:`--north-direction`. + + **Settings file:** + Option name: ``forcerender`` + + Format: A boolean + + Default: False + +.. cmdoption:: --imgformat + + Specifies the output format for the tiles. Currently supported options are + "png" or "jpg". + + **Settings file:** + Option name: ``imgformat`` + + Format: A string, either "png" or "jpg" + + Default: "png" + +.. cmdoption:: --imgquality + + When using ":option:`--imgformat` jpg", this specifies the jpeg quality + parameter. This can help save disk space for larger maps. + + For saving space with pngs, see :option:`--optimize-img` + + **Settings file:** + Option name: ``imgquality`` + + Format: An integer 1-100 + + Default: 95 + +.. cmdoption:: --no-signs + + Doesn't output signs to markers.js. This has the effect of disabling signs + on your map. + + **Settings file:** + Option name: ``nosigns`` + + Format: Boolean + + Default: False + +.. cmdoption:: --optimize-img + + When using ":option:`--imgformat` png" (the default), this performs file + size optimizations on the output. The level parameter is an integer + specifying one of the following: + + 1. Run pngcrush on all tiles + + 2. Run pngcrush plus advdef on all tiles + + 3. Run pngcrush plus advdef with more aggressive settings. + + These options may double the time or worse it takes to render your map, and + can be expected to give around 19-23% reduction in file size. + + These options also require the corresponding program(s) installed and in + your system path ($PATH or %PATH% environment variable) + + **Settings file:** + Option name: ``optimizeimg`` + + Format: an integer + + Default: not set (no optimization) + +.. cmdoption:: -p , --processes + + On multi-cored or multi-processor machines, The Overviewer will perform its + work on *all* cores by default. If you want to manually specify how many + workers to run in parallel, use this option. + + Example to run 5 worker processes in parallel:: + + overviewer.py -p 5 + + **Settings file:** + Option name: ``procs`` + + Format: an integer. + + Default: ``multiprocessing.cpu_count()`` + +.. cmdoption:: -q, --quiet + + Prints less output. You can specify this multiple times. + + **Settings file:** + Option name: ``quiet`` + + Format: an integer + + Default: 0 + +.. cmdoption:: --regionlist + + Use this option to specify manually a list of regions to consider for + updating. In normal operation, every chunk in every region is checked for + update and if necessary, re-rendered. With this option, only the chunks in + the specified regions are checked. + + This option should name a file containing, 1 per line, the path to the + region files to be considered for update. + + It's up to you to build such a list. On Linux or Mac, try using the "find" + command. You could, for example, output all region files that are older than + a certain date. Or perhaps you can incrementally update your map by passing + in a subset of regions each time. It's up to you! + + **Settings file:** + Option name: ``regionlist`` + + Format: A string representing the region list file. + + Default: Scan all region files. + + .. note:: + See sample.settings.py for an example on how to build a region list + file. + +.. cmdoption:: --skip-js + + Skip the generation and output of markers.js and regions.js to the output + directory. + + **Settings file:** + Option name: ``skipjs`` + + Format: Boolean + + Default: False + +.. cmdoption:: --textures-path + + Use this option to specify an alternate terrain.png to use for textures when + rendering a world. ``path`` specifies the **containing directory** of + terrain.png. + + The Overviewer will look for terrain.png in the following places in this + order: path specified by this option, the program's directory, the + overviewer_core/data/textures directory within the source directory, the + default textures that come with Minecraft if it's installed. + + .. note:: + + If you installed Overviewer from the Debian package or chose to install + the overviewer from source (``python setup.py install``), then there + isn't a source directory; this option may be necessary to specify + non-default textures. + + If you're having trouble getting The Overviewer to recognize your textures, + see the :option:`--check-terrain` option. + + Also see the :ref:`installing-textures` section of the documentation. + + **Settings file:** + Option name: ``textures_path`` + + Format: A string (path to a dir with a terrain.png) + + Default: None + +.. cmdoption:: -v, --verbose + + Prints more output. You can specify this multiple times. + + **Settings file:** + Option name: ``verbose`` + + Format: an integer + + Default: 0 + +.. cmdoption:: -V, --version + + Displays the version information and exits + + **Not available in settings file** + +.. cmdoption:: --web-assets-path + + When The Overviewer runs, it copies the files from the web_assets directory + to the destination directory. If you wish to override a file with your own, + for example, to make changes, you may put your modified copies in your own + directory and specify the directory with this option. + + Files in the folder specified by ``path`` will override files from the + web_assets directory, letting you customize the files. + + If you're running from source and are comfortable merging with Git, it may + be better to edit the web_assets directly. If we update one of the files, + you can use Git to merge in our changes with yours. + + If, however, you do not like Git, and don't mind having to manually update + or merge web assets (or don't care for web asset updates at all), then copy + all the web assets to a directory of your own and use this option. + + See the :ref:`web-assets` section for more info on customizing your web + assets. + + **Settings file:** + Option name: ``web_assets_path`` + + Format: A string (path to a directory to use for custom web assets) + + Default: Not set (no additional web assets used) + +.. cmdoption:: -z , --zoom + + .. warning:: + + This option does not do what you think it does. You almost certainly do + not want to set this. + + This option effectively sets *how far the map can be zoomed out*. The + Overviewer will by default determine how many *zoom levels* your map needs + to show the entire map. This option overrides that; setting this option + lower than automatically determined will *crop your map* and parts will be + cut off. (We acknowledge that name zoom is misleading) + + To be precise, it sets the width and height of the highest zoom level, in + tiles. A zoom level of z means the highest zoom level of your map will be + 2^z by 2^z tiles. + + This option map be useful if you have some outlier chunks causing your map + to be too large, or you want to render a smaller portion of your map, + instead of rendering everything. + + **If you are getting a "your map is waaaay too big" error** then this option + may help you render your map. That error is unlikely in naturally generated + worlds, but some really giant worlds may still cross the threshold. The + Overviewer will refuse to automatically render maps that require zoom level + 15 and above, so if you get this error, try specifying ``--zoom 15``. If + your map is still cut off around the edges, increase the zoom level by 1 and + try again. + + **Settings file:** + Option name: ``zoom`` + + Format: An integer. + + Default: Automatically calculated from the world size. + +.. note:: + + There are **more settings** that cannot be specified on the command line. + See the section below! + +Settings File +============= + +You can optionally store settings in a file named settings.py (or really, +anything you want). It is a regular python script, so you can use any python +functions or modules you want. To use a settings file, use the +:option:`--settings` command line option when you run the Overviewer. + +For a sample settings file, look at 'sample.settings.py'. Note that this file is +not meant to be used directly, but instead it should be used as a collection of +examples to guide writing your own. It contains a number of examples to get you +started, but you almost certainly don't want to use it as-is. + +You can specify *any of the above* options in your settings file *in addition to +the ones documented below*. For the command-line options, find its listed +"Option name" which is the Python identifier you will use. For example, if you +wanted to specify :option:`--bg-color`, you would look and see its option name +is "bg_color" (note the underscore) and you would put this line in your settings +file:: + + bg_color = "#000000" + +Settings file options +--------------------- + +In addition to the `Command line options`_, you can specify these options. + + +.. describe:: web_assets_hook + + This option lets you define a function to run after the web assets have + been copied into the output directory, but before any tile rendering takes + place. This is an ideal time to do any custom postprocessing for + markers.js or other web assets. + + Set this identifier to a Python *function object* to be called. + + This function should accept one argument: a + :class:`overviewer_core.googlemap.MapGen` object. + + .. warning:: + + Currently, this option only works if the :option:`--skip-js` option is + set + +.. describe:: rendermode_options + + Different rendermodes have different options. This option is a dictionary + that maps rendermode names to option dictionaries. + + See the `Render Modes`_ section for relevant options to the render modes. + +.. describe:: custom_rendermodes + + You can also specify your own custom rendermodes with this option. This is a + dictionary mapping your rendermode name to a dictionary of parameters to + use. + + See the `Defining Custom Rendermodes`_ section for more information. + +Render Modes +============ + +A rendermode is a unique way of rendering a Minecraft map. The normal render +mode was the original, and we've since added a render mode with proper lighting, +a rendermode for nighttime lighting, and we have a rendermode that only shows +caves. + +Beyond that, there are also render "overlays" that can be toggled on or off, +overlaying a proper rendering. These can be used to show where minerals are and +such. + +Specify your rendermodes with :option:`--rendermodes`. You can get a list of all +rendermodes installed with :option:`--list-rendermodes`. + +Options and Rendermode Inheritance +---------------------------------- + +Each mode will accept its own options, as well as the options for +parent modes; for example the 'night' mode will also accept options +listed for 'lighting' and 'normal'. Also, if you set an option on a +mode, all its children will also have that option set. So, setting the +'edge_opacity' option on 'normal' will also set it on 'lighting' and +'night'. + +Basically, each mode inherits available options and set options from +its parent. + +Eventually the :option:`--list-rendermodes` option will show parent +relationships. Right now, it looks something like this: + +* normal + + * lighting + + * night + * cave + +* overlay + + * spawn + * mineral + +How to Set Options +------------------ + +Available options for each mode are listed below, but once you know what to set +you'll have to edit your settings file to set them. Here's an example:: + + rendermode_options = { + 'lighting': { + 'edge_opacity': 0.5, + }, + + 'cave': { + 'lighting': True, + 'depth_tinting': False, + }, + } + +As you can see, each entry in ``rendermode_options`` starts with the mode name +you want to apply the options to, then a dictionary containing each option. So +in this example, 'lighting' mode has 'edge_opacity' set to 0.5, and 'cave' mode +has 'lighting' turned on and 'depth_tinting' turned off. + +Option Listing +-------------- + +Soon there should be a way to pull out supported options from Overviewer +directly, but for right now, here's a reference of currently supported options. + +normal +~~~~~~ + +* **edge_opacity** - darkness of the edge lines, from 0.0 to 1.0 (default: 0.15) +* **min_depth** - lowest level of blocks to render (default: 0) +* **max_depth** - highest level of blocks to render (default: 127) +* **height_fading** - darken or lighten blocks based on height (default: False) + +lighting +~~~~~~~~ + +all the options available in 'normal', and... + +* **shade_strength** - how dark to make the shadows, from 0.0 to 1.0 (default: 1.0) + +night +~~~~~ + +'night' mode has no options of its own, but it inherits options from +'lighting'. + +cave +~~~~ + +all the options available in 'normal', and... + +* **depth_tinting** - tint caves based on how deep they are (default: True) +* **only_lit** - only render lit caves (default: False) +* **lighting** - render caves with lighting enabled (default: False) + +mineral +~~~~~~~ + +The mineral overlay supports one option, **minerals**, that has a fairly +complicated format. **minerals** must be a list of ``(blockid, (r, g, b))`` +tuples that tell the mineral overlay what blocks to look for. Whenever a block +with that block id is found underground, the surface is colored with the given +color. + +See the *settings.py* example below for an example usage of **minerals**. + +Defining Custom Rendermodes +--------------------------- + +Sometimes, you want to render two map layers with the same mode, but with two +different sets of options. For example, you way want to render a cave mode with +depth tinting, and another cave mode with lighting and no depth tinting. In this +case, you will want to define a 'custom' render mode that inherits from 'cave' +and uses the options you want. For example:: + + custom_rendermodes = { + 'cave-lighting': { + 'parent': 'cave', + 'label': 'Lit Cave', + 'description': 'cave mode, with lighting', + 'options': { + 'depth_tinting': False, + 'lighting': True, + } + }, + } + + rendermode = ['cave', 'cave-lighting'] + +Each entry in ``custom_rendermodes`` starts with the mode name, and is followed +by a dictionary of mode information, such as the parent mode and description +(for your reference), a label for use on the map, as well as the options to +apply. + +Every custom rendermode you define is on exactly equal footing with the built-in +modes: you can put them in the ``rendermode`` list to render them, you can +inherit from them in other custom modes, and you can even add options to them +with ``rendermode_options``, though that's a little redundant. + +Example *settings.py* +--------------------- + +This *settings.py* will render three layers: a normal 'lighting' layer, a 'cave' +layer restricted to between levels 40 and 55 to show off a hypothetical subway +system, and a 'mineral' layer that has been modified to show underground rail +tracks instead of ore. + +:: + + rendermode = ['lighting', 'subway-cave', 'subway-overlay'] + + custom_rendermodes = { + 'subway-cave' : {'parent' : 'cave', + 'label' : 'Subway', + 'description' : 'a subway map, based on the cave rendermode', + 'options' : { + 'depth_tinting' : False, + 'lighting' : True, + 'only_lit' : True, + 'min_depth' : 40, + 'max_depth' : 55, + } + }, + 'subway-overlay' : {'parent' : 'mineral', + 'label' : 'Subway Overlay', + 'description' : 'an overlay showing the location of minecart tracks', + 'options' : {'minerals' : [ + (27, (255, 234, 0)), + (28, (255, 234, 0)), + (66, (255, 234, 0)), + ]} + }, + } + + rendermode_options = { + 'lighting' : {'edge_opacity' : 0.5}, + # 'night' : {'shade_strength' : 0.5}, + # 'cave' : {'only_lit' : True, 'lighting' : True, 'depth_tinting' : False}, + } + +.. _web-assets: + +Customizing Web Assets +====================== + +The web assets are the static html files stored in +overviewer_core/data/web_assets that are copied to the destination directory +when you run the Overviewer. Some of these files are actually templates and +certain parameters are set at render time depending on various factors. Others +are just straight up copied. + +You should not typically need to edit the files in here, but if you like +customizing things or want to edit them for whatever reason, here's two ways: + +1. If you're not afraid of Git and you're running the Overviewer from a Git + clone of our repository, you can edit the files in + overviewer_core/data/web_assets directly. When you pull in changes from us, + you will have to merge, but using Git should make this relatively painless. + +2. Otherwise, the recommended way is to use the :option:`--web-assets-path` + option. Use this option and point it to a directory of customized web assets + to copy. + + Files from the original web_assets directory are still copied, but any files + in the custom web assets directory will override the originals. This way you + can customize a few files and leave the rest alone. + + The downside is, if you want to upgrade you will have to merge in your + changes with any of our changes manually. To avoid merging entirely, just + copy *all* the web assets to your custom web assets folder. You'll keep the + old version of all files for eternity, missing out on new features we may + add, but you won't have to deal with merges at all. diff --git a/docs/running.rst b/docs/running.rst new file mode 100644 index 0000000..e5d873c --- /dev/null +++ b/docs/running.rst @@ -0,0 +1,139 @@ +====================== +Running the Overviewer +====================== + +Rendering your First Map +======================== + +Overviewer is a command-line application, and so it needs to be run from the +command line. If you installed Overviewer from a package manager, the command is +``overviewer.py``. If you downloaded it manually, open a terminal window and +navigate to wherever you downloaded Overviewer. For pre-compiled Windows builds, +the command is ``overviewer.exe``. For other systems, it's ``overviewer.py``. + +The basic usage for Windows is:: + + overviewer.exe [options] + +And similarly for other systems:: + + overviewer.py [options] + +**World** + World can be one of several things. + + 1. The path to your Minecraft world on your hard drive + 2. The name of a single player world on your current system. Note that if it + has spaces, you will need to put the world name in quotes. + 3. If your single-player world name is in the format "World #" (e.g. "World + 1"), you can just specify the number. + +**Output Dir** + This is the directory you would like to put the rendered tiles and + supporting HTML and javascript files. You should use the same output + directory each time; the Overviewer will automatically re-render only the + tiles that need rendering on subsequent runs. + +**options** + See the :doc:`options` page for a list of options you can + specify. + +For example, on Windows if your Minecraft server runs out of ``c:\server\`` and you want +to put the rendered map in ``c:\mcmap\``, run this:: + + overviewer.exe c:\server\world c:\mcmap + +For Mac or Linux builds from source, you would run something like this with the +current directory in the top level of the source tree:: + + ./overviewer.py /opt/minecraft/server/world /opt/minecraft/mcmap + +The first render can take a while, depending on the size of your world. + +When the render is done, open up *index.html* using your web-browser of choice. +Pretty cool, huh? You can even upload this map to a web server to share with +others! Simply upload the entire folder to a web server and point your users to +index.html! + +Incremental updates are just as easy, and a lot faster. If you go and change +something inside your world, run the command again and Overviewer will +automatically re-render only what's needed. + +.. _installing-textures: + +Installing the Textures +======================= +If you're running on a machine without the Minecraft client installed, you will +need to provide the terrain.png file manually for the Overviewer to use in +rendering your world. This is common for servers. + +All Overviewer needs is a terrain.png file. If the Minecraft client is +installed, it will use the terrain.png that comes with Minecraft. If the +Minecraft client is not installed or you wish to use a different terrain.png, +for example a custom texture pack, read on. + +You have several options: + +* If you have the Minecraft client installed, the Overviewer will automatically + use those textures. This is a good solution since the Minecraft Launcher will + always keep this file up-to-date and you don't have to do anything extra. + + * If you're running the Overviewer on a server, you can still put the + minecraft.jar file (not the launcher) into the correct location and the + Overviewer will find and use it, even if the rest of the client files are + missing. On Linux, try a command like this:: + + wget -N http://s3.amazonaws.com/MinecraftDownload/minecraft.jar -P ~/.minecraft/bin/ + +* You can manually extract the terrain.png from minecraft.jar or your favorite + texture pack. If you've built the Overviewer from source, simply place the + file in the same directory as overviewer.py or overviewer.exe. For + installations, you will need to specify the path... see the next bullet. + +* You can put a terrain.png file anywhere you want and point to its location + with the :option:`--textures-path` option. This should point to the directory containing + the terrain.png, not to the file itself. + +Note: the :option:`--check-terrain` option is useful for debugging terrain.png issues. +For example:: + + $ ./overviewer.py --check-terrain + 2011-09-26 21:51:46,494 [INFO] Found terrain.png in '/home/achin/.minecraft/bin/minecraft.jar' + 2011-09-26 21:51:46,497 [INFO] Hash of terrain.png file is: `6d53f9e59d2ea8c6f574c9a366f3312cd87338a8` + +:: + + $ ./overviewer.py --check-terrain --textures-path=/tmp + 2011-09-26 21:52:52,143 [INFO] Found terrain.png in '/tmp/terrain.png' + 2011-09-26 21:52:52,145 [INFO] Hash of terrain.png file is: `6d53f9e59d2ea8c6f574c9a366f3312cd87338a8` + +Running on a Live Map +===================== +If you're running the Overviewer on a live server or a single player world +that's running, read this section. + +Minecraft doesn't really like it when other programs go snooping around in a +live world, so running Overviewer on a live world usually creates a few errors, +usually "corrupt chunk" errors. You *can* do this, but it's not a supported way +of running Overviewer. + +To get around this, you can copy your live world somewhere else, and render the +copied world instead. If you're already making backups of your world, you can +use the backups to make the render. Many people even use their backups to run +Overviewer on a different machine than the one running the Minecraft server. + +There used to be a few things to be careful about, but right now there's only +one important thing left. + +Preserving Modification Times +----------------------------- + +The important thing to be careful about when copying world files to another +location is file modification times, which Overviewer uses to figure out what +parts of the map need updating. If you do a straight copy, usually this will +update the modification times on all the copied files, causing Overviewer to +re-render the entire map. To copy files on Unix, while keeping these +modification times intact, use ``cp -p``. For people who render from backups, +GNU ``tar`` automatically handles modification times correctly. ``rsync -a`` +will handle this correctly as well. If you use some other tool, you'll have to +figure out how to do this yourself. diff --git a/overviewer.py b/overviewer.py index b79f4dc..3399424 100755 --- a/overviewer.py +++ b/overviewer.py @@ -114,8 +114,8 @@ def main(): parser.add_option("--imgformat", dest="imgformat", helptext="The image output format to use. Currently supported: png(default), jpg.", advanced=True ) parser.add_option("--imgquality", dest="imgquality", default=95, helptext="Specify the quality of image output when using imgformat=\"jpg\".", type="int", advanced=True) parser.add_option("--bg-color", dest="bg_color", helptext="Configures the background color for the GoogleMap output. Specify in #RRGGBB format", advanced=True, type="string", default="#1A1A1A") - parser.add_option("--optimize-img", dest="optimizeimg", helptext="If using png, perform image file size optimizations on the output. Specify 1 for pngcrush, 2 for pngcrush+advdef and 3 for pngcrush-advdef with more agressive settings. This may double (or more) render times, but will produce up to 30% smaller images. NOTE: requires corresponding programs in $PATH or %PATH%", advanced=True) - parser.add_option("--web-assets-hook", dest="web_assets_hook", helptext="If provided, run this function after the web assets have been copied, but before actual tile rendering begins. It should accept a QuadtreeGen object as its only argument.", action="store", metavar="SCRIPT", type="function", advanced=True) + parser.add_option("--optimize-img", dest="optimizeimg", helptext="If using png, perform image file size optimizations on the output. Specify 1 for pngcrush, 2 for pngcrush+advdef and 3 for pngcrush-advdef with more aggressive settings. This may double (or more) render times, but will produce up to 30% smaller images. NOTE: requires corresponding programs in $PATH or %PATH%", advanced=True) + parser.add_option("--web-assets-hook", dest="web_assets_hook", helptext="If provided, run this function after the web assets have been copied, but before actual tile rendering begins. It should accept a MapGen object as its only argument.", action="store", metavar="FUNCTION", type="function", advanced=True) parser.add_option("--web-assets-path", dest="web_assets_path", helptext="Specifies a non-standard web_assets directory to use. Files here will overwrite the default web assets.", metavar="PATH", type="string", advanced=True) parser.add_option("--textures-path", dest="textures_path", helptext="Specifies a non-standard textures path, from which terrain.png and other textures are loaded.", metavar="PATH", type="string", advanced=True) parser.add_option("--check-terrain", dest="check_terrain", helptext="Prints the location and hash of terrain.png, useful for debugging terrain.png problems", action="store_true", advanced=False, commandLineOnly=True) @@ -124,7 +124,7 @@ def main(): parser.add_option("--skip-js", dest="skipjs", action="store_true", helptext="Don't output marker.js or regions.js") parser.add_option("--no-signs", dest="nosigns", action="store_true", helptext="Don't output signs to markers.js") parser.add_option("--north-direction", dest="north_direction", action="store", helptext="Specifies which corner of the screen north will point to. Defaults to whatever the current map uses, or lower-left for new maps. Valid options are: " + ", ".join(avail_north_dirs) + ".", type="choice", default="auto", choices=avail_north_dirs) - parser.add_option("--changelist", dest="changelist", action="store", helptext="Output list of changed tiles to file. If the file exists, it's contents will be overwritten.",advanced=True) + parser.add_option("--changelist", dest="changelist", action="store", helptext="Output list of changed tiles to file. If the file exists, its contents will be overwritten.",advanced=True) parser.add_option("--changelist-format", dest="changelist_format", action="store", helptext="Output relative or absolute paths for --changelist. Only valid when --changelist is used", type="choice", default="auto", choices=["auto", "relative","absolute"],advanced=True) parser.add_option("--display-config", dest="display_config", action="store_true", helptext="Display the configuration parameters, but don't render the map. Requires all required options to be specified", commandLineOnly=True) #parser.add_option("--write-config", dest="write_config", action="store_true", helptext="Writes out a sample config file", commandLineOnly=True) diff --git a/overviewer_core/chunk.py b/overviewer_core/chunk.py index 300cada..2df3fdb 100644 --- a/overviewer_core/chunk.py +++ b/overviewer_core/chunk.py @@ -143,8 +143,8 @@ solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 fluid_blocks = set([8,9,10,11]) # This set holds block ids that are not candidates for spawning mobs on -# (glass, half blocks, fluids) -nospawn_blocks = set([20,44]).union(fluid_blocks) +# (glass, slabs, stairs, fluids, ice, pistons, webs,TNT, wheat, cactus, iron bars, glass planes, fences, fence gate, cake, bed, repeaters, trapdoor) +nospawn_blocks = set([20,26, 29, 30, 33, 34, 44, 46, 53, 59, 67, 79, 81, 85, 92, 93, 94, 96, 107, 109, 101, 102]).union(fluid_blocks) class ChunkCorrupt(Exception): pass diff --git a/overviewer_core/data/web_assets/overviewer.css b/overviewer_core/data/web_assets/overviewer.css index 9085557..0ae76e5 100644 --- a/overviewer_core/data/web_assets/overviewer.css +++ b/overviewer_core/data/web_assets/overviewer.css @@ -111,7 +111,7 @@ body { border: 2px solid #000; font-size: 12pt; width: 20em; - background-colour: #fff; + background-color: #fff; } #searchControl>input.inactive { diff --git a/overviewer_core/data/web_assets/overviewer.js b/overviewer_core/data/web_assets/overviewer.js index b76a4fb..34fbfe8 100644 --- a/overviewer_core/data/web_assets/overviewer.js +++ b/overviewer_core/data/web_assets/overviewer.js @@ -248,27 +248,27 @@ var overviewer = { overviewer.collections.mapTypes[i].name, overviewer.collections.mapTypes[i]); } - - // Jump to the hash if given + + // Jump to the hash if given overviewer.util.initHash(); - - // Add live hash update listeners - // Note: It is important to add them after jumping to the hash + + // Add live hash update listeners + // Note: It is important to add them after jumping to the hash google.maps.event.addListener(overviewer.map, 'dragend', function() { overviewer.util.updateHash(); }); - + google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { overviewer.util.updateHash(); }); - - // Make the link again whenever the map changes + + // Make the link again whenever the map changes google.maps.event.addListener(overviewer.map, 'maptypeid_changed', function() { $('#'+overviewerConfig.CONST.mapDivId).css( 'background-color', overviewer.util.getMapTypeBackgroundColor( overviewer.map.getMapTypeId())); - //smuggled this one in here for maptypeid hash generation --CounterPillow - overviewer.util.updateHash(); + //smuggled this one in here for maptypeid hash generation --CounterPillow + overviewer.util.updateHash(); }); }, /** @@ -708,7 +708,7 @@ var overviewer = { // only create drop down if there's used options if (items.length > 0) { - overviewer.util.createDropDown('Signposts', items); + overviewer.util.createDropDown('Markers', items); } } @@ -843,12 +843,12 @@ var overviewer = { var searchInput = document.createElement("input"); searchInput.type = "text"; - searchInput.value = "Sign Search"; - searchInput.title = "Sign Search"; + searchInput.value = "Sign Search"; + searchInput.title = "Sign Search"; $(searchInput).addClass("inactive"); - - /* Hey dawg, I heard you like functions. - * So we defined a function inside your function. + + /* Hey dawg, I heard you like functions. + * So we defined a function inside your function. */ searchInput.onfocus = function() { if (searchInput.value == "Sign Search") { @@ -856,7 +856,7 @@ var overviewer = { $(searchInput).removeClass("inactive").addClass("active"); } }; - searchInput.onblur = function() { + searchInput.onblur = function() { if (searchInput.value == "") { searchInput.value = "Sign Search"; $(searchInput).removeClass("active").addClass("inactive"); @@ -957,8 +957,8 @@ var overviewer = { 'initHash': function() { if(window.location.hash.split("/").length > 1) { overviewer.util.goToHash(); - // Clean up the hash. - overviewer.util.updateHash(); + // Clean up the hash. + overviewer.util.updateHash(); // Add a marker indicating the user-supplied position var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); @@ -968,7 +968,7 @@ var overviewer = { 'y': coordinates.y, 'z': coordinates.z, 'type': 'querypos'}]); - } + } }, 'setHash': function(x, y, z, zoom, maptype) { window.location.replace("#/" + Math.floor(x) + "/" + Math.floor(y) + "/" + Math.floor(z) + "/" + zoom + "/" + maptype); @@ -976,7 +976,7 @@ var overviewer = { 'updateHash': function() { var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); var zoom = overviewer.map.getZoom(); - var maptype = overviewer.map.getMapTypeId(); + var maptype = overviewer.map.getMapTypeId(); if (zoom == overviewerConfig.map.maxZoom) { zoom = 'max'; } else if (zoom == overviewerConfig.map.minZoom) { @@ -988,19 +988,19 @@ var overviewer = { overviewer.util.setHash(coordinates.x, coordinates.y, coordinates.z, zoom, maptype); }, 'goToHash': function() { - // Note: the actual data begins at coords[1], coords[0] is empty. + // Note: the actual data begins at coords[1], coords[0] is empty. var coords = window.location.hash.split("/"); var latlngcoords = overviewer.util.fromWorldToLatLng(parseInt(coords[1]), parseInt(coords[2]), parseInt(coords[3])); - var zoom; - var maptype = ''; - // The if-statements try to prevent unexpected behaviour when using incomplete hashes, e.g. older links - if (coords.length > 4) { - zoom = coords[4]; - } - if (coords.length > 5) { - maptype = coords[5]; - } - + var zoom; + var maptype = ''; + // The if-statements try to prevent unexpected behaviour when using incomplete hashes, e.g. older links + if (coords.length > 4) { + zoom = coords[4]; + } + if (coords.length > 5) { + maptype = coords[5]; + } + if (zoom == 'max') { zoom = overviewerConfig.map.maxZoom; } else if (zoom == 'min') { @@ -1015,14 +1015,14 @@ var overviewer = { zoom = overviewerConfig.map.defaultZoom; } } - // If the maptype isn't set, set the default one. - if (maptype == '') { - // We can now set the map to use the 'coordinate' map type - overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId()); - } else { - overviewer.map.setMapTypeId(maptype); - } - + // If the maptype isn't set, set the default one. + if (maptype == '') { + // We can now set the map to use the 'coordinate' map type + overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId()); + } else { + overviewer.map.setMapTypeId(maptype); + } + overviewer.map.setCenter(latlngcoords); overviewer.map.setZoom(zoom); } diff --git a/overviewer_core/data/web_assets/overviewerConfig.js b/overviewer_core/data/web_assets/overviewerConfig.js index c99398e..e6889b4 100644 --- a/overviewer_core/data/web_assets/overviewerConfig.js +++ b/overviewer_core/data/web_assets/overviewerConfig.js @@ -1,11 +1,14 @@ var overviewerConfig = { /** - * These are things that will probably not need to be changed by the user, - * but are there because otherwise changing them is a giant PITA. + * These are things that will probably not need to be changed, but are there + * because otherwise changing them is a giant PITA. If you, the user, sees + * that its crucial for you to change these settings then the document + * repository might be able to assist you. + * http://docs.overviewer.org/en/latest/options/#customizing-web-assets */ 'CONST': { /** - * Height and width of the tiles in pixels (I think). + * Height and width of the tiles in pixels. */ 'tileSize': 384, /** @@ -88,6 +91,11 @@ var overviewerConfig = { 'center': {spawn_coords}, /** * Set this to tell browsers how long they should cache tiles in minutes. + * Essentially if set to 0, the url for tiles will end in .png + * if not set to 0 it will amend a number derived from the current time + * to the end of the url, like .png?c=123456. This is a great method for + * preventing browsers from caching the images. 0 saves bandwidth, not 0 + * prevents caching. */ 'cacheMinutes': 0, /** diff --git a/overviewer_core/quadtree.py b/overviewer_core/quadtree.py index 5c1b3ce..36978f2 100644 --- a/overviewer_core/quadtree.py +++ b/overviewer_core/quadtree.py @@ -80,7 +80,7 @@ class QuadtreeGen(object): if depth is None: # Determine quadtree depth (midpoint is always 0,0) - for p in xrange(15): + for p in xrange(64): # Will 2^p tiles wide and high suffice? # X has twice as many chunks as tiles, then halved since this is a @@ -92,10 +92,12 @@ class QuadtreeGen(object): if xradius >= worldobj.maxcol and -xradius <= worldobj.mincol and \ yradius >= worldobj.maxrow and -yradius <= worldobj.minrow: break + + if p < 15: + self.p = p else: - raise ValueError("Your map is waaaay too big! Use the 'zoom' option in 'settings.py'.") + raise ValueError("Your map is waaaay too big! Use the 'zoom' option in 'settings.py'. Overviewer is estimating %i zoom levels, but you probably want less." % (p,)) - self.p = p else: self.p = depth xradius = 2**depth diff --git a/overviewer_core/rendernode.py b/overviewer_core/rendernode.py index 9c4f047..cbd1ed2 100644 --- a/overviewer_core/rendernode.py +++ b/overviewer_core/rendernode.py @@ -108,15 +108,16 @@ class RenderNode(object): raise ValueError("there must be at least one quadtree to work on") self.options = options + # A list of quadtree.QuadTree objects representing each rendermode + # requested self.quadtrees = quadtrees #List of changed tiles self.rendered_tiles = [] #bind an index value to the quadtree so we can find it again #and figure out which worlds are where - i = 0 self.worlds = [] - for q in quadtrees: + for i, q in enumerate(quadtrees): q._render_index = i i += 1 if q.world not in self.worlds: @@ -163,18 +164,23 @@ class RenderNode(object): else: pool.map_async(bool,xrange(multiprocessing.cpu_count()),1) + # 1 quadtree object per rendermode requested quadtrees = self.quadtrees - # do per-quadtree init - - max_p = 0 + # Determine the total number of tiles by adding up the number of tiles + # from each quadtree. Also find the max zoom level (max_p). Even though + # each quadtree will always have the same zoom level, this bit of code + # does not make that assumption. + max_p = 0 total = 0 for q in quadtrees: total += 4**q.p if q.p > max_p: max_p = q.p self.max_p = max_p - # Render the highest level of tiles from the chunks + + # The next sections of code render the highest zoom level of tiles. The + # section after render the other levels. results = collections.deque() complete = 0 logging.info("Rendering highest zoom level of tiles now.") @@ -247,7 +253,8 @@ class RenderNode(object): self.print_statusline(complete, total, 1, True) - # Now do the other layers + # The highest zoom level has been rendered. + # Now do the lower zoom levels for zoom in xrange(self.max_p-1, 0, -1): level = self.max_p - zoom + 1 assert len(results) == 0 @@ -295,21 +302,21 @@ class RenderNode(object): requested, a new task is added to the pool and a result returned. """ if batch_size < len(self.quadtrees): - batch_size = len(self.quadtrees) + batch_size = len(self.quadtrees) batch = [] - jobcount = 0 + jobcount = 0 # roundrobin add tiles to a batch job (thus they should all roughly work on similar chunks) iterables = [q.get_worldtiles() for q in self.quadtrees] for job in roundrobin(iterables): # fixup so the worker knows which quadtree this is - job[0] = job[0]._render_index + job[0] = job[0]._render_index # Put this in the batch to be submited to the pool batch.append(job) jobcount += 1 if jobcount >= batch_size: - jobcount = 0 + jobcount = 0 yield pool.apply_async(func=render_worldtile_batch, args= [batch]) - batch = [] + batch = [] if jobcount > 0: yield pool.apply_async(func=render_worldtile_batch, args= [batch]) @@ -341,6 +348,7 @@ class RenderNode(object): @catch_keyboardinterrupt def render_worldtile_batch(batch): + # batch is a list. Each item is [quadtree_id, colstart, colend, rowstart, rowend, tilepath] global child_rendernode rendernode = child_rendernode count = 0 diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index a74859e..039746c 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -35,7 +35,7 @@ def _find_file(filename, mode="rb", verbose=False): * the textures_path given in the config file (if present) * The program dir (same dir as overviewer.py) - * The overviewer_core textures dir + * The overviewer_core/data/textures dir * On Darwin, in /Applications/Minecraft * Inside minecraft.jar, which is looked for at these locations @@ -303,9 +303,9 @@ def _build_block(top, side, blockID=None): composite.alpha_over(img, otherside, (12,6), otherside) composite.alpha_over(img, top, (0,9), top) else: + composite.alpha_over(img, top, (0,0), top) composite.alpha_over(img, side, (0,6), side) composite.alpha_over(img, otherside, (12,6), otherside) - composite.alpha_over(img, top, (0,0), top) # Manually touch up 6 pixels that leave a gap because of how the # shearing works out. This makes the blocks perfectly tessellate-able diff --git a/sample.settings.py b/sample.settings.py index e461189..015120b 100644 --- a/sample.settings.py +++ b/sample.settings.py @@ -111,7 +111,7 @@ if imgformat != "jpg": ################################################################################ ### web_assets_hook ## If provided, run this function after the web assets have been copied, but -## before actual tile rendering beings. It should accept a QuadtreeGen +## before actual tile rendering beings. It should accept a MapGen ## object as its only argument. Note: this is only called if skipjs is True ## Default: not yet ## Type: function diff --git a/setup.py b/setup.py index a0b8e35..cd1b7d0 100755 --- a/setup.py +++ b/setup.py @@ -105,7 +105,7 @@ if py2exe is not None: b = 3 else: b = 1 - setup_kwargs['options']['py2exe'] = {'bundle_files' : b, 'excludes': 'Tkinter'} + setup_kwargs['options']['py2exe'] = {'bundle_files' : b, 'excludes': 'Tkinter', 'includes':['fileinput', 'overviewer_core.items']} # # py2app options