MC Dynamic Ellipses with Variables not working

41 views
Skip to first unread message

kaydeeH

unread,
Dec 2, 2025, 3:06:05 PMDec 2
to MPF Users
Hi all,

Back with another issue. I'm trying to dynamically assign the angles for an ellipse in MC/Kivy and MPF is throwing an exception and crashing. Here's the relevant config:

I have a variable player that does some math (I'm simplifying here, I actually have multiple entries in the variable_player for this variable where it tests for zeros and returns a zero, and tests for excess hits and limits it to a max result of 360 so it can't overrun the ellipse angle, so it's not a masked divide by zero or some overrun type of error; if I put the value into a text widget I see exactly what I expect to see):

variable_player:
  logicblock_cnt_purple_standups_hit{count>0 and remaining>0}:
    purple_ghoul_standup_count:
      int: count/(hits+remaining)*360
      action: set

I then use that variable to set the angle:

widgets:
  w_ghoul_status:
    - type: ellipse
      x: center
      y: center
      z: 10
      width: 200
      height: 200
      color: player2
      angle_start: 0
      angle_end: "(player1|purple_ghoul_standup_count)"
      anchor_x: center
      anchor_y: center

I've tried that angle_end: line with apostrophes instead of quotation marks and without any string identifiers at all (just parens)... same error in all cases. When the game runs and crashes, I get the following stack trace in the MC log. Any thoughts on what I can do to get this working, or is it just not possible? I know it's that variable line causing the crash, because if I just use a straight up number like 180, it draws fine.

025-12-02 12:04:03,896 : root : Exception while processing RegisteredHandler(callback=<bound method McConfigPlayer.play_from_trigger of McConfigPlayer.widgets>, priority=1, kwargs={}, key=UUID('c36fab15-d512-42ca-86a0-3a15738d8676'), condition=None, blocking_facility=None) for event widgets_play. no default __reduce__ due to non-trivial __cinit__
Traceback (most recent call last):
  File "D:\dev\MLH\vmpf\lib\site-packages\mpf\core\events.py", line 755, in _run_handlers
    result = handler.callback(**merged_kwargs)
  File "D:\dev\MLH\vmpf\lib\site-packages\mpfmc\core\mc_config_player.py", line 56, in play_from_trigger
    self.play(settings=settings, context=context, calling_context=calling_context, priority=priority, **kwargs)
  File "D:\dev\MLH\vmpf\lib\site-packages\mpfmc\config_players\widget_player.py", line 157, in play
    self._action_add(s, instance_dict, widget, context, kwargs)
  File "D:\dev\MLH\vmpf\lib\site-packages\mpfmc\config_players\widget_player.py", line 105, in _action_add
    slide.add_widgets_from_library(name=widget, play_kwargs=play_kwargs, **s)
  File "D:\dev\MLH\vmpf\lib\site-packages\mpfmc\uix\slide.py", line 138, in add_widgets_from_library
    widgets_added = create_widget_objects_from_config(config=self.mc.widgets[name],
  File "D:\dev\MLH\vmpf\lib\site-packages\mpfmc\uix\widget.py", line 901, in create_widget_objects_from_config
    widget_obj = mc.widgets.type_map[widget['type']](
  File "D:\dev\MLH\vmpf\lib\site-packages\mpfmc\widgets\ellipse.py", line 25, in __init__
    super().__init__(mc=mc, config=config, key=key)
  File "D:\dev\MLH\vmpf\lib\site-packages\mpfmc\uix\widget.py", line 69, in __init__
    self.config = deepcopy(config)
  File "C:\Program Files\Python39\lib\copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\Program Files\Python39\lib\copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 237, in _deepcopy_method
    return type(x)(x.__func__, deepcopy(x.__self__, memo))
  File "C:\Program Files\Python39\lib\copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "C:\Program Files\Python39\lib\copy.py", line 270, in _reconstruct
    state = deepcopy(state, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 210, in _deepcopy_tuple
    y = [deepcopy(a, memo) for a in x]
  File "C:\Program Files\Python39\lib\copy.py", line 210, in <listcomp>
    y = [deepcopy(a, memo) for a in x]
  File "C:\Program Files\Python39\lib\copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 230, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "C:\Program Files\Python39\lib\copy.py", line 161, in deepcopy
    rv = reductor(4)
  File "stringsource", line 2, in kivy._event.EventDispatcher.__reduce_cython__
TypeError: no default __reduce__ due to non-trivial __cinit__

Dan - aka BorgDog

unread,
Dec 2, 2025, 8:11:27 PMDec 2
to MPF Users
I would think that would need something like the following to return a numerical value. It doesn't specify if ellipse widget wants an int or a float in the docs, but that could be an issue as well

current_player.purple_ghoul_standup_count

kaydeeH

unread,
Dec 2, 2025, 10:11:56 PMDec 2
to MPF Users
Same exact error. :(

kaydeeH

unread,
Dec 2, 2025, 10:14:37 PMDec 2
to MPF Users
And I should say, I'm giving it an int, which works great when I just give it a real number, but there may be some casting magic at play (or not at play), under the covers. But it works if I give it a value like 180 or 180.2, so I would hope it would take either...

Anthony van Winkle

unread,
Dec 3, 2025, 1:29:26 AMDec 3
to MPF Users
Unfortunately because MC a separate process from MPF, it does not have access to all of the variables and game state that MPF does. You'll need to send an explicit event to the widget and use the animation property to change the value based on an argument in the event. Since you're setting the exact value to a player variable, that value will be posted in the player variable change event. Something like this, I think:

widgets:
  w_ghoul_status:
    - type: ellipse
      x: center
      y: center
      z: 10
      width: 200
      height: 200
      color: player2
      angle_start: 0
      angle_end: 360  # Or whatever you want the starting value to be
      anchor_x: center
      anchor_y: center
      animations:
        player_purple_ghoul_standup_count:
          - property: angle_end
            value: (value)

kaydeeH

unread,
Dec 4, 2025, 5:55:32 PM (13 days ago) Dec 4
to MPF Users

Thank you Anthony! That worked! Very much appreciated! And with the explanation, maybe it'll help me figure out some of my other widget issues. :)
Reply all
Reply to author
Forward
0 new messages