1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

School system

Discussion in 'Civ4Col - Medieval: Conquests' started by Nightinggale, Aug 8, 2013.

  1. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    In my book I found a few names that you may be referring too. The pecking order went like this...

    Code:
    The Lord of the Manor
    -----Seneschal/Steward/General Manager
    ]]]]]]-----Bailiff/Intendent/Farm Manager
    ]]]]]]]]]]]]-----Reeve/Foreman 
    ]]]]]]]]]]]]]]]]]]----Beadle/Constable -collected taxes and fines
    ]]]]]]]]]]]]]]]]]]----Hayward -lead sowing and harvesting
     
  2. drjest2000

    drjest2000 Chieftain

    Joined:
    Dec 8, 2001
    Messages:
    332
    Location:
    retired
    Thank you! Reeve was the word I couldn't remember. I kept seeing it in my books, but in Anglo-Saxon times a reeve was a high office like a magistrate, so that's what confused me. After the Normans took over England, the reeve was demoted to the guy in charge of getting the peasants to do the work.

    In Vermont and Canada, they still sometimes use the term "reeve" for mayors or other local officials where there are still townships with "shire charters" -- which is more or less the Anglo-Saxon usage. But to be honest, the term is pretty rare these days thanks to the homogenizing effect of television and the Internet on vocabulary. Only old people and book-worms (like me) say it....
     
  3. orlanth

    orlanth Storm God. Yarr!

    Joined:
    Nov 17, 2001
    Messages:
    1,759
    and Hobbits! ;) there is a modern office that takes its name from the original "Shire Reeve", bet u can guess what it is :p
     
  4. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    Seeing that my work on journeyman has stalled I decided to face reality and declare it a future project (but not too distant future). Instead I implemented the TAC school system. I have done so now and pushed it to github,

    As I didn't just copy paste the code from RaR it ended up being with a few differences.

    For gamers:
    Schools learn new units even if no students are at the school at the moment.

    For modders:
    A unit, which can't be taught at school has teach level 0 in M:C (not 100). The XML file sets iTeachLevel to 0 unless explicit told otherwise.

    The number of teach levels is set with a define and isn't hardcoded to 3 (though 3 is used right now). This mean it's a one line change to allow 123 teach levels, though I can't think of a scenario where that many is positive for the gameplay.

    Non-educational buildings can have teach levels. This allows stuff like say building a "town hall" called "Lord's castle" with teach level 4, which makes the city in question the capital, which in turn is the only city, which can teach some super unit. I'm not saying we should make that feature, but the current implementation of teach levels allows it.


    The user interface is more or less copy-paste and the same goes for the teacher list and student ordering. Anybody who tried RaR should be able to figure out how to use this.

    Now go test this. I finished this today and haven't tested it much yet. However as much of it is well tested in RaR it should work fine, but do test. Any excuse for playing is a good excuse ;)


    Also do note that the Pedia for units is updated to tell about teach levels. I gave all units a teach level, but I don't know how balanced it is and is subject to change. Recommendations are welcome.
     
  5. orlanth

    orlanth Storm God. Yarr!

    Joined:
    Nov 17, 2001
    Messages:
    1,759
  6. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    First column is the tag, second has X if it can be skipped in XML and the third is the description. You added some description in the second line, which messed up the columns. I fixed it, but I can't tell if you deleted some X. Hopefully not because it's a pain to go through to make sure they are all there.

    Please take a look at how it looks now and hopefully the layout will survive.

    I figured out how iCasteAttribute work, well sort of. In the DLL it's sometime checked and it would appear that 7 means it's a bandit. 4 means it's a noble. All numbers 1-7 are used and each has an undocumented effect. We seriously need to rethink the caste design.

    Caste 4 mean it has -25% production when working on plots. It appears that there is a caste, which has -1 building production. Some castes appear to be banned from certain professions. I think it was caste 2, which can't have military professions.

    I question if caste 7 should be a caste at all. We should have isBandit() like we have isAnimal(). Caste appears to be difference between units in a single civ, not to tell the differences between different civs.

    Ideally we get an XML file, where all this can be configured and modded. However without truly knowing what goes on I don't know if it's a good idea. The production modifier ones should ideally be known at compile time for performance reasons. Maybe it is best to hardcode it in the DLL like it is right now.

    Whatever we do we should at least make an enum to get readable names instead of using magic numbers. Also it should be clear which effect each caste has.
     
  7. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    This was a work in progess and I haven't finished it yet:D In CIV4UnitInfos.xml I listed what the Cast System means...

    Code:
    <!--Caste System: 0 = Normal; 1 = NoBuilingsWorked; 2 = NoneMilitary; 3 = Squire; 4 = Craftsman/Nobleman; 5 = AI Units Only; 6 = no learn natives; 7 = None Animal Barbarian-->
    Then I started adding in a new enum as below but I haven't merged it into the Units list yet. You should be able to swap things like <iCasteAttribute>3</iCasteAttribute> with <iCasteAttribute>MODER_CODE_SQUIRE</iCasteAttribute> then in the DLL check for MODER_CODE_SQUIRE instead of "3". Like I said, I just haven't got a round toit yet:)

    EducationClass is the class a unit will Educate too instead of getting to select a mastery. Like A Criminal Educates to a Serf and also with the <RehibilitateUnitClass> tag the Criminal will educate to serf if units are working in a Court building.

    Units with a KnightDubbingWeight have a chance to be dubbed as a knight. This is to simulate the Merchant Class such as Bakers and Master Coat Makers being made honorary Knights as the separation of the Merchant Class and Noble Class grew closer.

    Code:
    enum DllExport ModCodeTypes
    {
        VOID_CODE = -1,
    
    	NO_MOD_CODE,
    	MODER_CODE_FASTER_CHOP_TREES,
    	MODER_CODE_SPICE_ROUTE,
    	MODER_CODE_SILK_ROAD_ROUTE,
    	MODER_CODE_TRADING_POST,
    	MODER_CODE_ONLY_NONE_NATIVES,
    	MODER_CODE_NATIVES_ONLY,
    	MODER_CODE_ANYONE,
    	MODER_CODE_NATIVES_VIKING_AGE,
    	MODER_CODE_ALLOWS_TRADE_FAIR,
    	MODER_CODE_CANNOT_WORK_BUILDINGS,
    	MODER_CODE_NONE_MILITARY,
    	MODER_CODE_SQUIRE,
    	MODER_CODE_CRAFTMEN_NOBLES,
    	MODER_CODE_AI_ONLY,
    	MODER_CODE_CANNOT_LEARN_NATIVE,
    
    
    #ifdef _USRDLL
    	NUM_MOD_CODE_TYPES
    #endif
    
    };
     
  8. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    I don't think 6 belongs there. I added which units the natives educates to Pedia by looping all natives and check if at least one of them teach the unit in question. Isn't that what it is supposed to mean?

    I'm not sure if it is the correct place to store 7 either.

    I came up with an idea for a design change. Instead of storing this in the current numbers, we should store it in a bitmask. That way we will get

    We can then define the castes in GlobalDefinesAlt.xml
    11=1+2+8 meaning it gets the abilities from those 3 castes classes. Each caste class should then have a clearly defined and we can use the XML defined name when setting up UnitClasses in XML.

    We should also consider if some of them should be split to ensure that they really have just one effect each. We do have 32 bits to use for this if we really want to.

    That is the most modder friendly approach I can think of. Sure the numbers aren't human readable, but if we in the enum write
    Code:
    CASTE_A = CASTE_FIELD_PENALTY + CASTE_AI_ONLY
    then the game will give us the number to copy paste when hovering the mouse over CASTE_A. We will not actually use CASTE_A in the code, but we will get it calculated for us automatically.

    One thing which is good about the bitmask approach is the speed. The game is equally fast at (caste == 4) and (caste & 4), which mean it's a single cycle check. Also it makes no difference when coding. Naturally we should use an enum and not hardcoded numbers.
     
  9. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    I started wondering about the bitmask and that gave me an idea about teach level.

    We could add buildings as requirements to educate units. They would be added as a list in XML just like any other list of say professions.

    When UnitInfos is read from XML, it goes through the list of needed buildings and calls a function for each to set it a unique building teach level where precisely one bit is set. The unit building teach level is then adding the building teach level of all needed buildings. The city's teach level is then adding the building teach level of all present buildings.

    The check to see if a unit can be taught would then be
    Code:
    (unit teach level < city teach level) && ((unit building teach level & city building teach level) == unit building teach level)
    That's a quick test on variables and all of those can easily be cached.

    This will be really fast and it's fairly easy to set up. The downside is that it might not be that easy to debug as the building teach level is configured at runtime. I think we can live with that as the buildings will get the same building teach level each time as long as the XML files aren't modified. Exploiting this info should be enough to figure out what goes on assuming we even need to debug this. The other tradeoff is that building teach level is an int, meaning it has 32 bits. This in turn will hardcode a limit of 32 extra buildings.

    There is also the issue of what if a building is replaced by another one. What if fishermen needs a dock and you build a shipyard? The docks will no longer be present, hence the fishermen can no longer be trained. At least not if we don't come up with a solution.

    And right when I clicked post I came up with a solution :lol:
    If we assign docks to say bit 5, then we look up all buildings replacing docks and set bit 5 for those. We do this recursively ensuring that even replacement's replacement sets this bit. There is one issue with this though. If unit a need a dock and unit b needs a shipyard and unit a is before unit b in the XML file, then unit b will not set a shipyard bit as it already had a bit assigned.... solved one problem and created a new one. This could possibly be solved by not setting bits in the replacements until after all units have been loaded. That way each building will tell if a unit demands this building specifically.

    EDIT: come to think of it, the bitmask can replace the teach level, which in turn is reduced to education price tag. This will separate the cost and the needed school building, allowing units with different education costs even though they have the same building requirements.

    The real question is: will this be used if I code it? I could code it only to discover that there is no ingame change compared to what the current code can provide.
    Also the newly added education system isn't wasted. Most of it would be reused.
     
  10. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    Bitmasks seem like a cool tool to use. I'm all for it as it will teach me something new and the ability to combine attributes will come in handy.

    "no learn natives" just means the unit can't learn from natives. Like I didn't want Serfs and Slaves learning from natives. But, you can also set <iNativeLearnTime> to -1 and get the same thing. So, I looked into the code to see why I did this and only can find it in the in CvGameTextMgr, so I did this so that the Pedia would show that these units can't learn from natives even though they do not have a Specialty or are a Master. I didn't want that information displayed for all those extra units. Now that I think about it I could have just used <iNativeLearnTime> and set it to -2 to display the message, so we can do that and remove that attribute and make room for another.

    All Animals use the bAnimal>1</bAnimal> and so any "Barbarian" owned unit that does not have the bAnimal tag would be a None Animal. In the code, however, all units with Caste of 7 are also treated as Natives as far as Native Combat Bonuses. Also, I have it coded so that only Animals and Units with the Caste of 7 will spawn for Barbarians. Not sure exactly why I did this actually...
     
  11. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    It's actually fairly simple, specially considering we aren't going to do advanced stuff with the bitmasks. It's just a matter of using AND and OR. We already do where they are called && and ||. They also exist in a bitwise version called & and |.

    Example with binary added:
    Code:
    A = 1 | 2; (01 | 10)
    B = 1 & 2; ( 01 & 10)
    C = 1 | 3; (01 | 11)
    D= 1 & 3; (01 & 11)
    The result from this is
    A=3 (11)
    B=0 (00)
    C=3 (11)
    D=1 (01)

    In a way you could say we will use an int as an array of 32 bools. The difference between this and and array of bools is that an int can fit in a register and as such can do &, | and == in a single cycle even when checking 32 bools. It can also be viewed and passed around like an int, which is what we could do with the XML file. I wonder if we can use hex in XML.
    Also an int uses the same amount of memory as a bool, which means memory is stored 32 times more efficiently.

    The downside to bitmasks is that we have a fixed number of bits. Int is 32 in CIV4 (64 bit compilers tend to give it 64 bits. Be careful!). The whole idea of a bitmask becomes a lot more complex if the number of bools exceeds this.
    Another tradeoff is that accessing a single bool in a bitmask is slower than reading a bool because you have to filter out the noise from the other bits.

    We will do this fairly simple. If (var & ENUM) will tell if the bit set in the enum is true. It works as long as only one bit is set in the enum.

    I also mentioned checking for multiple buildings at once. Here we check (buildings & demand). The resulting bit is 1 if it is 1 in both inputs. If buildings have all the needed bits set, then the result will be the same as demand. This is why if ((buildings & demand) == demand) will only be true if ALL the needed buildings are present.

    In other words we have a setup where we exploit the good parts of bitmasks perfectly while we avoid touching the parts where they have drawbacks. The only real drawback is writing the bitmask in XML as an int. We need to get an easy to use binary to int converter, but it's still not ideal. Setting up a bitmask in C++ is easy as you can do (ENUM_A|ENUM_B|ENUM_F) and you will have a bitmask with those 3 bits.

    Somehow I'm not surprised if people aren't looking much into bitmasks today. They are a low level approach to reduce memory usage and in a world with high level languages they are kind of old school. However in our case they increase speed, reduce memory usage and is fairly easy to code. Who cares if they are old school? :)

    Another usage for bitmask would be the networking code. We can transmit two ints and 4 bools. However we can also view that as 6 ints of range 0 to 1023 and 8 bools if we need that. Bitmasks would be extremely useful here as the only alternative would be to rewrite the exe to allow more ints.

    However generally speaking bitmasks aren't something we should add everywhere.

    As long as the duck tape holds and it works ingame, then I guess it's ok. I once used a pointer to a pointer to a pointer. It worked perfectly but rewrote it anyway with the fear that I might have to run that function in a debugger some day :lol:
     
  12. Androrc the Orc

    Androrc the Orc Chieftain

    Joined:
    Apr 19, 2004
    Messages:
    1,620
    Location:
    Vienna, Austria
    My understanding is that guilds were mostly related to urban professions (which mostly correspond to the "indoor" jobs in Civ4Col), specially manufacturing ones. As such, possibly it would be better to make journeymen only available for professions which are indoor ones, and perhaps also require that they be industrial professions.
     
  13. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    My plan is to make each profession have an on/off switch for journeyman. However I kind of view journeyman as labor experience. Even though farmers may not have been journeymen, I do say they should be able to gain experience. Maybe it should be called something else, but that would be a cosmetic change.

    Currently the work on journeyman is stalled. I keep getting more and more tasks I would like to do and I started to make a priority based on how much it will improve gaming enjoyment. This priority tells me that the screwed domestic sales is the first thing to fix. Journeyman is somewhat down the list as the game can be quite enjoyable without it. Still I would love to get it working, which mean it isn't the lowest priority.
     
  14. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    I have been thinking on how to handle this best and I came up with making new variables instead of sticking it into one.
    1 ?
    2 is ok as a bool
    3 ?
    4 gives -25% plot production. This could be a signed int with plot bonus.
    5 bool
    6 generate by DLL/python at runtime. This way it will be made automatically based on settings instead of multiple XML values, which could be out of sync. I wrote python to write precisely this info in RaR pedia. Well it tells the units, which can be taught by natives.
    7 bool: bBarbarianSpawn

    This will provide more flexibility. The caste system could be used as a set of predefined variables if we really want to. Add a new XML with the caste and add info on how the caste behaves. Once the XML files are loaded, all units in a caste can then get the data overwritten. This makes it quick to make multiple units with the same settings if that is the goal. However I think those predefined caste setups might be overkill.

    Bitmasks might not be that useful in this context anyway as a number of bools can do the same. Needless to say we can take all bools in UnitInfo and merge them into a bitmap, but we will not really gain much from doing so.
     
  15. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    I may have mentioned this but I did this so that I wouldn't have to keep continually adding new XML tags every time I wanted to add something. I would just add a new enum to the list and carry on. Are you saying we should add new XML tags for all of these? If think we should, then go for it:)

    Anyway, I'll explain their meaning...

    • 0 = Normal (had nothing assigned to this one yet)
    • 1 = NoBuilingsWorked(can not work in buildings in cities, plot professions only)
    • 2 = NoneMilitary(can't be military)
    • 3 = Squire (Squires are promoted to Knights either by learning, working, or battle)
    • 4 = Craftsman/Nobleman(this also determines if a unit can be promoted to an Honorary Knight, also it give -25% to plot production but that should be removed. Lots of Nobles worked their own land.
    • 5 = AI Units Only(Unit available only to the AI)
    • 6 = no learn natives(can't learn from natives)
    • 7 = None Animal Barbarian(Human Barbarian)
     
  16. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    One thing about Schools, most Professions did not use the school system in Medieval times, they used Apprentices/Journeyman and such, learned on the job, as we all know. Schools were used to educate the rich or clergy and they for sure didn't go into Blacksmithing after gaining that education. I feel like this should be a part of the Mod and would simplify what to do about Journeyman mods. Anyway, here are some ideas...

    -The rule could be that Schools only educate units to Clergy, Dignitaries, Diplomats and such.
    -Units being schooled generate Education, which adds to Culture. This is already a rule.
    -Common folk who you want to educate have a high tuition, while Pages, Squires, and other well to do folk have cheaper costs.
    -Merchants, Wily Traders, and such also sought education as it was needed in making profitable trade deals, so they should be part of the School system as well
    -Units who graduate from schools/Universities could gain Promotions that enhance their Profession. Like a Merchant could receive the Latin promotion, allowing him to make better trade deals as this was the language of merchants.

    Anyway, this would keep Journeyman mods from competing or conflicting with Schools.
     
  17. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    Ok, I have an issue. I am wanting to Train some LumberJack teachlevel 1, and I have a Schoolhouse which should be able to do this, except they do not appear in the list. I am totally unfamiliar with the new Teach code so I am not sure what has happened. I really like the Teacher interface btw, if I could just teach Lumberjacks, I can teach Carpenters (and yes I have a Lumberjack in the City). I did a quick debug and apparently the Lumberjack does not appear in the m_ba_ConTrainSpecialist array. So why are Lumberjacks not in this array but Carpenters are?
     
  18. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    The only problem I can think of offhand is that m_ba_ConTrainSpecialist updates on new turn event meaning you will not be able to train lumberjacks until the turn AFTER he is added. Once the school has learned how to train a specific expert, it will never forget it again even if the expert unit leaves the city. Placing expert workers in a city for one turn and then get to work is enough to continuously put out expert workers.
     
  19. Kailric

    Kailric Jack of All Trades

    Joined:
    Mar 25, 2008
    Messages:
    3,094
    Location:
    Marooned, Y'isrumgone
    Ahh, yeah that may have been the issue as I had just placed the Lumberjack there. I'll check later. I forgot the School system did that. If this is the case, perhaps this should be adjusted as new Players unfamiliar with the system would have the same issue I did, as it works different from vanilla. Also, this needs to be placed in some kind of tutorial or the Pedia.
     
  20. Nightinggale

    Nightinggale Chieftain Supporter

    Joined:
    Feb 2, 2009
    Messages:
    3,986
    Vanilla needed the units to be in the city as well. In fact it counts the turns the unit is in the city as the price of training drops. We have a fixed price.

    I have been thinking of making an outdoor task where an expert can do nothing on a city plot and deliver his expert type to the school. If that is possible, then it will be possible to automate an expert to go from city to city to enable all schools to teach this profession. This will make school setup a lot less hassle. Also the AI can make good use of all automation processes.
     

Share This Page