[MOD] Colonization: 2071

Ok I committed the allowed yield cache. I implemented it in some locations where we benefit from it. I skipped a number of locations as implementations there wasn't strait forward. On the other hand I added a number of TODO around the code (you do know that VC++ can make an interactive TODO list based on TODO keyword in comments, right?).

I added player.canUseYield(eYield) to python interface, though I didn't touch any python code and as such it isn't used yet. I figure it could be useful in the future.
The return value is simple. True mean the civ can use the yield here and now (invented or started with it) while false means it has yet to be invented. Also now that we use one function to calculate this, we will either get a bug everywhere or not at all. If a bug is everywhere, then we are more likely to discover it. Do use this function whereever it appears useful instead of reinventing the calculations.

I removed all hardcoded reference to yields when it comes to inventions. Now inventions vs yields are 100% controlled from XML.

I spotted bIsMustBeDiscovered in yield XML. I think that's a bad design decision. I propose that we remove it and instead set it to false for all yields at startup. At the end of XML load we then loop all inventions and set bIsMustBeDiscovered to true for all yields, which is enabled by at least one invention. That way invention and yield XML settings can't get out of sync as it will be controlled by inventions only. One less location to mess up.

Ah those were the days :p In one of my first schools as a child they had an ancient Commodore PET gathering dust in the back. It had a cassette tape drive, where you had to physically press Play and then type >LOAD DUNGEON or whatever.

Come to think of it, it booted almost 20 times faster than Windows 8 :crazyeye::lol:
I have a Commodore 64 in the closet with both tape and floppy drive :old:
It gives me a blue screen with white numbers each time I turn it on :lol:

There is actually a rather interesting story about the early floppy drives. A company developed a small version of the 8" main frame floppy for home users and went to expos and stuff with it, though nobody really paid it any attention. One day they had a bum in the lobby and one of the developers were assigned the task of getting rid of him. It turned out to be a real bum/hippie, with worn out cloth with holes in it, haven't washed himself in ages etc. That bum stood up and said "I have a business preposition for you". It turned out to be Steve Jobs and Steve & Steve at Apple Computer had figured out that if you insert a disk and do not remove it, you can easily read any part of it whenever you wanted. This meant that if you filled the disk with the application and instead of loading all at once, you loaded it when you need to, you would be able to have an application so complex that it wouldn't fit in memory. In other words with some clever coding applications could become 10 times as big. Basically they wanted to use the floppy as a system HD, but this is before the HD. They wanted two drives where the other one should be... well basically the user home dir. People could then have access to everything at once and they could replace disks to switch user or system. At that time one system was one application. No big deal today, but in a world with tapes this was visionary. The only real demand was that each drive should be lowered to $100. (from 125 or 150 or something like that).

It must have caused havoc at Commodore when Apple released their floppy drive computer in 1984. Commodore 64 is from '83 and didn't have a floppy. They made an external one for it, but it was ridiculously pricy. Still it was production costs and not profit which made it that pricy. The problem was that they never considered any other data storage than floppy when they designed the Commodore 64. Adding one after it's produced and is already at home with the customers was a huge challenge. They ended up building a drive and then set a computer together with it. The commodore 64 could then access that computer though a serial network cable. It worked rather well, but the extra computer was expensive. On the other hand you could daisy chain the drives and add multiple to one computer.
 
I just started 2071 without a single assert.

I updated the source code to fit the yields in XML. I couldn't find vehicles, so I decided to set YIELD_HORSES to YIELD_ROBOTICS. We can always change that later.

I changed the XML files to get rid of all asserts when it starts.

I added CIV4HurryInfo.xml from vanilla because it has a reference to YIELD_LUMBER. Now paying for hurrying construction will take YIELD_BIOPOLYMERS instead.

CIV4ForceControlInfos.xml asserts usually means that one of the GlobalAltDefines is missing or wrong or there is a discrepancy in the CvXMLLoadUtillitySet.cpp file.
It was GlobalDefinesAlt.xml.
I did a few liberal changes to make the game start. For instance DEFAULT_YIELD_ARMOR_TYPE is set to YIELD_NUTRIENTS. We should find proper solutions for those later. The important part right now is to get started.

Also I removed the DLL file. It was useless and git wants to commit the new one whenever we commit and we don't want to add the DLL in this branch.
 
I just committed a fix for the slowdown in CvPlot::calculateNatureYield(). Now it will no longer loop inventions, but rather use cache, which is recalculated every time the player gets a new invention. At the same time I noticed the code for handling AllowsBonus in invention XML was horribly broken. Now it works as intended. The only issue with it is that the map doesn't update when you get the invention to enable it. You have to enter a colony and exit it to get the on-map yields to update. Minor issue which is fixed by marking the map dirty (needs redrawing). However I don't know precisely what to mark dirty and as such so I skipped that part.

I decided to be lazy and store the cache in a just-in-time array to let that one handle allocation and freeing of the array, but then it occurred to me. If I store banned bonuses instead of allowed bonuses, then I get the same information. It's just a matter of inverting the bools. Now that no invention mentions bonuses, the entire array will end up being false. Remember that just-in-time arrays aren't allocated before a non-zero or non-false value is written to it and reading from an unallocated array returns false/0. This way we save 4 bytes * number of bonus types * number of players. Ok, it may not be a great deal, but go back to the important part here "reading from an unallocated array returns false". That is knowing what we will read from the array without accessing the memory. This is faster than just using an array, which is always there because we cut away the delay to access memory. Fully exploiting this, I set it to free the memory if possible every time the payer gets a new invention. Now CvPlot::calculateNatureYield() doesn't even have to access the cache if all bonuses are allowed, either by inventing them (late game) or available from the start. I don't know how much the code improves by doing this. Most likely not much as it's for the human players only, but we just might have an effect of it if the AI started using this code. I wish for the AI to have fewer special rules like that. I don't see a reason why the AI should have special rules regarding inventions.
 
I synced the latest commit and it loaded without a single assert! :king: :woohoo::rockon:

While in the mainmenu I browsed through all the Pedia pages and got a few nonfatal asserts below

Spoiler :
In Pedia for Founding Dignitaries
Assert Failed

File: CvGlobals.cpp
Line: 2205
Expression: eCivicNum < GC.getNumCivicInfos()
Message:
File: c:\users\teddy mac\documents\my games\sid meier's civilization iv colonization\mods\medieval_tech\dll_sources\CvPlayerAI.h
Line: 24
Expression: ePlayer >= 0
Message: Player is not assigned a valid value


In Pedia for Inventions
Assert Failed

File: CvGameTextMgr.cpp
Line: 4271
Expression: GC.getGameINLINE().getActivePlayer() != NO_PLAYER || !bPlayerContext
Message:

----------------------------------------------------------
Assert Failed

File: c:\users\teddy mac\documents\my games\sid meier's civilization iv colonization\mods\medieval_tech\dll_sources\CvPlayerAI.h
Line: 24
Expression: ePlayer >= 0
Message: Player is not assigned a valid value

----------------------------------------------------------
Assert Failed

File: CvGameTextMgr.cpp
Line: 4271
Expression: GC.getGameINLINE().getActivePlayer() != NO_PLAYER || !bPlayerContext
Message:

----------------------------------------------------------
Assert Failed

File: c:\users\teddy mac\documents\my games\sid meier's civilization iv colonization\mods\medieval_tech\dll_sources\CvPlayerAI.h
Line: 24
Expression: ePlayer >= 0
Message: Player is not assigned a valid value

----------------------------------------------------------
Assert Failed

File: CvGameTextMgr.cpp
Line: 4271
Expression: GC.getGameINLINE().getActivePlayer() != NO_PLAYER || !bPlayerContext
Message:

----------------------------------------------------------
Assert Failed

File: c:\users\teddy mac\documents\my games\sid meier's civilization iv colonization\mods\medieval_tech\dll_sources\CvPlayerAI.h
Line: 24
Expression: ePlayer >= 0
Message: Player is not assigned a valid value

----------------------------------------------------------
Then I started a Custom Game (just 1 player); I then did get a bunch of asserts from gameinfo/emphasizeinfos.xml; but I cleaned M:C specific content from this and synced a commit and now they're solved.:king:

Reloaded & started a new Custom Game, and got to the Dawn of Man screen then the game map without asserts or any other apparent problems! :goodjob::king::cool:

On building my first city, got one Assert:
Assert Failed

File: CvCity.cpp
Line: 409
Expression: eFreeNatureBuilding != NO_BUILDING
Message: Should get a Free Building

----------------------------------------------------------

but was able to progess past it without issues. It's probably the case anyway that civs will get a free building in most finished mods so I'm thinking this is a benign assert. And the basic cityscreen appears to be working! (hmm I guess that Cloth does look a little like Tissue Samples.. :scan::p)
 
I removed bIsMustBeDiscovered from YieldInfo in XML. Basically it tells if the yield in question can be enabled by invention. In other words, it's a cache to avoid looping all inventions each time it's used. Now all inventions are looped when the game starts to set this cache.

Now I started to wonder. I changed how the game reads the XML, but who reads the C++ code to figure out how to set up XML? Well besides me :p

I decided to make a wiki page to make notes on. https://github.com/Nightinggale/Medieval_Tech/wiki/XML_YieldInfos
If we fill out the description every time somebody figures out what a certain tag does, then we will eventually have decent XML coding documentation. It has all the tags, which the DLL reads and since I figured that we could do this with multiple XML files I extracted the tag names with a script. This mean we can just fill in more wiki pages with fairly little work.

I then did get a bunch of asserts from gameinfo/emphasizeinfos.xml; but I cleaned M:C specific content from this and synced a commit and now they're solved.:king:
Looking at the diff for that commit I say it looks like the same 12 lines over and over with the only difference being that it's a new yield. After that it's the same approach again with 12 different lines, yet they look rather similar. This should be very easy to script, specially since I already have a script, which reads all the yields from the header file and then loops though all of them.

On building my first city, got one Assert:

but was able to progess past it without issues. It's probably the case anyway that civs will get a free building in most finished mods so I'm thinking this is a benign assert. And the basic cityscreen appears to be working! (hmm I guess that Cloth does look a little like Tissue Samples.. :scan::p)
I don't think you should mess with python right now, at least not the main interface file. Kailric talked about splitting the city code into a file of it's own. That way we generate the yield rows every time we open the city screen instead of every time we open the game. This mean we can make a row of yields, which is the invented ones when you open the city screen, entirely skipping uninvented ones. I realized another bonus within reach if we do that. Right now there are two rows. We could set a threshold to switch between one and two rows. You have one when you start the game and once you invented enough you end up with two.

If you make your own changes before such a split, then you would have to port those changes as well.

An alternative approach would be to share python as well. Currently domestic advisor works in RaR as well as M:C and it makes a few setup decisions based on XML settings. We could do the same and we don't want to look much into XML to do this, we could change the DLL to allow python code like GC.isColonization2071 or GC.isMedievalConquest.

We can always fork a specific file if we feel the need to do that. Remember that git gives full access to ALL commits, meaning if M:C breaks compatibility with 2071, then we can fetch a pre-commit version of that file and give 2071.
 
I decided to make a wiki page to make notes on. https://github.com/Nightinggale/Medi...XML_YieldInfos
If we fill out the description every time somebody figures out what a certain tag does, then we will eventually have decent XML coding documentation. It has all the tags, which the DLL reads and since I figured that we could do this with multiple XML files I extracted the tag names with a script. This mean we can just fill in more wiki pages with fairly little work.
It'll be like a c4c version of the civ4bts Modiki :cool: I documented some tags, though this is based on subjective experience from modding XML rather than detailed knowledge of the DLL functions. I'm really not sure what those Latitude tags do, I don't remember noticing them before :confused:

Looking at the diff for that commit I say it looks like the same 12 lines over and over with the only difference being that it's a new yield. After that it's the same approach again with 12 different lines, yet they look rather similar. This should be very easy to script, specially since I already have a script, which reads all the yields from the header file and then loops though all of them.
I'd never thought of using scripts for XML but that makes sense.. :science::scan: Manual text-editing XML can create frustrating errors esp when multiple files are required to be changed at once such as Text xml names (results in a lot of weird indents too). I've been using the freeware version of XML Marker for quite a while which has helped some (especially the handy tabular feature) but it's still often slow going. What input format does your script read from to generate XML, and could it be adapted for other schemas as well?

I don't think you should mess with python right now, at least not the main interface file. Kailric talked about splitting the city code into a file of it's own. That way we generate the yield rows every time we open the city screen instead of every time we open the game. This mean we can make a row of yields, which is the invented ones when you open the city screen, entirely skipping uninvented ones. I realized another bonus within reach if we do that. Right now there are two rows. We could set a threshold to switch between one and two rows. You have one when you start the game and once you invented enough you end up with two.

If you make your own changes before such a split, then you would have to port those changes as well.

An alternative approach would be to share python as well. Currently domestic advisor works in RaR as well as M:C and it makes a few setup decisions based on XML settings. We could do the same and we don't want to look much into XML to do this, we could change the DLL to allow python code like GC.isColonization2071 or GC.isMedievalConquest.
Ok, I agree it's best to avoid breaking compatibility. I did have slightly modified screens which included an (if isNative) statement to display alternate graphics and text for Native players; maybe that would be usable in M:C too since it won't have any effect in mods where playable Natives aren't implemented.
I did a few liberal changes to make the game start. For instance DEFAULT_YIELD_ARMOR_TYPE is set to YIELD_NUTRIENTS. We should find proper solutions for those later.
To help compatibility with the M:C Armor feature I added 3 "Armor" yields to the design doc (Plasteel, Duralloy, and Crystalloy) in order of escalating prowess and expense :scan: . Would it cause any problems to have 3 instead of M:C's 4? (no worries, I'll easily come up with a special Progenitor Tech armor that can't be produced but is rarely recovered from special sites :hmm:)
 
It'll be like a c4c version of the civ4bts Modiki :cool: I documented some tags, though this is based on subjective experience from modding XML rather than detailed knowledge of the DLL functions.
It's probably good enough. It's about having an idea of what each tag does. Originally my plan was to keep track of which tags I modified/removed.

I'm really not sure what those Latitude tags do, I don't remember noticing them before :confused:
The C++ comments says they are an M:C addition. However there is no explanation for what they do. I could track the variables and see where they are used in the code, but I didn't do that. Kailric might remember what he did.

I'd never thought of using scripts for XML but that makes sense.. :science::scan: Manual text-editing XML can create frustrating errors esp when multiple files are required to be changed at once such as Text xml names (results in a lot of weird indents too). I've been using the freeware version of XML Marker for quite a while which has helped some (especially the handy tabular feature) but it's still often slow going. What input format does your script read from to generate XML, and could it be adapted for other schemas as well?
It's a really stupid script meaning there is little logic in it. It's mainly a copy paste script. It loops all yields, places the name of the yield in LINE (silly name until you remember that it loops the lines in the header file) and calls a function for each yield. Adding more functions to select from would be easy. Functions are selected by arguments when calling the script meaning there is no upper limit to how many it can handle.

The script function:
Spoiler :
In the case of emphasize it became a bit more advanced. modifier starts with containing 1 and once it's done it sets it to -1 and restarts.
PrintX are functions I wrote. They print the number of tabs the number indicate and then it prints the argument.
Anything within ${} is a variable name. It treats all variables as strings unless explicit states otherwise (like less than comparison).
The first line removes the first 6 characters from the string, in this case YIELD_.


{
name=${LINE:6}

if [ "${modifier}" == "-1" ]
then
name="NO_${name}"​
fi

print2 "<EmphasizeInfo>"
print3 "<Type>EMPHASIZE_${name}</Type>"
print3 "<Description>TXT_KEY_EMPHASIZE_${name}</Description>"
print3 "<Button>Art/Interface/Buttons/Governor/Food.dds</Button>"
print3 "<bAvoidGrowth>0</bAvoidGrowth>"
print3 "<YieldModifiers>"
print4 "<YieldModifier>"
print5 "<YieldType>${LINE}</YieldType>"
print5 "<iYield>${modifier}</iYield>"
print4 "</YieldModifier>"
print3 "</YieldModifiers>"
print2 "</EmphasizeInfo>"​
}

As you can see it's strait forward to apply this to other xml files. Looping though something other than yields takes a bit more work, but is likely still way faster than doing it by hand.

Did you really think I wrote all the code by hand? Look at this commit: https://github.com/Nightinggale/Medieval_Tech/commit/bdb47e57b3433462ca2bcb40bd68d479976d5eb1
Except for the changes in yield groups I auto generated all of it. Come to think of it I used scripts whenever I touched 2071 yields and I might not even have read the names of all of them :lol:
I wrote a new small script for this one. It looks the XML file and triggers on lines with <Type> written in them. For each triggered line, it prints two tabs, then whatever is between > and < followed by comma. That gave me all the yields in the correct order and I could likely have copied around 4-5 yields during the time it took me to write the script.

Ok, I agree it's best to avoid breaking compatibility. I did have slightly modified screens which included an (if isNative) statement to display alternate graphics and text for Native players; maybe that would be usable in M:C too since it won't have any effect in mods where playable Natives aren't implemented.
I think I will add enum values to the DLL to tell which mod it's compiled for. We might need them someday. M:C might have playable native and in fact it has now with the world builder. However it's used for debugging only.

To help compatibility with the M:C Armor feature I added 3 "Armor" yields to the design doc (Plasteel, Duralloy, and Crystalloy) in order of escalating prowess and expense :scan: . Would it cause any problems to have 3 instead of M:C's 4? (no worries, I'll easily come up with a special Progenitor Tech armor that can't be produced but is rarely recovered from special sites :hmm:)
I think the game can handle having no armor whatsoever. The count is certainly not important at all. The game should be able to handle 1 as well as 3 or 10. I wrote this to be modder friendly.

I have one issue with 2071. It crashes when I try to start a new game. The exe (not our code) tries to read from unallocated memory :confused:
Could I get a guide to start the game? Obviously you managed to start the game. I suspect it has something to do with map generation and missing XML info.

EDIT: Committed python access functions gc.isMedievalConquest() and gc.isColonization2071()
I also committed the script output. Come to think about it, only two people get an email when something new is pushed to github. We can't add a third. Instead the guidelines says that at least one of the two "people" could be a mailinglist. However I don't know how to set up one, or more importantly: who will provide one for free?
 
I have one issue with 2071. It crashes when I try to start a new game. The exe (not our code) tries to read from unallocated memory
Could I get a guide to start the game? Obviously you managed to start the game. I suspect it has something to do with map generation and missing XML info.
:confused: hmm I'm not sure why that would be. I was using a DLL I compiled from the DLL sources of the github M:C core branch a couple days ago, if you've made more changes since then I'll try compiling a new one when I get home to confirm that it still works for me.

After compiling, I added that DLL to a mod folder copied from the 2071 github branch, then I added Medieval FPK from Kailric's core download. On starting I selected Custom Game, then set all the other players except me to "Closed" (since there's currently one civ in the bare "framework" xml).
 
On starting I selected Custom Game, then set all the other players except me to "Closed" (since there's currently one civ in the bare "framework" xml).
That might be the problem. It tries to add more players than there are civs/leaders.

EDIT: yes that did the trick :)

I noticed this assert: No rule to set price for YIELD_BIONICS
It just mean that the yieldgrups are set up incorrectly and the AI will not be able to figure out how much that yield is worth in its planning stage. It sets the value to 0 just like hammers and stuff. It's fairly safe to ignore in general and completely safe to ignore with AI players.

Looks like there is a skeleton to build a new mod on. Should be a lot easier now that we can start the game and see the new units and stuff.

I renamed YIELD_NUTRIENTS in python. It is now called YIELD_FOOD as that is what it is already called in python. This minor change changed the domestic advisor from not working at all to work 100%.

I also changed the number of default players on tiny maps to 1 meaning all other players are closed. We can always set it back later. If we forgot it used to be 6, then we can just look in M:C. It still needs to be a custom game though.
 
I realized I made a major blunder. I read the XML info from the C++ XML reading code and it turns out that it uses a different order than the XML schema. Making up for my mistake I wrote a new script based on the XML schema. Also I finally figured out how those schemas work. I added a column to tell if the tag can be skipped. The result is as follows:

Yields: https://github.com/Nightinggale/Medieval_Tech/wiki/XML_YieldInfos
Units: https://github.com/Nightinggale/Medieval_Tech/wiki/XML_UnitInfos

I edited the top two lines of the unit page, but nothing in the table. This is the output from the script and it should work on all schemas :w00t:

Granted it didn't do a perfect job at UniqueNames, but the rest looks ok.


EDIT: I just had an inspiration about col 2071 gameplay.

At the start it's really tough as the land transport has yet to be invented and inland cities are somewhat useless. We should allow the peddler profession from the start. Unlike M:C there shouldn't be experts in it and they will always only have one slot. This slot can then be restricted to 10 or 20. That way they are no match for lorries when it comes to speed and how much they carry, but at the same time you can carry stuff around before you get the needed inventions. On top of that you need the correct yields to build your first transport, which is tricky as it needs multiple types of yields. What if you produce those in different cities?

Maybe the AI will benefit from this addition even more than human players as it's not coded to handle not having access to building land transports.

I'm not sure if it should be able to trade with the aliens, but why not? :)
 
EDIT: I just had an inspiration about col 2071 gameplay.

At the start it's really tough as the land transport has yet to be invented and inland cities are somewhat useless. We should allow the peddler profession from the start. Unlike M:C there shouldn't be experts in it and they will always only have one slot. This slot can then be restricted to 10 or 20. That way they are no match for lorries when it comes to speed and how much they carry, but at the same time you can carry stuff around before you get the needed inventions. On top of that you need the correct yields to build your first transport, which is tricky as it needs multiple types of yields. What if you produce those in different cities?

Maybe the AI will benefit from this addition even more than human players as it's not coded to handle not having access to building land transports.
Sounds good to me :scan::goodjob: Could call the profession Merchant or Smuggler. There might even be a role after all for a Wily Trader-esque Infamous Smuggler unlocked through the Criminal techline; which could have <Invisible> and <bRivalTerritory> (just looked those up in your XML reference;)) to be able to sneak through hostile territory and sell Narcotics. :cool:

About the issues with "inland" transport, that could all probably change a lot if using Space Domain & allowing ships to fly over planets and land on any planetary settlement. I'm not sure how to think about this though.. On one hand, its unrealistic and somewhat frustrating to always sail around a fixed "circumference". OTOH, there's part of me that enjoys having some kind of deep Heart-of-Darkness "interior" that's an actual challenge for humans to access and explore.

Exploration in vanilla game was way too easy, being able to quickly march across most of the map with a single Scout picking up goody huts. This is improved a lot with the M:C Animals; I'll look forward to challenging 2071 players to hack through steaming Killbot-infested jungles with Intrepid Explorers in search of Progenitor ruins :cool::p But if you can easily fly across and scan planets from above it takes away some of the challenge. Maybe some compromise where ships can move across planets but much slower than in Deep Space due to atmospheric turbulence etc.

I'm not sure if it should be able to trade with the aliens, but why not?
Sure I'd love it if AI traded with the Aliens (and also if Alien players sometimes sent Smuggler or Emissary units to trade rather than only giving gifts). One of my initial goals for the DLL was to eliminate many of the vanilla isNative checks, making the natives effectively regular players but with a few remaining rules like no closed borders, and using "goodyhut" improvements to produce yields from rather than sacking them for loot.
 
I added placeholder entries for several colonial and Native civs for testing. It still loads fine but gives the following assert on ending a turn. My guess would be the city AI may be trying to look for certain yields?
Assert Failed

File: CvPlayerAI.cpp
Line: 6163
Expression: pBestYieldCity != NULL
Message:
 
Sounds good to me :scan::goodjob: Could call the profession Merchant or Smuggler. There might even be a role after all for a Wily Trader-esque Infamous Smuggler unlocked through the Criminal techline; which could have <Invisible> and <bRivalTerritory> (just looked those up in your XML reference;)) to be able to sneak through hostile territory and sell Narcotics. :cool:
That's not really what I was thinking, but why not both? I mean those traders appear to be an interesting addition. Alternatively we can give a profession a free promotion if invention X is invented. I'm not sure if the DLL can handle that, but it wouldn't be unrealistic to add.

About the issues with "inland" transport, that could all probably change a lot if using Space Domain & allowing ships to fly over planets and land on any planetary settlement. I'm not sure how to think about this though.. On one hand, its unrealistic and somewhat frustrating to always sail around a fixed "circumference". OTOH, there's part of me that enjoys having some kind of deep Heart-of-Darkness "interior" that's an actual challenge for humans to access and explore.

Exploration in vanilla game was way too easy, being able to quickly march across most of the map with a single Scout picking up goody huts. This is improved a lot with the M:C Animals; I'll look forward to challenging 2071 players to hack through steaming Killbot-infested jungles with Intrepid Explorers in search of Progenitor ruins :cool::p But if you can easily fly across and scan planets from above it takes away some of the challenge. Maybe some compromise where ships can move across planets but much slower than in Deep Space due to atmospheric turbulence etc.
Flying over land would likely spoil the gameplay. Sure it sounds realistic and stuff, but something in the game dies if you have easy access to everything from the start.

As for the domain I wonder if space is the one to be added. I think it would be way easier to code if we keep space as ocean, at least in the DLL and then add planet_ocean or something. That way we can still access the ocean code to handle "sailing" space flight just like 2071 has done until now.
I haven't looked at the code, but this is what came to my mind when reading what you wrote.

Sure I'd love it if AI traded with the Aliens (and also if Alien players sometimes sent Smuggler or Emissary units to trade rather than only giving gifts). One of my initial goals for the DLL was to eliminate many of the vanilla isNative checks, making the natives effectively regular players but with a few remaining rules like no closed borders, and using "goodyhut" improvements to produce yields from rather than sacking them for loot.
I have been wondering if the aliens should be natives or "Europeans". Look at M:C. There are some "Europeans" with noteworthy different traits than the others, such as the Vikings. We should at least consider which approach is the right one.
 
I added placeholder entries for several colonial and Native civs for testing. It still loads fine but gives the following assert on ending a turn. My guess would be the city AI may be trying to look for certain yields?
This is the offending code. pBestYieldCity is never set by this code.
Code:
for(pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
{
	for (int iProfession = 0; iProfession < GC.getNumProfessionInfos(); ++iProfession)
	{
		CvProfessionInfo& kLoopProfession = GC.getProfessionInfo((ProfessionTypes)iProfession);
		[COLOR="Red"]if (kLoopProfession.getYieldsConsumed(0, getID()) == eLoopYield || kLoopProfession.getYieldsConsumed(1, getID()) == eLoopYield)[/COLOR]
		{
			[COLOR="Blue"]int iValue = pLoopCity->getProfessionOutput((ProfessionTypes)iProfession, NULL);[/COLOR]
			if (iValue > 0)
			{
				iValue *= 100;
				iValue += pLoopCity->getPopulation();
				if (iValue > iBestCityValue)
				{
					iBestCityValue = iValue;
					pBestYieldCity = pLoopCity;
				}
			}
		}
	}
}
The stop conditions are set in red and blue.

The red one mean at least one profession should consume the yield.
The blue one loops all buildings in each city.

I suspect the blue one is the cause of this. The lack of a free building means the colony lacks a building, which in turn make it fail to set iValue to anything different from 0, which then fails the larger than 0 test in the next line. However I'm not 100% sure. This is what I got from a brief view on the issue.

While looking in CvCity::getProfessionOutput() I found
Code:
if (GC.getUnitInfo(pUnit->getUnitType()).getCasteAttribute() == 4 && kProfessionInfo.isWorkPlot())
{
	iModifier += GC.getCache_NOBLE_FIELD_LABOR_PENALTY();
}
== 4 ???
Looks like the case of a missing enum. That could make it a bit more tricky to make this code work well for 2071. The code gives a penalty to nobles working in the fields outside the city. I wonder if I should try to make a caste class like we have unit class and building class. That way we will get a new XML file, which in turn allows setting variables like iFieldLaborPenalty. The DLL will then treat all of them identical, moving the setup from DLL to XML. I have to examine this closer to figure out if it's a good idea or not, but it is for sure something, which should be an enum!

Edit: now that I think about it, maybe it wasn't such a good idea to clean the XML files all at once. The problem is that we get problems with unknown causes. Now if we didn't clean anything at all from the start, but just took one file at a time, if something goes wrong, then we know which change caused the assert. Then the assert can be fixed and the game is stable and ready for the next change.
 
if we didn't clean anything at all from the start, but just took one file at a time, if something goes wrong, then we know which change caused the assert
unfortunately most of the xml relies heavily to tags referenced back and forth between multiple files, so it gets quickly problematic to remove/add anything piecemeal without screwing up quite a lot else. Anyway, it's promising that it already loads without any asserts after removing virtually all M:C specific content. I'd think there's bound to be some obscure residual hardcoding somewhere for a while though, eg re Nobles and the tradescreen system, which may be hard to find in either case since it might only pop up in specific game situations.

I have been wondering if the aliens should be natives or "Europeans". Look at M:C. There are some "Europeans" with noteworthy different traits than the others, such as the Vikings. We should at least consider which approach is the right one.
I also thought about making aliens entirely "human"-like and essentially having no civs with the <Native> tag.. but it turns out there are lots of other existing xml tags and core dll functions that refer to it in ways that are useful for 2071 Aliens. (e.g. ability to mod things like combat bonus vs aliens, diplo bonus/penalty vs aliens, land buying, flexible borders, not sacking goodyhuts, the missionary/convert/hybrid system, and now with M:C plenty more modular options to allow/disallow things specifically for civs with the Native tag.) So, there's plenty useful about it for modmods that want to differentiate between 2 classes of civ, though some of the vanilla native-specific DLL was annoying, like an AI food/horses/musket obsession (to be fair that's all they're about in vanilla) and a "native yield destruction" function that's a blatant attempt to cripple them. I'd tried clumsily deactivating some of the vanilla isNative code chunks in the old version, with reasonably good results for making their behavior somewhat more like standard players (at least so I thought).

Flying over land would likely spoil the gameplay. Sure it sounds realistic and stuff, but something in the game dies if you have easy access to everything from the start.
Yeah I kinda agree. At least at the beginning it's somehow good for gameplay to have a hidden "interior" that's hard to reach esp with various dread Beasts and Aliens seething out of it periodically:cool::scan: To cope with the odd reality of the "circumference" effect I think I had a fragment of Pedia backstory about how the strange magnetic fields of the New Worlds interact with fragile earth stardrives, causing them to only be able to navigate along a certain meridian :crazyeye::scan::p. But in late game after most of the map's discovered, maybe a later tech could allow some ships to have Atmospheric Shielding allowing them to move through the atmosphere but slower than through Space.

I think Androrc said he'd tried water+space terrain without adding a domain but it didn't work; something about how the graphics engine draws water and waves on the water domain, and "edges" between water/space and land/space only appear right if they're different domains. I guess one advantage of the current setup is space professions can use <bWater> in professioninfos.
 
I think Androrc said he'd tried water+space terrain without adding a domain but it didn't work; something about how the graphics engine draws water and waves on the water domain, and "edges" between water/space and land/space only appear right if they're different domains. I guess one advantage of the current setup is space professions can use <bWater> in professioninfos.

From what I recall, that is indeed the case: the transition between water and space didn't work quite so well (except that it was IIRC not related to domains, but rather plot types). Although, that issue could be avoided simply by having the map generator only create inland seas (perhaps not an optimal solution, but a practical one).
 
I received a mail saying the XML was changed. I ran the script to update the C++ code. While I was testing if I made typos (fat change the script does that, but still :)) I received another mail saying the header was changed. It turns out that YIELD_OPIATES is written at an incorrect location compared to XML. I fixed that but before I commit the XML change once again... this is not going well :lol:

Maybe we should coordinate a bit more. Also you shouldn't commit something you are going to change 20 seconds later. Change the XML until you are satisfied, then change C++ and execute the result. Change XML if needed etc. Commit it once you like the result.

Also you failed to update the cpp files. Yields are in one header and two cpp files. I can easily update the cpp files, but I need to know if you are done changing the XML file this time :p
 
lol yes, sorry it seems we were trying to fix the same things at the same time :lol::crazyeye:

I updated and expanded the 2071 branch yields.xml to the full list of yields in the design document; while working on that I was also attempting to update the Yields_Colonization_2071.h and Yields_Colonization_2071.cpp files in the master branch of DLL sources to reflect the XML updates and reordering; but later realised the order for YIELD_OPIATES was off. Methinks I should just leave those cpp and header files alone in future so you can operate using your scripts directly. Well, I think things should be sorted out now, or at least hopefully nothing is too badly broken :mischief::p The XML should contain everything now, and looks in the right order.

maybe I'm not knowledgeable enough yet re git, but is there some way to avoid members working on the same file without knowing it? there doesn't appear to be a file lock or "checkout" like my recollections of SVN.. :confused:

From what I recall, that is indeed the case: the transition between water and space didn't work quite so well (except that it was IIRC not related to domains, but rather plot types). Although, that issue could be avoided simply by having the map generator only create inland seas (perhaps not an optimal solution, but a practical one).
Obrigado, Androrc. :king: From what I recall it was necessary to have either all Ocean or all Land plot types bordering space (ie no Coast tiles exactly bordering space) due to graphical issues. If most ships won't be able to cross a planet, I guess that's a good reason to use inland seas too.

edit: actually, I wonder whether the M:C features for having units only enter owned or explored territory could be used to advantage, so that ships could only fly through and land in owned/settled areas. That way ships wouldn't be able to trivially "explore" planet interiors but could be able to land on "inland" colonies once they'd set up the appropriate transponders etc to facilitate navigation. :scan:
 
maybe I'm not knowledgeable enough yet re git, but is there some way to avoid members working on the same file without knowing it? there doesn't appear to be a file lock or "checkout" like my recollections of SVN.. :confused:
I don't think there is such a feature. After all git is basically an svn client and server inside the git client. This mean if you lock a file at the server you still only lock it on your own computer.

Besides I don't think you can prevent this from happening in svn either.

edit: actually, I wonder whether the M:C features for having units only enter owned or explored territory could be used to advantage, so that ships could only fly through and land in owned/settled areas. That way ships wouldn't be able to trivially "explore" planet interiors but could be able to land on "inland" colonies once they'd set up the appropriate transponders etc to facilitate navigation. :scan:
That's a good idea. I don't think it works without modifying the DLL though. It would be something like setting up "only travel in owned plots" for land and water domains while space domain should ignore it. I don't think the current implementation takes domains into account.

I think you should just focus on getting the game up and running in a playable state. Adding brand new features, which aren't even present in 1.42 should be postponed. You are talking about minor issues compared to the fact that there aren't even proper units and stuff in the game yet.

We should learn from Babbage mistake with his Difference Engine. Basically he had figured out how to build a mechanical computer in 1822. He spent years building one, but he kept on improving the design rather than just building what he had and eventually funds ran out after he had spent what was equal to the price of two war ships and he still didn't have a single complete machine. The replica made by engineering students is made by just following his blueprints without considering if it is good or not and that one actually works. He was right all along, but it wasn't proven until more than 100 years after his death because it was never "good enough" and nobody enjoyed the outcome of his brilliant idea.
 
lol too true. The Greeks didn't make that mistake and got right to it with the Antikythera Mechanism. (or was it the Progenitors all along...) :scan::p Well now the Yield tags are in place, that's one of the core XML files with the fewest references to other files. I think the next logical ones to tackle would be Professioninfos (requires Yieldinfos tags) and then buildinginfos (requires Professions and Yields tags).

Being inspired by your C++ generating script, I decided to start looking into the possibility of developing a simple script for XML generation using Perl XML::Simple . I think it may be possible to create a script that can read any XML file as a template (e.g. a file containing one standard XML entry for Yield or Unit or Profession etc), then read a second file listing content items to insert (eg list of all Professions); and then generate an XML file with one entry for each content item, while populating the content name across several tags appropriately for each content item (e.g. generating all the required tags for description and Pedia TXT_KEY references, dds icon file paths, etc.) It may take a little while to devise this and not 100% sure I can get one working (with my already rudimentary Perl skills being as rusty as the Antikythera mechanism:p), but if it's possible to get something like this working I think it could really accelerate development of total conversion mods/modmods and avoid tons of error-prone manual XML cut-and-paste.:cool:
 
Top Bottom