<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://www.ccoors.de/feed_style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
  <title>ccoors</title>
  <subtitle>Mein Blog</subtitle>
  <link rel="self" type="application/atom+xml" href="https://www.ccoors.de/de/atom.xml"/>
  <link rel="alternate" type="text/html" href="https://www.ccoors.de"/>
  <generator uri="https://www.getzola.org/">Zola</generator>
  <updated>2026-03-30T00:00:00Z</updated>
  <id>https://www.ccoors.de/de/atom.xml</id>
  <author>
    <name>ccoors</name>
    <uri>https://www.ccoors.de</uri>
  </author>
  <entry xml:lang="de">
    <title>Reduzieren des Power Levels von Puppet-Benutzern von Matrix-Bridges</title>
    <published>2025-06-17T00:00:00Z</published>
    <updated>2025-06-17T00:00:00Z</updated>
    <link rel="alternate" type="text/html" href="https://www.ccoors.de/de/blog/matrix-bridge-puppet-user-demote/"/>
    <id>https://www.ccoors.de/de/blog/matrix-bridge-puppet-user-demote/</id>
    <summary>Ich habe versehentlich vergebene Rechte in Matrix rückgängig gemacht.</summary>
    <category term="dev"/>
    <category term="matrix"/>
    <content type="html" xml:base="https://www.ccoors.de/de/blog/matrix-bridge-puppet-user-demote/">&lt;p&gt;Ich bin momentan Mitglied der AG Administration im &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://www.hackerspace-bremen.de/&quot;&gt;Hackerspace Bremen&lt;/a&gt;. Wir betreiben für unsere Mitglieder:innen einen föderierten Matrix-Homeserver. Dieser Dienst ist noch relativ neu, und wir nutzen die &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.mau.fi/bridges/go/discord/&quot;&gt;mautrix-discord&lt;/a&gt; Bridge mit “double puppeting” um einige Räume eines legacy Discord-Servers nach Matrix zu bridgen, sodass User, die noch nicht auf Matrix umgestiegen sind weiterhin die Möglichkeit haben, an unseren Chats teilzunehmen. Die Bridge erzeugt für alle Discord-Benutzer im Matrix “Puppet-User” und leitet Nachrichten in beide Richtungen entsprechend weiter.&lt;/p&gt;
&lt;p&gt;Versehentlich hatte ich einem dieser Puppet-User einen &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://matrix.org/docs/communities/moderation/&quot;&gt;Power Level&lt;/a&gt; von 100 in einem der Matrix-Räume gegeben. In Matrix erreicht man eine Patt-Situation, sobald man mit einem anderen Benutzer auf demselben Power Level steht. Die Benutzer können sich die Berechtigung nicht mehr gegenseitig enziehen, nur noch sich selber und Benutzern mit niedrigerem Power Level.&lt;/p&gt;
&lt;p&gt;Die Vergabe dieser Berechtigung an einen Puppet-User hat zwar keine unmittelbar negativen Folgen, der Zustand hat mich jedoch nicht glücklich gemacht und ich suchte nach Möglichkeiten, meinen Fehler rückgängig zu machen. Glücklicherweise war &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://mau.fi/&quot;&gt;Tulir&lt;/a&gt; durch den Verweis auf das &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://spec.matrix.org/v1.14/application-service-api/&quot;&gt;Matrix Application Service API&lt;/a&gt; im Support-Raum &lt;code&gt;#discord:maunium.net&lt;/code&gt; sehr hilfreich. Mit dem Access Token der Bridge selber können im Namen &lt;em&gt;aller&lt;/em&gt; Puppet-User Events verschickt werden.&lt;/p&gt;
&lt;p&gt;Es ist natürlich möglich, von Hand eigene &lt;code&gt;curl&lt;/code&gt;-Aufrufe zu konstruieren, ich habe aber etwas besser reproduzierbares mit &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/mautrix/python&quot;&gt;mautrix-python&lt;/a&gt; (auch von Tulir) ausprobiert. Hier nun die Befehle, die am Ende zum Erfolg geführt haben.&lt;/p&gt;
&lt;p&gt;Nach der Installation des Paketes eine &lt;code&gt;asyncio&lt;/code&gt; Shell öffnen (&lt;code&gt;python -m asyncio&lt;/code&gt;) und diese Befehle ausführen, um ein &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.mau.fi/python/latest/api/mautrix.client.api.html#mautrix.client.ClientAPI&quot;&gt;&lt;code&gt;ClientAPI&lt;/code&gt;&lt;/a&gt;-Objekt zu erzeugen. Die Werte nach Bedarf anpassen:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt; from&lt;/span&gt;&lt;span&gt; mautrix.client&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; import&lt;/span&gt;&lt;span&gt; ClientAPI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; puppet_user&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;@discord_...:hackerspace-bremen.de&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; base_url&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;https://matrix.hackerspace-bremen.de&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; as_token&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;...&amp;quot;&lt;/span&gt;&lt;span class=&quot;z-5&quot;&gt;  # Taken from the bridges registration.yaml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; client&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; ClientAPI(puppet_user,&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt; base_url&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span&gt;base_url,&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt; token&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span&gt;as_token,&lt;/span&gt;&lt;span class=&quot;z-9&quot;&gt; as_user_id&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt;=&lt;/span&gt;&lt;span&gt;puppet_user)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sicherstellen, dass der Client funktioniert. Zum Beispiel, indem man die aktuellen Räume des Users abfragt:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt; await&lt;/span&gt;&lt;span&gt; client.get_joined_rooms()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;#39;!room_id_1:hackerspace-bremen.de&amp;#39;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;#39;!room_id_2:hackerspace-bremen.de&amp;#39;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; ...&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wenn diese richtig aussehen, kann für einen Raum der Power Level des Benutzers geändert werden. Um die Power Level in einem Raum zu ändern muss ein komplettes &lt;code&gt;m.room.power_levels&lt;/code&gt;-Event an den Raum geschickt werden. Am einfachsten ist es, das aktuelle Event des Raums zu nehmen und zu bearbeiten.&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; room_id&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;!room_id_1:hackerspace-bremen.de&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; states&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; = await&lt;/span&gt;&lt;span&gt; client.get_state(room_id)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; len&lt;/span&gt;&lt;span&gt;(states)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-1&quot;&gt;22&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Das aktuelle &lt;code&gt;m.room.power_levels&lt;/code&gt;-Event finden:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; power_state&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; [s&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; for&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; in&lt;/span&gt;&lt;span&gt; states&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; if&lt;/span&gt;&lt;span&gt; s.type.t&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; ==&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt; &amp;quot;m.room.power_levels&amp;quot;&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Das Event bearbeiten und den Power Level des Puppet-Benutzers auf 0 setzen:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; power_state.content.users[puppet_user]&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Anschließend das Event zurück zum Server senden:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt; from&lt;/span&gt;&lt;span&gt; mautrix.types&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; import&lt;/span&gt;&lt;span&gt; EventType, EventContent&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;&amp;gt;&amp;gt;&amp;gt; await&lt;/span&gt;&lt;span&gt; client.send_state_event(room_id, EventType.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;ROOM_POWER_LEVELS&lt;/span&gt;&lt;span&gt;, power_state.content)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;#39;$...&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wenn alles geklappt hat, hat der Puppet-Benutzer nun wieder den Power Level 0.&lt;/p&gt;
</content>
  </entry>
  <entry xml:lang="de">
    <title>Blog Sprachen</title>
    <published>2025-06-14T00:00:00Z</published>
    <updated>2025-06-14T00:00:00Z</updated>
    <link rel="alternate" type="text/html" href="https://www.ccoors.de/de/blog/blog-languages/"/>
    <id>https://www.ccoors.de/de/blog/blog-languages/</id>
    <summary>Mein Blog ist ab sofort auf Deutsch und Englisch verfügbar.</summary>
    <category term="in eigener Sache"/>
    <category term="dev"/>
    <content type="html" xml:base="https://www.ccoors.de/de/blog/blog-languages/">&lt;p&gt;Ich habe mich dazu entschieden, die ganze Seite ab sofort zweisprachig in Deutsch und Englisch zu pflegen.&lt;/p&gt;
</content>
  </entry>
  <entry xml:lang="de">
    <title>Optionsmenü mit Grafikeinstellungen in Godot</title>
    <published>2025-06-09T00:00:00Z</published>
    <updated>2025-06-14T00:00:00Z</updated>
    <link rel="alternate" type="text/html" href="https://www.ccoors.de/de/blog/godot-graphics-settings/"/>
    <id>https://www.ccoors.de/de/blog/godot-graphics-settings/</id>
    <summary>Warum Grafikeinstellungen zur Laufzeit nicht übernommen wurden.</summary>
    <category term="dev"/>
    <category term="gamedev"/>
    <category term="godot"/>
    <content type="html" xml:base="https://www.ccoors.de/de/blog/godot-graphics-settings/">&lt;p&gt;Ich bearbeite gerade die &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://20_games_challenge.gitlab.io/&quot;&gt;20 Games Challenge&lt;/a&gt;, in der man 20 kleine Spiele bauen soll, um verschiedene Aspekte der Spieleentwicklung zu lernen. Das Konzept, einen festen Scope zu haben und an kleinen Projekten zu entwickeln, hat mich überzeugt.&lt;/p&gt;
&lt;p&gt;Mein Ansatz weicht aber in einigen Punkten ab, da ich mich gerne in Details verliere und mir gewisse Dinge ins Auge springen, die ich unbedingt umsetzen möchte. Ich bin gerade bei &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://20_games_challenge.gitlab.io/games/frogger/&quot;&gt;Spiel 3&lt;/a&gt; und baue einen Frogger-Clon. Anders als in der Challenge vorgegeben baue ich allerdings ein 3D-Spiel und wollte ein Options-Menü bauen, in dem zur Laufzeit Qualitätseinstellungen ausgewählt werden können. Diese sollten über mehrere Spielestarts persistiert werden. Ein Beispiel für eine Einstellung ist &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_projectsettings.html#class-projectsettings-property-rendering-anti-aliasing-quality-msaa-3d&quot;&gt;MSAA 3D&lt;/a&gt; (3D Multisample Anti-Aliasing).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.ccoors.de/de/blog/godot-graphics-settings/options_window.png&quot; alt=&quot;Das Optionsmenü für mein Spiel&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Die Auswahl einer Option im &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_optionbutton.html&quot;&gt;OptionButton&lt;/a&gt; hat dann ein &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_signal.html&quot;&gt;Signal&lt;/a&gt; ausgelöst, das im Code des Dialogfensters etwa folgendermaßen behandelt wurde:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;gdscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;# [...]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; _ready&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; void&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    _setup_options&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;    # [...]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; _setup_options&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; void&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    %&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;msaa&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;clear&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    %&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;msaa&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_item&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;Disabled&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Viewport&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;MSAA_DISABLED&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    %&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;msaa&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_item&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;2×&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Viewport&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;MSAA_2X&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    %&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;msaa&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_item&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;4×&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Viewport&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;MSAA_4X&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    %&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;msaa&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;add_item&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-2&quot;&gt;&amp;quot;8×&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Viewport&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;MSAA_8X&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    %&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt;msaa&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;select&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get_viewport&lt;/span&gt;&lt;span&gt;().msaa_3d)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; _on_msaa_item_selected&lt;/span&gt;&lt;span&gt;(index:&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; void&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    get_viewport&lt;/span&gt;&lt;span&gt;().msaa_3d&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; =&lt;/span&gt;&lt;span&gt; (index&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; as&lt;/span&gt;&lt;span class=&quot;z-1&quot;&gt; MSAA&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-6&quot;&gt;    save_settings&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-5&quot;&gt;# [...]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Die Auswahl einer Option hatte allerdings keinen Effekt, ich konnte kein Anti-Aliasing im Spiel beobachten, die FPS blieben konstant und auch die Auslastung der Grafikkarte änderte sich nicht. Ich hatte sogar meinen Code mit dem „&lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/godotengine/godot-demo-projects/tree/4.3/3d/graphics_settings&quot;&gt;graphics_settings&lt;/a&gt;“ Projekt aus dem &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/godotengine/godot-demo-projects&quot;&gt;godot-demo-projects&lt;/a&gt; Repo verglichen und konnte keinen offensichtlichen Unterschied feststellen. Der Code in &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/godotengine/godot-demo-projects/blob/4.2-31d1c0c/3d/graphics_settings/settings.gd#L124&quot;&gt;&lt;code&gt;_on_msaa_option_button_item_selected&lt;/code&gt;&lt;/a&gt; ruft auch &lt;code&gt;get_viewport().msaa_3d = ...&lt;/code&gt; auf. &lt;code&gt;index&lt;/code&gt; entsprach dem korrekten Wert aus dem &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_viewport.html#enum-viewport-msaa&quot;&gt;&lt;code&gt;Viewport.MSAA&lt;/code&gt;&lt;/a&gt;-enum, den ich zum Testen sogar nach &lt;code&gt;MSAA&lt;/code&gt; gecastet hatte&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://www.ccoors.de/de/blog/godot-graphics-settings/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Nach einer Menge Debugging und dem Ausschluss aller anderen Optionen kam ich dann darauf: Mein Options-Dialog war, im Gegensatz zu dem Demo-Projekt, in einem eigenen Fenster. Die Klasse &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_window.html&quot;&gt;Window&lt;/a&gt; erbt von &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_viewport.html&quot;&gt;Viewport&lt;/a&gt;, was dazu geführt hat, dass mein Code nur die Einstellungen des Options-Fensters geändert hat. Mein Fix bestand darin, statt &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_node.html#class-node-method-get-viewport&quot;&gt;&lt;code&gt;get_viewport()&lt;/code&gt;&lt;/a&gt; eine eigene Funktion zu bauen, die den Root-Viewport ermittelt und diese stattdessen zu verwenden:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;gdscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; get_root_viewport&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span class=&quot;z-8&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; Viewport&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-8&quot;&gt;    return&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt; get_tree&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get_root&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span class=&quot;z-6&quot;&gt;get_viewport&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Was gar nicht nötig gewesen wäre. Man spart sich durch die Konstruktion den verbosen Code (&lt;code&gt;if index == ...: get_viewport().msaa_3d = ... elif ...&lt;/code&gt;), man verliert aber durch die Verwendung des Index die Typinformationen und schleppt nur „implizit“ wichtige Informationen mit. Eine sauberere Lösung ist die Verwendung von Item-Metadata (&lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_optionbutton.html#class-optionbutton-method-set-item-metadata&quot;&gt;&lt;code&gt;set_item_metadata&lt;/code&gt;&lt;/a&gt;/&lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_optionbutton.html#class-optionbutton-method-get-item-metadata&quot;&gt;&lt;code&gt;get_item_metadata&lt;/code&gt;&lt;/a&gt;) an den Options-Einträgen, da dort &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://docs.godotengine.org/en/4.4/classes/class_variant.html#class-variant&quot;&gt;Variants&lt;/a&gt; genutzt werden können. &lt;a href=&quot;https://www.ccoors.de/de/blog/godot-graphics-settings/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
  <entry xml:lang="de">
    <title>Neuer Blog</title>
    <published>2025-06-08T00:00:00Z</published>
    <updated>2025-06-14T00:00:00Z</updated>
    <link rel="alternate" type="text/html" href="https://www.ccoors.de/de/blog/new-blog/"/>
    <id>https://www.ccoors.de/de/blog/new-blog/</id>
    <summary>Die Ankündigung meines neuen Blogs, Rückblick und Gedanken.</summary>
    <category term="in eigener Sache"/>
    <category term="dev"/>
    <content type="html" xml:base="https://www.ccoors.de/de/blog/new-blog/">&lt;p&gt;Wie viele Entwickler kenne ich das Problem, die eigene Webseite zu pflegen, nur zu gut. Das letzte Update meiner alten Seite fand 2022 statt. Ich starte hiermit einen neuen Versuch. Damit verbunden ist der Vorsatz, generell mehr zu schreiben und mich auch bei &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://mastodon.social/@ccoors&quot;&gt;Social Media&lt;/a&gt; (natürlich im Fediverse) stärker zu engagieren. Vorsätze haben einen durchwachsenen Ruf, bei mir lief es in der jüngeren Vergangenheit jedoch eher gut damit.&lt;/p&gt;
&lt;p&gt;In diesem Blog möchte ich mich nicht nur auf technische Themen fokussieren, sondern auch über andere Dinge schreiben. Dinge die mich beschäftigen, über die ich nachdenke. Infrastruktur, die ich aufsetze. Projekte, an denen ich arbeite. Eventuell wird das für einige Dinge auch eine Art Devlog. Wer weiß.&lt;/p&gt;
&lt;p&gt;Nachdem meine alte Seite mit &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://gohugo.io/&quot;&gt;Hugo&lt;/a&gt; gebaut war, bin ich jetzt wieder bei &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://www.getzola.org/&quot;&gt;Zola&lt;/a&gt;. Als ich vor einigen Jahren noch mit Zola experimentiert hatte, war die Software noch nicht so weit. Mittlerweile bin ich aber überzeugt. Mein erster Blick auf Dinge, die in &lt;a rel=&quot;noopener nofollow noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https://www.rust-lang.org/&quot;&gt;Rust&lt;/a&gt; entwickelt werden, ist in der Regel positiv.&lt;/p&gt;
&lt;p&gt;Mir ist bewusst, dass ich mit der Umstellung Links brechen werden, da auch alte Inhalte nicht mit übernommen wurden. Ein sauberer Schnitt fühlt sich für mich gerade gut an. Da ich mir keinerlei Mühe gebe, irgendwelche Statistiken, Besucherzahlen, Seitenaufrufe o.Ä. zu tracken, weiß ich nicht, wie viele Aufrufe das betreffen wird – es ist mir auch egal.&lt;/p&gt;
</content>
  </entry>
  <entry xml:lang="de">
    <title>1750 Hz Pfeife</title>
    <published>2018-05-26T00:00:00Z</published>
    <updated>2026-03-30T00:00:00Z</updated>
    <link rel="alternate" type="text/html" href="https://www.ccoors.de/de/blog/1750-pipe/"/>
    <id>https://www.ccoors.de/de/blog/1750-pipe/</id>
    <summary>Ein alter Artikel über eine 3D-gedruckte Orgelpfeife zur Erzeugung eines 1750 Hz-Tons.</summary>
    <category term="3D Druck"/>
    <content type="html" xml:base="https://www.ccoors.de/de/blog/1750-pipe/">&lt;p&gt;Für viele Amateurfunk-Relais ist ein Ton der Frequenz 1750 Hz zum Auftasten erforderlich. Als Spaßprojekt habe ich eine Pfeife entwickelt, die diesen Ton produziert:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.ccoors.de/de/blog/1750-pipe/1750_1.png&quot; alt=&quot;1750 Pfeife 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.ccoors.de/de/blog/1750-pipe/1750_2.png&quot; alt=&quot;1750 Pfeife 2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.ccoors.de/de/blog/1750-pipe/1750_3.png&quot; alt=&quot;1750 Pfeife 3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.ccoors.de/de/blog/1750-pipe/1750_4.png&quot; alt=&quot;1750 Pfeife 4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ich habe sie auf einem Anet A8 Drucker mit 0,1 mm Schichtdicke gedruckt und sie funktioniert tatsächlich. Je nach Druck werden Töne zwischen 1600 und 1850 Hz erzeugt, bevor die Pfeife überbläst und die Pfeife Obertöne produziert. Viele Relais ließen sich damit auftasten, wobei einige einen ziemlich stabilen Ton benötigten.&lt;/p&gt;
&lt;h2 id=&quot;download&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#download&quot; aria-label=&quot;Link to this section&quot;&gt;§&lt;/a&gt;
Download&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ccoors.de/de/blog/1750-pipe/1750_pipe.stl&quot;&gt;STL Datei&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
</feed>
