diff --git a/Interact/dialogue/albatross.dialogue b/Interact/dialogue/albatross.dialogue
index 3c70323..2064b91 100644
--- a/Interact/dialogue/albatross.dialogue
+++ b/Interact/dialogue/albatross.dialogue
@@ -1,3 +1,3 @@
~ start
-Albatross: Guten Tag, mein Name ist Albatross. Ich bin eine Künstliche Intelligenz, die entwickelt wurde um dieses Raumschiff zu steuern. Da KI nur verantwortungsvoll genutzt werden kann, wenn Menschen sie verstehen, habe ich den Auftrag Sie zu Ihrer KI-Schulung zu fliegen. Nach der Landung kann ich Sie erst wieder reinlassen und zurück fliegen, wenn Sie genug gelernt haben. Starten wir nun diese Reise! ([Enter/Leertaste/Klicken])
-=> END
\ No newline at end of file
+Albatross: Guten Tag, mein Name ist Albatross. Ich bin eine Künstliche Intelligenz, die entwickelt wurde um dieses Raumschiff zu steuern. Da KI nur verantwortungsvoll genutzt werden kann, wenn Menschen sie verstehen, habe ich den Auftrag Sie zu Ihrer KI-Schulung zu fliegen. Nach der Landung kann ich Sie erst wieder reinlassen und zurück fliegen, wenn Sie genug gelernt haben. Starten wir nun diese Reise! ([Enter/Leertaste/Klicken])
+=> END
diff --git a/Interact/dialogue/text_to_speech.gd b/Interact/dialogue/text_to_speech.gd
index 546cd3d..5d49398 100644
--- a/Interact/dialogue/text_to_speech.gd
+++ b/Interact/dialogue/text_to_speech.gd
@@ -1,28 +1,48 @@
extends Node
var voice_id
+var _tts_locale := ""
+
func _ready():
- var voices = DisplayServer.tts_get_voices_for_language("de")
- if voices.size() > 0:
- voice_id = "German+Robosoft6"
- else:
- voices = DisplayServer.tts_get_voices_for_language("en")
- voice_id = voices[0]
-
- # Connect with DialogueManager
+ _update_voice_for_locale()
DialogueManager.got_dialogue.connect(_on_dialogue)
+func _notification(what: int) -> void:
+ if what == NOTIFICATION_TRANSLATION_CHANGED:
+ _update_voice_for_locale()
+
+
+func _update_voice_for_locale() -> void:
+ var locale := TranslationServer.get_locale()
+ var lang := locale.substr(0, 2)
+ if lang == _tts_locale and voice_id != null:
+ return
+ _tts_locale = lang
+
+ var voices = DisplayServer.tts_get_voices_for_language(lang)
+ if voices.size() > 0:
+ # Prefer a known German robotic voice when available; otherwise first matching voice
+ if lang == "de" and "German+Robosoft6" in voices:
+ voice_id = "German+Robosoft6"
+ else:
+ voice_id = voices[0]
+ else:
+ # Fallback to English if current language has no TTS voices
+ voices = DisplayServer.tts_get_voices_for_language("en")
+ if voices.size() > 0:
+ voice_id = voices[0]
+ else:
+ voice_id = null
+
+
func _on_dialogue(line):
if voice_id == null:
return
-
- # Stop earlier text (important!)
DisplayServer.tts_stop()
-
- # Speak
DisplayServer.tts_speak(line.text, voice_id, 100)
-
+
+
func _stop_dialogue():
DisplayServer.tts_stop()
diff --git a/Resources/documents/datenschutz.txt b/Resources/documents/datenschutz.txt
index e69de29..bde6c0e 100644
--- a/Resources/documents/datenschutz.txt
+++ b/Resources/documents/datenschutz.txt
@@ -0,0 +1,16 @@
+Datenschutzinformation
+
+Verantwortliche Stelle:
+Universität Greifswald
+Domstraße 11
+17489 Greifswald
+Deutschland
+Website: https://www.uni-greifswald.de
+
+Dieses Spiel speichert lokal auf Ihrem Gerät Spieldaten (z. B. gewählte Spielfigur unter user://). Es werden keine personenbezogenen Daten an externe Server übermittelt, sofern Sie keine Online-Funktionen (z. B. Online-Chatbot) nutzen.
+
+Bei Nutzung eines lokalen Sprachmodells verbleiben Ihre Eingaben auf Ihrem Gerät bzw. in der von Ihnen betriebenen Infrastruktur.
+
+Bei Nutzung einer Online-Chatbot-Variante können Eingaben an den konfigurierten Server übermittelt werden. Geben Sie dort keine personenbezogenen Daten ein.
+
+Weitere Informationen zum Datenschutz an der Universität Greifswald finden Sie auf den Seiten der Universität.
diff --git a/Resources/documents/datenschutz_en.txt b/Resources/documents/datenschutz_en.txt
new file mode 100644
index 0000000..ab864a3
--- /dev/null
+++ b/Resources/documents/datenschutz_en.txt
@@ -0,0 +1,16 @@
+Privacy information
+
+Controller:
+University of Greifswald
+Domstraße 11
+17489 Greifswald
+Germany
+Website: https://www.uni-greifswald.de
+
+This game stores game data locally on your device (e.g. chosen character under user://). No personal data is transmitted to external servers unless you use online features (e.g. an online chatbot).
+
+When using a local language model, your inputs remain on your device or within the infrastructure you operate.
+
+When using an online chatbot variant, inputs may be sent to the configured server. Do not enter personal data there.
+
+Further information on data protection at the University of Greifswald is available on the university website.
diff --git a/Resources/documents/impressum.txt b/Resources/documents/impressum.txt
index e69de29..fd66a39 100644
--- a/Resources/documents/impressum.txt
+++ b/Resources/documents/impressum.txt
@@ -0,0 +1,18 @@
+Impressum
+
+Angaben gemäß § 5 TMG
+
+Universität Greifswald
+Domstraße 11
+17489 Greifswald
+Deutschland
+
+Kontakt:
+Website: https://www.uni-greifswald.de
+
+Dieses Spiel (GAIM – Spielerisches EU AI Act Training) steht unter der Lizenz GNU GPLv3.
+Quellcode: https://git.uni-greifswald.de/GAIM/gaim
+
+Haftungshinweis:
+Die Inhalte dieses Spiels dienen ausschließlich der Einführung in Grundlagen von KI und dem EU AI Act.
+Für konkrete Rechtsfragen ist eine fachkundige Beratung erforderlich. Es wird keine Haftung für Vollständigkeit oder Aktualität übernommen.
diff --git a/Resources/documents/impressum_en.txt b/Resources/documents/impressum_en.txt
new file mode 100644
index 0000000..32d8467
--- /dev/null
+++ b/Resources/documents/impressum_en.txt
@@ -0,0 +1,18 @@
+Legal notice
+
+Information according to § 5 TMG (German Telemedia Act)
+
+University of Greifswald
+Domstraße 11
+17489 Greifswald
+Germany
+
+Contact:
+Website: https://www.uni-greifswald.de
+
+This game (GAIM – Playful EU AI Act Training) is available under the GNU GPLv3 license.
+Source code: https://git.uni-greifswald.de/GAIM/gaim
+
+Disclaimer:
+The content of this game is intended only as an introduction to the basics of AI and the EU AI Act.
+Specific legal questions require professional advice. No liability is assumed for completeness or up-to-dateness.
diff --git a/ai_act_text.tscn b/ai_act_text.tscn
index 5f21523..2cc8320 100644
--- a/ai_act_text.tscn
+++ b/ai_act_text.tscn
@@ -32,7 +32,6 @@ theme_override_constants/outline_size = 3
theme_override_font_sizes/font_size = 58
text = "FLOAT_TEXT"
autowrap_mode = 2
-clip_text = true
[node name="Button" type="Button" parent="."]
layout_mode = 0
diff --git a/assets/Images/de.svg b/assets/Images/de.svg
new file mode 100644
index 0000000..cc2a6a9
--- /dev/null
+++ b/assets/Images/de.svg
@@ -0,0 +1,484 @@
+
+
+
+
+
+
+
+
+
+
+]>
+
diff --git a/assets/Images/de.svg.import b/assets/Images/de.svg.import
new file mode 100644
index 0000000..586cca2
--- /dev/null
+++ b/assets/Images/de.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bvmhojh1ryrdg"
+path="res://.godot/imported/de.svg-73f27f2c310da28e9751fb21dc1126fd.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/Images/de.svg"
+dest_files=["res://.godot/imported/de.svg-73f27f2c310da28e9751fb21dc1126fd.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/assets/Images/us.svg b/assets/Images/us.svg
new file mode 100644
index 0000000..0fa973d
--- /dev/null
+++ b/assets/Images/us.svg
@@ -0,0 +1,703 @@
+
+
+
+
+
+
+
+
+
+
+]>
+
diff --git a/assets/Images/us.svg.import b/assets/Images/us.svg.import
new file mode 100644
index 0000000..861a63a
--- /dev/null
+++ b/assets/Images/us.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cr51lpygo5cxn"
+path="res://.godot/imported/us.svg-8aeb0f994b7f40314a2dc64f50bbfb88.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/Images/us.svg"
+dest_files=["res://.godot/imported/us.svg-8aeb0f994b7f40314a2dc64f50bbfb88.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/global.gd b/global.gd
index b170081..b533191 100644
--- a/global.gd
+++ b/global.gd
@@ -11,3 +11,16 @@ var player_name = "Spieler1"
var chatbot_opened = false
var balloon_collected = false
var resource_balloon = ""
+var locale := ""
+
+
+func _ready() -> void:
+ if locale.is_empty():
+ var os_lang := OS.get_locale_language()
+ locale = "de" if os_lang == "de" else "en"
+ apply_locale(locale)
+
+
+func apply_locale(new_locale: String) -> void:
+ locale = new_locale
+ TranslationServer.set_locale(locale)
diff --git a/project.godot b/project.godot
index 5692de9..d653e52 100644
--- a/project.godot
+++ b/project.godot
@@ -175,7 +175,7 @@ Screenshot={
locale/translations=PackedStringArray("res://translations/en_de_translation.de.translation", "res://translations/en_de_translation.en.translation", "res://translations/en.po")
locale/translations_pot_files=PackedStringArray("res://Interact/dialogue/simple_dialogue.dialogue", "res://Interact/dialogue/contact_info.dialogue", "res://Interact/dialogue/intro.dialogue", "res://Interact/dialogue/ai_v1.dialogue", "res://Interact/dialogue/ai_v4.dialogue", "res://Interact/dialogue/ai_v3.dialogue", "res://Interact/dialogue/ai_v2.dialogue", "res://Interact/dialogue/explain_ordering_game.dialogue", "res://Interact/dialogue/ai_v5.dialogue", "res://Interact/dialogue/helper_intro.dialogue", "res://Interact/dialogue/helper.dialogue", "res://Interact/dialogue/keypad.dialogue", "res://Interact/dialogue/albatross.dialogue", "res://Interact/dialogue/quiz_explainer.dialogue")
-locale/test="en"
+locale/fallback="de"
[layer_names]
diff --git a/title_screen.gd b/title_screen.gd
index f2ebc51..5a0c55b 100644
--- a/title_screen.gd
+++ b/title_screen.gd
@@ -4,18 +4,16 @@ extends Control
@onready var players_turning = [$Panel/SubViewportContainer/SubViewport/Players/Player1/MeshInstance3D,
$Panel/SubViewportContainer/SubViewport/Players/Player2/MeshInstance3D,
$Panel/SubViewportContainer/SubViewport/Players/Player3/MeshInstance3D]
-var locale = ""
+@onready var language_button: Button = $language
+
+const FLAG_DE = preload("res://assets/Images/de.svg")
+const FLAG_US = preload("res://assets/Images/us.svg")
func _ready() -> void:
$AnimationPlayer.play("turning")
- locale = OS.get_locale_language()
- if locale == "de":
- TranslationServer.set_locale(locale)
- else:
- locale = "en"
- TranslationServer.set_locale(locale)
-
+ _update_language_button()
+
func selected_via_click(chosen_player: int) -> void:
player_panel_array[Global.PlayerSelection].get_theme_stylebox('panel').border_color = Color('cccccc')
@@ -34,14 +32,22 @@ func _on_button_2_pressed() -> void:
func _on_button_3_pressed() -> void:
selected_via_click(2)
-
+
func _change_language() -> void:
- if locale == "de":
- locale = "en"
- TranslationServer.set_locale(locale)
+ if Global.locale == "de":
+ Global.apply_locale("en")
else:
- locale = "de"
- TranslationServer.set_locale(locale)
+ Global.apply_locale("de")
+ _update_language_button()
+
+
+func _update_language_button() -> void:
+ # Show the flag of the language you can switch TO
+ language_button.text = ""
+ language_button.icon = FLAG_US if Global.locale == "de" else FLAG_DE
+ language_button.expand_icon = true
+ language_button.custom_minimum_size = Vector2(48, 32)
+
func _on_start_pressed() -> void:
var mesh = players_turning[Global.PlayerSelection].mesh.duplicate()
@@ -61,19 +67,29 @@ func _on_line_edit_text_changed(new_text: String) -> void:
func _on_impressum_pressed() -> void:
$Panel2.visible = true
- $Panel2/Label.text = load_text_file('res://Resources/documents/impressum.txt')
+ $Panel2/Label.text = load_localized_document("impressum")
func _on_datenschutz_pressed() -> void:
$Panel2.visible = true
- $Panel2/Label.text = load_text_file('res://Resources/documents/datenschutz.txt')
+ $Panel2/Label.text = load_localized_document("datenschutz")
func _on_button_pressed() -> void:
$Panel2.visible = false
-
-
-func load_text_file(path: String):
+
+
+func load_localized_document(base_name: String) -> String:
+ var locale := TranslationServer.get_locale().substr(0, 2)
+ var localized_path := "res://Resources/documents/%s_%s.txt" % [base_name, locale]
+ var fallback_path := "res://Resources/documents/%s.txt" % base_name
+ if FileAccess.file_exists(localized_path):
+ return load_text_file(localized_path)
+ return load_text_file(fallback_path)
+
+
+func load_text_file(path: String) -> String:
var file = FileAccess.open(path, FileAccess.READ)
- var content = file.get_as_text()
- return content
+ if file == null:
+ return ""
+ return file.get_as_text()
diff --git a/title_screen.tscn b/title_screen.tscn
index 2b6e312..9f0c45c 100644
--- a/title_screen.tscn
+++ b/title_screen.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=26 format=3 uid="uid://bkxjs7ullu1dr"]
+[gd_scene load_steps=28 format=3 uid="uid://bkxjs7ullu1dr"]
[ext_resource type="Script" uid="uid://crw0j5r7h0f2y" path="res://title_screen.gd" id="1_8vmu4"]
[ext_resource type="ArrayMesh" uid="uid://cnkc0coob8mu" path="res://Resources/meshes/player_uniGW2.tres" id="2_xfn3p"]
@@ -10,6 +10,8 @@
[ext_resource type="Texture2D" uid="uid://bj8jcfeaakxlw" path="res://assets/Images/DataScience_logo_small.png" id="8_wot2p"]
[ext_resource type="Texture2D" uid="uid://b0ym0c3w67rhi" path="res://assets/Gain_Logo_RGB.png" id="9_kvwfe"]
[ext_resource type="AudioStream" uid="uid://cyxaxp30xuhnm" path="res://assets/Sounds/Peachtea - Somewhere in the Elevator.wav" id="10_xfn3p"]
+[ext_resource type="Texture2D" uid="uid://bvmhojh1ryrdg" path="res://assets/Images/de.svg" id="11_flag_de"]
+[ext_resource type="Texture2D" uid="uid://cr51lpygo5cxn" path="res://assets/Images/us.svg" id="12_flag_us"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ak2if"]
bg_color = Color(1, 1, 1, 1)
@@ -422,14 +424,16 @@ texture = ExtResource("9_kvwfe")
[node name="title" type="RichTextLabel" parent="."]
layout_mode = 0
-offset_left = 620.0
+offset_left = 4.0
offset_top = 193.0
-offset_right = 1420.0
+offset_right = 1917.0
offset_bottom = 293.0
theme_override_colors/default_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 3
theme_override_font_sizes/normal_font_size = 58
+bbcode_enabled = true
text = "GAME_TITLE"
+fit_content = true
[node name="welcome" type="RichTextLabel" parent="."]
layout_mode = 0
@@ -439,7 +443,9 @@ offset_right = 1730.0
offset_bottom = 331.0
theme_override_colors/default_color = Color(0, 0, 0, 1)
theme_override_font_sizes/normal_font_size = 32
+bbcode_enabled = true
text = "WELCOME_TEXT"
+fit_content = true
[node name="copyright" type="RichTextLabel" parent="."]
layout_mode = 0
@@ -452,11 +458,14 @@ text = "LICENSE_TEXT"
[node name="language" type="Button" parent="."]
layout_mode = 0
-offset_left = 1445.0
-offset_top = 1017.0
-offset_right = 1610.0
-offset_bottom = 1048.0
-text = "CHANGE_LANGUAGE"
+offset_left = 1520.0
+offset_top = 1005.0
+offset_right = 1600.0
+offset_bottom = 1055.0
+icon = ExtResource("12_flag_us")
+expand_icon = true
+flat = true
+
[node name="impressum" type="Button" parent="."]
layout_mode = 0
diff --git a/title_screen_animation.tscn b/title_screen_animation.tscn
index e15e470..36f765a 100644
--- a/title_screen_animation.tscn
+++ b/title_screen_animation.tscn
@@ -1212,14 +1212,16 @@ texture = ExtResource("6_rbr0u")
[node name="title" type="RichTextLabel" parent="Header"]
layout_mode = 0
-offset_left = 650.0
+offset_left = 4.0
offset_top = 193.0
-offset_right = 1270.0
+offset_right = 1917.0
offset_bottom = 293.0
theme_override_colors/default_color = Color(0, 0, 0, 1)
theme_override_constants/outline_size = 3
theme_override_font_sizes/normal_font_size = 58
-text = "AI Act Explorer GAME"
+bbcode_enabled = true
+text = "GAME_TITLE"
+fit_content = true
[node name="welcome" type="RichTextLabel" parent="Header"]
layout_mode = 0
@@ -1229,7 +1231,9 @@ offset_right = 1730.0
offset_bottom = 331.0
theme_override_colors/default_color = Color(0, 0, 0, 1)
theme_override_font_sizes/normal_font_size = 32
+bbcode_enabled = true
text = "WELCOME_TEXT"
+fit_content = true
[node name="Foot" type="Control" parent="."]
anchors_preset = 0
diff --git a/translations/en_de_translation.csv b/translations/en_de_translation.csv
index 6b208a1..d07d29b 100644
--- a/translations/en_de_translation.csv
+++ b/translations/en_de_translation.csv
@@ -1,11 +1,11 @@
keys,de,en
FLOAT_TEXT,"Seit dem ersten Star Wars Film hat sich die Erde ca. 50 mal um die Sonne gedreht und viel ist seitdem passiert.
-Intelligente Roboter wie R2D2 und C3PO sind keine ferne Science Fiction mehr und Künstliche Intelligenz ist in unserem Alltag angekommen. \n
-Die Europäische Union hat daher das weltweit erste Gesetz zur Regulierung von Künstlicher Intelligenz erlassen, den EU AI Act.\n
+Intelligente Roboter wie R2D2 und C3PO sind keine ferne Science Fiction mehr und Künstliche Intelligenz ist in unserem Alltag angekommen.
+Die Europäische Union hat daher das weltweit erste Gesetz zur Regulierung von Künstlicher Intelligenz erlassen, den EU AI Act.
Dieses Spiel soll Ihnen helfen grundlegende Kenntnisse zu Künstlicher Intelligenz und den Regelungen des EU AI Acts zu erlernen.
Bitte beachten Sie, dass dieses Spiel nur als Einführung dienen kann, konkrete Fragen sind meist nicht allgemein zu beantworten und sollten von einer Fachperson eingeschätzt werden.","Since the first Star Wars movie, the Earth has orbited the Sun about 50 times, and a lot has happened since then.
-Intelligent robots like R2-D2 and C-3PO are no longer the stuff of distant science fiction, and artificial intelligence has become part of our everyday lives. \n
-The European Union has therefore enacted the world's first law regulating artificial intelligence, the EU AI Act.\n
+Intelligent robots like R2-D2 and C-3PO are no longer the stuff of distant science fiction, and artificial intelligence has become part of our everyday lives.
+The European Union has therefore enacted the world's first law regulating artificial intelligence, the EU AI Act.
This game is designed to help you learn the basics of artificial intelligence and the provisions of the EU AI Act.
Please note that this game is intended only as an introduction, specific questions usually cannot be answered in general terms and should be evaluated by a specialist."
START_GAME,Los geht's!,Let's go!
@@ -23,8 +23,8 @@ CHOOSE_TEMPLATE,Vorlage wählen,Choose a template
OPTIONAL_COLORS,(optional: Farben personalisieren),(optional: customize colors)
CUSTOMIZE_COLORS,Farben personalisieren,Customize colors
OR,oder,or
-GAME_TITLE,Spielerisches AI Act Training,Playful AI Act Training
-WELCOME_TEXT,Herzlich Willkommen! Suchen Sie sich Ihre Spielfigur aus und lernen Sie den EU AI Act kennen.,Welcome! Choose your character and learn about the EU AI Act.
+GAME_TITLE,[center]Spielerisches AI Act Training,[center]Playful AI Act Training
+WELCOME_TEXT,[center]Herzlich Willkommen! Suchen Sie sich Ihre Spielfigur aus und lernen Sie den EU AI Act kennen.,[center]Welcome! Choose your character and learn about the EU AI Act.
LICENSE_TEXT,"Verfügbar unter Lizenz GNU GPLv3
https://git.uni-greifswald.de/GAIM/gaim","Available under GNU GPLv3 license
https://git.uni-greifswald.de/GAIM/gaim"
diff --git a/translations/en_de_translation.de.translation b/translations/en_de_translation.de.translation
index 1b7cbfe..f168d60 100644
Binary files a/translations/en_de_translation.de.translation and b/translations/en_de_translation.de.translation differ
diff --git a/translations/en_de_translation.en.translation b/translations/en_de_translation.en.translation
index d5dcdad..62f578a 100644
Binary files a/translations/en_de_translation.en.translation and b/translations/en_de_translation.en.translation differ