I wanted to be able to do notifications in my Family Tree Add-On I'm working on without the cheat output window necessarily being open. A bit of playing around, with the hidden 'ui.dialog.notification_test' command yielded this working method:

The hard part was getting the client set without being able to pass _connection to the function. Once I solved that, everything fell into place nicely. Be sure to fix the long line starting "notification ="

I was asked for a clarification on how this worked, so I whipped up this as a "working example". If people are interested, I can expand on this with some examples using STBL support and/or custom icons:

Code:

import services
import sims4.commands
from sims4.localization import LocalizationHelperTuning
from ui.ui_dialog_notification import UiDialogNotification
def example_show_notification(text, title=None):
# We need the client to get the active sim for the icon
client = services.client_manager().get_first_client()
# If no title was given, use a default
if title is None:
title = "Example Title"
# Convert the strings to raw_text localized strings
localized_text = lambda **_: LocalizationHelperTuning.get_raw_text(text)
localized_title = lambda **_: LocalizationHelperTuning.get_raw_text(title)
# Prepare and show the notification
notification = UiDialogNotification.TunableFactory().default(client.active_sim, text=localized_text, title=localized_title)
notification.show_dialog(icon_override=(None, client.active_sim))
# An example via some cheat commands. Note you need to put quotes around the arguments
# when typing the commands at the cheat console, e.g.
# notification.example "this is the text of a notification"
# notification.example "this is a notification with an optional title" "title of notification"
@sims4.commands.Command('notification.example', command_type=sims4.commands.CommandType.Live)
def show_example_notification(text, title=None, _connection=None):
output = sims4.commands.CheatOutput(_connection)
output('Showing notification:\n text="{}"\n title="{}"'.format(text, title))
if title is None:
# With no title, we can leave off the title argument
example_show_notification(text)
else:
# Otherwise we need to send that to the notification function
example_show_notification(text, title=title)

I was asked for a clarification on how this worked, so I whipped up this as a "working example". If people are interested, I can expand on this with some examples using STBL support and/or custom icons...

Hello @scumbumbo! I have been looking over your recent mods to see if you have instituted a simple in-game notification with the newer patch versions of the Sims 4. I thank you for leaving the de-compiled .py files in your mods, it helps a lot!

Unfortunately. I have not found anything that has worked so far for me. I have a custom pie menu (thanks to your awesome tutorial) that I want one of it's functions to output some generated data in a notification. No buttons, nothing fancy, just text. I have it currently outputting 8 lines of text/numbers to the console, but it requires the console already open, which is a pain.

I have tested your above code with the most recent patch, and can verify that the console output at least still works when calling notification.example:

However, no notification pops up. You know better than I do how much EA has changed under the hood since 2014/2015. It is not surprising if they broke this as well.

I have been downloading random recently-updated mods that look like they use notifications with the hopes of finding .py files to pore over. I have found nothing yet. I see MC Command Center (deaderpool) has notifications on boot with recent patch versions, but everything of his is compiled.

I also found a bit of your code elsewhere from 2015 that deals with notifications:

Hi @verschijnsel - The code you're trying to use above appears to be from Change Career Branch and is used to display a notification with a string from a string table. You can use this method (although I would not use that mod as your source example as it's not been updated in two years or so), but would have to build an STBL with the strings you want to display in order for it to work. If you just want to use a normal Python string for the notification you need to use the method I posted in message #2 above. That still works fine (just tried it in game myself).

Other than a typo, the only reason I can think you may not be seeing the notification when using the example I posted would be if you have your game paused. Notifications are queued, not instantly displayed, so the game would have to be taken off pause before it will show that notification.

ETA - The core difference between the two methods (STBL vs. the example above) is the use of sims4.localization._create_localized_string to use a string from an STBL vs using LocalizationHelperTuning.get_raw_text for displaying just a raw text string.

Other than a typo, the only reason I can think you may not be seeing the notification when using the example I posted would be if you have your game paused. Notifications are queued, not instantly displayed, so the game would have to be taken off pause before it will show that notification.

Aww, you got me. I can't believe I did not test it un-paused. What a dumb mistake. I guess the good news is that this does still work. Thank you for confirming!

I was asked for a clarification on how this worked, so I whipped up this as a "working example". If people are interested, I can expand on this with some examples using STBL support and/or custom icons:

Okay, so I cobbled together a way to pull an icon from the selected Sim, thank's to Scumbumbo's help.

Using Scumbumbo's mailbox tutorial as a guide (this is one command for the "enable" testing cheats, just stripped down):

The object_manager() line retrieves a sim object with the obj_id passed from the XML argument "participant". "obj" now contains that "participant" sim, i.e the sim you clicked on.

Here is the notification function, again Scumbumbo's example, this time from above, but modified (in bold) to accept a sim object:

Code:

def example_show_notification(text, sim, title=None):
# We need the client to get the active sim for the icon
client = services.client_manager().get_first_client()
# If no title was given, use a default
if title is None:
title = "Example Title"
# Convert the strings to raw_text localized strings
localized_text = lambda **_: LocalizationHelperTuning.get_raw_text(text)
localized_title = lambda **_: LocalizationHelperTuning.get_raw_text(title)
# Prepare and show the notification
notification = UiDialogNotification.TunableFactory().default(client.active_sim, text=localized_text, title=localized_title)
notification.show_dialog(icon_override=(None, sim.sim_info))

The sim.sim_info line is able to pull an icon using the "obj" sim object passed to the notification function. The test in the first function makes sure you don't send an object to the notification that is not a sim.

I am guessing this would be the proper way to do this in this case, unless passing the obj_id and pulling the sim object in the notification would be more efficient? Either way, it does work.

The sim.sim_info line is able to pull an icon using the "obj" sim object passed to the notification function. The test in the first function makes sure you don't send an object to the notification that is not a sim.

I am guessing this would be the proper way to do this in this case, unless passing the obj_id and pulling the sim object in the notification would be more efficient? Either way, it does work.

For a simple example like this one, either method could be applicable - however in most modding situations you're going to be doing something with the sim or sim_info object in the caller method, so you already have a reference to that sim object. Sending the ID and making the notification method get a fresh reference to the sim object would be less efficient. So yeah, probably 95 times out of 100 the way you have chosen to do that is likely to be the best way.

You could pass just the sim_info item itself if you wanted, or even just a reference to the icon itself. But since you're not really passing all that data, just a reference to an existing object, that would be mostly a choice of style. Die-hard OOP programmers would probably disagree with me on that, but I don't think many die-hard OOP programmers choose to use Python to begin with!