Getting this error "add_child: Parameter "p_child" is null" and can't seem to track it down - godot

add_child: Parameter "p_child" is null
I suspect this is a Godot editor error because the game runs fine.
This one is hard to describe but basically I have a "memory" card game that runs from a grid. You select your difficulty and then press New Game. The first time, there are no errors but if you win or select "New Game" the errors start piling up and they seem to double each time, maxing out at 100 errors each time you press the new game button.
The only thing on the googles seems to be related to C++ (which that p_child name definitely suggests) but I'm not using C++, I'm using GDScript... this is why I'm thinking maybe it's just an editor error and Godot is just getting confused that I didn't add_child in the C++ way.
Any thoughts?
EDIT
the code generating the errors is this:
func dealDeck():
randomize()
deck.shuffle()
var c = 0
while c < deck.size():
Game.get_node('grid').add_child(deck[c])
c += 1
Game is just a reference to the main scene (/root/Memory) and deck is an array created previously that contains all the cards. I'm 99% sure that the problem isn't in the deck creation.
and to be clear, I am clearing the grid when a new game is started but I have my suspicions that something is going wrong with the whole process (even though the game is working)

Since Godot was written in C++, the errors given in the console are from the C++ side of the editor. This does not mean that your GDScript code is not responsible for the error. It seems like you're trying to add a child to an object but the child you are trying to add is null. This may be due to many reasons. You should start by looking at how you add the cards to your scene when a new game starts. Also, if you could show us some of the code we may be able to help you further.

Related

error: attempt to call function 'is_colliding' in base 'null instance' on a null instance

I've just started making a basic fps in the Godot engine, and I'm currently stuck on making a basic Raycast weapon. I've looked up tutorials from Coding With Tom, Gabaj YT, and multiple others, and yet no matter which one, I always end up writing the same piece of code:
if Raycast.is_Colliding:
and no matter how exactly I copy it down, I always end up with the same error:
error: attempt to call function 'is_colliding' in base 'null instance' on a null instance.
Raycast is a class. And is_colliding is one of its methods. But it is not an static method, you need an instance of Raycast.
Chances are, you do have an instance. If you have been following the tutorials, presumably you have a Raycast node in the scene tree added from the editor, and it is called… let me guess… Raycast. Yes, I do it too. Until it begins to be an issue and I rename it to something more meaningful or go for a different approach, but I digress.
The issue is that you are not referring the Raycast instance. You can reference nodes from your script using $, like this: $Raycast. It is a shorthand for using the get_node method. See Nodes and scene instances. To be clear, what you put after $ is the relative path on the scene tree, so it might not be just the name of the node. Here I'm assuming the node is a direct child of the node that has the script you are writing.
Thus, I would expect code like this:
if $Raycast.is_colliding():
Granted, you will see code that does look like this:
if raycast.is_colliding():
That is because somewhere in the script they have a line that looks something like this:
onready var raycast := $Raycast
Which declares a variable raycast and - on ready - sets it to a reference to the node, and then they can continue using that variable form there. With video tutorials some might skim over that. Here I found it on a Garbaj video on the topic: Godot FPS Hitscan Weapons Tutorial at 1:52

How to force reimport of texture in godot?

I have a sample.png file which is being changed outside godot
and after it's modified, godot recives a signal and when that signal is received
I want that specific sample.png file to be reimported
I tried this answer but I want to reimport in my script itself not create a plugin for it
(atleast that's what I'm assuming it does)
I also tried this from the documents but I'm not sure how to use it exactly
EditorFileSystem.update_file("res://Assets/sample.png")
so how do I achieve the desired result?
The class EditorFileSystem is intended for plugins.
You would call get_editor_interface() from an EditorPlugin (which would be where you would be writing code if you were making a plugin). And that gives you an EditorInterface object, on which you can call get_resource_filesystem() which gives you an EditorFileSystem object.
So the intended use is something like this:
extends EditorPlugin
func example() -> void:
var editor_file_system := get_editor_interface().get_resource_filesystem()
editor_file_system.scan_sources()
# editor_file_system.update_file("res://icon.png")
By the way, EditorInterface also has a filesystem_changed signal. Although I don't know how reliable it is.
Usually you don't have to do that. When you restore the Godot window, it will scan for changes in the project folder. So you might minimize Godot while you are working on something else and when you bring the Godot window back it will pick on the changes.
In practice, the only situations when I had to use scan or scan_sources was when I had a tool script that write a resource file which should be imported, and I wanted it to reflect right away.
Instead of making a custom plugin, I'll remind you that form a tool script (as long as it is running in the editor) you can simply create an EditorPlugin object. For example:
var ep = EditorPlugin.new()
ep.get_editor_interface().get_resource_filesystem().scan()
ep.free()
I had also shared this example in another answer I wrote for you a while back here, it is under the title "About saving resources from tool scripts".

XNA: I only have 1 supported display mode (800x600)

I'm trying to get my game to automatically set the window size as the correct resolution for the monitor.
For example, my desktop PC is at 1920x1080 resolution, so I want my game to run at 1920x1080 on here, however my laptop is at 1366x768 so I want my game to run at 1366x768 on there, etc.
I've tried so many different things such as GraphicsDevice.Adapter.CurrentDisplayMode.Width/Height, and even printed out the list of GraphicsDevice.Adapter.SupportedDisplayModes and they all tell me that the only display mode supported for me is 800x600. This is surely not the case, because I'm running my Windows 7 at 1920x1080.
So what on earth am I doing wrong? I tried putting this code in the Game1 constructor, the initialiser, I can't figure out why it isn't working properly!
Okay I fixed it. I just realised I was being a little bit stupid in that I forgot to mention this a "MonoGame" application, not a straight forward XNA project... (I didn't think it would make a difference but oh I was wrong)..
As it turns out, MonoGame has a massive bug to do with the graphics devices, and there is supposedly a way to solve it (build from the latest source or something?) but what I did was install the XNA 4.0 Refresh for Visual Studio 2013, and copied all my source code across to a new XNA project as opposed to a MonoGame project.
And hey presto, GraphicsDevice.DisplayMode.Width and Height are now correctly registering as 1920 and 1080 pixels. So now I can carry on with my game FINALLY.
Thanks to all the people that tried to help me solve this issue!
You can set the resolution of your game in the constructor by adjusting the graphics' PreferredBackBufferWidth and PreferredBackBufferHeight:
For example this will produce a game window that's 480x320:
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 320;
graphics.PreferredBackBufferWidth = 480;
}
Keep in mind that when in windowed mode your game will (by default) have a title bar which prevents the game window from being as big as your full screen.
This is my method on how to get your maximum supported resolution(and set it, as an example to clarify it):
// in the Initialize method
graphics.PreferredBackBufferWidth = GraphicsDevice.DisplayMode.Width;
graphics.PreferredBackBufferHeight = GraphicsDevice.DisplayMode.Height;
graphics.IsFullScreen = false;
graphics.ApplyChanges(); // <-- not needed in the Game constructor
However, I don't know what you're doing wrong.

wxWidgets application loop slideshow

I have a rather simple problem which I can't seem to solve.
I would like to write a slideshow program that also plays an audio file everytime the slide has changed. This audio files vary in lengths and I do not want to program to loop through the next entry / picture till the sound has finished playing.
Currently I have implemented a loop:
void UI_BRAINWASH::PlaySound_top()
{
wxString tmppath(parent->get_currentdirect()+parent->current_db.get_card(m_index)->get_topentryaudiopath());
ISound* firstsound = this->engine->play2D(tmppath.mb_str(), false, false, true);
while(engine->isCurrentlyPlaying(tmppath.mb_str()))
{
StaticTextTop->GetParent()->Update();
//wxSleep(3);
}
m_timer->Start(1000);
}
and this loops through the entries as expected and everything is dandy...
However, I would like, to be able to abort the programm by pressing the Escape amongst other things, but the while loop obviously hinders me from doing exactly that.
I also noticed that I can't move my window or close the programm while it is looping through the pictures.
So I have looked at threads and the wxIdleevent class. in: wxwidgets/samples/threads/ is an example of a "workers thread", which seems to be what I need.
My question now is: are threads not a bit of an overkill for a simple slideshow?
Is there another / better way of looping through my entries - waiting for the sound to have played, updating the gui and also being able to still move the window around?
What is engine?
Most APIs for playing sounds provide the ability to start playing a sound-file and then return immediatly. They will send an event when the sound is finished. They will also provide a call to interrupt a sound that is still playing. This is what you want.
You should check the docs for whatever API you are using and find this feature. If the feature is not available, than you need to find another API that does - most do.

WinRT - Windows Store - WinRT Originate Error - How do decipher such an error?

I'm working on a Windows Store app and I'm getting a WinRT error that doesn't really give me any information so I would like to know how to understand these sorts of errors.
Basically I get the error on the following line which is called inside OnPointerPressed:
m_gestureRecognizer->ProcessDownEvent(args->GetCurrentPoint(nullptr));
The error is:
First-chance exception at 0x76F54B32 (KernelBase.dll) in DXAML2.exe: 0x40080201: WinRT originate error (parameters: 0x80070057, 0x00000044, 0x03CEE72C).
This error didn't used to appear, the only thing I've changed is that this line is now wrapped in an if clause which tests if the current pointer's PointerId is the same as one I've stored just using == such as:
if(args->GetCurrentPoint(nullptr)->PointerId == m_UIPointerID)
I have no idea why this has started happening.
So my question is in two parts:
More generally, how do I understand what an error such as the above means?
And does anyone know this error has suddenly started happening now that I check the pointerId?
Thanks for your time.
P.S. I guess another thing that has changed is that there will already be 2 pointers on the screen (the one that gets pushed into this GestureRecognizer) as well as another one, hence the PointerId check.
"How to Decipher such an error"...
For any WinRT originate error, you can take the third address in the parameters list (in your example, 0x03CEE72C), and find a description of your error in the memory window.
While debugging, break when your error is thrown and open the memory window via Debug -> Windows -> Memory -> Memory 1
Copy and paste the address to get your "easy-to-find" error message.
As Raman said - it's good to look up the hex values shown. The first one is the memory location which won't tell you much without the symbols/source, which in this case is reported directly by Windows. Perhaps the public symbols can shed some more light on where the error came from, but the error code lookups are more helpful.
If you Bing for 0x80070057 you will find an MSDN article on Common HRESULT Values which lists
E_INVALIDARG : One or more arguments are not valid : 0x80070057
It doesn't give you all the details of course, so you're off to theorize. Perhaps you can only call args->GetCurrentPoint(nullptr) once and you should store/reuse the value? Maybe gesture recognizer is not configured correctly? Maybe the app window is not visible at the time the exception is thrown or the thread is wrong. Maybe some expected calls to gesture recognizer were missed due to filtering those out with these "if" statements.

Resources