Difference between revisions of "User:Quetzilla"
Jump to navigation
Jump to search
imported>Quetzilla (updated with description of Action concept) |
imported>Quetzilla m (revert - moved new info elsewhere) |
||
(8 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
* Base Concept: '''Actions''' | * Base Concept: '''Actions''' | ||
:'''Actions''' are object scripts attached to inventory items (generally Misc items) and form the basis of everything else in the mod. By using blocktypes in the form of ''OnAdd SomeContainer'' and the creation of different receiving containers, '''Actions''' can be defined to do multiple different things under different circumstances, which allows code to be better organized and consolidated. Since '''Actions''' are scripts attached to inventory objects, management of actions can be accomplished by storing them in different containers for various purposes, as shown in the rest of the features listed below. | :'''Actions''' are object scripts attached to inventory items (generally Misc items) and form the basis of everything else in the mod. By using blocktypes in the form of ''OnAdd SomeContainer'' and the creation of different receiving containers, '''Actions''' can be defined to do multiple different things under different circumstances, which allows code to be better organized and consolidated. Since '''Actions''' are scripts attached to inventory objects, management of actions can be accomplished by storing them in different containers for various purposes, as shown in the rest of the features listed below. | ||
:*Some may wonder why Actions may be preferable to traditional activator-functions (also known as Functional Activators), and there are a few reasons: | |||
:*#Easy management of groups of actions as explained above | |||
:*#Unlimited nesting | |||
:*#Ease of creation (no need to place objects in external cells) | |||
:*#Inheritance (blocks on actions can 'call' blocks from themselves or other actions dynamically, thereby inheriting code) | |||
:*There are drawbacks as well, the chief being that code for an action doesn't run until the frame after it has been added to the trigger container. This can be beneficial in certain cases though. If the player has a decent framerate to begin with, nested Action execution still takes place very quickly. | |||
* Hotkey management for any number of client mods | * Hotkey management for any number of client mods | ||
:This was the initial project and spawned everything else. Primarily a single script that maintains a mapping of DXScancodes to '''Actions''' and activates the corresponding actions whenever a key/button press is detected. Support for any keyboard/mouse key (currently missing wheel up/wheel down due to weirdness) as well as modifier keys. Multiple actions can be assigned to a single key, and there is no limit on the total number of hotkeys other than the number of physical keys recognized by DirectX. | :This was the initial project and spawned everything else. Primarily a single script that maintains a mapping of DXScancodes to '''Actions''' and activates the corresponding actions whenever a key/button press is detected. Support for any keyboard/mouse key (currently missing wheel up/wheel down due to weirdness) as well as modifier keys. Multiple actions can be assigned to a single key, and there is no limit on the total number of hotkeys other than the number of physical keys recognized by DirectX. | ||
* Pre-programmed Container Menu System | * Pre-programmed Container Menu System | ||
:Originally designed to display which keys have been assigned to which '''Actions''', it has been expanded to allow for a hierarchical menu system. There is a single Root menu, which is then linked to submenus by '''Actions''' that open the submenu container. Making a submenu for a client mod is as simple as attaching the single container script to any container reference and creating the '''Action''' to open it (code for this is 2 lines). The system is tightly integrated with the hotkey system in that any '''Action''' in a container menu can be assigned a hotkey directly from the container menu (including submenus), unless the Action opts out of having being hotkeyable. Also from the container menu the user can trigger the configuration custom-blocktype of '''Actions''' that register as being configurable (more on custom-blocktypes below). | :Originally designed to display which keys have been assigned to which '''Actions''', it has been expanded to allow for a hierarchical menu system. There is a single Root menu, which is then linked to submenus by '''Actions''' that open the submenu container. Making a submenu for a client mod is as simple as attaching the single container script to any container reference and creating the '''Action''' to open it (code for this is 2 lines). The system is tightly integrated with the hotkey system in that any '''Action''' in a container menu can be assigned a hotkey directly from the container menu (including submenus), unless the Action opts out of having being hotkeyable. Also from the container menu the user can trigger the configuration custom-blocktype of '''Actions''' that register as being configurable (more on custom-blocktypes below). | ||
:*One special advantage of the pre-programmed system is that I have coded it to intercept the actual mouse clicks on items (thanks 0015). What this means is that the items never actually get added to the player, and furthermore the player is disallowed from adding items to the container itself, which solves a few of the headaches with existing container menu systems. Thus the code for the Action simply uses [[RemoveMe]] in place of a call to [[return]] | |||
:*Another advantage is that the contents of the menu system are separate from the player's inventory, so where previously mods added misc item's to the player's inventory in order to activate menus for those mods, now those items can be coded as Actions and placed in the Root menu (or a submenu), thereby uncluttering the player's inventory. | |||
* Pre-programmed Messagebox Menu System | * Pre-programmed Messagebox Menu System | ||
:Writing menu loops is tedious -- this gets rid of the hassle by consolidating the loop/choice detection code into a single script and providing the means for '''Actions''' to control the messagebox text and button choices, as well as catch the button choices -- all without ever having to write additional loop code | :Writing menu loops is tedious -- this gets rid of the hassle by consolidating the loop/choice detection code into a single script and providing the means for '''Actions''' to control the messagebox text and button choices, as well as catch the button choices -- all without ever having to write additional loop code. The system as is has bonuses and drawbacks -- it's best used in situations where you simply want to give the user an option of do A B C ... and then do different code for each option ''without'' returning to the menu system. As such, each block set up to handle a button choice has to ''intentionally'' tell the messagebox to loop if it needs to loop (in this way it becomes much harder to end up with infinite looped menu bugs). The biggest drawback is that if you DO want to write a looped menu, local variables are not maintained across code for button choices (because the code is actually executing on different instances of the script), so such variables have to be tracked externally (usually a companion quest script with just variable declarations). Very useful to easily create simple menus, but for complex menus it may be better to use existing methods. | ||
* Pseudo-Custom blocktypes and Event detection system | * Pseudo-Custom blocktypes and Event detection system | ||
:Actions can define custom blocktypes in the form of ''begin onadd NewBlockType''. This is actually how the entirety of the above systems work. '''Actions''' can register to listen for a particular event by adding themselves to an Event container. Separate Event scripts monitor for the event in question and then trigger all items in the Event container by adding those items to the associated Event Trigger container. Currently several Events are included in the system but the system can be expanded to define Events specific to client mods (for example in survival mods, the mod could define an Event for exhaustion and then trigger any actions which have been registered to trigger when the player is exhausted). | :Actions can define custom blocktypes in the form of ''begin onadd NewBlockType''. This is actually how the entirety of the above systems work. '''Actions''' can register to listen for a particular event by adding themselves to an Event container. Separate Event scripts monitor for the event in question and then trigger all items in the Event container by adding those items to the associated Event Trigger container. Currently several Events are included in the system but the system can be expanded to define Events specific to client mods (for example in survival mods, the mod could define an Event for exhaustion and then trigger any actions which have been registered to trigger when the player is exhausted). | ||
Line 17: | Line 25: | ||
:pluggy allows for access to regular type .ini files but the functions require pluggy-strings as arguments, so these activator-functions allow modders to access .ini files in a manner similar to the [[MessageBoxEx]] system. Also included are activator-functions to extract string 'tokens' from other strings and in the future to be able to add/remove/replace/search for string 'tokens' as well. | :pluggy allows for access to regular type .ini files but the functions require pluggy-strings as arguments, so these activator-functions allow modders to access .ini files in a manner similar to the [[MessageBoxEx]] system. Also included are activator-functions to extract string 'tokens' from other strings and in the future to be able to add/remove/replace/search for string 'tokens' as well. | ||
* More advanced flow control | * More advanced flow control | ||
:This is still in a early stage but currently it allows for '''Actions''' to define callback '''Actions''' to be executed on the completion of other Actions. This is how the input menus work -- the originating action can define itself as the callback action to be activated once the input menu is finished. The action and custom-blocktype to be activated by the callback function can be specified. Currently only allows one level of nesting but would be simple to implement a stack based system. | :This is still in a early stage but currently it allows for '''Actions''' to define callback '''Actions''' to be executed on the completion of other Actions. This is how the input menus work -- the originating action can define itself as the callback action to be activated once the input menu is finished. The action and custom-blocktype to be activated by the callback function can be specified. Currently only allows one level of callback nesting but would be simple to implement a stack based system. | ||
:The flow controller is tightly integrated into the rest of the system and is used to activate the display of container menus, display and update of messagebox menus, as well as trigger Actions subscribed to Events. | :The flow controller is tightly integrated into the rest of the system and is used to activate the display of container menus, display and update of messagebox menus, as well as trigger Actions subscribed to Events. | ||
* Integrated debug features | * Integrated debug features |
Latest revision as of 18:41, 10 November 2008
Feature list for my WIP modder utility project[edit | edit source]
- Base Concept: Actions
- Actions are object scripts attached to inventory items (generally Misc items) and form the basis of everything else in the mod. By using blocktypes in the form of OnAdd SomeContainer and the creation of different receiving containers, Actions can be defined to do multiple different things under different circumstances, which allows code to be better organized and consolidated. Since Actions are scripts attached to inventory objects, management of actions can be accomplished by storing them in different containers for various purposes, as shown in the rest of the features listed below.
- Some may wonder why Actions may be preferable to traditional activator-functions (also known as Functional Activators), and there are a few reasons:
- Easy management of groups of actions as explained above
- Unlimited nesting
- Ease of creation (no need to place objects in external cells)
- Inheritance (blocks on actions can 'call' blocks from themselves or other actions dynamically, thereby inheriting code)
- There are drawbacks as well, the chief being that code for an action doesn't run until the frame after it has been added to the trigger container. This can be beneficial in certain cases though. If the player has a decent framerate to begin with, nested Action execution still takes place very quickly.
- Some may wonder why Actions may be preferable to traditional activator-functions (also known as Functional Activators), and there are a few reasons:
- Hotkey management for any number of client mods
- This was the initial project and spawned everything else. Primarily a single script that maintains a mapping of DXScancodes to Actions and activates the corresponding actions whenever a key/button press is detected. Support for any keyboard/mouse key (currently missing wheel up/wheel down due to weirdness) as well as modifier keys. Multiple actions can be assigned to a single key, and there is no limit on the total number of hotkeys other than the number of physical keys recognized by DirectX.
- Pre-programmed Container Menu System
- Originally designed to display which keys have been assigned to which Actions, it has been expanded to allow for a hierarchical menu system. There is a single Root menu, which is then linked to submenus by Actions that open the submenu container. Making a submenu for a client mod is as simple as attaching the single container script to any container reference and creating the Action to open it (code for this is 2 lines). The system is tightly integrated with the hotkey system in that any Action in a container menu can be assigned a hotkey directly from the container menu (including submenus), unless the Action opts out of having being hotkeyable. Also from the container menu the user can trigger the configuration custom-blocktype of Actions that register as being configurable (more on custom-blocktypes below).
- One special advantage of the pre-programmed system is that I have coded it to intercept the actual mouse clicks on items (thanks 0015). What this means is that the items never actually get added to the player, and furthermore the player is disallowed from adding items to the container itself, which solves a few of the headaches with existing container menu systems. Thus the code for the Action simply uses RemoveMe in place of a call to return
- Another advantage is that the contents of the menu system are separate from the player's inventory, so where previously mods added misc item's to the player's inventory in order to activate menus for those mods, now those items can be coded as Actions and placed in the Root menu (or a submenu), thereby uncluttering the player's inventory.
- Pre-programmed Messagebox Menu System
- Writing menu loops is tedious -- this gets rid of the hassle by consolidating the loop/choice detection code into a single script and providing the means for Actions to control the messagebox text and button choices, as well as catch the button choices -- all without ever having to write additional loop code. The system as is has bonuses and drawbacks -- it's best used in situations where you simply want to give the user an option of do A B C ... and then do different code for each option without returning to the menu system. As such, each block set up to handle a button choice has to intentionally tell the messagebox to loop if it needs to loop (in this way it becomes much harder to end up with infinite looped menu bugs). The biggest drawback is that if you DO want to write a looped menu, local variables are not maintained across code for button choices (because the code is actually executing on different instances of the script), so such variables have to be tracked externally (usually a companion quest script with just variable declarations). Very useful to easily create simple menus, but for complex menus it may be better to use existing methods.
- Pseudo-Custom blocktypes and Event detection system
- Actions can define custom blocktypes in the form of begin onadd NewBlockType. This is actually how the entirety of the above systems work. Actions can register to listen for a particular event by adding themselves to an Event container. Separate Event scripts monitor for the event in question and then trigger all items in the Event container by adding those items to the associated Event Trigger container. Currently several Events are included in the system but the system can be expanded to define Events specific to client mods (for example in survival mods, the mod could define an Event for exhaustion and then trigger any actions which have been registered to trigger when the player is exhausted).
- Pre-programmed Text and Numeric input menus
- These allow mods designed to use Actions to bring up a text or numeric input menu and then trigger other custom-blocktypes within the calling Action once the input has been confirmed. Both allow for various customizations to the input such as default and min/max values and so on.
- Ref renaming by user
- Derived feature of the text input menu, pass a ref to the action and it will rename the ref via the text input menu. Currently used to allow renaming of items and spells in inventory/spellbook but can be used by any client mod.
- Simplified file access and string manipulation
- pluggy allows for access to regular type .ini files but the functions require pluggy-strings as arguments, so these activator-functions allow modders to access .ini files in a manner similar to the MessageBoxEx system. Also included are activator-functions to extract string 'tokens' from other strings and in the future to be able to add/remove/replace/search for string 'tokens' as well.
- More advanced flow control
- This is still in a early stage but currently it allows for Actions to define callback Actions to be executed on the completion of other Actions. This is how the input menus work -- the originating action can define itself as the callback action to be activated once the input menu is finished. The action and custom-blocktype to be activated by the callback function can be specified. Currently only allows one level of callback nesting but would be simple to implement a stack based system.
- The flow controller is tightly integrated into the rest of the system and is used to activate the display of container menus, display and update of messagebox menus, as well as trigger Actions subscribed to Events.
- Integrated debug features
- The debug system is a hodge-podge of different features:
- Auto display of debug text on startup
- Auto resume of last save game on startup
- Display form IDs of spells and items on mouseover in various menus
- Cell scanning - basically a UI for the GetFirstRef/GetNextRef commands, allows the user to type in a type code (or none) and displays all refs found in a container menu with placeholder items. The items then provide sub options depending on the ref its associated with, so for example you could scan for all chests and then look inside it. Only the basics are done for this but it is also extensible in that the avaiable actions associated with each type can be supplied by client mods, so modders can add their own functionality.
- This feature will likely be expanded into a separate system integrated with Actions so that a mod could with about 3-5 lines of code say "Do this Action to every ref of this type in the current cell"
- Console access via script
- Currently this allows modders to send commands to the console similar to RunBatchScript but by setting the name of an object to the code to execute rather than using a (static) file. Not all console functionality is available (in the same exact way that RunBatchScript doesn't either). Currently several of the most popular console commands are available as Actions and users can create new console command actions (and edit existing ones) via the text input menu and the container menu system.
- Cycle saves
- Similar to the ever popular Streamsaves of streamline except that (thanks to the console command access) the cycle saves incorporate the player name, so you can have separate sets of cycle saves for each character (and therefore no longer have to worry about your streamsaves being overwritten if you like to switch between multiple characters). For users who want to use Streamline/streamsaves as well, a patch module will be made which hooks into the Streamsave system (with it's other bonuses) but includes the player name in the Streamsave name.
- Tips Display
- Derived from the messagebox menu system, this is manages display of Tips messageboxes. For example, when you first open the Root menu for the container menu system, a tip is displayed explaining how to assign hotkeys and configure actions, with the option to either click okay or also disable tips. Tip text is stored in a mod by mod basis via faction titles. Disabling tips is also on a mod by mod basis (with a general option to disable ALL tips. Useful for mods that add new gameplay or interface features to explain how to use them. Can also be used to display error messages and the like (mods can have more than one set of tips each).
- PLANNED: General Set/Get ref properties
- By the use of load order independent unique identifiers and .ini files, mods can set and get 'properties' of any type (numeric/string/ref) on any ref/baseobject in the game. Properties can be global (all mods access the same value) or mod specific (if one mod sets a 'parent' property, another mod setting the 'parent' property will not overwrite the first mod). Depending on performance costs it may be possible to have access be recursive, so if a the property 'child' of ref A is set to ref B, and ref B has a 'child' property set to ref C, it will be possible to access do something similar to "get A.child.child"
- PLANNED: Error throwing and catching
- Basically a specific use of the blocktype/event system, actions can throw Errors which will then trigger Error blocks in any other Action registered to catch those Errors.