Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TF2 VScript Mega Issue! #4481

Open
misyltoad opened this issue Nov 5, 2022 · 174 comments
Open

TF2 VScript Mega Issue! #4481

misyltoad opened this issue Nov 5, 2022 · 174 comments

Comments

@misyltoad
Copy link

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!

@unclamped
Copy link

Holy hell, amazing! Really looking forward to how this will end up looking like, sounds really promising!

@vrad-exe
Copy link

vrad-exe commented Nov 5, 2022

Finally, Bad Apple in Team Fortress 2

@Trico-Everfire
Copy link

Finally, we can have actual NPCs in TF2, not just skeletons, murrrasssmus and headless horseman.

@Batfoxkid
Copy link

Finally, we can have actual NPCs in TF2, not just skeletons, murrrasssmus and headless horseman.

https://www.youtube.com/watch?v=qTOgDZEuPMg

@nosoop
Copy link

nosoop commented Nov 5, 2022

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.)

@misyltoad
Copy link
Author

Dedicated server instance appears to be missing bin/vscript_srv.so.

Should be fixed in the next update.

@Yakibomb
Copy link

Yakibomb commented Nov 5, 2022

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.

@misyltoad
Copy link
Author

@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

@Yakibomb
Copy link

Yakibomb commented Nov 5, 2022

@Joshua-Ashton Awesome!! That's fabulous. Also seems like these aren't working ( spits out [Accessed null instance] )

CBaseEntity.GetHealth()
CBaseEntity.GetMaxHealth()

@RealBerke
Copy link

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:
resim
As you do this, output formatting gets broken due to quotation marks also being used in VMF to seperate things.
"OnUser1" "!self�RunScriptCode�PrintText("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.

@AwfulRanger
Copy link

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).

@Shadowysn
Copy link

Shadowysn commented Nov 5, 2022

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.

@pivotman319-owo
Copy link

pivotman319-owo commented Nov 5, 2022

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:
VScript error, blaming Validate Script Scope

VScript error, blaming Set Team

@samisalreadytaken
Copy link

CBaseEntity::ConnectOutput crashes the game.

CTriggerCamera script description is missing.

@Tsuey
Copy link

Tsuey commented Nov 5, 2022

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:

image

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.)

@misyltoad
Copy link
Author

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.

@samzanemesis
Copy link

nice

@Ashetf2
Copy link

Ashetf2 commented Nov 5, 2022

Is entity_activator_context necessary now that we have vscript? #3681

@FriskTheFallenHuman
Copy link

FriskTheFallenHuman commented Nov 5, 2022

Replying to #4481 (comment)

@Joshua-Ashton hey do you guys has this fixed right?

@ghost

This comment was marked as off-topic.

@horiuchii
Copy link

horiuchii commented Nov 5, 2022

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.

@ghost
Copy link

ghost commented Nov 5, 2022

Functions that stun and scare players (like on trigger_stun, for example) would be handy to have on the CTFPlayerShared class

@Shadowysn
Copy link

Shadowysn commented Nov 6, 2022

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.

@orinuse
Copy link

orinuse commented Nov 6, 2022

Two small things I'll be bringing attention to:

  1. 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.

  1. 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.

@SnowshoeIceboot
Copy link

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.

@Gamecube762
Copy link

 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.

@Shadowysn
Copy link

Shadowysn commented Nov 7, 2022

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?

@UndefinedBHVR
Copy link

There appears to currently be no way to respawn a player using vscript. Would you mind exposing ForceRespawn() or ForceRegenerateAndRespawn() to VScript?

@Yakibomb
Copy link

Yakibomb commented Nov 7, 2022

@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!

@Shadowysn
Copy link

Shadowysn commented Nov 8, 2022

Replying to #4481 (comment)

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

@Lizard-Of-Oz
Copy link

Another HUD-related feature request. The ability to force Vanilla HUD on the client.

A lot of players use Custom HUDs, and certain gamemodes might change the HUD so much, the best option would be to force the Vanilla HUD for that particular map.

While HUD customization is important for many, there's a point at which one would prefer to play with Vanilla HUD on that particular map, instead of having their Custom HUD overlap with the gamemode's new HUD elements.

@Ashref2002
Copy link

Is there currently a way to grab somebody's steam name?
I'd like to do some fun stuff like displaying "MYNAME has entered the trigger" text and other stuff.

honestly I wouldn't mind if it wasn't possible, just the implementation of Vscript itself is already God-sent.
Your work won't leave unappreciated.

@ChampionCynthia
Copy link

@MrSaturnGaming2002

Is there currently a way to grab somebody's steam name? I'd like to do some fun stuff like displaying "MYNAME has entered the trigger" text and other stuff.

There is no dedicated function, but you can grab a player's nickname through the m_szNetname netprop.

Here is an example that prints the nickname of all players on the server to the console:

local ply = null
while( ply = Entities.FindByClassname( ply, "player" ) )
{
    local name = NetProps.GetPropString( ply, "m_szNetname" )
    // Do stuff with the name…
    printl( name )
}

@Ashref2002
Copy link

Ashref2002 commented Jan 22, 2023

Replying to #4481 (comment)

That actually works, I'm impressed.

@treacherousfiend
Copy link

If possible, could some MVM populator stuff be made available? Pop files seem to be a very powerful tool but the only access to it Vscript has appears to be limited to the netprops for the enemies shown on the MVM hud, the name of the popfile, and standard CBaseEntity data for some populator related point entities.

While in theory these limitations could be worked around by writing a pop file reader in vscript, that would be limited by FileToString()'s 16KB limit on files, which many base game pop files already go well over, not to mention the sheer work involved in trying to recreate a pop file reader when the game already has one.
Plus, thats just the work required for reading pop files, let alone using them or potentially editing them on the fly.

@Lizard-Of-Oz
Copy link

Lizard-Of-Oz commented Jan 26, 2023

Feature request: filter_vscript. Works like an other filter entity (e.g. https://developer.valvesoftware.com/wiki/Filter_tf_class), but it calls a vscript function for a filtering condition.

A usecase example: triggers created from within vscript can only be rectangular, but a filter could allow to filter the players within a sphere.

@treacherousfiend
Copy link

treacherousfiend commented Jan 30, 2023

mini feature request: GetAreasWithTFAttributes function for CNavMesh. Likely due to being a different set of constants, GetAreasWithAttributes only works with default source engine nav mesh attributes, so the only way currently to get these areas is to manually iterate through all of the areas and use the HasAttributeTF function

Edit: CNavArea also has the function GetAttributes, which just gets the bits of all nav attributes, but does not have an equivalent GetAttributesTF function

@TheShermanTanker
Copy link

@Joshua-Ashton Is there a way to set the value of the underlying attribute classes directly without having to go through an attribute? (Eg like set_weapon_mode for example) If there isn't, would love if the ability to do so was added, since that would circumvent the troubles of defining custom attributes and all

@kamuixmod
Copy link

Saw in the Squirrel documentation (https://developer.electricimp.com/squirrel/squirrelcrib#program-control) that foreach is a thing but i can't find the function that gets me the player list. Do i have to use "Iterating Through Players" as noted in (https://developer.valvesoftware.com/wiki/TF2_VScript_Examples)?

for (local i = 1; i <= Constants.Server.MAX_PLAYERS; i++)
{
    local player = PlayerInstanceFromIndex(i)
    if (player == null) continue
    printl(player)
}

@Lizard-Of-Oz
Copy link

[Important BUG] It seems like OnTakeDamage hook is bugged (looked up - yep, it was and still is) - it doesn't account for damage fall-off/ramp-up and crit_type is always 0 regardless if damage is crit-boosted or not.

@Ashref2002
Copy link

Bumping this thread solely for this one request:

Please, add hud_deathnotice_time to the list inside vscript_convar_allowlist.

Currently Killfeed is covering my custom screen overlay and m_Local.m_iHideHUD isn't useful this time.
I tried editing the position of the feed inside hudlayout.res but that would mean forcing everyone to use the exact same hud layout just for a slight change so I don't want that either.
Thanks and please help.

@Lizard-Of-Oz
Copy link

Feature request: if the respawn time goes above a certain number (perhaps, 500 seconds) it should get replaced with "Respawning is not available".
Would be useful for gamemodes with no respawn which don't want to bring the rest of the Arena mechanics alongside it.

@Lizard-Of-Oz
Copy link

Lizard-Of-Oz commented Mar 15, 2023

Wanted to make Arena's Victory Panel appear mid-round. While you can make Normal Victory Panel appear mid-round by firing a teamplay_win_panel event, it does not work for arena_win_panel specifically.
Would like to use the Arena Panel (which displays damage and healing) for my custom gamemode (VS Saxton Hale) which can't be true arena for complicated reasons.

@Lizard-Of-Oz
Copy link

Feature request: would like to see player_loadoutchange event that fires when the game coordinator tells the game server that a player has changed their loadout, regardless if said player was forcerespawned or not (player_spawn triggers only when a player did forcerespawn).
Was trying to make the entire map act as a resupply room during setup, while also allowing for engineer buildings (which func_respawnroom doesn't allow for).

Alternatively/in addition would like to see a spawnflag for func_respawnroom which determines if it should act as a func_nobuild or not.

@rsedxcftvgyhbujnkiqwe
Copy link

rsedxcftvgyhbujnkiqwe commented May 5, 2023

Feature request - I am not sure how feasible this is given the codebase, but being able to generate (and hook off of) entirely custom game events would be invaluable. Not only would this help code coordination across a map, but it would give an easy avenue for sourcemod plugins and vscript to interact with eachother. As far as I am currently aware, only existing game events can be created.

@Lizard-Of-Oz
Copy link

Feature request. If custom VGUI support will be added, I can imagine people wanting to replace the class and team selection screens. There is no way to disable these menus and/or detect when a player wants to open a menu.
I can imagine these 2 menus (class and team selection screens) being the prime desired points of customization for custom gamemodes to look legit.

@Brain-dawg
Copy link

mp_restartgame and mp_restartgame_immediate are vscript whitelisted cvars, while mp_restartround is not

This cvar has a few differences compared to restartgame, notably it interacts with team_round_timer differently, and displays text on everyone's screen saying when the round will restart.

@Lizard-Of-Oz
Copy link

Feature request: The ability to add string attributes for weapons and players.
We can current add float attributes with CEconEntity#AddAttribute and CTFPlayer#AddCustomAttribute respectively, but not the attributes which require string

@horiuchii
Copy link

horiuchii commented Jun 2, 2023

Bug: scripts/vscripts/mapspawn.nut doesn't seem to get called on map spawn. Using script_execute to try and call it results in nothing aswell.
Tested with both a simple print function and a event hook inside the file.

Apologies, a file in a custom folder was taking priority without me realizing.

@Brain-dawg
Copy link

RefillAmmo/RegenerateAmmo function, behaves identically to Regenerate() except does not refill health. Alternatively add a bool argument to Regenerate() to toggle this functionality.

@silbinarywolf
Copy link

silbinarywolf commented Aug 12, 2023

Bug: Using mp_waitingforplayers_cancel 1 in console will stop OnGameEvent_teamplay_round_start from firing and working as expected.

To be more specific, when you either use this command manually in the console or fire it from VScript code while waiting and seeing the timer go down, OnGameEvent_teamplay_round_start won't fire.

@worMatty
Copy link

It'd be nice to be able to set m_flDamage of tf_projectile_rocket.

@WereTech
Copy link

The delay params on EmitSoundEx do not work. Using flags = 16 along with delay = 1.0 or sound_time = 1.0 does not work at all, and sound_time doesn't allow the sound to play at all.

@kstf2
Copy link

kstf2 commented Sep 11, 2023

On a listen server with SourceTV enabled (tv_enable 1), there are various bugs with VScript global functions and console commands:

Bug 1 (UTIL_GetListenServerHost):

  • Global VScript function SendToConsole() is broken
  • Global VScript function GetListenServerHost() returns the handle for the SourceTV bot rather than the player

Bug 2 (UTIL_IsCommandIssuedByServerAdmin):

  • VScript console commands such as script, script_execute or script_help do not work

The reason SendToConsole() is broken is because it relies on UTIL_GetListenServerHost(), which returns the player at a hard-coded entity index of 1. When SourceTV is enabled however, the STV bot will have ent index of 1, and the player 2. As a result, SendToConsole() has no effect on the actual player. Note: there are also console commands that use UTIL_GetListenServerHost() such as ent_fire or soundscape_flush which break with STV on the server.

VScript console commands (script, script_execute, etc) are broken because of UTIL_IsCommandIssuedByServerAdmin() which returns false if the issuing client is > 1. Of course, currently this will always be false when SourceTV is on the server. Other console commands such as tf_bot_add or tf_bot_kick are also broken for the same reason.

I would love to see these bugs addressed in a TF2 update 🙏 but in the meantime, if anyone finds it helpful here's a SourceMod plugin that detours these two functions as a fix: https://github.com/kstf2/stv-listen-server-fix

@ghost
Copy link

ghost commented Nov 10, 2023

VectorAngles/AngleVectors helpers would sure be nice!

@Brain-dawg
Copy link

Brain-dawg commented Jan 21, 2024

Posting a laundry list of stuff here just so it's somewhere more permanent.

  • There is currently no way to get the max ammo values for weapons, we have to use roundabout hacks by regenerating ammo, storing the reserve ammo value, then reverting it. There are many cases where this is not feasible.

  • Add a StringToFileRemote/FileToStringRemote function that reads/writes from a fileserver instead of the local scriptdata folder. This would be extremely useful if a creator wants to make a script that tracks player data across multiple servers, and would facilitate making a miniature plain text database. The remote location could be set by a cvar similar to sv_downloadurl, or in the function itself.

  • Add a CustomScriptFile popfile keyvalue for loading a global vscript file that loads once when the popfile is loaded for the first time. Currently, the only way to load vscripts inside of a popfile is to run them when a wave initializes or some other existing popfile I/O, Because of how popfiles are loaded this means you need to re-run the script file on every wave and then check if it was already loaded, a bit annoying.

  • MvM bot tags cannot be iterated through, this makes reading bot tags very limited.

  • SpawnEntityGroupFromTable currently doesn't return anything of value, it would be useful if this returned some sort of reference to the entities spawned, like an array of entities or entindexes.

  • It would be nice if SendToConsole could take a player argument, but block commands behind the server_can_execute flag for anyone besides the listen server host, replacing point_clientcommand.

The bot_generator entity offers a few functions that would be nice to have access to for MvM:

- SetBehaviorFlags, ClearBehaviorFlags, IsBehaviorFlagSet - Bot behavior flags for making bots ignore specific classes or sentry guns.

- SetActionPoint, GetActionPoint - These are exclusive to training mode and would need additional changes to facilitate using on MvM bots I believe.
  • There is currently no clean way to set an MvM bot's current action/behavior. The only option for changing bot behavior is setting BehaviorModifiers Push or BehaviorModifiers Mobber in the popfile, which both do the same thing as Attributes Aggressive. Manually setting other behavior like fetching the flag, attacking players, escorting the flag carrier, sniper/spy mission behavior, sentry buster behavior, etc, is very limited and requires roundabout hacks.

  • expose the StunPlayer function

  • Modify the mvm spawn point collection code to re-collect points when a popfile is loaded, to allow for creating custom info_player_teamspawn spawn locations.

I've been told these may be out of scope/will not happen but I will post them here anyway:

  • Transmitting entities to specific players currently requires esoteric hacks abusing a specific netprop, a dedicated SetTransmit function would be nice

  • Tempent spawning function similar to SpawnEntityFromTable would be nice. Useful for making one-off laser beams and particles and stuff.

  • Simulating netprop changes on clients. potato.tf currently runs an extension that adds a $SetClientProp entity input, which allows for sending netprop changes to clients only, the server does not see the change.

@Doclic
Copy link

Doclic commented Jun 10, 2024

In CBaseEntity::TakeDamage, the HSCRIPT object passed to the OnTakeDamage hook has both damage_custom & damage_stats mapped to CTakeDamageInfo.m_iDamageCustom. damage_stats should have presumably been mapped to CTakeDamageInfo.m_iDamageStats.
This means that in VScript the damage_custom field is effectively useless, as it's read to CTakeDamageInfo.m_iDamageCustom before damage_stats who then overwrites CTakeDamageInfo.m_iDamageCustom, as shown in the following reverse-engineered code:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests