Thoughts on a community DLL

This is a non-issue for me. I expect any new dll to break saves. Do it in whatever way is best based on other considerations.

New DLLs don't need to break saves unless you're improperly writing to and reading from the save files...it's caused a number of my crash bugs, but once I've fixed them, the game saves and loads just fine, even when updating the DLL.
 
I thought it was just a system for turning on and off notifications.

No, it was primarily written to enable mods to redefine existing notifications and also to be able to add their own clickable custom notifications - all via the standard notification queue (which means they are saved with the game and rebroadcast on load). The ability to switch individual notifications on/off was a secondary consideration.
 
New DLLs don't need to break saves unless you're improperly writing to and reading from the save files...it's caused a number of my crash bugs, but once I've fixed them, the game saves and loads just fine, even when updating the DLL.

Any DLL change that changes the structure of what is saved to the save files won't function correctly without some way to detect which version of the DLL was used to save the file it's loading and does the correct serialization/deserialization for that version. (Firaxis use a variable called uiVersion within their serialization functions to detect older save files and deserialize the right data from them.) The way notifications are done now, the "ID" of the notification is serialized into the save file and then reloaded when the save is loaded. If the enum is changed (eg. you've added a new notification in the middle) the all subsequent IDs are different, so the game will load the wrong notification type. Depending on which notifications are mismatched, it might be just confusing but some of them would lead to being unable to end your turn, potential crashes, etc. Ideally it would be great if the notification system wasn't reliant on a compile-time enum.
 
(eg. you've added a new notification in the middle)
Do not do this. There is no need. Always add at the end of all the enums. Some of the code assumes that enums match the xml ids, and some even assumes the sequential ordering of specific values within the enums.

Same with method signatures, never add parameters into the middle, but always at the end. If you don't you can unexpectedly break the UI as parameters are now in the wrong place.
 
I can imagine many new features or modding capabilities that would require some persistent info (not just notifications). So I thought it would be best to shoot down any expectation for savegame compatibility. Of course, there is no reason for every update to break saves.
 
Do not do this. There is no need. Always add at the end of all the enums. Some of the code assumes that enums match the xml ids, and some even assumes the sequential ordering of specific values within the enums.

Same with method signatures, never add parameters into the middle, but always at the end. If you don't you can unexpectedly break the UI as parameters are now in the wrong place.

Exactly, I was demonstrating how that causes those kinds of save problems. I'm hoping with my notification changes to break the notification system's dependence on the enum matching up with the IDs in the DB (like Firaxis have done with some other enums), and make it so that things like "prevent user from ending their turn" can be specified in XML rather than requiring each type of notification to be handled explicitly in the DLL. (For more abstract concepts, like "can I dismiss this notification", I've still got to evaluate the performance impact of this, but a test any Lua event seems like a good starting point.)
 
"can I dismiss this notification"
I'd forgotten about that one - another useful ability. I have to go play with Sneaks/Whoward's system so I can see what it does and doesn't do :) Popups, map centering, dismissing, blocking, and more complete icon control, handling saving/reload (which you have to do if you have blocking notifications)... those are the things I'm most interested in.
 
"can I dismiss this notification"

"UI - Notification Options" also adds shift-right-click to dismiss all similiar current notifications (eg 20 cities just went WLTKD, get rid of all of them) and control-right-click to dismiss all similiar in the queue and also switch them off for the rest of the game (don't show me any more WLTKD messages unless I switch them back on from teh dialog)
 
Popups - yes (via left click callback which you can get to do anything)
map centering - yes (via the callback)
dismissing - yes - single, all similiar and "no more this game"
blocking - only if you also mod the dll as these are completly non-modular in the Firaxis C++ code
more complete icon control - any UI controls you want, as you define the "finger" (the thing that slides down the right hand side of the screen)
handling saving/reload - yes (via the standard game mechanisms) - fully supports event rebroadcast
 
Popups - yes (via left click callback which you can get to do anything)
map centering - yes (via the callback)
dismissing - yes - single, all similiar and "no more this game"
blocking - only if you also mod the dll as these are completly non-modular in the Firaxis C++ code
more complete icon control - any UI controls you want, as you define the "finger" (the thing that slides down the right hand side of the screen)
handling saving/reload - yes (via the standard game mechanisms) - fully supports event rebroadcast

Definitely a very powerful system. I'd like to make the blocking XML-based, but otherwise all of these kinds of features would definitely be what I'm looking for. When I said "can I dismiss this notification", I meant more along the lines of the game working out whether or not the player is allowed to dismiss an individual notification. (Like it knows you can't dismiss the "choose new production" notification without dealing with it.)

I'm correct in thinking that adding a new notification type in "UI - Notification Options" requires declaring a new XML context for that notification? Like this one:

Code:
<?xml version="1.0" encoding="utf-8"?>
<Context Name="BombardNotification">
  <Instance Name="BombardItem" >
    <Container Anchor="R,C" Size="80,80" Offset="0,0" Hidden="0" ID="BombardContainer" ConsumeMouseButton="1" >
      <SlideAnim Anchor="L,T" Style="NotificationSlide" ID="NotificationSlide" >
        <AlphaAnim Style="NewFinger" />
        <Button Anchor="R,C" Size="80,80" Offset="0,0" Texture="NotificationClearBase.dds" ID="BombardButton" Hidden="0" >
          <Image Anchor="C,C" Offset="0,0" Size="64,64" Texture="CityBombard.dds" TextureOffset="0,64" />
          <AlphaAnim Anchor="C,C" Size="64,64" Texture="CityBannerStrengthAlpha.dds" Pause="0" Cycle="Bounce" Speed="2" AlphaStart="1" AlphaEnd="0"/>
        </Button>
      </SlideAnim>
    </Container>
  </Instance>
</Context>

I plan to make a few default contexts which could be used for multiple notification types (so like the wonder notification has different wonder textures hooked up to it, having a generic notification that can have any texture, specified in XML, hooked up to it.) That way new notification types don't necessarily need their own dedicated context. It should be possible to display any arbitrary UI context based on the notification's XML tag as well, correct? (If I'm remembering what I've read elsewhere correctly, it should be possible to use ContextPtr to interact with a standardized "Display" function in another context.)

Also, I believe I'm swapping back and forth between two different uses for the word "context" in the above paragraph, but hopefully I'm still making some sense.
 
(If I'm remembering what I've read elsewhere correctly, it should be possible to use ContextPtr to interact with a standardized "Display" function in another context.)

No, ContextPtr is local to the UI context the Lua is executing in. You can only get to other controls/instances if they are included via <LuaContext> tags - it works well for dialogs with multiple tabs (eg the Diplomacy popup) or dialogs that are called from different places in the menus (eg the load game popup) but for "generic" instances it is next to useless.

If you want a few generic "fingers" you'll need to use something similiar to the current system (multiple finger instances in the same UI context) and use the (somewhat limited) notification parameters to control them. If you want a modder to be able to add a completely customised finger, you'll be going down the "UI - Notification Options" route of callbacks to get into the correct context to add it to the notification stack

Like most of the UI system it does what it says on the tin with very little room for anything else being modded in
 
When I said "can I dismiss this notification", I meant more along the lines of the game working out whether or not the player is allowed to dismiss an individual notification. (Like it knows you can't dismiss the "choose new production" notification without dealing with it.)
Yes, those where the dismissing I was referring too - the dismissing of blocking notifications - like policy saving does.
 
Another value of the community dll is forming in my mind, though the design of it is eluding me a bit due to loss of sleep. I think, done as a toolkit, and done right, it can be more of a surgeons tool than the blunt instrument we have now. Let's say I want to modify the same InGame file but for different reasons. It doesn't matter if my code would be compatible, both mods can't run together. However, if they didn't have to modify the InGame file and could get what they needed from the DLL, both mods would run together fine.
 
Popups - yes (via left click callback which you can get to do anything)
map centering - yes (via the callback)
dismissing - yes - single, all similiar and "no more this game"
blocking - only if you also mod the dll as these are completly non-modular in the Firaxis C++ code
more complete icon control - any UI controls you want, as you define the "finger" (the thing that slides down the right hand side of the screen)
handling saving/reload - yes (via the standard game mechanisms) - fully supports event rebroadcast

Damn, that's impressive.
 
Another value of the community dll is forming in my mind, though the design of it is eluding me a bit due to loss of sleep. I think, done as a toolkit, and done right, it can be more of a surgeons tool than the blunt instrument we have now. Let's say I want to modify the same InGame file but for different reasons. It doesn't matter if my code would be compatible, both mods can't run together. However, if they didn't have to modify the InGame file and could get what they needed from the DLL, both mods would run together fine.

All of the core Lua files ultimately drive the UI, and we don't have the C++ code for the UI system - and the little we do have access to is wrapped in non-obvious ways (see http://forums.civfanatics.com/showthread.php?t=493469) So I'm going to suggest that trying to get the game code logic DLL (where shall I send my armies, what shall I construct next, where shall I place my next city, who do I trade with?) to do generic UI operations is almost certainly a way to maximum frustration for minimal return. And it will only take one modder to want a tiny thing that you've not allowed for in the UI to break all your code.
 
All of the core Lua files ultimately drive the UI, and we don't have the C++ code for the UI system - and the little we do have access to is wrapped in non-obvious ways (see http://forums.civfanatics.com/showthread.php?t=493469) So I'm going to suggest that trying to get the game code logic DLL (where shall I send my armies, what shall I construct next, where shall I place my next city, who do I trade with?) to do generic UI operations is almost certainly a way to maximum frustration for minimal return. And it will only take one modder to want a tiny thing that you've not allowed for in the UI to break all your code.
I was speaking of non-ui elements, or ui elements that can be enhanced, or events. And other things I'm not thinking off at the moment. You are 100% correct when you say the dll should not try to do UI. But, an example of a place I bet two mods could be made compatible with creative dll use: TechTree. My current TechTree is incompatible with Putmalk diplomacy dll because he adds to TechTree directly (to show an icon for what tech allows tech trading/map trading).

Neither my rolling 5+ button into tooltips, or his adding of new buttons, should require a file edit, and there is no reason for them to be incompatible.

Edit: Actually, mine still might require a file edit as we don't have access to the c++ functions being called. But, it seems like we are building a tree from data, changing the data and having the tree reflect that change should not be a ui issue, just a data issue. That doesn't mean it works that way now, just that it possibly could.
 
Neither my rolling 5+ button into tooltips, or his adding of new buttons, should require a file edit, and there is no reason for them to be incompatible.

They will require some form of edit to the core Lua file (as the current code just crashes if you give it more than 5 "things" to place on buttons), but what you should be able to achieve is a modular version of the tech tree lua code that both the mods can include (vfs=true) and are compatible with (I've done this with a number of my mods - summary bar, diplo corner, notifications, unit panel, wonder splash screen, etc)

But you should be able to achieve that with pure Lua (and possibly some XML additions) and not need any DLL changes.
 
They will require some form of edit to the core Lua file (as the current code just crashes if you give it more than 5 "things" to place on buttons), but what you should be able to achieve is a modular version of the tech tree lua code that both the mods can include (vfs=true) and are compatible with (I've done this with a number of my mods - summary bar, diplo corner, notifications, unit panel, wonder splash screen, etc)

But you should be able to achieve that with pure Lua (and possibly some XML additions) and not need any DLL changes.
Now that is actually pretty interesting, got me thinking. Perhaps this project is poorly named. Maybe community toolkit would be better. Because things like you just listed would be very valuable (things that make the lua core files more extensible and generic) community tools.

I think I will proceed that way: Finish adding iterators (I find them useful - I'm already using one in testing and wish I had it for a mod I'm working on but this DLL won't see the light of day for a long time yet, and at least nobody has said they shouldn't be in the DLL yet :p ). Then focus on a lua based toolkit, with it's own repository.

That way, not only do we get a more robust toolkit, but the lua code can drive what we find we need or want to do in the dll.
 
Feel free to re-write all UI lua/xml files if you like. ;) You could start with having policy branches use instances. Whoever wrote it didn't know about those.
 
Any DLL change that changes the structure of what is saved to the save files won't function correctly without some way to detect which version of the DLL was used to save the file it's loading and does the correct serialization/deserialization for that version. (Firaxis use a variable called uiVersion within their serialization functions to detect older save files and deserialize the right data from them.)

Just create a new variable for your mod and increment it when you update the DLL, the game will save properly.
 
Top Bottom