Source-1-Games
Source-1-Games copied to clipboard
TF2 VScript Mega Issue!
Hello! Today we are launching a beta branch of TF2 that has support for VScript in the vscript_test branch.
This is a big issue to collate feedback from Mappers/Server Hosts for the TF2 implementation.
Instead of filing individual issues or feature requests, please post anything related to it in here. Thanks!
Holy hell, amazing! Really looking forward to how this will end up looking like, sounds really promising!
Finally, Bad Apple in Team Fortress 2
Finally, we can have actual NPCs in TF2, not just skeletons, murrrasssmus and headless horseman.
Finally, we can have actual NPCs in TF2, not just skeletons, murrrasssmus and headless horseman.
https://www.youtube.com/watch?v=qTOgDZEuPMg
Linux dedicated server crashes on startup:
AppFramework : Unable to load module vscript_srv.so!
Unable to load interface VScriptManager010 from vscript_srv.so
Dedicated server instance appears to be missing bin/vscript_srv.so.
I'm not familiar with how VScript works, but I assume this is supposed to be working.
(Aside: Do consider having a dedicated issue-tracking repository for this to keep things organized.)
Dedicated server instance appears to be missing bin/vscript_srv.so.
Should be fixed in the next update.
Trying to access netprops, and I'm unable to. I'm also brand spankin new to vscript (started when I heard about this) so here's what I have
function OnPostSpawn() //executes on script load
{
local dispenserobj = SpawnEntityFromTable("obj_dispenser", { teamnum = 3} )
for ( local obj=null; obj = Entities.FindByClassname(obj, "obj_*"); )
{
obj.SetOrigin(Vector(90,3436,294)) //use 'getpos' in console to find a better origin
CNetPropManager.SetPropInt(obj, "m_iHealth", 1)
}
}
The part CNetPropManager.SetPropInt(obj, "m_iHealth", 1) is recognized by the game but spits out [Accessed null instance] and terminates the rest of the script.
@Yakibomb Hello! It looks like something was wrong with registering the singleton instance for netprops in that build. It will be fixed in the next update
@Joshua-Ashton Awesome!! That's fabulous. Also seems like these aren't working ( spits out [Accessed null instance] )
CBaseEntity.GetHealth()
CBaseEntity.GetMaxHealth()
You can't pass a string to a function using RunScriptCode input. This problem was present in other games with VScript too.
function PrintText(strText)
{
printl("Test " + strText);
}
To mark a variable as a string you have to cover it with quotation marks:
As you do this, output formatting gets broken due to quotation marks also being used in VMF to seperate things.
"OnUser1" "!selfRunScriptCodePrintText("Hello");0-1"
https://github.com/mapbase-source/source-sdk-2013/wiki/VScript-in-Mapbase#new-utilities One thing could be done is adding something similar to input above RunScriptCodeQuotable where double apostrophes is replaced by quotation marks during runtime, so it doesn't corrupt the VMF.
It seems that game event callbacks can be registered, but are never actually ran by the engine. Tested on Windows in both a listen server and a dedicated server.
function OnGameEvent_player_hurt( data ) { printl( "OnGameEvent_player_hurt: " + data ) }
__CollectGameEventCallbacks( this )
This works as expected in L4D2 but in TF2 does nothing (calling __RunGameEventCallbacks manually will run the callback function though).
The part
CNetPropManager.SetPropInt(obj, "m_iHealth", 1)is recognized by the game but spits out [Accessed null instance] and terminates the rest of the script.
Convars has the same [Accessed null instance] problem as well.
I'm noticing that the functions CBaseEntity::SetTeam(teamnum), CBaseEntity::GetScriptScope() and CBaseEntity::ValidateScriptScope() appear to be absent here in this implementation of VScript; P2 heavily depends on these functions in order to get choreography working properly. CBaseFlex::GetCurrentScene() also appears to be missing from vscript from further inspection.
OnPostSpawn() in choreo\glados.nut:
// OnPostSpawn - this is all the initial setup stuff
function OnPostSpawn()
{
local i = 0
//assign a unique id to each scene entity (uses SetTeam because that's the only thing available)
foreach (val in SceneTable)
{
i+=1
val.vcd.ValidateScriptScope()
val.vcd.SetTeam(i)
val.index <- i
}
//Initialize the deferred scene queue
QueueInitialize()
PuzzlePreStart()
//Map specific Spawn stuff
switch (curMapName)
{
case "sp_a1_wakeup":
EntFire("@glados","runscriptcode","sp_a1_wakeup_start_map()",1.0)
break
}
}
What happens inside TF2:


CBaseEntity::ConnectOutput crashes the game.
CTriggerCamera script description is missing.
Quick FYI about a long-standing Squirrel VM bug we fixed with L4D2 on April 14th, just to make sure it's gone in TF2:

For over a decade, this very rare and impossible to reproduce bug caused complete VScript failures that led to events, finales, and Mutations to suddenly not work until the map was reloaded. As players run more and more VScripts in TF2, keep this bug in mind, since it was our team's biggest nightmare post-TLS. (Not to be confused with race condition issues that often yielded a similar result, which we've fixed by adjusting the order script runs.)
Convars has the same [Accessed null instance] problem as well.
Yep, I fixed this when I fixed net props. It will also be fixed in the next update.
@Joshua-Ashton Awesome!! That's fabulous. Also seems like these aren't working ( spits out [Accessed null instance] ) CBaseEntity.GetHealth() CBaseEntity.GetMaxHealth()
Are you calling these functions on an actual entity or the class type. Seems like the latter which would give this behaviour.
It seems that game event callbacks can be registered, but are never actually ran by the engine.
Thanks, I will check it out.
nice
Is entity_activator_context necessary now that we have vscript? https://github.com/ValveSoftware/Source-1-Games/issues/3681
Replying to https://github.com/ValveSoftware/Source-1-Games/issues/4481#issuecomment-1304553207
@Joshua-Ashton hey do you guys has this fixed right?
@Joshua-Ashton heyo this is kind of unrelated, but are there any fixes coming for ping spoofing/fake pings in server browser for TF2?
one of communities i regulared just shut down cause competition took their traffic with fake low ping their servers show all ping 10 - 20 and when u join them its actually 300 - 400 in scoreboard
im not tech savvy but its something called anycast with a2s caching they use to spoof ping multiple communities do this and i hate it when i download files for 5 minutes for server with ping 50 then join and realize its 500
Could logic_eventlistener's Fetch Event Data functionality be backported aswell?
11/7/2022 Edit: It appears that the Fetch Event Data functionality does in fact exist in the latest version of the vscript-test branch. However, it doesn't appear in the FGD by default.
Functions that stun and scare players (like on trigger_stun, for example) would be handy to have on the CTFPlayerShared class
Could logic_eventlistener's Fetch Event Data functionality be backported aswell?
There's a script function called __CollectEventCallbacks which allows you to define OnGameEvent_x in any script scope and replicate the behavior of logic_eventlistener including fetching event data, and you can even define multiple events to listen to in one scope. Though as of currently it's not working as stated by AwfulRanger, but in due time it'll be fixed.
Two small things I'll be bringing attention to:
- Current description for
CBaseEntity::GetBaseVelocity()is `"Get Base? velocity", which.. leaves a lot more to be desired. I'd like the description to be this instead:
Get base velocity, which is any constant velocity currently being imparted onto the entity. (e.g. "trigger_push")
This is based off the one from Left 4 Dead 2's list of vscript functions.
CBaseEntity::GetScriptId()does not return the unique identifier stored in the"m_iszScriptId"prop, but instead the name of its current think function.
The following demonstrates this:
::labrat <- Entities.CreateByClassname("point_script_template")
::labrat.ValidateScriptScope()
local scope = ::labrat.GetScriptScope()
scope["dummythinker"] <- function()
{
return 1.0
}
AddThinkToEnt(::labrat, "dummythinker")
// ++ Print ++
// -----------
printl("SCRIPT ID: "+::labrat.GetScriptId())
printl("{")
__DumpScope(1, scope)
printl("}")
The output would be something like this:
SCRIPT ID: dummythinker
{
self = ([0] point_script_template)
__vname = "_4fca_point_script_template"
__vrefs = 1
dummythinker = (function : 0x565F9CC0)
}
Would be appreciated if these were addressed. I also want to give thanks to @Shadowysn for helping me with testing.
As a TF2 mapper, I'm not very familiar with VScript but will it be possible to remove existing attributes from weapons? Or give players weapons with completely custom stats, not just additional attributes.
failed to dlopen /home/steam/TF/bin/vscript_srv.so error=/home/steam/TF/bin/vscript_srv.so: file too short
failed to dlopen vscript_srv.so error=bin/vscript_srv.so: file too short
AppFramework : Unable to load module vscript_srv.so!
Unable to load interface VScriptManager010 from vscript_srv.so
Linux dedicated server is still failing to start, bin/vscript_srv.so is no longer missing but it fails to load.
As a TF2 mapper, I'm not very familiar with VScript but will it be possible to remove existing attributes from weapons? Or give players weapons with completely custom stats, not just additional attributes.
It depends on whether Valve wants TF2 mappers to make inconsistent weapon behavior with the rest of the game on a specific map. It would be incredibly great for custom maps as a whole, but there's eventually gonna be that one mapper who completely changes every weapons' stats and tries to submit it to a seasonal map roster. And with how Wutville got in... (Thinking about it though, this could work for a Halloween map's bonus special effect) The problem I see with it, is how can these new weapon attribute changes be informed to players?
There appears to currently be no way to respawn a player using vscript. Would you mind exposing ForceRespawn() or ForceRegenerateAndRespawn() to VScript?
@Joshua-Ashton Awesome!! That's fabulous. Also seems like these aren't working ( spits out [Accessed null instance] ) CBaseEntity.GetHealth() CBaseEntity.GetMaxHealth()
Are you calling these functions on an actual entity or the class type. Seems like the latter which would give this behaviour.
Ah, I meant calling it via entity. This was fixed in the most recent update. Thank you!
Replying to https://github.com/ValveSoftware/Source-1-Games/issues/4481#issuecomment-1304503077
Can confirm this, also occurs with __CollectEventCallbacks, the non-wrapper function for purely game events only as opposed to both script and game events with __CollectGameEventCallbacks