Raised This Month: $ Target: $400

[L4D2] Why game_text doesn't work and what can we do?

Post New Thread Reply   
Thread Tools Display Modes
Author Message
Great Tester of Whatever
Join Date: Jun 2018
Old 11-13-2022 , 05:12   [L4D2] Why game_text doesn't work and what can we do?
Reply With Quote #1

This topic is not tutorial nor guide but just a information. Everything here is provided as "acquaintance".
So I recently got interested in game_text entity and tried to use it in Left 4 Dead 2 but unfortunately this entity is completely broken.
It doesn't matter what will be your attempts, you can't fix this entity from server side but what about clientside?
Well that's where most intresting part starts.
Why it doesn't work
Before explanation i should mention that game_text doesn't draw anything "directly" to clients actually this entity is wrapper for HudMsg UserMessage. Whenever you pass "display" input to game_text it sends user message to specific client with given settings then client reads received message and paint text respectively
At this point for consistency I will call "CHudMessage" as client side and "HudMsg" as server sided parts accordingly
It means if HudMsg works then game_text and sm hud synchronizer will also work.

So whats can go wrong?
At first glance everything can be very simple, if you ever tried to find any information on game_text entity then you probably saw some useful posts (#1, #2).
By default CHudMessage uses font called g_hFontTrebuchet24. This font is loaded by CHud class from clientscheme.res file.
Yep the problem is due to valve forgot or knowingly didn't add font settings to clientscheme.res file.
This makes g_hFontTrebuchet24 to be null and therefor CHudMessage doesn't draw anything.
Ok, i am going to add missing settings to clientscheme.res file and use game_text again to see if it fixes entity.
Since we can't override clientscheme.res with addons or by placing your own scheme to corresponding folder. I will hex edit pak01_dir.vpk to force game load my custom clientscheme.res file.

And we got....

Going deeper

As you can see no magic happened, game_text still doesn't work. Why?
Well, after hours of debugging i got a answer. Theres is a second issue with CHudMessage which is more complex that was before and this is due to splitscreen system. Before we start we need to go a little deeper about how CHudMessage works.
First of all see how CHudMessage inherits from multiple classes and one of them is ITextMessage (keep that in mind). When client receives HudMsg, CHudMessages assignees new message to any free client_textmessage_t.
A bit after it iterates over all client_textmessage_t's and then do general stuff to make text look good (calculates fade in/out effect, converts text from ANSI to UNICODE, calculates every character size).
After all this calculations every character is added one by one to m_Messages vector. This vector could be considered as sequences of what to do next. It can hold unicode character and its color, actions to set paint position and also
change text font. In the end it will read entire m_Messages vector and do corresponding actions.

Every step does what it should except for "Read entire m_Messages vector and do corresponding actions" step. During debugging m_Messages count always was zero and after couple of hours i found why.
Even so CHudMessages inherits from ITextMessage it does not use "this" as a caller but a global textmessage var (to fill m_Messages). This variable assigned in CHudMessage constructor and this is where problem lies.
Splitscreen system forces CHud::Init to be called N times where N is number of allowed split screen players. Left 4 Dead 2 can have max 2 split screen players on PC.
This makes CHud::Init to be called two times and create 2 different CHudMessage's. This is the reason why HudMsg is broken. If you don't see the point then check steps below.
  1. First call to CHud::Init creates CHudMessage for first splitscreen player
  2. Global var textmessage now assigned to newly created CHudMessage
  3. Second call to CHud::Init creates CHudMessage for second splitscreen player
  4. Global var textmessage now assigned again to newly created CHudMessage but now it holds CHudMessage of second splitscreen player
  5. Server sends HudMsg
  6. CHudMessage reads it HudMsg and constructs actions which should be added to m_Messages vector
  7. CHudMessage uses global textmessage var to fill m_Messages vector but textmessage holds CHudMessage of second split screen player and therefor nothing will be added to vector of "this" CHudMessage instance.
  8. CHudMessage will try to print read entire m_Messages vector but it's empty so nothing to paint.

What we can do

This is the saddest part and for the server side this is dead end.
In order to fix this we need to patch client.dll and add additional check against global textmessage var (and this check was added for csgo branch) which is impossible from server side.
So in conclusion, there's nothing we can do except for asking valve to correct clientscheme.res and add check for textmessage.
But we still can use it for.... debugging? textmessage variable can be directly assigned to right CHudMessage instance via MemoryEx or any other library that gives access to client.dll.
This could be used to paint debug information.
Another way is to run game with second split screen player.
Use any addon for split screen game but this is listen server only, makes your screen splitted into two, text will be visible only for second player but this doesn't require to patch client.dll

Anyway this is results with splitscreen player and with patched client.dll.


Attached Files
File Type: sp Get Plugin or Get Source (hud_text_test.sp - 79 views - 3.0 KB)

Last edited by BHaType; 11-13-2022 at 07:14.
BHaType is offline
Send a message via AIM to BHaType
Join Date: Sep 2021
Old 11-24-2022 , 22:23   Re: [L4D2] Why game_text doesn't work and what can we do?
Reply With Quote #2

So the problem is sever only send the second split screen message to client?
LinLinLin is offline
Great Tester of Whatever
Join Date: Jun 2018
Old 11-25-2022 , 13:39   Re: [L4D2] Why game_text doesn't work and what can we do?
Reply With Quote #3

Originally Posted by LinLinLin View Post
So the problem is sever only send the second split screen message to client?
Not exactly, when server sends HudMsg, client will read it successfully but CHudMessage will draw only for second split screen player.
BHaType is offline
Send a message via AIM to BHaType

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT -4. The time now is 13:10.

Powered by vBulletin®
Copyright ©2000 - 2023, vBulletin Solutions, Inc.
Theme made by Freecode