Who's that?

Nov 6, 2011, 3:45 am
#26
Joined: Dec 3, 2007
Occupation: Chaos Weaver
Location: Standing between all life and death
Posts: 2,825
Depends how much you're asking Squash. We might be able to scrape that together as a community.
Nov 6, 2011, 12:14 pm
#27
Joined: Sep 8, 2010
Occupation: Petty Functionary
Location: Drinking pea soup in the world map
Interests: Mangoes
Posts: 1,111
SquashMonster wrote
I just saw what vasilly did with the dungeon dat and it's really great. We absolutely should have that feature. Is his code available and in a working state? I saw that he was working on replacing all scripts with some fancy thing and we don't need that (especially since it doesn't seem to have happened) but everything else from his version sounds like a fantastic base.
...
Also, if I understand correctly (I often don't) you added a number of extra dungeons in CLIVAN, yeah? Do you have a general system for that, or in general an idea how we'd do Phase 1 point 2?

Vasily has a git repository here. As far as I know he only works with linux. Apparently he stopped working on his VASYA script because of this.

Worldmap:

The method I used is post somewhere in the forum under Programming.

The way that the devs implemented the placement of locations is a little bit muddy. Most of the "bugs" were written in worldmap.cpp. I have a special interest in improving this because I'd like to try to introduce named continents (named after forum members ). Should be easy though because continents already have numbers.
The bugs include continents being too big (i think I fixed this in CLIVAN). One which I did not fix was this line:

if(AttnamPos != TunnelExit && ElpuriCavePos != TunnelExit)
{...

The above was invented by the devs and it works fine for IVAN 0.50 and CVS, but causes problems for instance when you add more locations. As an example, while testing CLIVAN I once loaded a game where I could not find the "Dark Forest" location anywhere on the map, and I can only presume another location ("Muntuo" since it is the same terrain type i.e. Leafy Forest) was written over the top of it.
I'm sure if each location had a unique terrain type, then this would be solved, but then the game would have to spend inordinate time trying to generate a continent that "PetrusLikes".
So basically I have a feel for some of the undocumented features and some points about what is wrong, but to overhaul this would take me maybe 80 to 120 hours to come up with a paper model.

Oh, and no money for me please leave it for the pros, like Squash. I already have a job, this can be my hobby.
Nov 6, 2011, 3:47 pm
#28
Joined: Nov 3, 2011
Posts: 8
Okay, this post got a little technical so here's the tl;dr version. I think I can make the whole worldmap generation thing a whole lot simpler, and way easier to add new locations to. Maybe I could even port it to a script file instead of people having to touch code to add dungeons. But the catch is that the New Attnam continent will average slightly bigger (4 to 10 cells instead of 2 to 4) and that it might not always be as close to the Attnam continent as before (the underwater tunnel could be improbably long). Is that acceptable?


Great tutorial, Warheck!

So, to clarify a little, the way things are working in the code there are that wterras.h contains a bunch of class definitions for classes that extend owterrain and gwterrain. owterrain is towns and dungeons and the like, gwterrain is forests and tundras and the like - I have no clue what the two names are supposed to mean, they're both overworld terrain. OWTERRAIN(namehere, owterrain) is a macro that does part of the class definition for you. What you are filling in at wterras.cpp are the actual methods of the class, which contain the class data. Nothing is actually being added to the game at this point though, just the code. Down in worldmap.cpp when you call ChangeOWTerrain(namehere::Spawn()) you are calling a method in the class namehere (which you unwittingly made with that OWTERRAIN macro) which creates an instance of that class and puts it into that square of the map.

This is actually rather inside-out. All the dungeons and towns could share a class, and different objects of that class would have their different name strings, graphics positions, etc. This would also be convenient because it'd allow you to make an actual list of places in the game, which then allows you to replace that whole mess at the start of worldmap::Generate() with something that looks like:

 for(uint c = 1; c < Continent.size(); ++c)
{
    if(Continent[c]->GetSize() > 25 && Continent[c]->GetSize() < 1000)
    {
        truth aPlaceForEveryone = true;
        for(uint i = 0; i < ImportantPlaces.size(); i++)
        {
            if(Continent[c]->GetGTerrainAmount(ImportantPlaces[i]->GetLocalEnvironment())
            {
                aPlaceForEveryone = false;
                break;
            }
        }
        if(aPlaceForEveryone)
        {
            PerfectForAttnam.push_back(Continent[c]);
        }
    }
}

Which doesn't need to be changed when you add places, you just need to make sure ImportantPlaces gets your new location added to it at some point if it needs to be in the Attnam continent. And the AttnamPos, ElpuriCavePos stuff can be done easily with a list, as can the end spawning.

This can be extended to work for multiple continents pretty easily too. ImportantPlaces becomes a list of lists, things that need to go in the first continent go into the first list, next continent the second list, and so on. I can write code if that makes it more clear, but what I really want to get at is that there is a big messy hitch to all of this.

New Attnam is not actually on a continent. The game doesn't even look for a tiny island for it. Wherever the exit to the underwater tunnel goes, the game looks a certain radius outwards for some ocean and builds a tiny island on the spot, midway through the part where the other locations are looking for a place in the already-existing world. It's really hacky and I don't know how to generalize that.

So what I was thinking is maybe I make it so the game can check for different required sizes for the different continents (see above, it's looking for 25 to 1000 for the Attnam continent). Then the multi-continent thing above would let it put New Attnam on a small real continent, instead of a small continent it summoned out of the aether. The problem is that by default those continents wouldn't be anywhere near eachother. I could pretty easily add a generic thing that says two overworld locations try to be close to eachother (by repeatedly sampling possible locations and taking the best of N samples) which increases generation time slightly and improves the tunnel situation so far as at least making the two ends be as close as they can be on their continents (which is to say, if the continents are on opposite sides of the world, at least the tunnels are facing eachother). I could also put in a hard limit (discard the world if two locations are not within X of eachother), which fixes the problem entirely but that would probably increase generation time a fair deal, especially as people add more locations that use this requirement.

Anything that reduces special locations to objects instead of classes has another benefit. It's the prerequisite to being able to port that off to a script file. But learning how to make new script files is a big challenge in and of itself, I'd say this is something that should be done in two steps.

So... go for it, or use your tutorial as the official way to add new things to the world?
Nov 6, 2011, 5:06 pm
#29
Joined: Sep 8, 2010
Occupation: Petty Functionary
Location: Drinking pea soup in the world map
Interests: Mangoes
Posts: 1,111
SquashMonster wrote
I think I can make the whole worldmap generation thing a whole lot simpler, and way easier to add new locations to. Maybe I could even port it to a script file instead of people having to touch code to add dungeons.

I vote we put Squash on the payroll.
That stuff about the OWTERRAIN macro really clarifies things for me (a bit), thanks!

SquashMonster wrote
I have no clue what the two names are supposed to mean, they're both overworld terrain.

I think gwterrain is supposed to mean ground-world terrain, or everything on the world map that is the ground, in the same way that glterrain refers to ground-level terrain.

SquashMonster wrote
(which you unwittingly made with that OWTERRAIN macro)
Certainly it was unwitting, as I say, it was reverse engineered

It strikes me that the world map generation may be the most antiquated part of the code, since it has that hand-made feel to it.

SquashMonster wrote
New Attnam is not actually on a continent.
Maybe we need an island spawner, or that a certain proportion of the continents generated are islands (jeez, where's that Sid Meier at?). I don't know. If the island is placed last then it will be fine, there will be a way even if it is hacked. It would be good to have a general way of doing it though. Hmm. I think it would pay to put the island close by underwater tunnel. What about an inland island on a lake on the continent that PetrusLikes??

SquashMonster wrote
The game doesn't even look for a tiny island for it. Wherever the exit to the underwater tunnel goes, the game looks a certain radius outwards for some ocean and builds a tiny island on the spot, midway through the part where the other locations are looking for a place in the already-existing world.

This explains everything that I ever wanted to know about how New Attnan comes to be upon Valpuri, thank you

SquashMonster wrote
Anything that reduces special locations to objects instead of classes has another benefit. It's the prerequisite to being able to port that off to a script file. But learning how to make new script files is a big challenge in and of itself, I'd say this is something that should be done in two steps.

Learning to make (and make) dungeons is labour intensive no matter what. I have already been asked to document dungeon building in IVAN and I'm happy to do it, regardless of whether there is an overhaul of world generation or not. The way I see it is that basically there is no end to the power of cut-and-paste, and the IVAN community is endlessly creative, so if it is easier to make dungeons without coding then I imagine people will be attracted enough to that feature + good documentation to script their own dungeons.

SquashMonster wrote
So... go for it, or use your tutorial as the official way to add new things to the world?

I say go for it. It is such low-hanging fruit . The existing manner in which continents are generated is too clunky and converting the classes to objects fulfills a step toward making novel world locations scriptable.
Nov 7, 2011, 11:04 am
#30
Ernomouse's avatar
Master mine stomper


Joined: Dec 16, 2007
Occupation: Pouring molten bronze in sand
Location: In the cold end
Posts: 2,047
//TOPIC MOVED TO PROGRAMMING FROM GENERAL DISCUSSION. FEAR THE POWER OF THE PURPLE PINK EMPEROR!//
Nov 7, 2011, 3:29 pm
#31
Joined: Sep 8, 2010
Occupation: Petty Functionary
Location: Drinking pea soup in the world map
Interests: Mangoes
Posts: 1,111
I just wrote this note (attached) on a suitable method for editing graphics in IVAN. It explains a way of opening and editing pcx files using a couple of free graphics editing programmes in windows.
Feb 12, 2012, 5:35 pm
#32
Joined: Sep 8, 2010
Occupation: Petty Functionary
Location: Drinking pea soup in the world map
Interests: Mangoes
Posts: 1,111
Continuing this thread. Performing a diff using WinMerge on Vasily's script.cpp with the one from IVAN CVS, reveals that the changes required to "burst" the script files involve less than fifteen lines of code:

In script.cpp:
...
    if (Word == "Include") 
    {
      Word = SaveFile.ReadWord();
      if (SaveFile.ReadWord() != ";") 
        ABORT("Invalid terminator in file %s at line %ld!", SaveFile.GetFileName().CStr(), SaveFile.TellLine());
      inputfile incf(game::GetGameDir()+"Script/"+Word, &game::GetGlobalValueMap());
      ReadFrom(incf);
      continue;
    }
    if (Word == "Message")
    {
      Word = SaveFile.ReadWord();
      if (SaveFile.ReadWord() != ";") ABORT("Invalid terminator in file %s at line %ld!", SaveFile.GetFileName().CStr(), SaveFile.TellLine());
      fprintf(stderr, "MESSAGE: %sn", Word.CStr());
      continue;
    }
...

But then I think you'd have to add his LoadGlobalValueMap() function before InitGlobalValueMap() in game.cpp. And you might have to add a bunch of other stuff.
May 17, 2012, 4:01 pm
#33
Joined: Sep 5, 2010
Posts: 103
i hardly remember the whole picture, but there were changes in parser too (i added #enum and #bitenum pseudocommands), Extend for extending existing object definitions and so on.

and yes, i'm not dead, i'm just trying to keep development speed comparable with official I.V.A.N. %-)

now i'm slowly porting CLIVAN features.

p.s. new repo

scripting support is not the top priority for now. and windoze support is broken. i think 64-bit systems support is broken too. but we are not dead yet! %-)

upd: windoze support is back again. just read the original announce: i fixed links in the first post.
Jump to