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

[Draft] Added nametags, implements #30 #103

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

chinese-soup
Copy link
Contributor

@chinese-soup chinese-soup commented Apr 15, 2021

@execut4ble on #30:

Add hovering nametags above teammates or all players, either always visible or instantly when the player mouse-overs them like in CSGO/Overwatch.
Could also add their health/armor status next to the name if they're your teammate.

So I've implemented this based on a request from egg and only yesterday I've noticed exec posted that issue back in 2017. 😃

I've first tried implementing this using drawn sprites above player heads. This went fine, just making an ASCII table sprite and having each frame correspond to an ASCII letter was a breeze, unfortunately it probably creates too many sprites as it crashes the game whenever there's more than > 5 players. If anyone can tell a dummy how to debug this kind of crashes (the game just exits, no error about edicts or anything), I'd be much appreciated. :) An example of that implemention can be seen here:
image

Since that didn't work I then moved on to creating the hovering tags using DrawConsoleString and DrawHudString.

Obviously this has its downsides, for starters: you cannot change the font size as its "set in stone" for DrawHudString and depends on what the user has in their resource file for DrawConsoleString. (Uses the same font as the chat etc.)

Therefore I tried to use a VGUI1 label, since you could potentially change the font size depending on how far the player is, but no luck there either, the coordinate updates are way too slow as can be seen in this video:
https://user-images.githubusercontent.com/5108747/114897287-5ef9e480-9e11-11eb-972f-dd3f163aa9ce.mp4

Consider this a draft for now, but here's a list of stuff that is implemented or should be decided:
exec wrote:

Add hovering nametags above teammates or all players

Currently the "rules of visiblity" of the implementation are:

  • you have to be in the same PVS as the player
  • you have to be able to see the head of the target player in order for a nametag to appear above them
  • you can see enemies nametags if you are closer to them than 600 units.
  • you can see teammate's nametag if you closer to them than 600 units OR your hud_nametags_team_always is set to 1
  • OR you are spectating = you can see nametags for ALL players
  • OR you are on a server that's currently in Kreedz gamemode = you can see nametags for ALL players
  • OR you are playing a demo = you can see nametags for ALL palyers (TODO: does this actually work?)

instantly when the player mouse-overs them like in CSGO/Overwatch.
Could also add their health/armor status next to the name if they're your teammate.

I'll implement the mousing over and also health is not yet implemented either as that would require hooking the PlayerId message and therefore merging this code with hud_playerid.cpp.

I was thinking having a switch if you want to have the tags visible only on hover or "always" (as per the "rules of visibility" above).

Something like hud_nametags_hover_only 1 (or whatever):

  • if hud_nametags_hover_only = 1 and you hover over a teammate, show his name + health + armor, if enemy show just the name
  • if hud_nametags_hover_only = 0 and you hover over a teammate (+ the "rules of visibility" above), show his name + health + armor, once you stop hovering and a timer expires -> switch back to showing just his name

Current cvars:

  • hud_nametags 1/0 - enable/disable
  • hud_nametags_team_always 1/0 - show/hide teammate name tags even if they are > 600 units away
  • hud_nametags_type 0/1 - default 1 - "same font as chat" (DrawConsoleString); 0 = "hud font" (DrawHudString)

Ones I've thought would be good:

  • hud_nametags_hover_only 0/1 like mentioned there ^
  • hud_nametags_color_nicknames 0/1 - this would only work for DrawHudString as that's written per character and could be used to enable showing colored nicknames (right now it's supposed to have the color of the team, but only works for type 1 - "font as chat")

Up for discussion cc @execut4ble:

  • I'd honestly just disable showing nametags for enemies altogether (not just when they are 600 units away) & only show them ON HOVER as it makes the players too visible "horizontally" - seeing as you cannot change the font size (reason why I tried to use the VGUI labels) and only show them on hover. What do you think?
  • Or change the 600 units distance to something else (for both enemies & teammates (without team_always 1)?

Still TODO:

  • Merge with PlayerId, since cannot get health / armor normally without serverside changes (same as would be required in Team info HUD element #27)
  • DrawHudString currently doesn't show team colors (nor the colored nicknames, see above @ cvars).
  • Change the origin of the text (in world, before translating to screen coords) based on how far away the target player is. (So that the nametag_type 0 for example don't end up being inside the player's head instead of above if you are too far away)
  • Properly center "DrawConsoleString"

The current state can be see in action here:
DrawHudString:
image
DrawConsoleString:
image
https://youtu.be/rPt24qYXo8s

@chinese-soup chinese-soup marked this pull request as draft April 15, 2021 16:50
@YaLTeR
Copy link
Owner

YaLTeR commented Apr 15, 2021

This is cool!

how to debug this kind of crashes (the game just exits, no error about edicts or anything)

coredumpctl gdb usually works

Therefore I tried to use a VGUI1 label, since you could potentially change the font size depending on how far the player is, but no luck there either, the coordinate updates are way too slow as can be seen in this video:
https://user-images.githubusercontent.com/5108747/114897287-5ef9e480-9e11-11eb-972f-dd3f163aa9ce.mp4

Huh, is this a VGUI1 thing? Would be a shame if we can't vary font size.

hud_nametags_type 0/1 - default 1 - "same font as chat" (DrawConsoleString); 0 = "hud font" (DrawHudString)

I'd keep just DrawHudString and make it always color nicknames. There should be code that does this because voting UI uses it I believe.


I'd like to get some feedback from people who requested / would use the name tags too.

@chinese-soup
Copy link
Contributor Author

chinese-soup commented Apr 15, 2021

coredumpctl gdb usually works

Thanks, will check it out and see if I can make it work. I had an idea of using a TEMP entity with write_message stuff instead of gEngfuncs.CL_CreateVisibleEntity(ET_NORMAL, pEnt); and maybe that would fix the crashes. Will see what the debugging leads to.
BTW: Sprites could also be potentially a good alternative if VGUI can't be made to work (without importing in VGUI2 from e.g.'s tmp64's repo https://github.com/tmp64/BugfixedHL, but dunno if that isn't VAC-able etc.) seeing as the sprites scale automatically based on the distance from the target player. Here's a short sprites demo from couple of days ago:
https://kopr.today/2021-04-05_03-05-58.mp4 (scale is settable for a sprite entity, and the rotation was currently only set to 4 angles, as you can see in the video)

Huh, is this a VGUI1 thing? Would be a shame if we can't vary font size.

I'd assume it's a VGUI1 thing, but I've tried both vgui::Label and the one (tmp64 added?) ScorePanel uses aka CLabelHeader - which should be VGUI2(?), but it unfortunately does the same thing when you update the position like this.
I'll try playing around with the VGUI2 CLabelHeader again, but I dunno if it will lead anywhere. It's a real shame because CLabelHeader can draw unicode and "create" & render system fonts and therefore create different sizes that you could interchange.

I'd keep just DrawHudString and make it always color nicknames. There should be code that does this because voting UI uses it I believe.

Personally, I prefer the DrawConsoleString appearance (with just the team color of the player/chat color if default/no team, as I am conservative and don't use a colored nickname myself, but at the same time I am liberal in the sense that I think having more options is always better than not having one at all) because of the size mostly (which if we could get VGUI labels to actually update position @ correct FPS would become redundant).

I'd like to get some feedback from people who requested / would use the name tags too.

Yep, agreed. :)

@execut4ble
Copy link
Contributor

execut4ble commented Apr 15, 2021

This is sick.

I'd honestly just disable showing nametags for enemies altogether (not just when they are 600 units away) & only show them ON HOVER as it makes the players too visible "horizontally" - seeing as you cannot change the font size (reason why I tried to use the VGUI labels) and only show them on hover. What do you think?

Yeah for sure, I think disabling nametags for enemies altogether (including on-hover) makes the most sense, otherwise it could be too advantageous to spot a nametag when otherwise the enemy visibility is low. We already have a HUD element that displays the playername on hover in the center of the screen. So just have nametags for teammates.

you can see enemies nametags if you are closer to them than 600 units.

Perhaps make this adjustable, even though there's hud_nametags_team_always which can be used for really long distances.

Also make sure to test this in other gamemodes without team deathmatch, such as FFA, Arcade, Arena (and some others). Everyone is an enemy, so no nametags should be displayed here, even if they share the same "model".

@chinese-soup
Copy link
Contributor Author

chinese-soup commented Apr 15, 2021

Yeah for sure, I think disabling nametags for enemies altogether (including on-hover) makes the most sense, otherwise it could be too advantageous to spot a nametag when otherwise the enemy visibility is low. We already have a HUD element that displays the playername on hover in the center of the screen. So just have nametags for teammates.

👍 True & agreed, didn't think of the on hover making an "accidental" "reveal" of an enemy. So yeah, let's not show nametags for enemies at all.

This however means that it would be non-trivial (for me anyway since AFAIK I can't hook to PlayerId if hud_playerid.cpp already does?) to make health & armor appear for the teammates on hover, so I guess we could just not show health / armor at all in the NameTag even when you hover on a teammate, seeing as it's already showed in the hud_playerid HUD.

Perhaps make this adjustable, even though there's hud_nametags_team_always which can be used for really long distances.

Will consider it, at the time always showing seemed more "trivial" for the end-user to change as the code checks if you can actually see the person and AG maps usually don't have many huge "rooms" (can only think of the square in stalkx, really, but I'm not really an avid AG DM player rn).
EDIT: replaced hud_nametags_team_always with hud_nametags_team_max_distance.

Also make sure to test this in other gamemodes without team deathmatch, such as FFA, Arcade, Arena (and some others). Everyone is an enemy, so no nametags should be displayed here, even if they share the same "model".

Yep I already tested this (since the hud_nametags_team_always feature already required this) so this should already be working correctly since the code checks if teamplay is on as well as the teamname being same. Obviously will test again once I remove the nametags for enemies.

@chinese-soup
Copy link
Contributor Author

chinese-soup commented Apr 15, 2021

  • Disabled nametags for enemies (tested on non-teamplay modes and all 👍)
  • Replaced hud_nametags_team_always with the hud_nametags_team_max_distance cvar as per @execut4ble's comment.
  • Tested demo playback just now - it works correctly and draws all the nametags (incl. enemies) while playing back a demo.

Regarding the sprites:
It's probably just as I thought, the sprites thing is probably just hitting the max number of temp entities (it's drawing one per letter). Gdb doesn't tell me much because it's from the engine.

Program terminated with signal SIGSEGV, Segmentation fault.
#0  AddTEntity (pEnt=0xc90c3d14 <g_VoiceStatus+192820>) at ../engine/r_trans.c:187
187	../engine/r_trans.c: No such file or directory.
[Current thread is 1 (Thread 0xf76f86c0 (LWP 1059137))]

Dunno if there was ever a leak of HL1 engine src code, but a quick google finds stuff like ValveSoftware/halflife/issues/206 so I'd assume the limitation of temp entities is hit, not the limitation of loaded sprites/models (we're only loading & precaching one .spr).

That's a shame, can't combine the sprites on-the-fly into "one big sprite" for each player name in the client library, so I guess we're out of lock with "in-world sprites" in the client...

Will check and see if I can do anything using the sprites/TGAs in HUD and also try the VGUI2 again as I've already said before. (Cuz font size would be a very useful feature...)

Also:
If we can't make the font size work with VGUI/VGUI2 there's one last rather drastic resort, that I can think of, for implementing a dynamic "font" size 😄 -- gEngfuncs.pTriAPI, but dunno if that isn't overkill for a feature like this...

@chinese-soup chinese-soup force-pushed the nametags_new branch 2 times, most recently from cff4f53 to fd09872 Compare April 16, 2021 00:04
@tmp64
Copy link
Contributor

tmp64 commented Apr 16, 2021

This looks really cool!

VGUI and VGUI2 are pretty much a dead end: you can only scale them by creating a new font handle and you can't remove existing font handles. No transformations are possible either.

A better option would be to use TriangleAPI. It allows you to use a sprite as a texture (on a side note, you should probably put all ASCII chars into one sprite frame to reduce the number of texture switches: it's a fairly expensive operation for the GPU). The only downside is that may be inefficient and may reduce the FPS (not much if all chars are in one texture, something like from 500 to 400-450 if there is a lot of text) because it would require many draw calls.

The best option, in my opinion, is to buffer all rendered vertices and then draw them in one go. This is used in the engine for text rendering (link).

If you want to improve the quality of the text without increasing the resolution, you should look into signed distance field font rendering. Of course, that requires shaders and hacks to make it cooperate with fixed pipeline of the engine and it's way overkill and way too much work. It looks like it's possible to be done without shaders. But it's still overkill.

I think you shoud start by implementing it using TriAPI and then work from that. Vertex buffering is easy to implement and shouldn't cause any problems. You can find TriAPI docs in Half-Life SDK on Steam (in the "tools" section).

@chinese-soup chinese-soup force-pushed the nametags_new branch 4 times, most recently from 9ead009 to 3661495 Compare November 25, 2021 01:33
@chinese-soup
Copy link
Contributor Author

chinese-soup commented Nov 25, 2021

TODO:

  • Center the nametags above heads (currently first char starts at the center and continues to the right, calc strlength*charwidth (same in monospace lel))
  • Fix up the "origin above head" based on the targetPlayer's distance
  • Color tags support (currently whole string is hud_color's - add a hud_nametags_colortags 0/1 or sth, cuz I hate them tbh;)))
  • Nick in team color (+colortags over it obv, basically default_color (^9 & ^0)=team color, just like in oldscoreboard) (for spectating deathmatch matches mostly)
  • Buffering
  • Fix up ypos positioning (letters "jumping" up and down)
  • Fix up the sprite (vertical spaces between lines)
  • Fix up the distance scaling (the idea is there and is pretty OK, but needs some more investigation on good vlaues)
  • Fix rendering in HLTV demos
  • Don't draw for player if g_iUser2 == playerWeAreAboutToDrawFor && OBS_INEYE in demos and live spectating (visible when player jumps))
  • Add more pre-made font sprites(?)
    • and make sure they are added to the OpenAG full mod package on release!
    • spit a message if user enables hud_nametags and doesn't have the sprites
  • Tidy up the code

Might TODO eventually(TM) (or in a later PR):

  • Create an online website generator for a custom ASCII table sprite(?)
  • hud.txt-style so that font doesn't have to be monospace & doesn't have to be same width&height? (Or "fix" this issue using the website generator?)

@solidi
Copy link

solidi commented Jun 14, 2022

@chinese-soup - hi, this change makes reference to sprites/ascii_table.spr and sprites/ascii_single.spr but are not apart of the pull request. Can you share these assets?

@sabianroberts
Copy link
Contributor

sabianroberts commented Sep 25, 2023

@chinese-soup - hi, this change makes reference to sprites/ascii_table.spr and sprites/ascii_single.spr but are not apart of the pull request. Can you share these assets?

bumping this! could you please share the sprites?

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

Successfully merging this pull request may close these issues.

6 participants