Hi modders! The beta launch will contain some modding changes that you all should be aware of. Most of these changes are in preparation for the release of a new cross platform launcher. It'll be a few weeks before the launcher is deployed, but in the mean time here's what's changing: No modifications should be done where official PA files are installed. The new launcher is going to "own" the directory tree where the game is installed. In order for your changes to not be clobbered you will want to move your stuff in to the new mod location specific to your platform. MOD Home Windows: %LOCALAPPDATA%\Uber Entertainment\Planetary Annihilation\mods On a typical install %LOCALAPPDATA% will be C:\Users\<username>\AppData\Local We don't actually use the environment variable but the windows system call SHGetKnownFolderPath with FOLDERID_LocalAppData. OSX: ~/Library/Application Support/Uber Entertainment/Planetary Annihilation/mods This corresponds to a query of NSApplicationSupportDirectory Linux: $HOME/.local/Uber Entertainment/Planetary Annihilation Where $HOME typically maps to something like /home/<username> (Note: These are subject to change. The point is to get custom user files out of the main PA tree.) Consider a virtual file system that has one of the above install paths mounted as /mods. Your mod will live under /mods/<modname> where <modname> must be unique. (No strategy yet for avoiding collisions). Configuration A mod called 'example' would be located at /mods/example. The engine will scan all top level directories under /mods and look for a json configuration file that corresponds to the mod name. e.g. /mods/example/example.json The structure of the example.json configuration file is simple: { "enabled" : true, "name" : "example", "description" : "makes all your wildest dreams come true", "author" : "ooo27", "version" : "1.0", "signature" : "(not yet implemented)" } The mod will not be loaded if the json file does not exist, contains syntax errors, or if 'enabled' is set false. Once your mod is loaded all files are accessible by addressing them with virtual file paths. When referring to files within your mod scripts and html you are encouraged to use relative paths, such as '../img/foo.png'. If for some reason you really need a fully qualified path name it would be /ui/mods/example/img/foo.png. Shadowing You can now completely override any PA media file without altering the original source. This is done by "shadowing" the file. This applies to all files in all subdirectories in the "media" folder under the main installation folder. The engine's virtual file system mounts the PA media folder as "/". If your mod has a shadow folder in it /mods/example/shadow it too will be mounted as "/", but mounted before the default one. When the engine searches for files it will look in your shadow directory first. If it finds the file it uses yours, if it doesn't find the file it uses the engine version. (We may add a way to hide the system version of a file too if its deemed useful). Example: /mods/example/shadow/ui/alpha/start/start.html When PA starts it loads /ui/alpha/start/start.html. As you can see this full path exists under the mod's shadow folder. So the engine will find our mod's version first and use that. Inside my custom start.html file I can do pretty much anything to the UI. I might load other resources from my mod via script tag, reference other images, etc. <script src="/mods/example/test.js" type="text/javascript"></script> What's Next? I don't know yet. We'll see what usage patterns develop, where the system works, where it falls down, and we'll adjust accordingly. If you have any suggestions, don't hesitate to ask in this thread or PM me. I'm going to be focusing on getting the new launcher deployed in the next couple of weeks. Hopefully this is enough info to get you all going.
Will the ability remain to just include JavaScript/CSS files like we have currently? Most of the time this is enough and I won't usually want to be overriding the whole page just to add a script tag. That's because if you guys say add a menu item I'll have to update my mod to reflect that.
And on a tangent, it might be cool if you guys could implement some kind of menu system mods could hook into. For instance I plan on making a tournament page link on the start page, and another modder might want another menu item on the start page. But if we're both shadowing the same file our mods wont work together... Anyway I'm keen to get my hands on this and see how it works practically shortly. Thanks for the update! EDIT: *High five BulletMagnet!*
Seconded. I'd also suggest a "requires": "mod_name" and possibly "load_before": "mod_name" & "load after": "mod_name" attributes in the mod json file to account for framework mods that other mods make use of. Edit: Will the contents of these mod json files be accessible from within the game, and if so, how are these accessed (eg., what variable are they stored under?)
Those would have to be tables, just in case someone needs to load before/after multiple mods. But that's going to get very messy, very quickly. I remember some of the modding problems suffered in Sup1 because of ordering.
True, although this mainly applies when both load_before AND load_after are present. I'd settle for just "requires", which is trivial to implement.
Does this influence how the current ui mods work or can I just place them in the new folder and load them as always?
I'm not entirely sure if shadowing is the proper way to do this. Lets say that two mods heavily modify live_game.js; how is shadowing going to compensate for this? Such problems exist in aspect oriented programming too. I think you guys hit the nail on the head originally. Objects that can be extended, but hooks and event observers should be made available for every function. Knockout is very extendable, and jquery (while I'm not a huge fan) is superbly powerful. Moreover, there should be easier ways to access local storage, session storage etc. Perhaps an options object, something like: Code: $.fn.paOpts = function( options ) { $.extend( {}, $.fn.paOpts.defaults, options ); }; would be easy enough. For things that modify the view, we should add onBeforeShow, onAfterShow and so on. More objects that can be extended with their returns, init methods and so on. In MVC this is "skinny controllers, fat models". Lets plump those objects up. I highly encourage us all to utilize a javascript traits library, which would solve a lot of problems that I see coming. The biggest reason I'm against shadowing is that as soon as the original source is updated, the mod becomes incompatible. While some mod authors stick around for years, others will maintain one or two releases and then fall off the grid. Sometimes another user will pick up their work, oftentimes not. By not supporting modifying/shadowing the original source, we can encourage the longevity of mods, keep mod filesizes down, etc. I do like the suggestion of mod dependencies (heh, maybe I can start putting together a mod framework), but I don't think loads_before and loads_after is a good idea. I've seen this before, and mods fighting with eachother is difficult to resolve and just darned tiresome. Instead, take some concepts from mod manager and build a supported mod listing & install app to put the mods control in the players hands. I would like to see a mod definition file (such as example.json) that would be required for the mod to load, list the required files and load them. Pushing files to the head stack is darned tedious for every player. I would also like to see some naming conventions. For instance, since the mods are going to be folder delimited, core files should be named according to their namespace (live_game.js, global.js), and perhaps an "extras" loader. For example (just off the top of my head). Code: { "enabled" : true, "name" : "example", "description" : "makes all your wildest dreams come true", "author" : "ooo27", "version" : "1.0", "signature" : "(not yet implemented)" "load_files": { "global_mod_list": [ '../../mods/playerrep/global.js', '../../mods/playerrep/global.css' ], "live_game": ['../../mods/playerrep/live_game.js'] } } Alternatively, like I did in the player_rep, require one file (mod_init.js) that loads the mod files itself, such as: Code: global_mod_list.push('../../mods/playerrep/growl.js'); global_mod_list.push('../../mods/playerrep/global.css'); scene_mod_list.server_browser.push('../../mods/playerrep/server_browser.js'); scene_mod_list.live_game.push('../../mods/playerrep/live_game.js'); I'm not particularly attached either way. But these are just suggestions. Either way, I'm 100% behind whatever you guys do, and look forward to seeing what you come up with in the coming weeks.
I think shadowing will still be great for some things, like strategic icons, shaders etc. But yeah, we'll need something more robust for HTML/CSS/JS
None of the existing facilities changed. I'm focused on getting your files out of the main PA tree in to a safe location that won't be mucked with by the new launcher. I'm going to make a few tweaks to the system today based on feedback from here. This new stuff will be available in the next build, which is a Beta release candidate coming later today (I think). Also, the shadowing facility is more a convenience for total conversions and not really intended for smaller UI mods.
Server-side is still a ways off, but the plan is to deliver that ability to you guys well before the beta ends. Still have a ton of work to do!
Hey, I was toying with the possibility of adding a "commander cam" in the upper right corner. Unfortunately, I couldn't figure out a way to create another camera instance with just the UI api. Which I didn't expect to be able to. Just going to leave that little tidbit of information here, and suggest sometime in the future there's a way to create another camera instance through the api.
For the Linux directory the parent post says, "Linux: $HOME/.local/Uber Entertainment/Planetary Annihilation," is that supposed to be, "Linux: $HOME/.local/Uber Entertainment/Planetary Annihilation/mods?"
This is a must have. There are many situations where a mod need another cam. I can think on in-game events that can be highlighted via a secondary cam, like alerts.
I think I might be the only one planning to attempt some work on a total conversion so far. This is still pretty early, but it is appreciated you are thinking of this in advance. Also, +1 on releasing server side well enough ahead of beta end. We might have an established mod database by launch yet if we get the time to crank some stuff out. It is amazing how much has already been made in lack of server side.
There will be an API for opening windows with a different camera view. We need that facility for some game features we're planning to add.
I've found a bug/issue with the new system: the AppData folder isn't created in the correct spot; In my thread someone has tried to install it, but the Uber Entertainment folder entirely has been installed not in Appdata but in the game's program files: start of issue discussion: https://forums.uberent.com/threads/rel-ui-that-other-ui-mod-v-0-6-b-54757.52235/#post-800663 screenshot of no Uber Entertainment folder: https://forums.uberent.com/threads/rel-ui-that-other-ui-mod-v-0-6-b-54757.52235/page-2#post-800826 another forum-goer explains his form of the problem: https://forums.uberent.com/threads/rel-ui-that-other-ui-mod-v-0-6-b-54757.52235/page-2#post-801274 It seems like if some problem occurs with creating the folder, it relocates, and due to program files being owned by the new game setup, it won't work correctly.