A heads up to developers, the 0.7 release, when it comes out, will absolutely include breaking changes, although all breaking changes that do appear in the primary interfaces should be trivial to correct. Along with documentation, things are being moved around to make the library more accessible from Intellisense etc.
If there are any outstanding suggestions or changes people would like to see, now would be an excellent time to suggest them. mcschematic support is still on my list.
My best guess is that chunks are being incorrectly evicted from the cache, either because their dirty bit is not being tracked correctly, or because dirty chunks are not being correctly preserved. If you don't mind building Substrate from source (from the 0.6.1 zip, not from SCM), you could try poking this bug by changing the size of the cache in Utility/ChunkCache.cs. I would anticipate that if it is a cache bug, significantly reducing the size would result in more data loss.
I think this is a bug that should definitely be fixed, BUT I think it's still good for you to periodically save chunks. If you don't, every modified chunk has to be held in memory so you could use quite a bit of space if you touched a lot of chunks.
Paintings are actually entities, not tile entities. Each chunk has an Entities property that you can query for all entities of a specific type, like Painting. There's also functions to remove and add entities so you could use a combination of that to move a painting. You will manually need to update the position of the entity before inserting it into a new chunk. They're generally painful to deal with and maybe paintings deserve some special handling due to their pseudo-block nature.
Level has a Time property that is used to set the creation time of worlds. Current UTC would probably make a more sensible default value. LastPlayed is not settable, I don't think it makes much semantic sense to do so, but if it actually affects MC's behavior then I can change that.
Anything to do with MC's natural terrain generator is unfortunately out of scope. I can't call the generator to produce new chunks and I can't emulate it. It's also a higher-level construct, although that one might be genuinely useful even in an SDK. Rendering on the other hand is very open-ended and that's why we have so many different map renderers in the first place. It's definitely application-domain, but using something like Substrate makes implementing them much easier.
Thanks for checking the bug, I guess i have some poking around to do. The easy workaround, of course, is to modify* less than 256 chunks before saving (* With lighting or fluid recalculation, multiple chunks may be modified during a single block operation).
It's probably going to be at least a couple weeks before the next release, since the API and internal implementation changes are turning out to be more substantive than I estimated. On the plus side I am expecting to include schematic support and a couple other nice things in the release.
Entities aren't *that* bad. You want something like this (I do not guarantee the code to be correct).
int xdiff = (newchunk.X - oldchunk.X) * 16;
int zdiff = (newchunk.Z - oldchunk.Z) * 16;
List<Entity> entities = oldchunk.Entities.FindAll("Painting");
foreach (Entity entity in entities) {
EntityPainting painting = entity as EntityPainting;
painting.TileX += xidff;
painting.TileZ += zdiff;
painting.Position.X += (double)xdiff; // These may not even be used
painting.Position.Z += (double)zdiff;
newchunk.Entities.Add(painting);
// oldchunk.Entities.Remove(painting); // Todo: Add support for this method
}
oldchunk.Entities.RemoveAll("Painting");
Ugh, this is what I get for trusting the Minecraft wiki. I almost feel compelled to dive into the real MC source just to verify these types.
Fortunately when 0.7 comes out, NBT type errors will actually get printed out to the console before dying, making these problems easier to track down. The Minecart and Painting schemas need to be updated.
Where? I didn't find them from google code page... Thanks for telling that relighting stuff, appreciated :biggrin.gif:
My generator project has started to take a shape (or more likely only testing...)! It has been quite easy to code to this point, just some sinus functions and nothing random :tongue.gif:
Can I have the code as some kind of base for my generator? As being in 8th grade my knowledge of trigonometry is limited.
Well, I'm not giving the full source of Interference to you, but for what I did for that image, was something like this:
...(for loop with X and Z values)
int Height = 70; //Default height (and average also)
Height += Math.Sin((X / 50.0 + Z / 30.0) / Math.PI) * 10; //Wavelenght on X-axis:50, Z-axis:30, amplitude 10 blocks
Height += Math.Sin((X / 10.0 + Z / 200.0) / Math.PI) * 20; //Wavelenght on X-axis:10, Z-axis:200, amplitude 20 blocks
for (int Y = 0; Y <= Height; Y++)
{
...Add block to place X, Y, Z. To determine which block id to use, try to check if Y < Height - 5 for stone, Y < Height for dirt and Y == Height for grass...
}
...iterate
I didn't write that code inside code editor, so there might be typos. And I don't remember the code to place a block.
I posted on Nbtoolkit but here I come again to have your help :
I just want to change blocks from Industrial Craft by air or dirt in a big map (3000*3000) and nb toolkit seems to have for 3 days to do that :smile.gif:
How can I do with substrate to do that ? (I'm a noob with coding !)
Might prove a bit hard to pull off without any basic coding skills. :wink.gif:
Your best bet might be to use a mapeditor like MCEdit or its command line version, MCE.
Rollback Post to RevisionRollBack
External server browser: Created by me, made for you.
Not working atm, and will not get updated in the near future, sorry.
The Meaning of Life, the Universe, and Everything.
Join Date:
7/17/2010
Posts:
39
Member Details
I may have a bug - I receive the following NullReferenceException when calling GetBlock(in, int, int) on am AlphaBlockCollection in a Chunk:
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object
at Substrate.Block..ctor (IAlphaBlockCollection chunk, Int32 lx, Int32 ly, Int32 lz) [0x00000] in <filename unknown>:0
at Substrate.AlphaBlockCollection.GetBlock (Int32 x, Int32 y, Int32 z) [0x00000] in <filename unknown>:0
at CityGenerator.Grid.Data.Buildings.BuildingFloor.CopyChunkToBlocks (Int32 XPosInBlocksArray, Int32 ZPosInBlocksArray, Substrate.Chunk Source) [0x00015] in ****Building.cs:83
at CityGenerator.Grid.Data.Buildings.BuildingFloor..ctor (INBTWorld TemplateWorld, Int32 TemplateChunkX, Int32 TemplateChunkZ, Int32 XSize, Int32 ZSize) [0x000c9] in ****Building.cs:61
....
The error continues, but it's all my code past that point. The method that generates this exception is as follows:
private void CopyChunkToBlocks(int XPosInBlocksArray, int ZPosInBlocksArray, Chunk Source) {
for (int X = 0; X < 16; ++X) {
for (int Z = 0; Z < 16; ++Z) {
for (int Y = 0; Y < Height; ++Y) {
Blocks[X + XPosInBlocksArray, Y, Z + ZPosInBlocksArray] = Source.Blocks.GetBlock(X, Y + 64, Z);
}
}
}
}
Source is set as a chunk retrieved from a BetaWorld ChunkManager. I know the chunk should not be malformated, because it retrieved unmodified from a Minecraft world, saved by Minecraft. The world is opened with a call to BetaWorld.Create();
[edit]
Inspecting with the debugger reveals that the _stream variable in the Chunk class is null. Don't know if that helps, but it is the only null reference I can find in the Chunk object. I did not go through the private variables referencing System types. It also worth noting that this error can be worked around by getting the ID and Data fields individually, then constructing a new Block object out of them. Using this workaround, everything is OK until attempting to use the SetBlock() method, where it all blows up again, unless you use the same trick, in reverse(Setting the ID, then the Data from the Block in my Blocks array).
I need more source code to determine what is actually going on. Optimization is resulting in a stack trace that does not accurately pinpoint the problem. What is being created with BetaWorld.Create()? Since that returns a world with no chunks.
I need more source code to determine what is actually going on. Optimization is resulting in a stack trace that does not accurately pinpoint the problem. What is being created with BetaWorld.Create()? Since that returns a world with no chunks.
Saying BetaWorld.Create() was me being lazy. The actual call is BetaWorld.Create("./templates/templateworld/"). I'm writing this on Ubuntu Linux, hence the / instead of \\ like on Windows. I can assure you that there is in fact a world on the end of that call, because I have other code that copies chunks from it into another world. If you want, I can build a version of Substrate with the debug mode for Mono on, so maybe it can give you a better stack trace. As for more code, here is the call to the method that generates the crash:
CM is the chunk manager of the world created with the aformentioned BetaWorld.Create("./templates/templateworld/") call. TemplateChunkX has a value of 6, and TemplateChunkZ has a value of 0. The chunk at that position exists, as verified visually in Minecraft. The Blocks array in the method I previously posted has the definition of:
I guess it may technically work with BetaWorld.Create, but if you're opening an existing world, you should use BetaWorld.Open (it will do more checking and load a proper level.dat).
Manipulating arrays of Blocks is a little unusual and I still can't really tell what is going on. If you feel comfortable with sending me your project, I can debug it and find the problem. Otherwise you should recompile a debug build and try to hone the problem a little better.
The Meaning of Life, the Universe, and Everything.
Join Date:
7/17/2010
Posts:
39
Member Details
I'm starting to think that it's my code, not yours, so I will be taking a closer look at my code before pointing more fingers. I will try to work on it some more tomorrow. The reason that I am working with arrays of blocks is that I am trying to make a city generator that takes an specially formatted image as input, and turns it into a Minecraft save. Instead of procedurally generating the buildings and roads, I want to have a world that is used as a "template" for the infrastructure. For instance, at chunk 0, 0 I have the North/South road segment and at chunk (0, 1) I have the West/East road segment. The program then analyses the image and determines where the other roads are, and based on that data copies in the appropriate road segment. That works, because I just create a copy of the Chunk instance at the appropriate location in the template, set it's position and dump it into the output world. I want to do a similar thing with the buildings, but have them a random height. To accomplish this, I have the different possible floors of the building laid out in the template save (like the north east corner for the middle level is at chunk position 6, 0). So, I have to read those floors into a Block array. When the grid requests a chunk, the necisary section of the Blocks array is copied into that chunk, which is compounded with the other floors and returned to the grid. Now that I have written a thoroughly confusing description, code of what I just described can be found here.
I tried, but I can't compile a debug build of Substrate because the Mono compiler isn't very flexible, and it won't compile the library without the Schematic.cs file in the IO directory. I appreciate your help.
The Meaning of Life, the Universe, and Everything.
Join Date:
7/17/2010
Posts:
39
Member Details
The bug I found is reproducible. The following code generates the exception:
public static void Main (string[] args) {
INBTWorld World = BetaWorld.Open("./test/");
ChunkManager CM = (ChunkManager) World.GetChunkManager();
CM.GetChunk(6, 0).Blocks.GetBlock(0, 0, 0);
}
The world I used to test this can be found here, as hosted by dropbox. You will need to rename the world folder to "test" (without the quotes) and place it in the same directory as the code is executing in.
Change the block's ID to the spawner ID. Create a new TileEntityMobSpawner, set its EntityID property to 'Skeleton', then assign the object back to the block with SetTileEntity.
A heads up to developers, the 0.7 release, when it comes out, will absolutely include breaking changes, although all breaking changes that do appear in the primary interfaces should be trivial to correct. Along with documentation, things are being moved around to make the library more accessible from Intellisense etc.
If there are any outstanding suggestions or changes people would like to see, now would be an excellent time to suggest them. mcschematic support is still on my list.
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate
I think this is a bug that should definitely be fixed, BUT I think it's still good for you to periodically save chunks. If you don't, every modified chunk has to be held in memory so you could use quite a bit of space if you touched a lot of chunks.
Paintings are actually entities, not tile entities. Each chunk has an Entities property that you can query for all entities of a specific type, like Painting. There's also functions to remove and add entities so you could use a combination of that to move a painting. You will manually need to update the position of the entity before inserting it into a new chunk. They're generally painful to deal with and maybe paintings deserve some special handling due to their pseudo-block nature.
Level has a Time property that is used to set the creation time of worlds. Current UTC would probably make a more sensible default value. LastPlayed is not settable, I don't think it makes much semantic sense to do so, but if it actually affects MC's behavior then I can change that.
Anything to do with MC's natural terrain generator is unfortunately out of scope. I can't call the generator to produce new chunks and I can't emulate it. It's also a higher-level construct, although that one might be genuinely useful even in an SDK. Rendering on the other hand is very open-ended and that's why we have so many different map renderers in the first place. It's definitely application-domain, but using something like Substrate makes implementing them much easier.
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate
It's probably going to be at least a couple weeks before the next release, since the API and internal implementation changes are turning out to be more substantive than I estimated. On the plus side I am expecting to include schematic support and a couple other nice things in the release.
Entities aren't *that* bad. You want something like this (I do not guarantee the code to be correct).
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate
Fortunately when 0.7 comes out, NBT type errors will actually get printed out to the console before dying, making these problems easier to track down. The Minecart and Painting schemas need to be updated.
Here's a patch, copy these files into the entities directory, and rebuild from source.
http://www.hocuspocus.taloncrossing.com/rii/substrate-patch-0.6.1a.zip
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate
Can I have the code as some kind of base for my generator? As being in 8th grade my knowledge of trigonometry is limited.
[edit]
Also how do you set blocks using BlockManager?
I <3 you (no homo)
I posted on Nbtoolkit but here I come again to have your help :
I just want to change blocks from Industrial Craft by air or dirt in a big map (3000*3000) and nb toolkit seems to have for 3 days to do that :smile.gif:
How can I do with substrate to do that ? (I'm a noob with coding !)
THanks a lot
Your best bet might be to use a mapeditor like MCEdit or its command line version, MCE.
External server browser: Created by me, made for you.Not working atm, and will not get updated in the near future, sorry.
The error continues, but it's all my code past that point. The method that generates this exception is as follows:
Source is set as a chunk retrieved from a BetaWorld ChunkManager. I know the chunk should not be malformated, because it retrieved unmodified from a Minecraft world, saved by Minecraft. The world is opened with a call to BetaWorld.Create();
[edit]
Inspecting with the debugger reveals that the _stream variable in the Chunk class is null. Don't know if that helps, but it is the only null reference I can find in the Chunk object. I did not go through the private variables referencing System types. It also worth noting that this error can be worked around by getting the ID and Data fields individually, then constructing a new Block object out of them. Using this workaround, everything is OK until attempting to use the SetBlock() method, where it all blows up again, unless you use the same trick, in reverse(Setting the ID, then the Data from the Block in my Blocks array).
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate
Saying BetaWorld.Create() was me being lazy. The actual call is BetaWorld.Create("./templates/templateworld/"). I'm writing this on Ubuntu Linux, hence the / instead of \\ like on Windows. I can assure you that there is in fact a world on the end of that call, because I have other code that copies chunks from it into another world. If you want, I can build a version of Substrate with the debug mode for Mono on, so maybe it can give you a better stack trace. As for more code, here is the call to the method that generates the crash:
CM is the chunk manager of the world created with the aformentioned BetaWorld.Create("./templates/templateworld/") call. TemplateChunkX has a value of 6, and TemplateChunkZ has a value of 0. The chunk at that position exists, as verified visually in Minecraft. The Blocks array in the method I previously posted has the definition of:
XSize has a value of 5, Height a value of 6 and ZSize a value of 5.
I hope this helps. If you need any more information, just ask.
Manipulating arrays of Blocks is a little unusual and I still can't really tell what is going on. If you feel comfortable with sending me your project, I can debug it and find the problem. Otherwise you should recompile a debug build and try to hone the problem a little better.
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate
I tried, but I can't compile a debug build of Substrate because the Mono compiler isn't very flexible, and it won't compile the library without the Schematic.cs file in the IO directory. I appreciate your help.
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate
The world I used to test this can be found here, as hosted by dropbox. You will need to rename the world folder to "test" (without the quotes) and place it in the same directory as the code is executing in.
Block.cs, line ~34, there is this line:
It needs to be changed to:
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate
Mods I Develop: Garden Stuff -- Storage Drawers -- Hunger Strike
Tools I Develop: NBTExplorer -- Substrate