أصبح الذكاء الاصطناعي موجودًا في كل مجال ويستفيد منه المطورون لتسريع عملهم وتحقيق نتائج أفضل. وسنعرفكم في مقال اليوم على خطوات تطوير أداة ذكية باستخدام OpenAI تُمكّن مطوري الألعاب من دمج الذكاء الاصطناعي مع محرك الألعاب جودو Godot والاستفادة منها في تحسين الشيفرات البرمجية للألعاب.
فوائد دمج OpenAI مع محرك الألعاب جودو
يمكننا الحصول على فوائد عديدة من دمج منصة الذكاء الاصطناعي OpenAI مع محرك الألعاب جودو ومن أبرزها ما يلي:
تلخيص الأكواد
من خلال تطوير أداة تربط بين محرك جودو و OpenAI، سنتمكن من تلخيص الأكواد البرمجية المتتابعة بسهولة وبضغطة واحدة على زر Summarize. توفر هذه الميزة الكثير من الوقت والجهد، لاسيما عندما نتعامل مع شيفرات برمجية معقدة ومتشابكة ونرغب في تبسيطها وفهمها بسرعة.
تنفيذ إجراءات على الكود
أليس من الرائع أن نتمكن من إعطاء محرر الأكواد أمرًا بكتابة دالة أو وظيفة معينة، أو نطلب منه إعادة كتابة كود دالة ما بطريقة أكثر احترافية؟ هذه واحدة من أهداف الأداة التي سنطورها، فهي تساعدنا على كتابة وتنقيح الكود البرمجي من داخل محرر الأكواد مباشرة.
مساعدة مطور الألعاب
تساعدنا أداة التكامل بين محرك ألعاب جودو ومنصة الذكاء الاصطناعي OpenAI في توفير شرح مفصل للأكواد التي لا نفهمها أو التي نواجه مشكلات فيها، كل ما علينا هو تظليل الكود المطلوب والضغط على زر help وستتولى الأداة توفير شرح نصي واضح يساعدنا على فهمه وتحليل المشكلة التي تواجهنا.
التواصل مع مفتاح واجهة برمجة التطبيقات
تسمح لنا هذه الأداة بالتواصل المباشر مع واجهة برمجة التطبيقات OpenAI API، أي إنها تسمح لنا بالتواصل مع كافة النماذج Models القوية التي توفرها OpenAI وسؤالها عن أي شيء ضمن الكود من داخل محرر الأكواد نفسه، ويساعدنا ذلك على استكشاف الثغرات وتنقيحها وتحسين أكوادنا البرمجية.
بعد أن تعرفنا على فائدة الأداة التي سنطورها لجودو، لننتقل الآن لشرح عملية التطوير خطوة بخطوة.
الحصول على مفتاح الواجهة البرمجية OpenAI API
أول خطوة سنبدأ بها لتطوير أداة التكامل بين جودو وOpenAI هي الحصول على مفتاح واجهة برمجة التطبيقات من موقع OpenAI، فإن لم يسبق لنا استخدام خدمات OpenAI من قبل فعلينا بداية إنشاء حساب جديد في OpenAI وتسجيل الدخول، والانتقال إلى حسابنا الخاص في الموقع، ثم الضغط على زر View API Keys كما في الصورة التالية:
نحتاج الآن إلى توليد مفتاح واجهة برمجة تطبيقات جديد وذلك بالضغط على زر Create new secret key، ثم تسمية المفتاح بأي اسم مناسب ونسخه.
البدء مع جودو Godot
الخطوة التالية هي إعداد الإضافة Plugin الخاصة بأداتنا داخل محرك الألعاب جودو، وذلك ببدء مشروع جديد، ثم فتح إعدادات المشروع Project Settings، ثم الدخول إلى إضافات Plugins وإنشاء إضافة جديدة Create New Plugin.
نسمِّي الإضافة باسم مناسب مثل Godot GPT Integration، ونحدد المجلد الفرعي res://addons/GPT_Integration
، ونكتب اسم المطور في الحقل author، ونجعل رقم النسخة 1.0، وأخيرًا نختار لغة المشروع لتكون GDScript، كما يمكن اختيار لغة #C ولكن في هذا الحالة لن يتمكن المستخدم من تثبيت الإضافة في الإصدار العادي من جودو وسيحتاج لنسخة Godot Mono.
بعد الانتهاء من ملء البيانات المطلوبة نضغط على زر أنشئ Create، ستنشأ إضافة محرر Editor Plugin، وإضافات المحرر هي أدوات إضافية تعمل أثناء تشغيل محرر جودو لمساعدة المطورين على كتابة الشيفرات بسهولة.
إنشاء واجهة المستخدم
ننتقل لتطوير واجهة الأداة والتي ستكون مشهد ثنائي الأبعاد يضم صندوق محادثة Chat Box، وحقل نصي Text Field، ومكونات أخرى كما في الصورة أعلاه. لتصميم هذه الواجهة علينا اتباع الخطوات التالية:
ننتقل للتبويب مشهد من داخل محرك جودو، وننشئ عقدة تحكم رئيسية Control ونعدِّل اسمها إلى Chat، ثم نضغط بزر الفأرة الأيمن على المنطقة الفارغة في تبويب المشهد، ونختار إضافة عقدة فرعية Add Child Node. ستظهر مجموعة من الاختيارات لتحديد نوع العقدة الفرعية، نختار TextEdit، ثم نحدد العقدة الفرعية ونبحث في قائمة الفاحص عن خاصية Anchor Preset في قسم Layout والتي تحدد مكان العقدة داخل المشهد، سنحدد خيار على كامل المستطيل Full Rect ثم نضبط حجم العقدة بشكل مناسب، فهذه العقدة ستكون صندوق الدردشة الذي سنتواصل منه مع نموذج OpenAI.
بعدها نضيف عقدة فرعية أخرى من نوع Button، ثم نضبط الخاصية Anchor Preset لها بالقيمة Bottom Right أي في الأسفل يمينًا، ثم نعدّل أبعاد الزر وأخيرًا نعدل خاصية نص الزر Text إلى Chat، ثم نضيف عقدة فرعية جديدة أخرى نوعها TextEdit، ونحدد الخاصية Anchor Preset لها في الأسفل يمينًا لتكون أسفل يمين الواجهة، ونحدد أبعادها ونجعلها أعلى زر Chat.
بعد ذلك نضيف عقدة فرعية نوعها حاوية HBoxContainer، ونحدد مكانها ضمن Anchor Preset إلى القيمة Bottom Wide أي بالعرض بالأسفل، ثم نضبط أبعادها، بعدها ننقر بالزر الأيمن على العقدة ونضيف لها ثلاث عقد فرعية من نوع Button، ثم نعدل أسماء تلك الأزرار إلى Summary و Action وHelp ونحدد الأزرار الثلاثة وننتقل إلى Layout ومنها إلى Container Sizing ونختار Expand و Fit كي تتوسع هذه الأزرار وتتناسب مع الحاوية HBoxContainer.
أخيرًا نضبط قياسات صندوق الدردشة ومنطقة تحرير النصوص لتتناسب مع أحجام الأزرار، ويمكن إضافة عقدة فرعية من نوع HSeparator لأسباب جمالية، وفيما يلي الشكل الذي ستظهر عليه شجرة العقد ضمن المشهد:
بعد الانتهاء من تصميم الواجهة، سنحفظها في ملف باسم chat.tscn، والآن صارت واجهتنا جاهزة لبدء كتابة الأكواد البرمجية اللازمة لعمل الإضافة.
أولاً، سنحتاج إلى إنشاء متغير يمثل كائن ضندوق الدردشة الذي سننشؤه داخل محرك جودو، سنسمي هذا المتغير chat_dock
. بعد ذلك، سنقوم بإنشاء الكائن وإضافته إلى مكان مناسب في واجهة محرك جودو. وهنا سنختار وضعه في تبويب علوي بجانب تبويب المشهد، ولكن يمكنك اختيار أي مكان نفضله. بمجرد أن نقوم بذلك، يجب أن نرى تبويبًا جديدًا باسم Chat في محرر Godot يمثل نافذة الدردشة الخاصة بنا كلما قمنا بتفعيل الإضافة وسيختفي عند إلغاء تفعيلها.
سيبدو تبويب إضافة الدردشة ضمن محرك جودو بالشكل التالي:
إعداد الكود البرمجي
حان دور كتابة الكود البرمجي لأداتنا والذي سيوفر تكاملًا مع الواجهة البرمجية OpenAI API، نبدأ بوراثة الصنف EditorPlugin
، وتعريف بعض المتغيرات والثوابت، كالآتي:
@tool extends EditorPlugin const MySettings:StringName = "res://addons/GPTIntegration/settings.json" enum modes { Action, Summarise, Chat, Help } var api_key = "" ## put the API key here var max_tokens = 1024 # How many tokens can you use to generate your response var temperature = 0.5 # how "crazy" you want it to be var url = "https://api.openai.com/v1/completions" # the open api url var headers = ["Content-Type: application/json", "Authorization: Bearer " + api_key] var engine = "text-davinachi-003" # What engine you want to use var chat_dock var http_request :HTTPRequest var current_mode var cursor_pos var code_editor var settings_menu
عرَّفنا في هذه الشيفرات الثابت MySettings
، والذي يشير إلى ملف JSON الذي سنخزن فيه إعداداتنا، كما عرفنا متغير modes
الذي يسمح للأداة أن تعمل بأساليب مختلفة فهو متغير من نمط تعدادي enum يعرّف الأوضاع التي يمكن أن تتواجد فيها الإضافة وإن كانت ستُنفذ إجراءً محددًا، أو تلخص نصًا، أو ستجري محادثة مع المستخدم، أو توفر مساعدة.
أنشأنا كذلك المتغيرات api_key
و max_tokens
و tempreture
و url
و header
و engin
المسؤولة عن التفاعل مع واجهة برمجة تطبيقات OpenAI، وعرفنا أيضًا متغيرات chatdock
و http_request
و cursor_pos
و current_mode
و codeeditor
وsettings_menu
وهذه المتغيرات مسؤولة عن التفاعل مع محرك جودو
.
الدخول للشجرة
عند الدخول إلى شجرة المشهد، سنعرض تبويب الدردشة chat dock الذي يتضمن صندوق الدردشة، وإضافته بجانب تبويب المشهد وربط الأزرار في صندوق الدردشة بالوظائف الخاصة بها. كما نرغب في إضافة عنصر إلى قائمة الأدوات Tool Menu لعرض الإعدادات. إليك كيفية القيام بذلك:
func _enter_tree(): print('_enter_tree') chat_dock = preload("res://addons/GPTIntegration/Chat.tscn").instantiate() add_control_to_dock(EditorPlugin.DOCK_SLOT_LEFT_UR, chat_dock) chat_dock.get_node("Button").connect("pressed", _on_chat_button_down) chat_dock.get_node("HBoxContainer/Action").connect("pressed", _on_action_button_down) chat_dock.get_node("HBoxContainer/Help").connect("pressed", _on_help_button_down) chat_dock.get_node("HBoxContainer/Summary").connect("pressed", _on_summary_button_down) add_tool_menu_item("GPT Chat", on_show_settings) load_settings() pass
نبدأ في هذا الكود بتحميل نافذة الدردشة في التبويب chat dock، ثم نستنسخه ونضيفه إلى التبويب العلوي الأيسر -بجانب تبويب المشهد- بعد ذلك، نحصل على عقد الأزرار Button
و Action
و Help
و Summary
من نافذة الدردشة ونربطها حدث الضغط عليها بالدوال المناسبة on_chat_button_down
و on_action_button_down
و on_help_button_down
و on_summary_button_down
على التوالي. كما نضيف عنصرًا في قائمة الأدوات باسم GPT Chat الذي يستدعي الدالة on_show_settings
عند النقر عليه. وأخيرًا، نستدعي الدالة load_setting
لتحميل الإعدادات من ملف JSON.
الخروج من الشجرة
عند الخروج من شجرة المشهد، سنحتاج لإزالة تبويب نافذة الدردشة chat dock الذي أضفناه في الخطوة السابقة مع حفظ الإعدادات، كما يلي:
func _exit_tree(): remove_control_from_docks(chat_dock) chat_dock.queue_free() remove_tool_menu_item("GPT Chat") save_settings() pass
نُزيل في هذه الشيفرة كل ما يتعلق بإضافة روبوت المحادثة ثم نضعه ضمن المحذوفات، كما نُزيل التبويب GPT Chat، وأخيرًا نستدعي الدالة save_settings
لحفظ إعدادات الإضافة إلى ملف JSON.
معالجة أحداث الضغط على الأزرار
الآن لنعالج ضغطات أزرار الأداة، فحين نضغط على زر Chat مثلًا نريد أن ترسل الأداة طلبًا إلى نموذج OpenAI بالنص أو المُوجّه prompt المكتوب في المساحة النصية TextEdit، وفيما يلي كيفية تنفيذ ذلك:
func _on_chat_button_down(): if(chat_dock.get_node("TextEdit").text != ""): current_mode = modes.Chat var prompt = chat_dock.get_node("TextEdit").text chat_dock.get_node("TextEdit").text = "" add_to_chat("Me: " + prompt) call_GPT(prompt)
فحصنا بالكود أعلاه إن كانت العقدة TextEdit غير فارغة وتتضمن مُوجّه Prompt مكتوب للتواصل مع نموذج الذكاء الاصطناعي، ففي هذه الحالة نضبط الإضافة إلى الوضع Chat، ثم نستنسخ النص ونضعه في الصياغة Me: prompt
ليظهر بهذه الصياغة في واجهة المستخدم، ثم نحذف النص من TextEdit، ونستدعي الدالة call_GPT
ونمرر لها المُوجّه الذي نود إيصاله إلى نموذج OpenAI.
ننتقل بعد ذلك إلى معالجة حدث الضغط على زر Action نود أن نرسل إلى نموذج OpenAI طلب لتنفيذ الأمر المكتوب على الشيفرات المحددة، وفيما يلي كيفية تنفيذ ذلك:
func _on_action_button_down(): current_mode = modes.Action call_GPT("Code this for Godot " + get_selected_code())
حوَّلنا في الشيفرات السابقة وضع الملحق إلى Action، ثم استدعينا الدالة call_GPT
مع إعطائها المُوجّه prompt الذي نرغب في تنفيذه.
وبعد ذلك نعالج حدث الضغط على زر Help، حيث نرغب بالحصول على شرح للأكواد المحددة عند الضغط عليه، ولتنفيذ ذلك نكتب:
func _on_help_button_down(): current_mode = modes.Help var code = get_selected_code() chat_dock.get_node("TextEdit").text = "" add_to_chat("Me: " + "What is wrong with this GDScript code? " + code) call_GPT("What is wrong with this GDScript code? " + code)
بدَّلنا في هذه الشيفرات وضع الإضافة إلى Help، ثم أضفنا المُوجّه المكتوب في TextEdit وفق الصياغة Me: prompt
الظاهرة في واجهة المستخدم، ثم حذفناه من العقدة TextEdit واستدعينا الدالة call_GPT
لترسل الأمر إلى OpenAI للمساعدة في فهم الشيفرات المحددة.
وأخيرًا، نعالج حدث الضغط على زر Summary نود من نموذج OpenAI أن ترسل تلخيصًا للشيفرات المختارة، وذلك كما يلي:
func _on_summary_button_down(): current_mode = modes.Summarise call_GPT("Summarize this GDScript Code " + get_selected_code())
استبدلنا وضع الأداة إلى Summarise، ثم استدعينا الدالة call_GPT
ومررنا لها مُوجِّه لتلخيص الأكواد المحددة.
معالجة الاستجابة
الآن، لنعالج استجابات الطلبات التي حصلنا عليها من OpenAI وسنفعل ذلك باستخدام الدالة on_request_completed
. وسنعتمد على الوضع الحالي للأداة فهل هو Chat أو Summarise أو Help أو Action لنحدد فيما إذا كنا سنضع الإجابة التي حصلنا عليها في مساحة الدردشة بالروبوت أم ضمن أكواد المحرر مباشرة.
func _on_request_completed(result, responseCode, headers, body): print(result, responseCode, headers, body) var json = JSON.new() var parse_result = json.parse(body.get_string_from_utf8()) if parse_result: printerr(parse_result) return var response = json.get_data() if response is Dictionary: print("Response", response) if response.has("error"): print("Error", response['error']) return else: print("Response is not a Dictionary", headers) return var newStr = response.choices[0].text if current_mode == modes.Chat: add_to_chat("GPT: " + newStr) elif current_mode == modes.Summarise: var str = response.choices[0].text.replace("\n" , "") newStr = "# " var lineLength = 50 var currentLineLength = 0 for i in range(str.length()): if currentLineLength >= lineLength and str[i] == " ": newStr += "\n# " currentLineLength = 0 else: newStr += str[i] currentLineLength += 1 code_editor.insert_line_at(cursor_pos, newStr) elif current_mode == modes.Action: code_editor.insert_line_at(cursor_pos, newStr) elif current_mode == modes.Help: add_to_chat("GPT: " + response.choices[0].text) pass
نحلل في الكود أعلاه الاستجابة التي حصلنا عليها من OpenAI ونتحقق مما إذا كانت عبارة عن قاموس dictionart، فإذا كانت كذلك سنستخرج النص من الاستجابة، وفي حال كان الوضع الحالي المحدد في الأداة هو Chat نضيف النص إلى الدردشة مع وضع البادئة GPT. وإذا كان الوضع الحالي هو وضع Summarise فسندرجه في محرر الأكواد كنسخة ملخصة من الكود المحدد بحيث لا يتجاوز طول كل سطر 50 حرفًا ويبدأ كل سطر برمز # ، وإذا كان الوضع الحالي هو Action، سندرج نص الاستجابة في محرر الأكواد مباشرة. أما إذا كان الوضع الحالي هو Help فسنضيف نص الاستجابة إلى الدردشة مع البادئة GPT.
حفظ وتحميل الإعدادات
لنعمل الآن على حفظ إعدادات الإضافة عن طريق الدالة save_settings
حيث سننشئ ملف JSON يحتوي قيم المتغيرات api_key
maxtokens
و maxtokens
وengine
، ونحدد المجلد res://addons/GPTIntegration
لتخزين هذا الملف، بعدها نحمّل الإعدادات من خلال الدالة load_settings
التي تفتح الملف JSON وتستخرج بياناته وتعين قيم المتغيرات api_key
maxtokens
و maxtokens
وengine
بناء عليها وفيما يلي كيفية تنفيذ ذلك:
func save_settings(): var data ={ "api_key":api_key, "max_tokens": max_tokens, "temperature": temperature, "engine": engine } print(data) var jsonStr = JSON.stringify(data) var file = FileAccess.open(MySettings, FileAccess.WRITE) file.store_string(jsonStr) file.close()
أنشأنا في الشيفرات السابقة قاموسًا يضم المتغيرات api_key
maxtokens
و maxtokens
وengine
، ثم حولنا هذا القاموس إلى تنسيق JSON، ثم فتحنا ملف JSON على وضع الكتابة وحفظنا فيه البيانات ثم أغلقناه.
func load_settings(): if not FileAccess.file_exists(MySettings): save_settings() var file = FileAccess.open(MySettings, FileAccess.READ) if not file: printerr("Unable to create", MySettings, error_string(ERR_CANT_CREATE)) print_stack() return var jsonStr = file.get_as_text() file.close() var data = JSON.parse_string(jsonStr) print(data) api_key = data["api_key"] max_tokens = int(data["max_tokens"]) temperature = float(data["temperature"]) engine = data["engine"]
فحصنا في الشيفرات السابقة ما إذا كان ملف الإعدادات موجودًا، فإن لم يكن موجودًا سنستدعي الدالة save_settings
لإنشائه، ثم فتحنا الملف وضع القراءة واستدعينا البيانات المخزنة فيه واستخرجنا القيم المناسبة لضبط المتغيرات api_key
maxtokens
و maxtokens
وengine.
الكود الكامل لإضافة جودو
فيما يلي الكود النهائي الكامل لأداتنا التي تضيف ميزات الذكاء الاصطناعي لمحرر ألعاب جودو:
@tool extends EditorPlugin const MySettings:StringName = "res://addons/GPTIntegration/settings.json" enum modes { Action, Summarise, Chat, Help } var api_key = "" var max_tokens = 1024 var temperature = 0.5 var url = "https://api.openai.com/v1/completions" var headers = ["Content-Type: application/json", "Authorization: Bearer " + api_key] var engine = "text-davinachi-003" var chat_dock var http_request :HTTPRequest var current_mode var cursor_pos var code_editor var settings_menu func _enter_tree(): printt('_enter_tree') chat_dock = preload("res://addons/GPTIntegration/Chat.tscn").instantiate() add_control_to_dock(EditorPlugin.DOCK_SLOT_LEFT_UR, chat_dock) chat_dock.get_node("Button").connect("pressed", _on_chat_button_down) chat_dock.get_node("HBoxContainer/Action").connect("pressed", _on_action_button_down) chat_dock.get_node("HBoxContainer/Help").connect("pressed", _on_help_button_down) chat_dock.get_node("HBoxContainer/Summary").connect("pressed", _on_summary_button_down) # Initialization of the plugin goes here. add_tool_menu_item("GPT Chat", on_show_settings) load_settings() pass func on_show_settings(): settings_menu = preload("res://addons/GPTIntegration/SettingsWindow.tscn").instantiate() settings_menu.get_node("Control/Button").connect("pressed", on_settings_button_down) set_settings(api_key, int(max_tokens), float(temperature), engine) add_child(settings_menu) settings_menu.connect("close_requested", settings_menu_close) settings_menu.popup() func on_settings_button_down(): api_key = settings_menu.get_node("HBoxContainer/VBoxContainer2/APIKey").text max_tokens = int(settings_menu.get_node("HBoxContainer/VBoxContainer2/MaxTokens").text) temperature = float(settings_menu.get_node("HBoxContainer/VBoxContainer2/Temperature").text) var index = settings_menu.get_node("HBoxContainer/VBoxContainer2/OptionButton").selected if engine == "text-davinchi-003": index = 0 elif index == 1: engine = "code-davinci-002" elif index == 2: engine = "text-curie-001" elif index == 3: engine = "text-babbage-001" elif index == 4: engine = "text-ada-001" elif index == 5: engine = "code-cushman-002" settings_menu_close() pass func settings_menu_close(): settings_menu.queue_free() pass # This GDScript code sets the settings in a settings # menu. It sets the API key, the maximum number of tokens, # the temperature, and the engine. The engine is set # by selecting the corresponding ID from a list of options. func set_settings(api_key, maxtokens, temp, engine): settings_menu.get_node("HBoxContainer/VBoxContainer2/APIKey").text = api_key settings_menu.get_node("HBoxContainer/VBoxContainer2/MaxTokens").text = str(maxtokens) settings_menu.get_node("HBoxContainer/VBoxContainer2/Temperature").text = str(temp) var id = 0 if engine == "text-davinchi-003": id = 0 elif engine == "code-davinci-002": id = 1 elif engine == "text-curie-001": id = 2 elif engine == "text-babbage-001": id = 3 elif engine == "text-ada-001": id = 4 elif engine == "code-cushman-002": id = 5 settings_menu.get_node("HBoxContainer/VBoxContainer2/OptionButton").select(id) func _exit_tree(): # Clean-up of the plugin goes here. remove_control_from_docks(chat_dock) chat_dock.queue_free() remove_tool_menu_item("GPT Chat") save_settings() pass func _ready(): http_request = HTTPRequest.new() add_child(http_request) http_request.connect("request_completed", _on_request_completed) func _on_chat_button_down(): if(chat_dock.get_node("TextEdit").text != ""): current_mode = modes.Chat var prompt = chat_dock.get_node("TextEdit").text chat_dock.get_node("TextEdit").text = "" add_to_chat("Me: " + prompt) call_GPT(prompt) func call_GPT(prompt): var body = JSON.new().stringify({ "prompt": prompt, "temperature": temperature, "max_tokens": max_tokens, "model": "text-davinci-003" }) var error = http_request.request(url, ["Content-Type: application/json", "Authorization: Bearer " + api_key], HTTPClient.METHOD_POST, body) if error != OK: push_error("Something Went Wrong!") func _on_action_button_down(): current_mode = modes.Action call_GPT("Code this for Godot " + get_selected_code()) func _on_help_button_down(): current_mode = modes.Help var code = get_selected_code() chat_dock.get_node("TextEdit").text = "" add_to_chat("Me: " + "What is wrong with this GDScript code? " + code) call_GPT("What is wrong with this GDScript code? " + code) func _on_summary_button_down(): current_mode = modes.Summarise call_GPT("Summarize this GDScript Code " + get_selected_code()) # This GDScript code is used to handle the response from # a request and either add it to a chat or summarise # it. If the mode is set to Chat, it will add the response # to the chat with the prefix "GPT". If the mode is set # to Summarise, it will loop through the response and # insert it into the code editor as a summarised version # with each line having a maximum length of 50 characters # and each line starting with a "#". func _on_request_completed(result, responseCode, headers, body): printt(result, responseCode, headers, body) var json = JSON.new() var parse_result = json.parse(body.get_string_from_utf8()) if parse_result: printerr(parse_result) return var response = json.get_data() if response is Dictionary: printt("Response", response) if response.has("error"): printt("Error", response['error']) return else: printt("Response is not a Dictionary", headers) return var newStr = response.choices[0].text if current_mode == modes.Chat: add_to_chat("GPT: " + newStr) elif current_mode == modes.Summarise: var str = response.choices[0].text.replace("\n" , "") newStr = "# " var lineLength = 50 var currentLineLength = 0 for i in range(str.length()): if currentLineLength >= lineLength and str[i] == " ": newStr += "\n# " currentLineLength = 0 else: newStr += str[i] currentLineLength += 1 code_editor.insert_line_at(cursor_pos, newStr) elif current_mode == modes.Action: code_editor.insert_line_at(cursor_pos, newStr) elif current_mode == modes.Help: add_to_chat("GPT: " + response.choices[0].text) pass func get_selected_code(): var currentScriptEditor = get_editor_interface().get_script_editor().get_current_editor() code_editor = currentScriptEditor.get_base_editor() if current_mode == modes.Summarise: cursor_pos = code_editor.get_selection_from_line() elif current_mode == modes.Action: cursor_pos = code_editor.get_selection_to_line() return code_editor.get_selected_text() func add_to_chat(text): var chat_bubble = preload("res://addons/GPTIntegration/ChatBubble.tscn").instantiate() chat_bubble.get_node("RichTextLabel").text = "\n" + text + "\n" chat_dock.get_node("ScrollContainer/VBoxContainer").add_child(chat_bubble) #chat_dock.get_node("RichTextLabel").text += "\n" + text + "\n" # This GDScript code creates a JSON file containing the # values of the variables "api_key", "max_tokens", "temperature", # and "engine", and stores the file in the "res://addons/GPTIntegration/" # directory. func save_settings(): var data ={ "api_key":api_key, "max_tokens": max_tokens, "temperature": temperature, "engine": engine } print(data) var jsonStr = JSON.stringify(data) var file = FileAccess.open(MySettings, FileAccess.WRITE) file.store_string(jsonStr) file.close() # This GDScript code opens a JSON file, parses the data # from it, and assigns the values to variables. The variables # are api_key, max_tokens, temperature, and engine. func load_settings(): if not FileAccess.file_exists(MySettings): save_settings() var file = FileAccess.open(MySettings, FileAccess.READ) if not file: printerr("Unable to create", MySettings, error_string(ERR_CANT_CREATE)) print_stack() return var jsonStr = file.get_as_text() file.close() var data = JSON.parse_string(jsonStr) print(data) api_key = data["api_key"] max_tokens = int(data["max_tokens"]) temperature = float(data["temperature"]) engine = data["engine"]
الخاتمة
عملنا اليوم على تطوير أداة تكامل بين محرر جودو والنماذج اللغوية لشركة OpenAI، ننصح بتجربة تنفيذ هذه الأداة والاستفادة منها في تنفيذ مهام عديدة أثناء تطوير الألعاب، بدءًا من كتابة الشيفرات، مرورًا بتلخيصها، وصولًا إلى شرحها وغيرها من الوظائف المفيدة.
ترجمة -وبتصرف- لمقال Building a Godot Engine Tool Script for Interacting with OpenAI
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.