Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: Reading DF Tilesets (Javascript)  (Read 1210 times)

tme321

  • Escaped Lunatic
    • View Profile
Reading DF Tilesets (Javascript)
« on: April 12, 2010, 12:52:18 am »

I'm not sure if this is the correct place to post this, seeing as how this is more of an idea for a tool than a mod, but it seemed a bit more appropriate than the general discussion area.

I'm in the middle of creating a program that will use javascript to render DF tilesets for fortress planning purposes.  Currently I have it working just with the standard ascii character set, but I would like to enable it to also use any of the player made tilesets as well. 

So in that vein I'm wondering has anyone bothered to write the code to read in these tilesets besides Toady himself?  Any language would be fine, but if someone has already done it in Javascript that would be double plus good. 

I already understand that it's basically displaying a portion of a BMP based on a pointer to the starting location of the tile and that sort of stuff, but I figured if someone has already gone to the trouble of doing this it would save me some time. 

If no one has done that, is there anywhere where the specification for the tilesets is written more completely than the wiki?  The information there is geared more towards other people making their own tilesets, rather than information on how to read them properly. 

I also must admit, this has also been my excuse to learn Javascript, so if someone knows a better way to go about this with js I'm all ears to that option as well.

Thanks for any help.
Logged

Rochndil

  • Bay Watcher
  • Mad Modder
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #1 on: April 12, 2010, 02:54:03 pm »

Good afternoon.

I can't offer much in the way of assistance for your project, but I can say that this is something I've been needing for some time. It's very tedious to have to generate a whole world to properly test out a tileset. If you can create an app that will allow the user to specify a tileset, color spec, and then allow the tile(s) to be rendered accurately, that would help IMMENSELY in designing a tileset, which is a task I've attempted more than once. Being able to have several tiles rendered together (as would be logical for a design program) would help to see the "tiling" of the tiles, making sure they work as a group as well as individually.

Rochndil, not working on the MMO at the moment, but thinking about conversion issues...
Logged
Build an Elf a fire, keep him warm for a day.
Drown an Elf in magma, keep him warm for the rest of his life!

Stargrasper

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #2 on: April 12, 2010, 03:15:16 pm »

What seems to happen is that we write a tileset and Toady's code is apparently resilient enough to handle it.  What you may do is ask the guy that created the Custom Workshop Workshop.  His system does something similar to what you're asking about.  It's for the purpose of visualising what a custom workshop will look like and how to code it.  It may be similar enough to your goals that you can learn something if you ask him.
Logged

Shoku

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #3 on: April 12, 2010, 04:22:38 pm »

If it works with the default tileset what is stopping you from making it read a different file?
Logged
Please get involved with my making worlds thread.

Razputin

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #4 on: April 12, 2010, 04:39:11 pm »

Why are you using java script over java?

I could tell you how to easily do this in java but i don't know much about javascript.  Perhaps explaining the process I use in java to read tilesets would be helpful though.

All of the tilesets for any for DF are in the same format a large image which is a 16 x 16 grid of smaller images the size of the smaller images varies but this can be easily figured out by dividing the height or width of the image by 16 (total width / number of images = width of image) you may want to do this again for the height of the images in case they are not square.

So now you have the dimensions of each tile in the tileset you can start extracting them from the actual image.  This is where I probably can't help much with javascript but I will explain the proccess in java in case it is helpful.

In java there is a class called BufferedImage which stores an image loaded from a file, it has a method getSubimage which takes an x position, a y position, width and height and returns a new BufferedImage object from that section of the larger image.  Then all that is left is to use a switch or an if/elseif statement to draw the correct image for each tile on the map.

This will work for any tileset because they all have the same basic format with images for say the ramp always in the same place.  Here is my code for loading a spritesheet in java and then getting images from it:
Code: [Select]
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.File;
import javax.imageio.ImageIO;

public class SpriteSheet
{
    private BufferedImage sheet; //the spritesheet containing all images
    private int spriteDimension = 8; //the size of the image
    /**
     * Constructor for objects of class SpriteSheet
     */
    public SpriteSheet(String filename)
    {
        try
        {
            sheet = ImageIO.read(new File(filename));//load image
        }
        catch(IOException e)
        {
            System.out.println("IO error File: " + filename);
        }
           
    }
    public SpriteSheet(String filename, int dimension)
    {
        spriteDimension = dimension;
        try
        {
            sheet = ImageIO.read(new File(filename));//load image
        }
        catch(IOException e)
        {
            System.out.println("IO error File: " + filename);
        }
           
    }
    //get a new image from the sheet using the default dimension
    //xIndex and yIndex are the image index so for the second picture on the top row
    //you would use (1,0)
    public BufferedImage getSprite(int xIndex, int yIndex)
    {
        return sheet.getSubimage(
            xIndex * spriteDimension,//adjust to pixels
            yIndex * spriteDimension,
            spriteDimension,
            spriteDimension);
    }
    //get a new image from anywhere on the sheet xPos and yPos must be in pixels
    public BufferedImage getSprite(int xPos, int yPos, int xD, int yD)
    {
        return sheet.getSubimage(
            xPos,
            yPos,
            xD,
            yD);
    }
}


If it works with the default tileset what is stopping you from making it read a different file?

I assume he is using ascii by default not a tileset
Logged

Stargrasper

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #5 on: April 12, 2010, 04:51:21 pm »

Why are you using java script over java?

He said he's doing it specifically to learn to use javascript.  Yeah, I agree java is better, but I won't argue with learning something new.  That being said, I know java but have never done anything like this.  So, I'm glad somebody else has an example to offer.
Logged

Phoebus

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #6 on: April 12, 2010, 05:15:10 pm »

This is a really bad project to learn JavaScript with.
One of the principal flaw of JavaScript is it's lack of native support for binary strings/data, and what you are trying to do is all manipulation of binary data.
Also, browser JavaScript does not have the ability to open files on your hard-disk.
This will be painful.
Logged

Shadowlord

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #7 on: April 12, 2010, 05:38:05 pm »

A firefox plugin can open files on the hard disk. It'll still be painful though. Getting it to read a tileset and split the images up in javascript, I don't have a clue how you'd do that, and I do know javascript. Messing with images is not something you want to do in javascript. Besides being not even remotely suited for it, javascript is s-l-o-w.

You could do it in flash, you could do it in java, you could do it in C# but it wouldn't be quite portable (despite microsoft's claims of portability, they have no intention of actually doing anything towards portability, and mono seems to have... problems with breaking other things when installed last I heard). You could do it in any number of other languages, but java or c# will probably make it easiest.
« Last Edit: April 12, 2010, 05:41:53 pm by Shadowlord »
Logged
<Dakkan> There are human laws, and then there are laws of physics. I don't bike in the city because of the second.
Dwarf Fortress Map Archive

Phoebus

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #8 on: April 12, 2010, 05:44:46 pm »

Besides being not even remotely suited for it, javascript is s-l-o-w.
Modern JavaScript engines are around 10 time faster than other high-level languages like PHP or Python.
Logged

soul4hdwn

  • Bay Watcher
  • make due with what you have
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #9 on: April 12, 2010, 06:05:02 pm »

java is actually moderately slow but it is fairly strong.
c++ is very fast but has memory leaking and ugly syntax (compared to java)
Logged

Shadowlord

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #10 on: April 12, 2010, 08:09:56 pm »

I didn't suggest writing it in PHP or Python, did I? :P
Logged
<Dakkan> There are human laws, and then there are laws of physics. I don't bike in the city because of the second.
Dwarf Fortress Map Archive

tme321

  • Escaped Lunatic
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #11 on: April 12, 2010, 08:45:33 pm »

Thanks for all the replies. 

My purpose behind javascript as the driving force is I plan on making this an application that can be used from the browser as a nod to the DF players who aren't on Windows.  I have already discounted Java because I really don't like the direction the language has taken but I don't think this is the place to have a long winded discussion on the merits of various languages.

The good news is after messing around with HTML + CSS + Javascript I found that this will be actually much simpler than I originally planned, I already have a small demo that displays a single tile.  Each time the user clicks on it the image changes to the next tile in the sequence.  So now that I have proven the concept it's only a matter of implementation  ;).

As for the "default tileset" I mentioned, I meant the ascii characters that DF uses.  So a text mode, not a graphics mode, if you will.  But as I said the graphics are working now so it is now just a matter of time.

I think I am going to work on an initial version that will simply be something along the lines of a 16x16 grid of tiles that can be changed to anything in the tile set. 

I'm thinking the user will be presented with one drop down box for the tiles that represent background images (floors, smoothed floors, engraved floors, etc) and one that represents the images that can be layed down on top (the dwarves, furniture, walls, etc).  Then the user would just click where on the 16x16 grid to place the selection of background and foreground images.

This initial version will be both a proving ground as to the viability of the project and also something that will garner me the eternal love and gratification of the tileset creators out there.

Long term I plan on adding the following features:

-Support for larger spaces the user defines, so if they wish they can represent an entire actual level of a map in DF.

-Multiple layers to switch between as per the actual game.

-The ability to designate whole "rooms" at once, both square and circular.  A click on the first point and drag to the second point style kind of thing similar to the way you draw squares and circles in something like MS Paint.

-Ability to save fortress designs

-A "homepage" for the program where new tilesets can be added and previous fortress layouts can be loaded from.

-Allowing the user to also configure what material type things are so they can see what a black bronze plated room will look like vs a simple granite one.

Possible very long term features:

-Ability to create "rooms" across muiltiple levels, think cube and sphere instead of just square and circle.

If anyone wants to help with any of this I would appreciate it.  I am not at the computer that has the initial demo at the moment, so I will get it tomorrow and try to find someplace to store it so others can take a look.

More than the actual code though, I would especially like some advice and ideas on how the GUI should look.  Keep in mind this will be webpage-like so stuff like drop down boxes and buttons are very easy but some style of controls will be very hard or impossible.

Also I'd love to hear any suggestions for further features, I probably won't get to them for a long time (think months at earliest) but I'd love some ideas.

Finally, if you aren't interested in a discussion about language choices you can stop reading here.

Quote
c++ is very fast but has memory leaking and ugly syntax

True but it is overkill for this project.  I don't need to reinvent the wheel on how to display a simple BMP image to the screen (or hunt down a library that allows me to), I just need capabilities already present in a webbrowser.

Quote
A firefox plugin can open files on the hard disk.

This is perhaps a valid point, I have not looked at the ability of javascript to save files locally.  I assumed that they have to be able to since webservers generate files on the fly (yes I know they are normally just kept in memory...), but I might end up having to use a clutch like that which means this might end up firefox only but I'm going to try not to go that route.

Quote
You could do it in flash
Did you honestly suggest flash and then comment on the speed of any other language in existence?  Plus, I have other issues with using highly proprietary languages when others exist that can fill the niche.  I would not be above C# if I were going windows only, but I have already decided against that because I already know C# and want portability.

Quote
This is a really bad project to learn JavaScript with.
Not entirely sure this is as true as you think, but even if it is that just means I'll know the language that much better when I'm done.

Quote
One of the principal flaw of JavaScript is it's lack of native support for binary strings/data, and what you are trying to do is all manipulation of binary data.

First, with some of the HTML5 tags available I have a lot of capability dealing with binary data.  Second, I'm not actually dealing with binary data at all (directly) because the browser already has the libraries it needs to display images.  This is really a non-issue.

Razputin thanks for the info, but I actually already knew this much.  If I were implementing the program from something like Java or C I would know exaclty how to do it, it would just be all the hassle of doing the math and setting up pointer arrays, blah blah.  Instead I'm trying to utilize features that are already found in browser languages.

As far as speed of rendering and such is concerned it won't be an issue.  First, I'm going to be dealing with a single image, the tileset chosen, to load into memory.  Everything else is just pointers to which part of the tileset to display at any given point on the screen.  And javascript plenty fast these days for rich applications.  To the computer the difference might be whether it has 1,000 nullops between user actions or 1,000,000, but the end user won't see much difference compared to say C. 

Since I get to make heavy use of HTML and CSS most of the memory footprint of the program will already be wrapped up in the browser, so as long as your computer can run Firefox it shouldn't be a deal breaker.  Remember, that while it will run in your browser, the program will be local so the only speed issue is your PC, not the internet connection. 

And I have a hard time believing that any computer made within the last 6 years would have a hard time rendering a bunch of tiles inside of a browser which is made for that sort of purpose.

Anyway, thanks for all the replies so far.  I'll provide updates as I can manage.
Logged

Stargrasper

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #12 on: April 12, 2010, 10:22:38 pm »

A not-necessarily-windows project...always good...it gets annoying launching everything in wine or just passing it up.

If you can get this working, I look forward to it.  Good luck.
Logged

Shadowlord

  • Bay Watcher
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #13 on: April 12, 2010, 10:37:30 pm »

Quote
You could do it in flash
Did you honestly suggest flash and then comment on the speed of any other language in existence?  Plus, I have other issues with using highly proprietary languages when others exist that can fill the niche.  I would not be above C# if I were going windows only, but I have already decided against that because I already know C# and want portability.

I'd note that I have never used Flash myself and pointed it out because similar things with tiles have been done quite well by the DF Map Archive, and that I have no idea how fast or slow Flash really is since I haven't used it, and presumed that Adobe would have made it at least reasonably fast, considering how much money it costs (and that the map archive does not appear slow, but I know that it is well-optimized, too, so... :P).

The DF Map Archive does quite well at rendering maps, although it doesn't serve the same purpose that you're talking about (it reads the maps from a format that my map compressor exports, and the compressor generates those from the exported bmps that DF writes out. The compressor is written in  c#, though some day I may eventually get around to porting the entire thing properly to something else besides java (I don't particularly care for java myself, it has too many flaws which bug me too much, such as the lack of unsigned integers, the need to catch every single exception that anything could throw rather than leave certain ones alone which aren't expected to occur so that if they do occur you're notified by the exception stack trace, java webstart's flaws, etc... But c# isn't that great for portability, even with mono)).
« Last Edit: April 12, 2010, 10:39:13 pm by Shadowlord »
Logged
<Dakkan> There are human laws, and then there are laws of physics. I don't bike in the city because of the second.
Dwarf Fortress Map Archive

tme321

  • Escaped Lunatic
    • View Profile
Re: Reading DF Tilesets (Javascript)
« Reply #14 on: April 12, 2010, 10:44:04 pm »

The problem with flash is that for the most part it is unoptimized.  The latest version for windows, 10.1 I think, is much better but the Mac OSX version is notoriously slow and causes massive CPU spiking.  This is one of the reasons that Apple refuses to allow Flash on the iPhone/iPad.  And the Linux version is no better.

Javascript on the other hand has gone through a transformation as of the last couple of years.  Google Chrome showed just how fast JIT and smart optimizations could make the language and every browser out there is making good gains in increasing their JS performance as well to catch up.
Logged