[Code] A Thread On Lambdas And Other Epsilons


simplex

Recommended Posts

Glad to see relevant bugs being fixed!

 

Speaking of bugs. This one is just silly. It happens when describing the beans.

Wow, I thought this had been fixed. This used to happen for some Unicode characters, but it was supposedly fixed a long time ago. Maybe the fix was only applied to (the strings resulting from) translation files, and not to "core" strings.

But anyway, the issue is that Luggs used a Unicode quote mark, "’", instead of an ASCII one, "'", in 13 places. I just fixed and pushed it.

EDIT: Damn, the forum's font shows no difference between the quote marks (unless you're writing the post in "advanced" mode, where a monotype font is used). The two quote marks are:

EDIT2: As you can see, I tried to show the quote marks in the previous edit (in a code block). But this had the side effect of making my whole post invisible, somehow, so I give up. Just look them up in gedit, in the strings.lua file before my latest commit :razz:.

Link to comment
Share on other sites

Wow, I thought this had been fixed. This used to happen for some Unicode characters, but it was supposedly fixed a long time ago. Maybe the fix was only applied to (the strings resulting from) translation files, and not to "core" strings.

But anyway, the issue is that Luggs used a Unicode quote mark, "’", instead of an ASCII one, "'", in 13 places. I just fixed and pushed it.

EDIT: Damn, the forum's font shows no difference between the quote marks (unless you're writing the post in "advanced" mode, where a monotype font is used). The two quote marks are:

EDIT2: As you can see, I tried to show the quote marks in the previous edit (in a code block). But this had the side effect of making my whole post invisible, somehow, so I give up.

 

Wow, Don't Starve in general doesn't agree much with Unicode.

Link to comment
Share on other sites

Wow, Don't Starve in general doesn't agree much with Unicode.

To be honest, Lua is to blame here. Many scripting languages have native Unicode support, but Lua does not.

(this is a presentation by one of Lua's creators; check page 2, and then page 10)

Link to comment
Share on other sites

@debugman18

I implemented biome (room) callbacks (on entry/exit), and used this to implement permanent snow in the snow biomes.

However, the detection is much less precise than I'd like. Apparently the rooms are not real Voronoi cells, but distorted ones. Sometimes I have to walk up to three tiles into a biome for it to detect I'm in that biome. And once in my testing I wasn't detected to be in a snow biome at all in a large portion of it, though I think that's because it was adjacent to the starting biome (since the starting biome is simply plopped into the formed map, so the geometry doesn't work out). This is fine for effects like snow fall, but it might be too inaccurate for our idea of switching colourcubes per biome (it could still work, though).

When testing, note that I'm only checking for biome change every 2-3 seconds.

Link to comment
Share on other sites

@debugman18

I implemented biome (room) callbacks (on entry/exit), and used this to implement permanent snow in the snow biomes.

However, the detection is much less precise than I'd like. Apparently the rooms are not real Voronoi cells, but distorted ones. Sometimes I have to walk up to three tiles into a biome for it to detect I'm in that biome. And once in my testing I wasn't detected to be in a snow biome at all in a large portion of it, though I think that's because it was adjacent to the starting biome (since the starting biome is simply plopped into the formed map, so the geometry doesn't work out). This is fine for effects like snow fall, but it might be too inaccurate for our idea of switching colourcubes per biome (it could still work, though).

When testing, note that I'm only checking for biome change every 2-3 seconds.

 

Hmm. From what I just read of voronoi cells, isn't their usefulness nullified if you distort them? I was looking at graphedge and graphnode. Are either of these where the distortion is happening, or am I way off?

 

     -- We add 1 here because the map will be rendered in 0->width-1 instead of lua's 1->width    map:DrawLine(n1center.x+1, n1center.y+1, n2center.x+1, n2center.y+1,  value)

 

function Edge:DrawDebug(draw, map)    local n1center = self.node1:GetCenterRelativeToMap(map)    local n2center = self.node2:GetCenterRelativeToMap(map)        draw:Line((n1center.x-map.width/2.0)*TILE_SCALE, (n1center.y-map.height/2.0)*TILE_SCALE, (n2center.x-map.width/2.0)*TILE_SCALE, (n2center.y-map.height/2.0)*TILE_SCALE, self.colour.r, self.colour.g, self.colour.b, self.colour.a)end

 

On the subject of rooms, could you explain what's happening here?

 

                    custom_tiles={                        GeneratorFunction = RUNCA.GeneratorFunction,                        data = {iterations=3, seed_mode=CA_SEED_MODE.SEED_CENTROID,        num_random_points=1,                                    translate={    {tile=GROUND.GRASS, items={"grass"},         item_count=3},                                                {tile=GROUND.GRASS, items={"sapling","berrybush"},     item_count=5},                                                {tile=GROUND.FOREST, items={"evergreen_short"},     item_count=17},                                                {tile=GROUND.FOREST,  items={"evergreen_normal"},    item_count=16},                                                {tile=GROUND.FOREST,items={"evergreen_tall"},         item_count=16},                                        },                                centroid=     {tile=GROUND.FOREST,     items={"cavelight"},            item_count=1},                        },                    },

 

It seems like it's basically making a pseudo-randomized setpiece to me. I'm not sure where the RUNCA.GeneratorFunction is.

Link to comment
Share on other sites

Hmm. From what I just read of voronoi cells, isn't their usefulness nullified if you distort them?

It's not nullified, but greatly diminished. The characteristic property of a Voronoi diagram is that each point in the plane belongs to the cell to which center it is closest. If you deform the cells, this will only be approximately true (and in the case of DS worldgen, the approximation is not very accurate).

 

I was looking at graphedge and graphnode. Are either of these where the distortion is happening, or am I way off?

 

     -- We add 1 here because the map will be rendered in 0->width-1 instead of lua's 1->width    map:DrawLine(n1center.x+1, n1center.y+1, n2center.x+1, n2center.y+1,  value)
 

 

function Edge:DrawDebug(draw, map)    local n1center = self.node1:GetCenterRelativeToMap(map)    local n2center = self.node2:GetCenterRelativeToMap(map)        draw:Line((n1center.x-map.width/2.0)*TILE_SCALE, (n1center.y-map.height/2.0)*TILE_SCALE, (n2center.x-map.width/2.0)*TILE_SCALE, (n2center.y-map.height/2.0)*TILE_SCALE, self.colour.r, self.colour.g, self.colour.b, self.colour.a)end

No, these functions are just building the skeleton of the map, attaching an edge between the center of two rooms. Two rooms with an edge between their centers become biomes with a shared border (in technical terms, it is building the dual graph of the map graph).

I think the strongest tell of the deformation on the Lua side is the specification of background rooms for each room and of a background ground type for tasks. If the map were a proper Voronoi diagram, each room would be a Voronoi cell and each point in the map would belong to one of them (or the additional cells representing the ocean, which receive the id "background"), so the background rooms and ground types would never be used. So their purpose seems to be indicating what to use as a filler when distorting the cells.

Since the actual map generation is done in the engine, with the Lua side just computing which parameters to pass the world builder, we can't see exactly how and why the distortion is applied.

 

On the subject of rooms, could you explain what's happening here?

 

 

                    custom_tiles={                        GeneratorFunction = RUNCA.GeneratorFunction,                        data = {iterations=3, seed_mode=CA_SEED_MODE.SEED_CENTROID,        num_random_points=1,                                    translate={    {tile=GROUND.GRASS, items={"grass"},         item_count=3},                                                {tile=GROUND.GRASS, items={"sapling","berrybush"},     item_count=5},                                                {tile=GROUND.FOREST, items={"evergreen_short"},     item_count=17},                                                {tile=GROUND.FOREST,  items={"evergreen_normal"},    item_count=16},                                                {tile=GROUND.FOREST,items={"evergreen_tall"},         item_count=16},                                        },                                centroid=     {tile=GROUND.FOREST,     items={"cavelight"},            item_count=1},                        },                    },
 

It seems like it's basically making a pseudo-randomized setpiece to me. I'm not sure where the RUNCA.GeneratorFunction is.

Yes, this defines a randomized set piece, which in this case is those groups of trees illuminated by surface light found in caves.

It is used here, in graphnode.lua

function Node:SetTilesViaFunction(entities, width, height)	if self.custom_tiles_data == nil then				return	end	self.custom_tiles_data.data.node = self	self.custom_tiles_data.data.width = width	self.custom_tiles_data.data.height = height	self.custom_tiles_data.GeneratorFunction(self.id, entities, self.custom_tiles_data.data)	self.populated = trueend
As you can see, it's calling the generator function (RUNCA.GeneratorFunction, is the example) to do the actual work. This function is defined in room_functions.lua:

local function RunCA(id, entities, data)		--print(id.." RunCa", data.iterations, data.seed_mode, data.num_random_points)	WorldSim:RunCA(id, data.iterations, data.seed_mode, data.num_random_points)	if data.translate ~= nil then		local points_x, points_y, points_type = WorldSim:GetPointsForSite(id)		if #points_x == 0 then			print(id.." RunCA() Cant process points")			return		end		local current_pos_idx = 1		for current_pos_idx = 1, #points_x do			if points_type[current_pos_idx]-1 < #data.translate then				local current_layer = data.translate[points_type[current_pos_idx]-1]				WorldSim:SetTile(points_x[current_pos_idx], points_y[current_pos_idx], current_layer.tile)								if current_layer.item_count >0 then					--print("RunCA ", current_layer.items[1], data.width, data.height)					data.node:AddEntity(current_layer.items[1], points_x, points_y, current_pos_idx, entities, data.width, data.height, {}, {}, true)					current_layer.item_count = current_layer.item_count -1				end			end		end	end	if data.centroid ~= nil then		local c_x, c_y = WorldSim:GetSiteCentroid(id)		WorldSim:SetTile(c_x, c_y, data.centroid.tile)		data.node:AddEntity(data.centroid.items[1], {c_x}, {c_y}, 1, entities, data.width, data.height, {}, {}, true)	endendRUNCA = {GeneratorFunction = RunCA, DefaultArgs = {iterations=6, seed_mode=CA_SEED_MODE.SEED_CENTROID, num_random_points=1} }
though, since the bulk of the work is done in the engine, by the call WorldSim:RunCA(), this doesn't give much insight on the specifics of what's done.

And I'm not sure what CA stands for here. A guess would be <a data-ipb="nomediaparse" data-cke-saved-href="https://en.wikipedia.org/wiki/Arnold" href="https://en.wikipedia.org/wiki/Arnold" s_cat_map"="">Arnold's Cat Map, which is a technique for shuffling planar points around using successive iterations (as seems to be the case here), but this would've been shortened to AC, not CA, so I don't know.

EDIT:

By the way, here's a tip for looking for strings inside game files. The following was run in vanilla's scripts/map:

$ find . -type f -exec grep -Hn RUNCA {} \;./rooms/caves.lua:9:						GeneratorFunction = RUNCA.GeneratorFunction,./rooms/caves.lua:47:						GeneratorFunction = RUNCA.GeneratorFunction,./rooms/caves.lua:81:						GeneratorFunction = RUNCA.GeneratorFunction,./rooms/caves.lua:147:						GeneratorFunction = RUNCA.GeneratorFunction,./rooms/caves.lua:406:						GeneratorFunction = RUNCA.GeneratorFunction,./rooms/caves.lua:423:						GeneratorFunction = RUNCA.GeneratorFunction,./room_functions.lua:35:RUNCA = {GeneratorFunction = RunCA, DefaultArgs = {iterations=6, seed_mode=CA_SEED_MODE.SEED_CENTROID, num_random_points=1} }
The "-type f" means to take into consideration only regular files (and not directories and other kinds of file). If there were non Lua scripts there as well, "-name '*.lua'" would be more appropriate instead. The "-exec grep -Hn RUNCA {} \;" means to run this command ("grep -Hn RUNCA {}") on every file found, replacing the "{}" with the file's name.
Link to comment
Share on other sites

It's not nullified, but greatly diminished. The characteristic property of a Voronoi diagram is that each point in the plane belongs to the cell to which center it is closest. If you deform the cells, this will only be approximately true (and in the case of DS worldgen, the approximation is not very accurate).

 

No, these functions are just building the skeleton of the map, attaching an edge between the center of two rooms. Two rooms with an edge between their centers become biomes with a shared border (in technical terms, it is building the dual graph of the map graph).

I think the strongest tell of the deformation on the Lua side is the specification of background rooms for each room and of a background ground type for tasks. If the map were a proper Voronoi diagram, each room would be a Voronoi cell and each point in the map would belong to one of them (or the additional cells representing the ocean, which receive the id "background"), so the background rooms and ground types would never be used. So their purpose seems to be indicating what to use as a filler when distorting the cells.

Since the actual map generation is done in the engine, with the Lua side just computing which parameters to pass the world builder, we can't see exactly how and why the distortion is applied.

 

Yes, this defines a randomized set piece, which in this case is those groups of trees illuminated by surface light found in caves.

It is used here, in graphnode.lua

function Node:SetTilesViaFunction(entities, width, height)	if self.custom_tiles_data == nil then				return	end	self.custom_tiles_data.data.node = self	self.custom_tiles_data.data.width = width	self.custom_tiles_data.data.height = height	self.custom_tiles_data.GeneratorFunction(self.id, entities, self.custom_tiles_data.data)	self.populated = trueend
As you can see, it's calling the generator function (RUNCA.GeneratorFunction, is the example) to do the actual work. This function is defined in room_functions.lua:

local function RunCA(id, entities, data)		--print(id.." RunCa", data.iterations, data.seed_mode, data.num_random_points)	WorldSim:RunCA(id, data.iterations, data.seed_mode, data.num_random_points)	if data.translate ~= nil then		local points_x, points_y, points_type = WorldSim:GetPointsForSite(id)		if #points_x == 0 then			print(id.." RunCA() Cant process points")			return		end		local current_pos_idx = 1		for current_pos_idx = 1, #points_x do			if points_type[current_pos_idx]-1 < #data.translate then				local current_layer = data.translate[points_type[current_pos_idx]-1]				WorldSim:SetTile(points_x[current_pos_idx], points_y[current_pos_idx], current_layer.tile)								if current_layer.item_count >0 then					--print("RunCA ", current_layer.items[1], data.width, data.height)					data.node:AddEntity(current_layer.items[1], points_x, points_y, current_pos_idx, entities, data.width, data.height, {}, {}, true)					current_layer.item_count = current_layer.item_count -1				end			end		end	end	if data.centroid ~= nil then		local c_x, c_y = WorldSim:GetSiteCentroid(id)		WorldSim:SetTile(c_x, c_y, data.centroid.tile)		data.node:AddEntity(data.centroid.items[1], {c_x}, {c_y}, 1, entities, data.width, data.height, {}, {}, true)	endendRUNCA = {GeneratorFunction = RunCA, DefaultArgs = {iterations=6, seed_mode=CA_SEED_MODE.SEED_CENTROID, num_random_points=1} }
though, since the bulk of the work is done in the engine, by the call WorldSim:RunCA(), this doesn't give much insight on the specifics of what's done.

And I'm not sure what CA stands for here. A guess would be

So the actual seed modes are engine-level, or can we see those? I'd like to use randomized setpieces, since working in Tiled feels weird to me. Having everything positioned so precisely is strange, and gives the setpieces a bit of a repetitive feel.

Link to comment
Share on other sites

So the actual seed modes are engine-level, or can we see those? I'd like to use randomized setpieces, since working in Tiled feels weird to me. Having everything positioned so precisely is strange, and gives the setpieces a bit of a repetitive feel.

Engine-level, as we wouldn't know how to interpret them anyway without seeing how they're used :razz:. But taking what's used in caves and tweaking it should work.

We'll definitely need some static set pieces, but randomizing what may be randomized is always better.

I found that when googling it, but since that's a script for DNA sequencing I don't think that's quite what it means in the Don't Starve code :razz:.

Link to comment
Share on other sites

I found that when googling it, but since that's a script for DNA sequencing I don't think that's quite what it means in the Don't Starve code :razz:.

 

Well...DNA sequencing...Do Not Arve (a rather uncommon abbreviation of Starve in countries like Borduria) or spoken without a tongue (don't discriminate the tongue-less)

 

you coul...possibly...ahem...well.........O_O''

Link to comment
Share on other sites

Heh. I just realized all those shenanigans for fetching road data from savedata are utterly unnecessary. The following is done in gamelogic.lua:

	if savedata.map.roads then		Roads = savedata.map.roads
so I can just grab the data from the global variable Roads :razz:.

I think I'll keep the current system, though, if for nothing else than to ensure road data has been gathered before any game/sim postinits run.

EDIT: Nah, I'll change it. There's no point keeping a more complex implementation around, I'll just code the replacement in a way that ensures road data is compiled early anyway: I'll make it compile at the first time it's requested, which also makes redundant the previous requirement of having to load the wicker module game.topology.roads explicitly to trigger the compilation.

Link to comment
Share on other sites

I gave ambrosia a special trait; when consumed, it has a 1 in 15 chance of respawning you on death.

 

However, this comes at a cost, since when consumed, it can take up to 40 points from any given stat, or possibly give up to 20 to any given stat. This makes it difficult to spam them, since they could easily make your life very difficult.

 

And of course, there is no way (aside from console) to know whether or not you have an extra life until you die.

 

Does anyone dislike this, or should it be balanced more? It's easily removable, but I feel it makes a nice high risk/reward consumable.

 

I got the idea for it since ambrosia tends to represent immortality in various mythos.

Link to comment
Share on other sites

@debugman18

As you well know (since I took a few hours fixing the Winnie portraits bugs, which required fixing/extending ktech), I set up an automatic system for build zips and image TEXes compilation via makefiles. Besides the Makefile in the base mod directory, there are two more now, one in anim/ and other in images/. You shouldn't have to use them directly, though, since they are called by the base Makefile.

Now, typing

$ make
will compile all animation zips and image TEXes (provided their dependencies are newer than them).

When compiling an animation zip, the atlas-0.png is compressed into atlas-0.tex on the fly using ktech, and afterwards erased (but if it existed previously it is kept). I kept only the atlas-0.png in each animation folder, erasing the .tex, since it's best to keep the originals around, and the .tex is automatically generated when needed anyway (and only when needed, if the zip is not older than its dependencies no TEX compression takes place). In the cases where an atlas-0.png did not exist, I converted the atlas-0.tex into atlas-0.png and erased the .tex, also putting a WARNING.txt file in those folders to remind us that replacing this reconverted atlas-0.png with the original one is better, since the reconversion process produces an image with inferior quality (since the TEX format uses lossy compression). The build.bin files are also automatically renamed using tools/kbr.pl to the name of their folder.

However, I noticed the aliens build dir has an atlas-1.png (and .tex) there. What does it stand for? It's currently not being added to the zip.

The pngs in images/ are automatically converted into TEX, with proper parameters for each kind of image (inventoryimages, portraits, etc.; though of course this is a very recent addition, made after the Winnie fiasco :razz:). Here the TEXes are not erased, of course, since they are the final format.

So, in a nutshell, just type "make" to bring all compiled assets up to date (and only those which need recompilation). This should be used as a go-to command for whenever any asset is added or tweaked (you don't need to list assets anywhere for it to work).

If you type

$ make clean
all compiled assets (and the release zip, if any) will be erased, so "make clean" followed by "make" will recreate all assets (though a simple "make -B" would have the same effect, since this option forces recreation of all targets regardless of their dependencies' modification time).

The old use of the Makefile to generate the release zip is now done via

$ make dist
as is done with most projects using Makefiles.


 

I gave ambrosia a special trait; when consumed, it has a 1 in 15 chance of respawning you on death.

 

However, this comes at a cost, since when consumed, it can take up to 40 points from any given stat, or possibly give up to 20 to any given stat. This makes it difficult to spam them, since they could easily make your life very difficult.

 

And of course, there is no way (aside from console) to know whether or not you have an extra life until you die.

 

Does anyone dislike this, or should it be balanced more? It's easily removable, but I feel it makes a nice high risk/reward consumable.

 

I got the idea for it since ambrosia tends to represent immortality in various mythos.

This sounds like an interesting trait to me. Are the stat penalties permanent?

Link to comment
Share on other sites

@debugman18

As you well know (since I took a few hours fixing the Winnie portraits bugs, which required fixing/extending ktech), I set up an automatic system for build zips and image TEXes compilation via makefiles. Besides the Makefile in the base mod directory, there are two more now, one in anim/ and other in images/. You shouldn't have to use them directly, though, since they are called by the base Makefile.

Now, typing

$ make
will compile all animation zips and image TEXes (provided their dependencies are newer than them).

When compiling an animation zip, the atlas-0.png is compressed into atlas-0.tex on the fly using ktech, and afterwards erased (but if it existed previously it is kept). I kept only the atlas-0.png in each animation folder, erasing the .tex, since it's best to keep the originals around, and the .tex is automatically generated when needed anyway. In the cases where an atlas-0.png did not exist, I converted the atlas-0.tex into atlas-0.png and erased the .tex, also putting a WARNING.txt file in those folders to remind us that replacing this reconverted atlas-0.png with the original one is better, since the reconversion process produces an image with inferior quality (since the TEX format uses lossy compression). The build.bin files are also automatically renamed using tools/kbr.pl to the name of their folder.

However, I noticed the aliens build dir has an atlas-1.png (and .tex) there. What does it stand for? It's currently not being added to the zip.

The pngs in images/ are automatically converted into TEX, with proper parameters for each kind of image (inventoryimages, portraits, etc.; though of course this is a very recent addition, made after the Winnie fiasco :razz:). Here the TEXes are not erased, of course, since they are the final format.

So, in a nutshell, just type "make" to bring all compiled assets up to date (and only those which need recompilation). This should be used as a go-to command for whenever any asset is added or tweaked (you don't need to list assets anywhere for it to work).

If you type

$ make clean
all compiled assets (and the release zip, if any) will be erased, so "make clean" followed by "make" will recreate all assets (though a simple "make -B" would have the same effect, since this option forces recreation of all targets regardless of their dependencies' modification time).

The old use of the Makefile to generate the release zip is now done via

$ make dist
as is done with most projects using Makefiles.


This sounds like an interesting trait to me. Are the stat penalties permanent?

 

 

Most of the atlas-1 images were simply to avoid overwriting atlas-0 during editing.

 

As for the stat penalties, they're not permanent, although adding a permanent stat penalty to the resurrection seems like a fitting addition.

Link to comment
Share on other sites

As for the stat penalties, they're not permanent, although adding a permanent stat penalty to the resurrection seems like a fitting addition.

Well, not to post-resurrection, since then the player would eventually wither :razz:. But I think a permanent stat change until the next respawn would be interesting (though it is very likely to make players think the risk is not worthy...; provided ambrosias are rare enough, it might be more sensible to just decrease the current stat, as now, and not the maximum value).

Link to comment
Share on other sites

Well, not to post-resurrection, since then the player would eventually wither :razz:. But I think a permanent stat change until the next respawn would be interesting (though it is very likely to make players think the risk is not worthy...; provided ambrosias are rare enough, it might be more sensible to just decrease the current stat, as now, and not the maximum value).

 

Well currently ambrosias drop from skytraps, but we could make them a rare drop easily.

Link to comment
Share on other sites

@debugman18

Now the automatic asset compilation is also taking care of tiles/noise textures in levels/. I also noted the noise textures were not using the ideal compression (unlike pretty much everything else, they should use DXT1 instead of DXT5), so I recompiled them. I also set up automatic compilation of colour cubes (which require very unique parameters), even though we aren't using custom ones at the moment.

So now every type of texture is being taken care of, and the parameters used for the compilation of each kind match those in vanilla.

Link to comment
Share on other sites

@simplex

 

Moved from candyland. :p

 

So running premake4 gmake produces this:

Target OS not specified. Assuming it's the host OS.which "unzip" &>/dev/nullmkdir -p "../build"/usr/bin/unzipmkdir -p "../build/dont_starve/mods"unzip -q -o "../pkg/tst/wand.zip" -d "../build/dont_starve/mods"mkdir -p "../build/linux/mod_tools"cp -rT "../pkg/cmn/mod_tools" "../build/linux/mod_tools"mkdir -p "../build/linux/mod_tools/buildtools/linux/Python27"cp -rT "../pkg/unix/Python27" "../build/linux/mod_tools/buildtools/linux/Python27"mkdir -p "../build/linux/mod_tools"cp -rT "../pkg/unix/mod_tools" "../build/linux/mod_tools"Building configurations...Running action 'gmake'...Generating ../build/proj/Makefile...Generating ../build/proj/scml.make...Generating ../build/proj/png.make...Generating ../build/proj/autocompiler.make...Generating ../build/proj/modtoollib.make...Done.

The difference now is there is a "proj" folder in the build folder, which has some make files in it.

 

There's still no "scml" or "png" scripts in my build/linux/mod_tools directory.

 

Actually, I got it. I went into the proj folder and ran make and it seemed to do the trick.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.