svencoop ignores func_train's origin; trigger_createentity and trigger_random not working Created 2 years ago2021-07-30 11:19:40 UTC by kimilil kimilil

Created 2 years ago2021-07-30 11:19:40 UTC by kimilil kimilil

Posted 2 years ago2021-07-30 11:19:40 UTC Post #345815
Hello all!

I'm creating a train map for sven co-op, with lots of func_trains and path_corners. All func_trains have an origin brush each.

Here's a setup of the problem: I'm creating a func_train on the gangway connection between train carriages to simulate the effect of the train wobbling. The origin brush is off to the upper-side corner of the entity for tidiness sake. So are the path_corners that go back and forth; they're on the same y/z axes as the origin brush.
The setup. In the top view you can see the origin brush embedded inside the func_corner's bounding boxex.The setup. In the top view you can see the origin brush embedded inside the func_corner's bounding boxex.
And here's the thing in game:
*facepalm**facepalm*
Very obviously, the game engine decides to completely ignore the origin brush and put the geometric center of the entity to the path_corner. I can confirm that the origin of the entity model exist in the proper place in the BSP.
Origin point (dark gray dot) as rendered in BspguyOrigin point (dark gray dot) as rendered in Bspguy
This is clearly not how a GoldSrc engine is supposed to work. What is going on here? Is there a hidden spawnflag not found in the FGD that causes this? A svencoop cvar or setting that turns off the proper function of entity origins by default? Is there anything else I can do other than reconfiguring every func_train entity so that their geometric center becomes the origin, and move all the path_corners?

This is just one of the issues I'm having right now. some others being:
  • trigger_createentity creating nothing even when target brush entity's +model is properly set. The trigger didn't fail, as the "Trigger after spawn" gets fired.
  • trigger_random working *uck all, to the extent that I resorted to use – that's right – even more path_corners and func_trains to time and randomize things in the map.
Help and/or clarification is much appreciated!

p.s. somebody might have brought this up to the discord, talking about some guy from LambdaGeneration. that's me!
Posted 2 years ago2021-07-30 11:29:33 UTC Post #345816
Somebody did, in fact, bring up func_trains with origins for their iceberg on the TWHL Discord. I believe the map compilers are to blame, because they're the ones which generate a brush model and give the brush entity an "origin" keyvalue to position it.

I'm gonna look at VHLT's source code to see if it does anything counter-productive with func_train.
Admer456 Admer456If it ain't broken, don't fox it!
Posted 2 years ago2021-07-30 11:53:01 UTC Post #345818
Alright, so the problem comes from two things:
  • according to the HL SDK code, the train explicitly sets its position as the centre of its bounding box
  • according to VHLT code, origin brushes do not count towards the bounding box
Maybe you could try using the BOUNDINGBOX tool texture instead of the origin brush:
User posted image
User posted image
Just make sure it's large enough to encompass most of the train, otherwise it'll start disappearing when the boundingbox brush goes outside your FOV, like it did for me:
User posted image
Well, in that instance it works fine, but if I look slightly up, it disappears.

Either way, yeah, this is one hacky workaround you could use.

Edit:
BTW you might wanna describe how exactly you're using trigger_random & trigger_createentity, i.e. post their keyvalues :>
Admer456 Admer456If it ain't broken, don't fox it!
Posted 2 years ago2021-07-30 13:59:18 UTC Post #345820
Thanks for the suggestion. That's certainly a new mechanic that could be useful, but because the original path_corners were set to be out of the way (hidden from view), now the thing is flashing in and out of existence. So, I decided to just do away with origin altogether, and adjusted brushes/paths accordingly. The die is cast.

Now, the next step is to bash my head against the wall to figure out trigger_createentity.
Here be the keyvalues.Here be the keyvalues.
I don't think a basic func_train need any more keyvalues to get working.
Posted 2 years ago2021-07-30 15:02:15 UTC Post #345821
I haven't mapped for SC in a long time, but how are you sure trigger_createentity is creating nothing? In my test map, with basically the same keyvalues as yours (except the rendermode), it created a train at the trigger_createentity's position, but it didn't start moving. Not even triggering made it move. (note: the train had also an origin brush so I could see where it spawned)

I suppose there is a way to make them work, involving a bunch of trigger_changevalue, but depending on what you wanna do, it can evolve into entity spaghetti real quick.

BTW every time you'd shoot at the train, bullethole decals would be duplicated, since all instances are using the same brush model.
User posted image
Not sure how applicable this could be, but I'd personally keep things super simple but slightly more laborious, and have a line of 10 or so trains waiting in a queue in a separate room, to be teleported into action. I think this is something the Sven Co-op Developers Discord could resolve much better.

What about trigger_random?
Admer456 Admer456If it ain't broken, don't fox it!
Posted 2 years ago2021-07-31 07:27:46 UTC Post #345824
how are you sure trigger_createentity is creating nothing?
I have the trigger_createentity in a dev room, and a func_button that triggers it. The trigger_createentity's "Trigger after spawning" is set to fire a game_text. When I press the button, the game_text shows indicating a successful spawn (according to the entity guide).

I've set the created func_train's "First stop target" to a path_corner. The path_corner also have a "trigger on pass" fire a game_text. But this game_text never gets triggered, meaning the spawned func_train didn't do what you think spawned func_trains are supposed to do – to immediately teleport to its first stop target. every path_corner in the entire path_ chain is also set to fire a unique game_text. Those didn't trigger either.
User posted image
And yeah, I couldn't see the created func_train. Not in the dev room where the trigger_createentity is, nor at the targeted path_corner. If the case is that the train's there but invisible the path_corners would tell me with game_texts.

Wrt duplicated decals, it's a nonissue as these would be outside the play area (the "actual train") that players can't reach.
there is a way to make them work, involving a bunch of trigger_changevalue, but depending on what you wanna do, it can evolve into entity spaghetti real quick.
it's already started...it's already started...
As it stands now, the non-working of trigger_random has already resulted in entity spaghetti in the dev room with a bunch of path_corners doing the timing and logic that trigger_random was supposed to do.
keep things super simple but slightly more laborious, and have a line of 10 or so trains
My dude, the train is very long! 16 carriages cut to 4 sections and linked by seamless teleports (at least these work!). If I have the scenery func_trains the same length of each carriage, I'd need 27 to fill the entire outside area. Also, there are overlaps in the 4 sections so at some points in time and space 2 identical func_trains that need to exist in relatively the same areas as seen from the inside. This means I need to keep track of 2 entities for each piece of the scenery. More logic entities!

Here, let me show you the whole map, and NOT super simple and FAR more laborious the alternative is:
User posted image
I'd like to point out that there's one map in scmapdb called build that appear to use trigger_createentity. I downloaded and loaded the map but nothing seems to happen. No boxes that were supposed to be spawned by trigger_createentity gets spawned. Not sure if it needs more players for the map logic to start, or what.
something the Sven Co-op Developers Discord could resolve
Of course, there's a discord! I somehow couldn't find a link to it. [Not to mention the forums were nuked and redirected to an entirely non-condusive steam discussion]

You know, wrangling the engines to work how they're supposed to is frankly fast draining my interest in the project. The only saving grace here and miles around is MESS. I'd win the gold medal in going insane if I had to clone and align the 19 cars every time I change one. (and there's 4 unique cars)
Posted 2 years ago2021-07-31 09:13:04 UTC Post #345825
func_train entities teleport to their first target when their Activate() method is called.

Here's a diagram showing how entities work (from Source but applies to GoldSource as well):
User posted image
Creating entities at runtime won't call Activate(), so they won't teleport. You should make a request to the Sven Co-op team to update trigger_createentity to optionally call Activate() so the entity gets set up properly. Or alternatively making entities like these work properly when spawned at runtime without requiring a separate Activate() call.

As a workaround you could try triggering the train to make it teleport, but i can't guarantee that will work.

You could also try using Angelscript to handle the creation of the trains, then you can call Activate() yourself.
Posted 2 years ago2021-07-31 12:27:33 UTC Post #345828
"I somehow couldn't find a link to it."
Here be the invite: https://discord.gg/hDSrpCDXhD (and if that's expired: https://discord.gg/8VhuRpNt)
"the spawned func_train didn't do what you think spawned func_trains are supposed to do – to immediately teleport to its first stop target"
Solokiller explained it pretty well. In the HL SDK at least, func_train doesn't do anything special in Spawn:
Move train to the "origin" keyvalueMove train to the "origin" keyvalue
Only after all entities have spawned, Activate() is called, which does the actual first path corner logic:
Move train to the target path_corner, align it to the bounding box centre tho'Move train to the target path_corner, align it to the bounding box centre tho'
This here is what effectively "ignores" origin brushes.

Also, in trigger_createentity, you seem to copy the parent train's rendermode. I'm assuming it's anything but Normal. It'd be a good idea to copy renderamt as well, otherwise it'll default to 0, which means invisible.
"it's already started..."
'w'
I gotta say, that's actually quite compact. But, you didn't answer my question: how did you exactly use trigger_random? What was the expected output? What did it (not) do?
Admer456 Admer456If it ain't broken, don't fox it!
Posted 2 years ago2021-08-01 14:32:39 UTC Post #345829
Also, in trigger_createentity, you seem to copy the parent train's rendermode. I'm assuming it's anything but Normal. It'd be a good idea to copy renderamt as well, otherwise it'll default to 0, which means invisible.
This is solved. The entity's rendermode's set to solid, but my trigger_createentity didn't explicitly set the renderamt so it apparently defaulted to 0. I've now added renderamt. and it now shows up as expected, and at the first stop target as it's supposed to.

The problem with triggering the train has also been solved, at long last! Somehow I need to turn it OFF first before I turn it on, using a multi_manager. Or maybe it needs a break in the trigger chain, which the mm provided. Doesn't explain why my delayed trigger_relay doesn't activate it though.

The very final problem now is to figure out how to kill these func_trains, as they don't have unique names, and no trigger entity seem to be able to take !activator for killtarget.
how did you exactly use trigger_random
The map no longer uses trigger_random, so the following setup is a recreation:
  • target count: 3
  • target #: the intended targets
  • minimum delay: the intended delay (say, 1.125)
  • max delay: 0
  • spawnflags: [1] Start on + [8] timed
I kinda don't want to deal with it now that I don't have to.
Posted 2 years ago2021-08-01 15:49:39 UTC Post #345830
The very final problem now is to figure out how to kill these func_trains
Okay, I figured this one out as well!
  1. a trigger_entity_iterator is turned on on map start and iterates over all func_trains of the name I set
    • "Entity's TriggerTarget" set to the following entity
  2. a trigger_condition:
    • monitors the !activating func_train's origin,
    • and compares it to the origin an info_target placed on the map perpendicular to the end of the line
    • comparator check that the monitored func_train had passed the compared info_target on the relevant axis
    • spawnflags:
      • set to ignore other irrelevant axes,
      • cyclic (does its job once on trigger by previous entity),
      • [IMPORTANT] keep !activator
    • set to fire the following entity on true condition
  3. a trigger_changevalue
    • destination entity set to "!activator"
    • change the destination's targetname to a morbid one
    • trigger after action set to the following entity
  4. finally, a trigger_relay set to killtarget the just-renamed entity

All the core issue has been solved! Thanks to everyone who helped me go though this! :heart:

findings:
  1. origin brush is unused in func_train.
  2. when in doubt, "turn it off and on again" (still can't believe this worked!)
  3. thank goodness there's an !activator chain available. It would be way, way easier if more classic entities support !activator directly.
You must be logged in to post a response.