|
Post by fufu508 on Dec 26, 2018 20:34:27 GMT -5
Hi everyone, I am trying to get an understanding of using Python to modify game interactions, like (as a seemingly simple example) by SACRIFICIAL in this post. That mod is working fine in game, no problems seen .
I wanted to see if I could start "small" by attempting to add a pie menu.
I tried following the Testing Cheats Mailbox tutorial pdf from scumbumbo but using Sims 4 Studio for the package manipulation.
After failing to get my package to work (assuming the two Python scripts listed below plus my package should be all that's need to get this to work) I tried the package file from the zip file (see list below) and even with the two Python scripts and the package (either one) being the only thing in the mods folder it still didn't cause the custom pie menu to show up on the mailbox, just the mailbox stock menu.
Below is a link to download the zip file containing the tutorial files as shown.
Is any one else able to get the tutorial (and/or my) package and the two Python scripts to work in game? Perhaps I am missing a basic step? Once I have a handle on the basics from this I hope to get more advanced, for example using the tutorial by andrew - sims4studio.com/thread/15145/started-python-scripting
File Type: zip Tutorial - Mailbox Testing Cheats.zip (248.4 KB, 1198 downloads) - View custom content Package file Size Type Description MailboxTestingCheats.package 2,110 Unknown 0 2015-03-22 14:39 Tutorial - Mailbox Testing Cheats/ 2110 2017-11-26 16:40 Tutorial - Mailbox Testing Cheats/ MailboxTestingCheats.package 309 2015-03-22 02:14 Tutorial - Mailbox Testing Cheats/S4_03E9D964_00000000_88CDD71DF4862017.xml 99 2015-03-22 02:30 Tutorial - Mailbox Testing Cheats/S4_220557DA_00000000_00918772618D89D4.stbl 413 2015-03-22 02:17 Tutorial - Mailbox Testing Cheats/S4_545AC67A_00E9D967_88CDD71DF4862017.data 5385 2017-11-26 15:57 Tutorial - Mailbox Testing Cheats/S4_B61DE6B4_00000000_0000000000003A5C.xml 1749 2017-11-26 15:47 Tutorial - Mailbox Testing Cheats/S4_E882D22F_00000000_9C65A60650DB3221.xml 1776 2017-11-26 15:47 Tutorial - Mailbox Testing Cheats/S4_E882D22F_00000000_E11EE2714E206770.xml 0 2015-03-22 14:34 Tutorial - Mailbox Testing Cheats/Scripts/ 889 2014-09-29 20:25 Tutorial - Mailbox Testing Cheats/ Scripts/injector.py 1474 2017-11-26 16:57 Tutorial - Mailbox Testing Cheats/ Scripts/mailbox_testing_cheats.py 274155 2017-11-26 16:38 Tutorial - Mailbox Testing Cheats/Tutorial - Mailbox Testing Cheats.pdf Since I am planning to do social interactions anyway (not object interactions as much), I would be fine with just getting a more solid handle on how in particular that's done. I understand it involves modifying "SocialMixerInteraction" elements in the package. Again, I only expect walk (simple pie menu) before I can run with this stuff. I have been trying various approaches to add custom interactions and custom animation, with (mostly) success using the instructions in a live stream on YouTube by SACRIFICIAL (thanks again for posting that video!)
Thanks in advance for any tips my fellow modders can offer!
|
|
|
Post by fufu508 on Dec 27, 2018 10:23:18 GMT -5
Ok I confirmed (at least) one problem is I had the mod too deep within the Mods folder, so presumably the game couldn't find them. I also didn't have the .py files in a folder called Scripts. I had inadvertently moved them out of that folder when putting them in the game's Mods folder. That said, even with the original package in place, it's providing the pie menu on the mailbox, but I only get the Testing Cheats > Enable Testing Cheats menu flow, not the Disable Testing Cheats
Any suggestions on what might be used (Python logging perhaps?) to get a better idea of what the game is doing when it encounters my (erroneous) testing cheats package?
|
|
|
Post by andrew on Dec 31, 2018 3:03:42 GMT -5
fufu508 did you use the python scripts as is or did you modify them to include the instance id's of your own interactions? Line 10 of the mailbox interactions has specific ids used by the tutorial package, but since your interactions are named differently, you will need to update the script to use yours instead.
|
|
|
Post by fufu508 on Dec 31, 2018 11:15:18 GMT -5
Thanks andrew ! I had overlooked that step for line 10 in the tutorial PDF. I believe I also confirmed what the ID in line 11 is, the Instance ID of the object to attach the Pie Menu to (the mailbox in this case). I fixed that but the pie menu still doesn't appear.
I have some missing/invalid reference 15283375139539021163 in creating the Pie Menu within the package it seems: <desyncdata>Error: Failed to locate category info for interaction category with key: 15283375139539021163 at gamedata.Gameplay.InteractionMenu::InteractionCategory/Create() at gamedata.Gameplay.InteractionMenu::InteractionMenuData/FetchCategory() at gamedata.Gameplay.InteractionMenu::InteractionMenuData/PopulateMap() at gamedata.Gameplay.InteractionMenu::InteractionMenuData/GenerateTree() at widgets.Gameplay.PieMenu::PieMenuMain/HandlePieMenuCreate() at olympus.io::CommunicationObject/Dispatch() at olympus.io::CommunicationManager/SendUIMessage() rtim=7762</desyncdata>
I'm continuing to investigate.
|
|
|
Post by fufu508 on Dec 31, 2018 11:27:42 GMT -5
Found the problem! I forgot to FNV64 hash my category tuning name. Once I changed 15283375139539021163 to the correct value of 6060003102684245355 (the hash for "fufu508:Mailbox_testing_cheats_pieCategory") the menus showed up. <?xml version="1.0" encoding="utf-8"?> <I c="PieMenuCategory" i="pie_menu_category" m="interactions.pie_menu_category" n="fufu508:Mailbox_testing_cheats_pieCategory" s="6060003102684245355"> <T n="_collapsible">False</T> <T n="_display_name">0xAFA1E55D<!--Testing Cheats--></T> <T n="_display_priority">3</T> </I>
Now to confirm that the testing cheats are actually toggling...
Yep! The following console command's availability corresponds to the latest click on the mailbox.
Money 100000
|
|
|
Post by fufu508 on Jan 1, 2019 17:57:50 GMT -5
Happy new year everyone I have attempted to write a step by step procedure that uses Sims 4 Studio instead of the tools mentioned in the "Mailbox Testing Cheats/Tutorial - Mailbox Testing Cheats.pdf" file contained in the zip file I linked to in the first post in this thread. With today's package (2019), like my package from Dec 31 (yesterday, using Scumbumbo's tutorial PDF interpreting the instructions on the fly to do them in Sims 4 Studio), I was able to get the enable and disable cheats menu items working after using my new steps but these do not show up under a main "Testing Cheats" menu item, they show up directly when clicking the mailbox.
Also I may have misinterpreted how these two lines work, but with them in place like this, it doesn't show the disable cheats menu item.
Here is a link to the draft instructions.
Here is original package (with XML tag for cheats removed as described in the draft instructions above)
It's probably simple mistakes I made but if I can figure them out (with a little help from fellow modders?) hopefully the draft instructions at the link above can turn into a useful tutorial.
|
|
|
Post by andrew on Jan 2, 2019 1:26:07 GMT -5
fufu508 I see a few things that need to be fixed with the 2019 package. 1. The pie menu category has the same instance number as the original which means it will override the sim_Friendly pie menu category. I'd suggest using the auto renumber feature that you used in step 15 for the pie menu category as well. Once you renumber the pie menu category tuning, copy it's instance number and update the instance number of the Sim Data to match it (the Sim Data should always have a matching instance with it's associated tuning resource). 2. The string table also has the same instance as the original pie menu category. The string table should get a unique name with the first two digits removed (or set to 0). This will be the English one. You should also use the Tools>Modding>Copy string tables to all languages to generate the additional string tables for other languages. It will use the same text you put in English until you update it, but without doing this, people that play in other languages will see the word debug instead of the words in your string table. 3. After fixing the pie menu category instance numbers, it still didn't show up in the sub menu. It looks like you are missing this from the two interaction tunings: <T n="category">14677720317969648255<!--fufu508-TestingCheatsMailbox-pieMenu--></T> 4. Once all of that was changed, like you said, only the enable interaction was showing up when cheat is set to True on the disable. It did however, show up when I shift-clicked the mailbox. I'm not sure if this was the intended behavior or if the meaning of the cheat flag has changed since the tutorial was written? I guess I'd just leave out Cheat=True part for the disable cheats. There are other ways that the interactions could be hidden when they aren't applicable, but that may be a little much for this tutorial. 5. The tuning descriptions from EA say this about the "debug" value of an interaction: " If checked, this interaction will only be available from the debug pie menu. The debug pie menu is not available in release builds and only appears when shift-clicking to bring up the pie menu. " I guess I would just say, if the interaction you are basing it on has it, delete it since nobody but EA will be running the game in debug mode.
|
|
|
Post by fufu508 on Jan 2, 2019 7:06:01 GMT -5
Thanks andrew ! I'll make the changes to the procedure and my test files later today hopefully. Regarding item #4 I didn't intend to require shift-clicking to see the pie menu. I'm interested in learning more about the ways to manage visibility of pie menus and their items. For item #5 I assume you used the download from here? forums.thesims.com/en_US/categories/technical-discussionsSpecifically forums.thesims.com/en_US/discussion/953069/1-48-90-tdescsI extracted the 1.48.90-TDESC.zip file from that post, found interaction.tdesc, and I found the text you quoted: EA-Sims4-Tuning-Descriptions\1.48.90-TDESC\Interactions\Descriptions\Interaction.tdesc (1 hit) Line 21635: <Tunable type="bool" name="debug" class="Tunable" default="False" display="Debug" muid="79D33F069AA8423B" description="If checked, this interaction will only be available from the debug pie menu. The debug pie menu is not available in release builds and only appears when shift-clicking to bring up the pie menu." Deprecated="False" filter="0" group="Availability" />
I had heard about "tdesc" but wasn't quite sure about how it is used. This is definitely one very helpful way, thanks again! Does Sims 4 Studio have built-in access to this info? If not, I'll put in a feature request if it's ok with you and orangemittens . P.S. I confirmed what you suspected in #4 EA-Sims4-Tuning-Descriptions\1.48.90-TDESC\Interactions\Descriptions\Interaction.tdesc (1 hit)
Line 21078: <Tunable type="bool" name="cheat" class="Tunable" default="False" display="Cheat" muid="64B86F3490929007" description="If checked, this interaction will only be available from the cheat pie menu. The cheat pie menu is available in all builds when cheats are enabled, and only appears when shift-clicking to bring up the pie menu." Deprecated="False" filter="0" group="Availability" />
|
|
|
Post by fufu508 on Jan 6, 2019 20:59:10 GMT -5
Thanks again andrew for your help! I was able to successfully create the menu structure as intended. I have updated the procedure. I'm still interested in knowing to manage run-time visibility of pie menus, presumably via Python? I'm also interested in customizing the icon that appears with Pie Menu Category Tuning resource. Based on looking at other packages I assume I need to import a .png file (128x128 pixels) into the package as a DST reference. I'll dig around more for how that's done.
Hi Mathcope, in case you know about these I mention you in this post.
|
|
|
Post by andrew on Jan 10, 2019 0:18:21 GMT -5
fufu508 one way to accomplish this with Python would be to make a subclass of the ImmediateSuperInteraction. As a test, I added a new tunable field to specify whether or not the interaction should show up while cheats are enabled, and an override of the test function to use that field. mailbox_cheat_tutorial.py import services import event_testing.results from interactions.base.immediate_interaction import ImmediateSuperInteraction from services.cheat_service import CheatService from sims4.tuning.tunable import Tunable from sims4.utils import flexmethod
class MailboxCheatInteraction(ImmediateSuperInteraction): INSTANCE_TUNABLES = {'cheats_on': Tunable(tunable_type=bool, default=False)}
@flexmethod def test(cls, inst, *args, **kwargs): inst_or_cls = inst if inst is not None else cls cheat_service: CheatService = services.get_cheat_service() if inst_or_cls.cheats_on: if cheat_service.cheats_enabled: return event_testing.results.TestResult.TRUE else: if not cheat_service.cheats_enabled: return event_testing.results.TestResult.TRUE return event_testing.results.TestResult(False)
With that script in the game, the tuning can be changed to use that instead of ImmediateSuperInteraction. The module name (m) is based on the file name of the .py file above, and the class (c) is based on the name of the class in the script above.
<I c="MailboxCheatInteraction" i="interaction" m="mailbox_cheat_tutorial" n="fufu508:EnableTestingCheats" s="15005049486891778103"> and the new field set: <T n="cheats_on">False</T>
I set it to false for the enable cheats interaction since it should not show if cheats are already on, and True for the disable since it should only show up if the cheats are on already. For the icon, in your pie menu category, it is reference as instance ea4aa419d39866ff. You can look that up in the game file cruiser (tools menu) to see the original (a DST that is 46x46 pixels). All you need to do is add your own DST image of the same size with a unique instance, and update the pie menu category and it's sim data to use your instance instead of ea4aa419d39866ff and it should work
<T n="_icon" p="InGame\UI\Icons\PieMenu\Category\icon_piemenu_category_friendly.png">2f7d0004:00000000:ea4aa419d39866ff</T>
The "p" is not used in the game and can be ignored, changed, or removed.
|
|
|
Post by fufu508 on Jan 12, 2019 11:25:09 GMT -5
Hi andrew , thanks for the example!
I'm going to annotate mailbox_cheat_tutorial.py to convey my (mis)understanding and ask some questions. I have several but want to get more familiar with Python before asking them. One below is "#what are cls and inst?"
# mailbox_cheat_tutorial.py # by Andrew # http://sims4studio.com/post/118820/thread # This script controls visibility of interaction (e.g. in a pie menu) based on status of # a game setting (testing cheats enabled/disabled in this case).
import services import event_testing.results #we'll make a subclass of ImmediateSuperInteraction from interactions.base.immediate_interaction import ImmediateSuperInteraction from services.cheat_service import CheatService from sims4.tuning.tunable import Tunable from sims4.utils import flexmethod
class MailboxCheatInteraction(ImmediateSuperInteraction): INSTANCE_TUNABLES = {'cheats_on': Tunable(tunable_type=bool, default=False)} # the value of the cheats_on tunable field is used to control visibility of the relevant # menu choice in game, i.e. true: show "disable cheats" , false: show "enable_cheats"
# decorate flexmethod which was imported from sims4.utils. @flexmethod def test(cls, inst, *args, **kwargs): #what are cls and inst? inst_or_cls = inst if inst is not None else cls cheat_service: CheatService = services.get_cheat_service() if inst_or_cls.cheats_on: if cheat_service.cheats_enabled: return event_testing.results.TestResult.TRUE else: if not cheat_service.cheats_enabled: return event_testing.results.TestResult.TRUE return event_testing.results.TestResult(False)
|
|
|
Post by andrew on Jan 13, 2019 14:50:37 GMT -5
fufu508 cls is the tuned subclass of MailboxCheatInteraction in this case. Inst would be an instance of the tuned subclass. EA's flexmethod basically just allows a method to be called as a class method or an instance method and provides a reference to the class and (if called as an instance method) the instance. Since I only needed the tuning anyway, I could have just checked cls.cheats_on (when called as an instance, the class is still provided).
Here is a small example of flexmethod usage:
import functools
# EA's flexmethod implementation. # Allows a function to be called as a class method or an instance method. class flexmethod: __slots__ = ('__wrapped_method__',)
def __init__(self, method): self.__wrapped_method__ = method
def __get__(self, instance, owner): return functools.partial(self.__wrapped_method__, owner, instance)
# Test class with a flexmethod class FlexMethodTestObject(object): # removing the @flexmethod would cause the code below to fail because it would expect 3 parameters instead of 1 @flexmethod def test_flex(cls, inst, text): print(f'class:{cls} instance:{inst} {text}')
# Call as a class method FlexMethodTestObject.test_flex('static call') # output: # class:<class '__main__.FlexMethodTestObject'> instance:None static call
# Call as instance method a = FlexMethodTestObject() a.test_flex('instance call') # output: # class:<class '__main__.FlexMethodTestObject'> instance:<__main__.FlexMethodTestObject object at 0x000001CB260DFDA0> instance call
|
|
|
Post by fufu508 on Jan 13, 2019 16:08:39 GMT -5
Thanks andrew, So is there ever a situation when the calling instance method is not appropriate/applicable, given that the class is provided in that case anyway? Sorry if the question has an obvious answer
|
|
|
Post by andrew on Jan 18, 2019 2:22:26 GMT -5
fufu508 I'm by no means an expert on the use of flexmethod. It seems a little strange to have something that is called in both an instance and class context, but the reason for calling it without an instance would probably be just that there is no reason to make an instance at the time of calling the function. I'm not sure of the specifics of when it would call the test on an instance, but in my test of the mailbox it was called before there was an instance.
|
|