Jump to content

R&D XCOM UI/Flash modding


tracktwo

Recommended Posts

While I believe that Firaxis recognizes the general want for "more models, more textures, more scripts", I would think that XCOM2 mod support wouldn't extend far into Scaleform UI territory. Sadly, user interface stuff remains a mostly overlooked aspect of games and while Scaleform is a pretty powerful solution it's also a bit more technical, so providing support for models, textures, etc. seems like the 'easier' option.

 

Take Skyrim as an example - a game that also uses Scaleform UI integration - of the myriads of mods available for that game only a handful concern the UI. Skyrim's modding kit is better suited to modifying game logic and putting new models into the game after all; digging around the UI requires similarly hacky approaches as we have to resort to for XCOM1 :)

 

That said, I wouldn't count on Firaxis releasing .fla sources; that would be akin to them releasing .psd files for all their textures or .fbx files for all their models :) Nevertheless I think we can manage without; same as we can right now with XCOM1 as Flash decompilers do an admirable job of deconstructing the game's files - just not in an easily-accessible and editable fashion. So for the forseeable future I expect UI modding to remain an expert topic of sorts :)

Link to comment
Share on other sites

Heh yeah I am not counting on getting anything in particular, but just putting some ideas out there for any firaxis employees that may happen to be lurking threads here ;). Getting ui mods on their radar would be nice. There's a lot of opportunity in a game like xcom for this, maybe more so than on like skyrim.

 

Stubbing is pure grunt work, but its easy enough to do. Even if we don't get the .as sources we can continue with this method in xcom2. The biggest gripe I have over it is that it's currently unclear if we can share the stubs - right now everyone needs to reimplement their own.

Link to comment
Share on other sites

Stubbing is pure grunt work, but its easy enough to do. Even if we don't get the .as sources we can continue with this method in xcom2. The biggest gripe I have over it is that it's currently unclear if we can share the stubs - right now everyone needs to reimplement their own.

I suppose that depends, stubs can be rather detailed depending on your needs, e.g. Flash won't compile if you have a script accessing a variable in another class which hasn't been formally declared in it. So in the worst case a stub would have all variables and methods laid out, just without any actual logic, i.e. no variable assignments and empty methods. This may already be considered borderline intellectual property theft, but given Firaxis' rather lenient stance on sharing sources w.r.t. UnrealScript logic in XCOM2 I'd assume they'd turn a blind eye towards people extracting and sharing ActionScript sources.

 

If push comes to shove there'd still be the option of creating a tool that creates stubs from your local game files, so no sharing of copyrighted assets required. Might as well automatically rip and decompile all the needed ActionScript byte code sources at that point though, no need for stubs if you can have (an approximation of) the real deal :smile:

 

The downside to using decompiled sources is that they can be hard to read in many cases. This is mainly because the notion of local variables with distinct names typically gets lost in translation during the publishing procedure in Adobe Flash, i.e. variable names aren't part of the byte code and local variables are only referenced by pointing to a numbered memory register. Also I think for loops are transformed into while loops during the byte code compilation process, there's a number of things going on at the very least.

So a bit of cleanup to reintroduce sensible variable names can help immensely to improve code readability, but that can't be automated easily.

Edited by XMarksTheSpot
Link to comment
Share on other sites

All for loops must convert to Whileism. This is the way of the One True Code.

 

I don't know why, but I enjoy following people more knowledgeable than I discovering things I barely understand. :)

 

So is the initial intent here to override the "Build an arc thrower, zap that guy!" dialogs with something more in-depth and Long War specific?

Link to comment
Share on other sites

So upon coming back from vacation I discovered that absolutely nothing worked :smile: I had upgraded to b15f just before leaving to verify my exalt VO skipping mod still worked properly and this wiped out my changes to the .ini files and broke everything. I spent a little while today getting this back up and running, which took longer than expected. Here's the story on .ini settings for the custom flash for future generations and for me to remind myself when I upgrade LW and blow away my .ini changes next time.

 

In my case I have 3 relevant files: "CampaignSummary.upk" (the streaming map), "gfxCampaignSummary_SF.upk" (package containing the .swf files), and "XComCampaignSummary.upk" (the script package).

 

  • The script package needs to be under [Engine.ScriptPackages] in DefaultEngine.ini. I also discovered it needs to be set as "+NativePackages" not "+NonNativePackages". I suspect this is because I also embedded my UI classes in here that are subclasses of UI_FxsScreen, a native class. If you keep the UI stuff separate from the rest, you can probably use NonNativePackages like the other LW extension packages.
  • The map package doesn't need to be listed at all if you load it via a "AddStreamingMap" call in uscript. It seems to locate and load the package as long as it exists somewhere under CookedPCConsole.
  • The graphics package containing the swf to play needs to be associated with the map it'll be loaded from in DefaultContent.ini under [Content.MapContent]. Since I load mine in the strategic layer, I added a line "Package=gfxCampaignSummary" under the section for "Map=Command1". Loading the gfx in other places, eg in the sections in DefaultEngine.ini, doesn't seem to work.

 

And to answer Devon_v: This thread is just to discuss the technical aspects of how to get custom flash into Xcom. It isn't specific to any particular feature, LW or otherwise and is mostly going to be useful for other modders who want to add custom UI to their mods. I'm working on an actual practical implementation of this over on the campaign summary thread.

Edited by tracktwo
Link to comment
Share on other sites

Regarding communication from flash to unrealscript:

 

The vanilla classes use a complicated set of actionscript classes to set up mouse and keyboard input handling. Notably the xcom widgets are not flash buttons, they're just regular movieclips and the button behavior is all custom written. I'd like to avoid having to use all of that because it means re-implementing a lot of these utility classes, so I'm currently focusing on using stock flash buttons for my basic mouse handling.

 

The bottom line is there is a vanilla actionscript class called MouseHandler that does the mouse work. It's fairly simple: the widgets register themselves with the mouse handler, which has a number of event functions, e.g. MouseHandler_onRelease. I haven't completely unraveled all the handler chaining and such, but it looks to me like a mouse event will call-back into any actionscript callback associated with the object (so the flash itself can react to the event) and then propagate up the parent chain until finally it invokes the UnrealScript by a call to flash.external.ExternalInterface.call("FlashRaiseMouseEvent", callbacktarget, eventId, mc) where eventId is an enum value for the various events like mouse pressed or mouse released. Mouse released is 391, which is a constant you frequently see in the OnMouseEvent() function in unrealscript.

 

So my thinking was I can simply skip all this MouseHandler malarky and just invoke the ExternalInterface call to "FlashRaiseMouseEvent" in a handler for my button. In scaleform, calling the externalinterface just calls the function named in the GFxMoviePlayer instance containing the flash movie that's playing, passing along all the rest of the arguments. In this case, our movie player instance is actually the interface manager, which is a subtype of UIFxsMovie. It's this UIFxsMovie class that contains the FlashRaiseMouseEvent function, which is responsible for figuring out which UI_FxsScreen or UI_FxsPanel object needs to get the message.

 

Sadly, it isn't working yet - but it's close. I can see from traces in my ActionScript that the event is firing and invoking the external interface. I've instrumented the unrealscript FlashRaiseMouseEvent function with LogInternals and it is entering that code, but it isn't forwarding the call off to my screen. Likely this is an issue either with how I've registered my screen instance with the UI manager or I'm just not passing the right values as arguments to the external interface call. I'll hopefully be able to track this down tomorrow and have working mouse input. After that, keyboard should be similar - just using a different external interface function.

Link to comment
Share on other sites

  • 2 weeks later...

Well, I had a big writeup here detailing how I just got mouse input communicating from Flash down to my UScript class working, but then a badly timed "backspace" sent Firefox back a page and I lost it all. Sigh. I'll post a full set of instructions on how to get mouse working tomorrow, but I just wanted to say that it is possible and does work! Next up: keyboard.

Link to comment
Share on other sites

Attempt #2

 

Getting mouse input back into unrealscript from flash turned out to be not so big of a deal once I figured out how to organize things in Firaxis' system. When using the built in screen/panel system, mouse input is managed by the interface manager, UIFxsMovie. To communicate between your flash movie and your UI_FxsScreen or UI_FxsPanel sub-class, you just need the following:

 

  1. The s_package, s_screenId, and s_name fields in your UI_FxsScreen or UI_FxsPanel subclass need to be set correctly: s_package to the package and object containing your flash, s_screenId to a unique Id to identify your screen, and s_name to name the "main" movieclip in your movie.
  2. On the flash side, your main movieclip instance needs to be exported for actionscript in the first frame.
  3. Register and display your screen through the interface manager: The convention is to have some "manager" class spawn and initialize your UI class by calling Init() and passing the XComPlayerController as the manager and a interface manager instance (e.g. PRES().GetHUD() for the strategy hud interface manager) as the 2nd. Your Init() function should call LoadScreen() on the manager you passed in, passing self. This will set your movie up as a child screen of the interface manager.
  4. After completing any setup on the flash side, call the externalInterface function "FlashRaiseInit", passing along the full path to your mc (ie. flash.external.ExternalInterface.call("FlashRaiseInit", string(this)). This is required to tell both the interface manager and your UI object that your flash code has completed any initialization. This call will be handled by the UIFxsMovie instance manager, which will call the OnInit function in your subclass. It looks up the correct UI object to invoke by looking at the first argument to FlashRaiseInit. This means that the full path as returned by string(this) in flash needs to match the screen ID and name fields in your UI subclass, otherwise it won't find the right object to call. Failing to call FlashRaiseInit will prevent the interface manager from forwarding any mouse input to your UI as it thinks it is not yet initialized and ready for input processing.
  5. Mouse events are raised by the external interface call FlashRaiseMouseEvent. This call is handled by the interface manager and dispatches to the OnMouseEvent function in your UI class.The flash external call takes three additional arguments. The first is the main MC of the clip again (as for FlashRaiseInit, this is how the interface manager finds the correct UI instance to call). The second is an int which represents the input event type. The third is an arbitrary string "args". The convention used by most vanilla UIs is to pass the full path to the movieclip that generated the event here. The interface manager will split this string on "." and pass the array of strings that make up the argument to your OnMouseEvent function. In UScript, OnMouseEvent takes 2 args: the int command and the args array of strings.
  6. All the flash external interface calls must be generated through a movieclip exposed to actionscript and exported in the first frame of your movie or scaleform won't process them.
Edited by tracktwo
Link to comment
Share on other sites

Arrgggghh-- :wink:

 

You see, that's the kind of technical details that i just can't fully grasp anymore. Old age is gimmicky enough that even if i were to recall anything that i once barely controlled (in programming), the pace of progress have outrun me by great leaps and turns for many years.

 

I think i'll restrict myself to design & graphical stuff... but if you say Flash will be fine to handle some of my wicked ideas along with everyone's best gameplay principles -- **IF** someone --as skillfull as you (and many others) are-- has the brain energy to produce fair results... i'm all for witnessing that magic.

 

Keep us updated! :smile:

 

PS; Speaking of "Magic"...

 

This is all very early in the design phase -- but, here's what i have so far for the "LW-Pedia" project.

EDIT -- ... has been updated!

 

 

 

 

http://s12.postimg.org/i9m1wn88t/LW_Pedia_Mockup_Sample_Test.png

 

On the right side, a drop-down of various multiple Lists can be invoqued via the top Buttons that mean these;

1) Gameplay Concepts -- New Objectives -- Vehicules+SHIVs -- Small-Items -- MEC Armors+Weaponry

2) Research -- Foundry Projects -- Build Facilities -- Weapons+Pistols -- Armors -- GeneMods -- Psionic-Perks

 

The central-left area is where the whole Tech-Tree (and much more, btw) gets deployed.

 

This minimal sample only exposes a structure that should be used for what i called the "Starters". When the first Mission completes, we are given access to 3-Techs, 7 .. 8-Buildings ((EDIT; Skipped the Access-Lift earlier)) & Infinite ((Symbols inserted)) supply of 2-Armors, 11-Weapons and 13 Small-Items... all of which should become accessible via clicks on their colored placeholders and represented on the top section.

 

** Added some Mission-Control principles as they are shown on the Ant-Farm; Engineering, ScienceLabs, Hangar & Barracks.

 

Presently it only offers the Sectoid-Commander Interrogation details and IC-picture. More to come...

 

PS; I'll be updating this sample as i delve deeper into the essential elements of the generic concept. So keep track of this post... for further progress. :wink:

 

 

 

 

Mind-boggling to try determining what sort of code acrobatics would be required to implement it! :D

Edited by Zyxpsilon
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...