Just as I documented my creation process in the godot project forums. I am documenting my porting process from godot to defold.
1/3/2021 I reproduced the main menu in Defold.
my struggles: Trying to add gui- my dyslexia had me misreading “add component from file” as "add component".
I read every tutorial on gui’s I could find after an hour of this I went back to the gui tutorial and read it backwards (I tricked I learned as sci fi editor years ago) and discovered my mistake. The rest of the menu took me about ten minutes. It would have been 5 minutes but I had to learn I call the node not the parent in my event input.
I am very happy though.
The screenshot with blue buttons is godot, the screenshot red buttons is defold.
Added music
Added options menu
rewrote gui
added gui to individual go’s
But I worked on this most of the night:
Collection Proxies and gui collection
challenge:
could not get child gui to show because main gui was on top.
2nd could not get child gui to receive focus
SO I read probably 2 dozen posts tutorials and responses by Britzl. I found it fascinating he doesnt always use the same solutions but goes a variety of ways based on the person he was chatting with.
How I fixed the problem:
added the 2 gui collections to2 children game objects of main game object this immediately fixed the view problem.
the focus problem was more tricky and took a lot reading- but finally Britzl wrote somewhere I have to pass focus to the the new collection after load and enabled and also at collection init or startup .
The node messaging back and forth is new to me but its interesting to think of the nodes as people working together via messages.
I also found that the addressing can be touchy- if I ctrl z- it can actually affect nodes not in view such as node names or script assignments. I use crtl z alot and so this caused probs till I realized what was happening. Im getting there.
This is mentioned in the Input manual but it is not very prominent. I rearranged the content a bit and made sure to give the section on collection proxies more visibility (it should be available in a minute or two):
There is usually more than one way to solve a problem and I might not be consistent over time.
Let us know if you get stuck! Loading and unloading collections usually requires you to track a bit of state and pay attention so you don’t try to load or unload the same thing twice.
There are assets in the Asset Portal that can help with this, but I recommend that you learn how collection proxies work before leaving that up to an asset!
if gui.pick_node(closeButton, action.x, action.y) then
print('closebutton')
msg.post(".", "disable")
msg.post(".", "unload")
end
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_unloaded") then
print(' Ok, the world is unloaded...')
else
print(message_id)
end
send this message:
INFO:DLIB: SSDP: Started on address 192.168.0.11
DEBUG:SCRIPT: closebutton
DEBUG:SCRIPT: hash: [disable]
DEBUG:SCRIPT: hash: [unload]
INFO:DLIB: SSDP: Done on address 192.168.0.11
so that it never gets the proxy_unloaded message
and of course throws this error on reload:
ERROR:GAMESYS: The collection /main/OptionsMenu.collectionc could not be loaded since it was already. Message 'load' sent from main:/go#MainMenu to main:/go#OptionsMenuProxy.
To my ignorant eyes this should work but it doesnt. I read several of your other posts on this forum about this same issue and to me it looks like should work.
The snippet of code you shared doesn’t look complete. I don’t see the end of the on_input() function, which makes me thing that function on_message() is declared inside the on_input() function.
if gui.pick_node(closeButton, action.x, action.y) then
print('closebutton')
msg.post(".", "disable")
msg.post(".", "unload")
end
end -- <-- this was missing!
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_unloaded") then
print(' Ok, the world is unloaded...')
else
print(message_id)
end
I dont think there’s an end missing I pulled the full script file:
We are only looking at the “close” button the others just exit for now.
function init(self)
msg.post(".", "acquire_input_focus") --message to self to get focus of all input
end
function on_input(self, action_id, action)
if action_id == hash("touch") and action.pressed then --get mouse button input
local closeButton = gui.get_node("close") -- these five sections check to see which button is clicked then do code- as place holder exit game
if gui.pick_node(closeButton, action.x, action.y) then
print('closebutton')
msg.post(".", "disable")
msg.post(".", "unload")
end
local soundONButton = gui.get_node("soundON")
if gui.pick_node(soundONButton, action.x, action.y) then
msg.post("@system:", "exit", {code = 0})
end
local soundOFFButton = gui.get_node("soundOFF")
if gui.pick_node(soundOFFButton, action.x, action.y) then
msg.post("@system:", "exit", {code = 0})
end
local musicONButton = gui.get_node("musicON")
if gui.pick_node(musicONButton, action.x, action.y) then
msg.post("@system:", "exit", {code = 0})
end
local musicOFFButton = gui.get_node("musicOFF")
if gui.pick_node(musicOFFButton, action.x, action.y) then
msg.post("@system:", "exit", {code = 0})
end
end
end
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_unloaded") then
print(' Ok, the world is unloaded...')
else
print(message_id)
-- do things
end
end
Oh, hold on. It seems like you are unloading the collection from a script within the collection. This is not recommended since everything, including your own script will stop running when you disable and unload the collection through the proxy.
Loading and unloading collections should be handled from outside the collection. Usually from some kind of central scene/screen handler.
Hmm that makes sense Ill try that. In the other engines I use you its preferred to delete a scene or object from inside that object I figured it was same here.
BTW Are you the same bjorn thats in the youtube videos demonstrating and talking about defold?
My problems were basically I just needed a main collection with loader GO and a controller script to load and unload levels / collections. The collection I was trying to unload needs a 3rd party collection to perform these calls, or it deletes itself and the address. All the messages are sent to where the collection was loaded- kinda like writing your self a letter to delete yourself but continue working after youve deleted yourself!
In my flowcharts I am seriously thinking of using people avatars to represent these message interactions.
I was trying to do it from within the scripts of the levels I was trying to unload. I actually did not realize that any node can send a message to anywhere in the game.
Until I found a forum post discussing that as well as the manual entry and the wonderful tutorials.
I dont actually cut and paste tutorials I read / watch them and then try build something different the principles to see if I understand. save for small snippets I usually retype the code.
Luckily I love stuff like this. So no screenshot but remade my progress from scratch. So Im back where I was, but now its working.
In Defold unloading a collection proxy is different from deleting a game object. There is for instance nothing wrong with using go.delete() in an enemy.script to delete the enemy itself. But unloading a collection like you did will not work since you are unable to react to the proxy_unloaded message.
Yes I am!
Yep your own description of the situation is spot on!
Oh, that was probably Oleg. He used to work with Defold as a developer evangelist and he is in several YouTube videos. I’m not in nearly as many as Oleg.
Hmm Ive been getting a lot of java errors- Im thinking its my computer.
I hit a weird road bump with libraries that I am about to tackle now that I have some direction from the library creator. I also need to create my game’s logo.
So today I first started by recreating my studio logo and created my splash startup collection:
and 3 animations:
* start: a transparent frame, play=none ,
* forward: playing animation= forward,
* backwards: playing animation= backwards.
timer called timer_0.
II added the game object and sprite and atlas to both collections and set z to 1, and set their default animation as start. So it gives me a transparent frame as timer counts down.
in starting scene I created a function that set a timer the length of the animation, when timer finished I changed scenes via collection proxy and on the initialization of the next scene I played the backwards animation.
So the lines close over the first collection, the scene changes, and the then the lines retract off the second collection.
I know there are scene handlers that do transitions and this isnt as flashy, but it was a simple solution for me.