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..c5c1790 --- /dev/null +++ b/docs/building.rst @@ -0,0 +1,152 @@ +=================================== +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 `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) + +Building with Visual Studio +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Get the latest 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 `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 `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..794c403 --- /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', 'sphinx.ext.viewcode'] + +# 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'2011, Andrew Brown and Contributors' + +# 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.0' +# 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'Andrew Brown and Contributors', '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'Andrew Brown and Contributors'], 1) +] diff --git a/docs/design/cube_parts.png b/docs/design/cube_parts.png new file mode 100644 index 0000000..19e4ef4 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..81749b7 --- /dev/null +++ b/docs/design/cube_parts.svg @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 24 + 24 + + + + + + + + + 25 + + + + + + diff --git a/docs/design/designdoc.rst b/docs/design/designdoc.rst new file mode 100644 index 0000000..d94391e --- /dev/null +++ b/docs/design/designdoc.rst @@ -0,0 +1,232 @@ +==================== +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! + +.. 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:: dirt_top.png + :alt: Top of dirt + +On the left is the top of the dirt 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:: dirt_side.png + :alt: The sides of the dirt block + +Again, the left are the two sides of the dirt 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 +---------------- + +Chunk Rendering +=============== +.. This goes over the rendering of a chunk + +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/dirt_side.png b/docs/design/dirt_side.png new file mode 100644 index 0000000..0634307 Binary files /dev/null and b/docs/design/dirt_side.png differ diff --git a/docs/design/dirt_top.png b/docs/design/dirt_top.png new file mode 100644 index 0000000..118fc54 Binary files /dev/null and b/docs/design/dirt_top.png differ diff --git a/docs/design/pixelfix.png b/docs/design/pixelfix.png new file mode 100644 index 0000000..228c1c5 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..0d7fd98 --- /dev/null +++ b/docs/design/pixelfix.svg @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + 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..8c773ea 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..2cace2e --- /dev/null +++ b/docs/design/tessellation.svg @@ -0,0 +1,400 @@ + + + + + + + + + + + + + + + + + + + + + + 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..2903b58 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..fdb73f2 --- /dev/null +++ b/docs/design/texturesidesteps.svg @@ -0,0 +1,401 @@ + + + + + + + + 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..bb89610 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..aa4d0a8 --- /dev/null +++ b/docs/design/texturetopsteps.svg @@ -0,0 +1,531 @@ + + + + + + + + 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..ab555a0 --- /dev/null +++ b/docs/faq.rst @@ -0,0 +1,22 @@ +========================== +Frequently Asked Questions +========================== + +**The full map doesn't display even when fully zoomed out!** + Are you using the `-z` or `--zoom` 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. + +**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 + `--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:ref:`centos` + +**The background color of the map is black, and I don't like it!** + You can change this by using the ``--bg-color`` command line option, or + ``bg_color`` in settings.py. See the `Options `_ page for more + details. + diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..fb5e7c0 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,68 @@ +======================== +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 `_. + +Download +======== + +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 +`Installation `_ page. + +**If you would like to build the Overviewer from source yourself (it's not that +bad)**, head to the `Building `_ page. + +.. _Github Homepage: https://github.com/overviewer/Minecraft-Overviewer + +Help +==== +**IF YOU NEED HELP COMPILING OR RUNNING THE OVERVIEWER** feel free to pop in +IRC: #overviewer on freenode. Not familiar with IRC? `Use the web client +`_. There's usually someone on +there that can help you out. + +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..edc96fd --- /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 `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 `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 `Running the Overviewer `_ page! diff --git a/docs/options.rst b/docs/options.rst new file mode 100644 index 0000000..2d21a58 --- /dev/null +++ b/docs/options.rst @@ -0,0 +1,340 @@ +======= +Options +======= + +.. 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:: --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. + + See the `Render Modes`_ section for more information. + +.. cmdoption:: --list-rendermodes + + List the available render modes, and a short description of each. + +.. cmdoption:: --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. + +.. cmdoption:: --settings=PATH + + Use this option to load settings from a file. For more information see the + `Settings File`_ section below. + +Less Useful Options +------------------- + +.. cmdoption:: -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 + +.. cmdoption:: -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 + +.. 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. + +.. cmdoption:: --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! + + + +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 --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. + +Render Modes +============ + +.. _rendermode-options: https://github.com/agrif/Minecraft-Overviewer/tree/rendermode-options + +Rendermode options are a new way of changing how existing render modes +work, by passing in values at startup. For example, you can change how +dark the 'night' mode is, or enable lighting in 'cave' mode. + +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 *settings.py* 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. + +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. + +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**. + +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}, + } diff --git a/docs/running.rst b/docs/running.rst new file mode 100644 index 0000000..8c9904d --- /dev/null +++ b/docs/running.rst @@ -0,0 +1,135 @@ +====================== +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. + +**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 `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 rerender only what's needed. + +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 ``--textures-path`` option. This should point to the directory containing + the terrain.png, not to the file itself. + +Note: the ``--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.