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

Building Resources

Discussion in 'Civ5 - Mod Components' started by Whys, Nov 1, 2010.

  1. elistor

    elistor Warlord

    Joined:
    Jan 12, 2008
    Messages:
    111
    adding his lua to one of my mods that was just waiting for this now, let you know in 10min or less. :D
     
  2. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    There is one change you're going to need to make. It's the first line of actual code in BuildingResources.lua:
    Code:
    include( "SaveUtils" ); MY_MOD_NAME = "b218b309-9df5-4af5-baf9-c297e593398a";
    You'll want to change the MY_MOD_NAME = "???" to what ever your mod's unique id is. That will prevent overwriting of data for other mods running at the same time. Provided of course that those mods are also using SaveUtils to save data to a target. Otherwise there will be conflicts. There is only one save slot per target, so mods have to treat it in a compliant manner.
     
  3. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    I don't foresee any reason that wouldn't work. It just uses the resource type tags, so whatever tags exist should apply.
     
  4. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    Regarding mod combining, allow me to explain it another way. Do a search for the following:

    SetScriptData
    GetScriptData

    These two commands should only appear in SaveUtils.lua. If they appear anywhere else, there is the potential for conflict. Specifically, BuildingResources.lua saves data to all players. If these two commands do appear elsewhere, you need to rewrite that line of code in the following manner, where target is a player, plot, or unit:

    target:SetScriptData( value ); becomes save( target, key, value );
    data = target:GetScriptData(); becomes data = load( target, key );

    key can be any integer or string you want to use, it just has to be the same in load. Basically it names the save and you recall that save by name. Different names for different data being used by different lua files.

    If you need some help combining it, just let me know and I'll give it a look.
     
  5. elistor

    elistor Warlord

    Joined:
    Jan 12, 2008
    Messages:
    111
    Positive, it works great with existing resources.
    Negative, So far I am unable to get it to work with a new resource. I even ignored the custom resource i want and just duplicated everything in the XML about RESOURCE_IRON and then renamed IRON to BLOODIRON (on everything but the art tags) and nothing. No error gets generated in either database.log or lua.log. If I swap the <Building_ResourceChange> <ResourceType> to an existing one it supplies said resource just fine, but if I switch it back to a custom resource it fails.

    Sigh, I'll work at it more tomorrow but if anyone wants to see the code for my resource here it is.
     

    Attached Files:

  6. Decimatus

    Decimatus King

    Joined:
    Oct 22, 2005
    Messages:
    853
    Perhaps try using an existing resource mod and then applying it to the building mod? Such as Dales Hardwood mod?
     
  7. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    I've tried it and it works. Chances are yours works too, it's just not visible. Try also running the mod "AgS - Resource Info Panel" and the new resource will show up in the resource panel. Issues regarding visibility and map resource placement are discussed here:
    http://forums.civfanatics.com/showthread.php?t=389782
     
  8. Decimatus

    Decimatus King

    Joined:
    Oct 22, 2005
    Messages:
    853
    Oh right I found that out this morning. You have to have a unit somewhere in your game that requires a resource for it to be considered strategic and visible at the top info panel. Unless of course you run some other mods that take care of this.



    So the SaveUtils part of this mod. I may need some coffee, but what is the purpose of this exactly?

    IE is it required to save the game period, or just an enhanced save mechanic for the mod? And is it required to get the building resource mechanic to work properly?


    I will probably implement your mod into mine at some point, maybe in a few weeks, perhaps a month or so. Looks like it should make a pretty good addition for corporation mechanics among other things. :)
     
  9. elistor

    elistor Warlord

    Joined:
    Jan 12, 2008
    Messages:
    111
    I was wondering why it used to show up top but stopped doing so, didn't notice it was when i removed the unit requirements. Figures I turn off all other mods when working on mine so thus didn't have the resource info panel loaded. Thanks folks.
     
  10. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    In order to save data so that it shows up again when you reload a saved game you have to put that data in the ScriptData. Otherwise you save your game, come back, and the mod no longer works. This is true of all mods that require saved data, which is just about any mod that's any good. Problem is the only data you can put in ScriptData is a string. Keep in mind, every mod running at the same time also uses the same ScriptData save slot that exists on players, plots, and units. There is only one slot per player, plot, and unit and it can only hold a single string. The solution to this limitation is something called serialization. Which is a fancy way of saying it turns complex data structures into a single string. What SaveUtils does is allow you to save what ever you want, strings, tables, booleans, whatever. And you can save as many of them as you want, you just have to give them different keys to identify them by. Best of all, it allows every mod currently running to use the save slot the very same way without over writing the other mod's data. But it does require that every running mod accessing saved data use SaveUtils functions save() and load(). Otherwise conflicts will occure and one mod will overwrite the data of another mod and things will break down. SaveUtils does all the serialization and manages the different mods data. It is also the reason BuildingResources.lua can save a complex table that it recalls each turn.

    It is a lot to digest, I know. It is an issue that has been discussed at length by others in this community. SaveUtils is designed to take the work out of it and make it all easy. It just requires that all saving and loading be done thru the save() and load() functions.
     
  11. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    Sorry to say, modding has not reached a level of easy that one might wish. It really helps to understand a little Lua, otherwise you're pretty much stuck with simple changes to the XML.
     
  12. Decimatus

    Decimatus King

    Joined:
    Oct 22, 2005
    Messages:
    853
    Ah, so if you start using LUA in your mod, you need the SaveUtils to be able to play your saved game again?

    So far, I have gotten by with just XML changes while waiting for people to get spun up on how LUA works in the game.

    Getting pretty close to the point where I will begin adding some LUA files to my mod though, so this is good to know.

    I am sure once I start trying to combine several LUA files in my mod I will be all over the place trying to make sure it works right. :)
     
  13. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    I'm more than willing to help. In order for SaveUtils to be truly useful, it has to be adopted. As BuildingResources demonstrates, SaveUtils makes things possible, so there is good reason to adopt it. But more than that, it makes all compliant mods compatible, so the more widely adopted, the easier things get for everyone.

    The deserialize() function represents a total of about 30 hours worth of work, by the way. It changes that single save string back into a complex table. I don't mind saying it is one of the more difficult things I have programmed. That's why I put my real name on it. :)

    So for combining files, each Lua file that saves or loads will need to have that same line at the top of the file.
    Code:
    include( SaveUtils ); MY_MOD_NAME="???"
    This gives each file access to the save() and load() functions and lets it know what mod it is saving and loading data for. The name should be unique to your mod; I like to use the mod id shown in modbuddy.

    Then just make sure the commands SetScriptData and GetScriptData only show up in the SaveUtils file. That it's job and its job only.

    I'm happy to look at what ever you have.
     
  14. Decimatus

    Decimatus King

    Joined:
    Oct 22, 2005
    Messages:
    853
    So pretty much all I have to do is include your SaveUtils.lua in my mod, change the 1 line to something like this:

    And then make sure it is the last update on my list, and it should work fine as long as no other lua in my mod change SetScriptData/GetScriptData?


    So what is the best way to test it when I am ready to implement? Load my mod including a lua file, run a couple of turns, and then try and load it? And then do the same after I include the SaveUtils lua?
     
  15. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    I'm not sure what you mean by "last update on [the] list", but everything else looks correct. If none of the other files use GetScriptDate or SetScriptData then all you need to do is change the MY_MOD_NAME. Your example name should work just fine.

    There are several ways to test it out, but I believe the most effective is to run another small mod at the same time who's only job is to inspect the save slot on players. Then you can see what the other mods are saving to the player targets.

    This should work: --improved version in post below.
    Code:
    include( "SaveUtils" ); MY_MOD_NAME = "Procylon's Call to Power Project";
    function inspect()
    	setCacheState( 0 ); --no cache.
    	for index,pPlayer in pairs( Players ) do
    		if pPlayer ~= nil and pPlayer:IsAlive() then
    			print(out(load( pPlayer )));
    		end
    	end
    end
    Events.ActivePlayerTurnStart.Add( inspect );
    Incidentally, there is one player target for each human, AI, citystate, and one for what I assume is the minor civ, aka: barbarians. First cities also seem to have the id 8135 or something like that. You'll see it in the output.
     
  16. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    I'm not sure what controls execution order when running multiple mods. So keep in mind that the inspect might run before BuildingResources, so the output data from inspect might appear a turn behind.
     
  17. jenks

    jenks Prince

    Joined:
    Jan 9, 2006
    Messages:
    494
    Location:
    Yorkshire, UK
    ace little component
    thanks for the work :)
     
  18. Whys

    Whys Between the Lines

    Joined:
    Oct 20, 2007
    Messages:
    456
    Actually, let me make a correction. This should work better:

    Code:
    include( "SaveUtils" ); MY_MOD_NAME = "[COLOR="blue"]Player Save Inspector[/COLOR]";
    function inspect()
    	setCacheState( 0 ); --no cache.
    	for index,pPlayer in pairs( Players ) do
    		if pPlayer ~= nil and pPlayer:IsAlive() then
    			print(out(load[COLOR="Blue"]( pPlayer, nil, false )[/COLOR]));
    		end
    	end
    end
    Events.ActivePlayerTurnStart.Add( inspect );
     
  19. MilkmanDan

    MilkmanDan Chieftain

    Joined:
    Dec 24, 2005
    Messages:
    54
    Out of curiosity, was it not possible to make a new table and save the data into the table? From what I've seen of the sql side, it seems possible but not sure if it's as easy to access from lua. That should take care of the save game issue without requiring serializing to a specific string, or is this more because you need flexible non-typed data storage?
     
  20. JeBuS27

    JeBuS27 Heretic

    Joined:
    Sep 21, 2005
    Messages:
    321
    If you save to the database, not only can it be completely overwritten / deleted the next time mods are changed, but it will not be part of the save game file. That would mean you couldn't take a save from one computer and use it on another.
     

Share This Page