Search Home Members Contacts
About Us
Products
Downloads
Community
Support
Pages: [1]
  Print  
Author Topic: Delphi:Minecraft Level Chunk Loading  (Read 2908 times)
Simon84
Community Member
*
Posts: 5


« on: October 19, 2010, 09:01:35 AM »

Hi i started programming an import tool for the Named Binary Tag format used by minecraft.
http://www.minecraft.net/docs/NBT.txt

Lately implemented support for level chunk files.
http://www.minecraftwiki.net/wiki/Alpha_Level_Format#Chunk_File_Format

Source code is far away from optimized, and there is still a lot of work to do.
Sorry no comments Wink Shame on me!
I saw that other forum members here also working on minecraft inspired projects,
so i decided to contribute my actual state of work, maybe the nbt import code helps someone.

!!!The nbt files of minecraft are gzipped you have to add their name an .gz and unzip them to work with this sourcecode...



(old)Source Code:
source.zip

Later maybe further description of code or more code, but out of time now Wink

Edit:
Yeeehaa it´s working fine, now loading 8x8level chunk files into a class and creates them as mini meshes.
Need to do more Occlusion Culling, only thing done yet is to disable all blocks completely sorrounded by other blocks, but framerate still drops to 9fps on AMDX2|5000+ with Ati Radeon HD4870.

:outside:


:inside:


:stats:


0.1a Windows Executeable+Source-BDS2006-Delphi
you may have to copy tv3d65.dll to system32 or run regtv3d65.bat, to get it working
Keyboard: WSAD:move around RF:up/down
« Last Edit: October 23, 2010, 11:42:44 PM by Simon84 » Logged
Simon84
Community Member
*
Posts: 5


« Reply #1 on: October 19, 2010, 07:53:31 PM »

Okay finished with cleaning up source of the nbt loader and made an object of it.
nbt.pas

TNamedBinaryTag =Class(TObject)
provides methods:

LoadFromFile(filename,TGauge) //gauge to show loading progress
  Loads NBTFile to self.cmp = TCompound
    TCompound is a Tree structure root node consists of
    tags   = Dynamic Array of pointer-->NBT_Tag  | last element always =end_tag
    sub    = Dynamic Array of pointer-->Compound | last element always =nil
    parent = pointer-->Compound

To view complete datastructure you can set breakpoint to line
Showmessage(Cmp.name); at the end of procedure LoadFromFile(); and
browse it in local variables then


  NBT_Tag is an dynamic record which always contains
    name:string;
    type:byte;  ->defines type of carried data
    0: ();
    1: (byte:byte);
    2: (short:SmallInt);
    3: (int:Integer);
    4: (long:Int64);
    5: (float:Single);
    6: (dbl:Double);
    7: (pba:PByteArray);     pointer-->dynamic array of byte
    8: (str:PString);        pointer-->string
    9: (pla:PNBTListArray);  pointer-->dynamic array of NBTList_Tag

NBT_List_Tag is same as NBT_Tag without 9:(pla:PNBTListArray), tags in lists are not named

AddToTree(pointer-->TTreeView)
  Add self.cmp to Treeview

There is no support for writing data back to file, cause i dont need to, but i think its could be simply implemented in the same way writing it to tree view, but you have to mention the reversed byte order for all datatypes longer 1 byte exept string. I think
best way to change byte order is to sort the bytes in an array with element count of
designated datatype size in bytes and then set pointer-->datatype=@byteArray[0]
Code:
    BlockRead(NBTFile,ba[3],1);
    BlockRead(NBTFile,ba[2],1);
    BlockRead(NBTFile,ba[1],1);
    BlockRead(NBTFile,ba[0],1);
    pfloat:=@ba[0];
    float:=pfloat^;

Also there is, still, no support for gzip so you have to un-/repack files yourself,or,better, add it, and post it here Wink i´m to lazy to, maybe later when my levelfiles grow.

further explaination:
self.cmp is the root node of the the compound tree, self.ptr is a pointer used to navigate
throuh compound tree.

Tree Navigation Example:
cPtr:=@cmp;
//set pointer to root node

if cPtr^.tags[0].typ<>0 then
    for i:=0 to High(cPtr^.tags)-1 do
      cptr^.tags.typ:=x;
//acces Tags in compounds pointer points to

procedure readsub;
  if cPtr.sub[0]<>nil then
    for i:=0 to High(cPtr.sub)-1 do
    begin
      cptr:=cptr^.sub;   //one level down
      //do sth with tags of compound

      //here you have to use an recursive call to read sub compounds of sub cmp´s of ..
     readsub;
     cPtr:=cPtr^.parent; //one level up
    end;
end
//acces sub compounds pointer points to

Other usefull:

Convert NBT_Tag Value to string:
Code:
  case Tag.typ of
    1 : result:=IntToStr(Tag.byte);
    2 : result:=IntToStr(Tag.short);
    3 : result:=IntToStr(Tag.int);
    4 : result:=IntToStr(Tag.long);
    5 : Result:=FloattoStr(Tag.float);
    6 : Result:=FloattoStr(Tag.dbl);
    7 : Result:='['+InttoStr(Length(Tag.pba^)-1)+']';
    8 : Result:=Tag.str^;
    9 : begin;
        Result:=' of '+IntToStr(Length(Tag.pla^)-1)+'*';
        Result:=Result+getEnumName(TypeInfo(TTagName),Tag.pla^[0].typ)+': ';
        for i:=0 to High(Tag.pla^)-1 do
          Result:=Result+':'+ListTagValToStr(Tag.pla^[i]);
    end;

NBT_Tag --> NBT_List_Tag
Code:
    ListTag.Name:=tCmp.tags[i].name;
    ListTag.typ:=tCmp.tags[i].typ;
    case tcmp.typ of
      1 : ListTag.byte  := tCmp.tags[i].byte;
      2 : ListTag.short := tCmp.tags[i].short;
      3 : ListTag.int   := tCmp.tags[i].int;
      4 : ListTag.long  := tCmp.tags[i].long;
      5 : ListTag.float := tCmp.tags[i].float;
      6 : ListTag.dbl   := tCmp.tags[i].dbl;
      7 : ListTag.pba   := tCmp.tags[i].pba;
      8 : ListTag.str   := tCmp.tags[i].str;
    end;

Optimization:
in Read ByteArray introduce var point:Pointer;
and change:
Code:
  for i:=0 to len-1 do
    ba[i]:=Read_TAGByte(false);
to
Code:
  point:=@ba[0];
  BlockRead(NBTFile,point^,len);
  point:=nil;
more then 10 times increased speed for loading levelChunk files cause they contain
several 16k or 32k lenght byte arrays

Simple gzip function:
Install 7zip and copy executable to programm dir.
Create .bat file to call programm.
Code:
7z x -y -o%2 %1
Run .bat file from Program:(uses ShellApi)
Code:
  RenameFile('.\biglc\'+FName,'.\biglc\'+FName+'.gz');
  if (fileExists('.\biglc\uc\'+FName) <> true) then
  begin
    ShellExecute(0, nil, PChar('.\test.bat'),PChar('".\biglc\'+FName+'.gz" ".\biglc\uc\"'), PChar('G:\Minecraft'), SW_SHOW);
    sleep(1000);
  end;
  AssignFile(NBTFile,'.\biglc\uc\'+FName);

to be continiued...






 
« Last Edit: November 01, 2010, 08:41:25 AM by Simon84 » Logged
PaulTheAxeman
Community Member
*
Posts: 37


« Reply #2 on: October 20, 2010, 03:21:10 PM »

Good work. I'm doing something similar. Trouble with the mini meshes though, you can't do a lot with them. Can't seem to collision check with them, can't seem to light them either.
Logged
AriusEso
Customers
Community Member
*****
Posts: 940

Esoteric


« Reply #3 on: October 21, 2010, 03:27:39 AM »

Good work. I'm doing something similar. Trouble with the mini meshes though, you can't do a lot with them. Can't seem to collision check with them, can't seem to light them either.

You can run physics on them and you can light them -- per-pixel if you want. You just have to do the work yourself as TV doesn't do this for you. They were originally intended as a light weight solution to grass and general clutter that didn't need collision. They less they could do the faster they were.

Ex: http://www.youtube.com/watch?v=E_NASpV5u7A
Logged

-...-

PaulTheAxeman
Community Member
*
Posts: 37


« Reply #4 on: October 21, 2010, 06:35:42 AM »

Ah.. so you can do some stuff with them. All is not lost then. thanks. Just need to work out how to do it.!! Wink Very new to this.
Logged
Simon84
Community Member
*
Posts: 5


« Reply #5 on: October 21, 2010, 06:35:14 PM »

Quote
can't seem to light them either

An really easy way to light them is to create materials, for them.
Logged
AriusEso
Customers
Community Member
*****
Posts: 940

Esoteric


« Reply #6 on: October 21, 2010, 06:58:52 PM »

An really easy way to light them is to create materials, for them.

I think you are limited to one directional light if you do that. In order to do multiple lights and point/spot lighting you need to write shaders.
Logged

-...-

Zaknafein
Customers
Community Member
*****
Posts: 2940


WWW
« Reply #7 on: October 21, 2010, 11:34:11 PM »

It'll be hard to use, but you might wanna check that out : http://www.truevision3d.com/forums/indevelopment/custom_hiperformance_minimeshes_octree_culling-t19164.0.html
Logged

Simon84
Community Member
*
Posts: 5


« Reply #8 on: October 22, 2010, 04:05:52 PM »

It'll be hard to use, but you might wanna check that out...

Thx, just read the thread some days ago, really great work, and defenitly also one of my next TODO´s.
Logged
PaulTheAxeman
Community Member
*
Posts: 37


« Reply #9 on: October 23, 2010, 06:56:37 PM »

I had a look at the octree stuff. Very good, unfortunately in c# and conversion to vb.net didn't quite make it  Sad
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.3 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks