Welcome to Office Hours, it's your weekly half hour segment where I answer questions
about Neos.
We go ahead and get questions answered based on the questions and the order that they appear
inside the thread, so get those questions entered into that thread, and I'll get them
not answered in the order that they appear in.
If you're not sure what's going on, check the Office Hours check chat, the chat is above
the one you're currently in.
Looking at the list we have a few questions lined up, so go ahead and get those answered
whilst I try and find my English language inside my brain.
Spex asks, "Now that MMC is done this year, what's on your plate for Neos things?
Got any projects you're waiting to get into?"
Not really, just the same projects that existed that were kind of just delayed by MMC.
I got to the end of last week, sort of Sunday, which is yesterday, no day before yesterday,
and I sort of thought like, "I haven't done anything this week!" and then I looked and
was like, "Um, no, you kind of, you know, ran the voting for the rest of the weekend,
that's last weekend, or weekend before last, sorry, time is confusing."
You know, ran the voting, judged the entries, rehearsed the award show, went to the award
show, like lots went on, it just didn't feel like it did, so I was productive last week.
But yeah, that's all over now, so back on other things.
As a reminder for those who don't know what the MMC is, or even those that do, even if
you won, lost, entered, didn't enter, whatever it is, just remember that the stuff that is
created at the MMC can be created at any point during the year, you don't need the MMC as
an excuse to make it, so carry on making cool stuff in EOS, I love seeing it.
Moving forwards to the next question there, which is from Lex, who says "When silencing
a user through the sessions tab, the one that mutes a user for everyone, does that user's
voice audio stream stop being transmitted, or does it set the volume to zero?"
I don't know, I'd have to open the codebase and go take a look, I'll go ahead and get
that open, and then I'll dig back into it when I get a chance, as we go through the
normal ebb and flow of questions.
Unnamed Cyborg Cat says "Ever heard of Copy Kitty?
It's an amazing game the devs worked on very hard on, super underrated."
I have not.
I have like 1,800 games on Steam, and like 2,000+ on my wishlist, so probably it's on
there, I don't know though.
And with that, all the questions are over, I'm gonna mute Tech Humongous, Tech Humongous
scops of water, and then I'll be back.
And I'm back, there are no additional questions, if you have additional questions drop them
in the office hours texture, I'll get to them in the order that they appear in, whilst there
are no questions I'm just gonna sit here and think about cheese.
You'll be pleased to know my Amazon order has shipped, I don't know what it is, I don't
remember what it is.
What shipped?
I don't know, I'll figure that out later.
I was just reading the code on silence, looks like it will actually prevent the audio from
being transmitted, don't quote me, do your own testing, but based on my limited understanding
of how that works, it won't write to the value stream.
We have a question here from UnnamedCyborgCat, who says "Does Nio support any proprietary
mobile formats in the Source Engine?"
So the Nio's wiki has a list of stuff which people have looked at, and sort of work-ish.
Some of the problem here is that we, it's like, what we support isn't entirely up to
us, it's more up to Asimp, which we use to import assets.
If it's supported by those, then it will sometimes work.
Sometimes there's extra work we have to do once Asimp has handed it to us, but you can
see a list there.
Is that an alphabetical?
Yeah, that's an alphabetical.
Alphabetical.
It's difficult because things like FBX are technically proprietary, so yeah, BS supports
a proprietary file format, FBX is technically proprietary.
Don't use FBX, by the way.
I read this question like three times before unmuting it, so I'll just go ahead and read
it again and then think about it some more.
Lex asks "Why does setting the parent of a slot using the set parent node of an invalid
or null to slot parents the from slot to root?"
Set parent with an invalid to parents the from slot to root.
I mean, it should just cancel the operation.
I also wish more nodes had failure states.
Let me take a look here.
What I want is more nodes to have on failure, so if it pulsed with onFail coming out of
set parent, then it would be good to do that.
The new parent will default to the root slot if you pass in null or an invalid value.
I think a lot of this is just like various sort of hacky patches that we've been doing
over the years to try and prevent null parents from happening.
Anywhere that touches the slot hierarchy model, we try and basically interject and say "hey,
you're about to null parent this, don't do that!"
No, don't do that.
The behavior change that you're requesting where it doesn't do that is something that
would be cool.
Unfortunately it would also be a somewhat breaking change though, because it would increase
the amount of times where the set parent node wouldn't do something.
Like ran out, it would basically not do something if the thing you're trying to parent is null,
or if the new parent is a child of the target object, so you can't put something inside
itself.
In those cases it won't output failure, it will just literally do nothing, there will
be no output.
I hate nodes that don't have an output, because it's just very difficult to operate with.
It just defaults to world root if there's a problem.
Rampa says "nulling parent should just make nears destroy stuff, it has no parent so it
can't exist."
No not really, so while you, and I say you with a bunch of people who write mods in here
that know I'm wrong, but generally speaking, you are only able to access one hierarchy,
which is the world root hierarchy.
There are other hierarchies of slots and other types of components, and other lists and other
tree-based systems that exist outside of that system that some of this stuff operates in,
and so it's incorrect to say that if it's outside of the world root, it should be deleted.
It's kind of correct to say that it should be deleted if it doesn't have a parent, but
then again we should try and correct that rather than deleting it.
Your MMC project accidentally parents itself to null.
Yeah we delete it instead of trying to save your work for you and send it back to the
world root.
It's one of those things where it's like, this is gonna, yeah, um, I, Lex says "people
who are intentionally using that to parent things to root, or people who have different
logics to catch an unintentional root parent shouldn't be doing that."
Yeah, they shouldn't be doing that.
In fact if you're using root slot and you're not the owner of the world, I question your
motives.
Always use local user space, it is for the most part the world root, but in those one
few cases where you have world management systems using local user space, will keep
those world management systems more performant and easier to use.
So local user space.
Local user space returns the parent of the user who is running the set parent operation.
There is usually no downside of using local user space, I can think of a couple of cases
but only in world management systems where that might be problematic, so just use local
user space.
The amount of guns, RPGs, rocket launchers, grenades, bows and arrows, rifles, crossbows,
drink systems I see that are just like "cool, because I'm inconsiderate, I'll parent a bunch
of stuff to root when people use me."
It's like "cool, how about no."
So yeah, do think about that.
If you have a gun that produces, I should say entities, in a more traditional gaming
sense, like for those who are unaware, most guns in games are non-entity producing, so
they do bullets, and yeah sure bullets have animations, muzzle flash, smoke, explosions,
that sometimes traces the line that they take etc.
Those don't produce additional entities in the world, there's basically sort of a hitscan
with various complexities depending on what type of game it is.
Guns that produce entities are things like grenades, rocket launchers, the Needler from
Halo would be another good example.
They add additional stuff to the world when they are fired.
Crossbow and bow and arrow being a good sense, it sticks an entity to you.
Like a big rifle doesn't stick a world entity to the person, a bow and arrow does.
Which is kind of strange, because all weapons leave residue, guns leave impacted bullets
and casings and stuff like that.
I've never really seen a game make use of casings, sometimes they'll fall on the floor
but usually they're particle systems so they'll clear up after a bit, but I dunno, maybe it'll
be funny in a random shooting game, you start tripping over yourself if you stand still
for too long and start firing, you just can't keep your feet still when there's like casings
rolling under your feet.
Casings are usually quite easy to squish though, like dropping a bag of marbles on the floor
but just because you've been firing in the same place for too long.
Specs, actually let's go through a couple of comments here, so, Rampus says "the only
thing I can imagine not using user space is death effect".
No, user space should still work, because it'll parent above the user, not in the user.
If your world management system deletes the slot pertaining to the user when they leave,
then yes though, depends what's going on.
And test those, like extremely test them, it's difficult to test something where it's
like "when I leave the world, do something I can't see", because you're gone, but you
know what I mean, be careful.
Lex says "it's always funny when I see people using custom parenting systems to attach to
someone, then de-parent themselves to what a parent or parent thought they were in, and
get deleted when the user they previously parented to leaves".
Yeah, I've seen that happen a lot.
Virtual parent might be a solution there, if you know that it might be an unstable user
connection who might leave.
Specs says "there's a lot of cases where I've seen folks rely on uninitialized behaviour
and logics like that, and I have to admit it makes me wince.
No should users specifically initialize logics nodes with values instead of relying on default
behaviour that may change at any moment, unless a node is like a specifically duplicated design
to have an initial value that has some promise not to change without notice".
Yeah, nulls are terrible.
I am quite liking nullables in some C# projects I'm in right now, but it's just really annoying
like how much it comes up.
If you look it up, there's various articles, various quotes, various versions of it.
Someone in the computing world invented null, and they regret it.
I don't remember exactly who it was, it was either, I don't remember the name, it was
one of the big computer people from early on in computing.
It's the same thing with, the easiest way to identify null is if you look at a boolean.
So a boolean has true or false, on or off, yes or no, whatever you want to say.
But then with null, you introduce a third state of boolean, which is "I don't have a
value", and that's what null means in that case, "I don't have a value".
And that's perfectly fine to be used as "I don't know" or "I don't have a value because
I'm not initialised yet", but make that a value in your program.
Make the value be "I am initialised", not "I am null".
A good example of that comes up is in the sort of task-based system that C# has.
You have to wait for a task to complete, that's great.
Instead you could have written that and C# developers would have had hate about it, where
whilst you're waiting for a web request to happen, you have to while loop over the result
of that web request and check if it's not null, and you'd be like "Ah, it's happened!"
Instead they made this whole task system where it's like "Has the task completed?
The task has completed, here is the task's result".
And so it's like sort of implicitly built into the API that null doesn't occur, even
though it still does when people do tasks that return null for some reason.
When you're programming you should always be wondering "What do I do when X Y Z happens?
What do I do when X Y Z happens?"
If the code is telling you there's a possibility that null could exist here, you need to handle
it.
Like "Oh, the result of this method operation could be null, what are we going to do about
that?"
Same thing with objects though, we need more onFails.
What if the parenting fails, I need to know about it.
Yeah I don't like people who do that.
I always add the default of 0 anyway and people question why and I say "Well, it's there,
I can change it if I need to, I don't usually need to, but I also find it a little bit easier
to sort of compute in my head when I can see the default value, otherwise I have to remember
extra information, not only what the default value is, but is the default value acceptable
for that occurrence?"
For those who are like "Well I don't like adding the default value because that's an
extra slot", just go away.
Like it's one extra slot, come on.
I mean in most cases it will default to 0.
In cases where we have changed the default value of something, we are able to upgrade
logics to inject the old default value.
We did that once with findChildByName or something like that.
Say for example, I don't know, the inputs to + default to 0, let's say they change to
1, for some ungodly reason, the world would be quite screwed up for that to happen.
But we would basically, when we load your logics back in, we would detect "Hey you haven't
specified a default, so we will default this to 0".
And preserve the old behavior by automatically injecting a 0 input node for you, and that
way you'll be fine.
It might be the divide node, let me see, div float, nah, I forgot about that, yeah.
The divide nodes will allow divide by 0 errors, I forgot about that.
That's why we have the filter invalid node, to get rid of those cases where you have an
invalid value.
I always put, or try to, I often forget, I try to put filter invalid in places where
a 0 might occur with user input.
For example if there's a form field where they're entering a number, if they need to
clear out all of the number to enter their new number, then it might, for an update or
two, it might have a 0 in it.
And a couple of times that stung me and broken something, because I don't expect there to
be a 0 there, so filter invalid helps with that.
For example the value graph recorder, or it might be the graphing mesh, can't remember
which, it doesn't like if the number of values that it can store is less than 2.
It has to be 2 or greater, or it breaks and disables itself.
>> Are there any additional questions?
We've got about 5 minutes left in this office hours segment, we could talk about much more
programming stuff for a long time, or we could, any questions that happen, go for them.
Whatever you feel like.
>> Whilst I wait for questions.
There's a TV show on Netflix called Shadow and Bone, I don't know what it's called.
Shadow and Bone, yeah there we go.
Shadow and Bone.
I was quite enjoying it until they literally resolved the entire storyline in the finale.
Like there were a couple of episodes in the middle of the first season where nothing was
happening, and in the last episode an entire season worth of content happens and I'm just
like, "Guys, this isn't how you end a season."
You know, it's just like, "Oh yeah, it's mid-season episode, the characters have a cup of tea."
End of the season.
The characters travel halfway across the world, defeat the big baddie, throw the ring into
Mordor, and go home.
Very annoying.
>> So Lex asks, "Would you possibly know when closing a session, sometimes it doesn't happen,
immediately it takes a few seconds to kick everyone and then close."
I think it's resolving stuff.
There's stuff it has to resolve.
Like for example if you're saving the world, that's going to add extra time to it closing
of course, but if you're not saving the world, there's got to be something that's resolving.
I'd have to look into it.
There's got to be something that's preventing it from closing, some sort of process that
needs to finish or something.
>> Nationwide asks, "Why do sessions that have been open for about three days start
to get all funky?
Do my headless pack all logics into the world into a single random thought?"
It did that by itself, or did it do that when you next tried to pack logics?
That sounds like it shouldn't...
I can understand if it's funky how you packed it.
Yeah, so after about three days, numbers start getting weird.
Like I know tea has issues, but I haven't really worried about that.
Like if you see tea getting issues, it's like you're doing something wrong probably.
So input tea will get funky after a little while.
I don't remember exactly how long, but it's basically when floating point imprecision
takes over and the value of tea starts getting funky if you use tea for everything.
Then maybe it ran out of like...
I don't know if it ran out of references or something?
I don't know why that would happen.
Dynamic impulses should be fine as well.
I'd have to look into the numbers involved with packing.
It's by sure a number problem.
It just doesn't look like it.
It's something...
We have one more question.
So I was distracted by reading through the logics to see what was going on there.
Ishimwade asks, "one more very quick, does the headless client have a memory leak?"
It's possible that the entirety of Neos has a memory leak.
Sometimes I have to remind people, and I get all the circumstances and everything, I'm
not here to talk about them, but I'm here to state facts.
When it comes to the headless client, you are playing with an alpha pre-release of a
feature for an early access beta video game.
So yeah, it's possible it has a memory leak.
All right, that is half past and I don't see any more questions coming.
So I'm going to go ahead and leave things there.
As a reminder, if you have questions, please feel free to direct message them, drop them
in the questions and help channel, or send a carrier pigeon my way.
I'll get to them as soon as I can and I will speak to you guys next week