Forum posts

Posted 7 months ago2023-09-20 13:40:53 UTC
in Half-Life Updated (custom SDK) Post #347866

Map Decompiler beta 12 released

Map Decompiler beta 12 has been released: https://github.com/SamVanheer/HalfLife.UnifiedSdk.MapDecompiler/releases/tag/V0.12.0.0-beta012

Changes:
  • Remove collinear points immediately to avoid merging faces into concave shapes
This fixes the Face-To-Brush decompiler generating bad brushes sometimes.

For example in ba_canal2:

Before:
User posted image
After:
User posted image
The cause of this problem was that collinear vertices (vertices that lie on the same line, like a triangle whose vertices are all in a straight line) were removed after faces were merged. The face merging algorithm (which dates back to the original Quake 3 codebase) assumes the 2 faces don't have collinear points so this sometimes resulted in concave faces being created which level editors can't reconstruct properly.

This problem could also result in some brush faces in the .map file having NaN values.

Thanks to almix for reporting this issue.
Posted 7 months ago2023-08-31 20:44:46 UTC
in Half-Life Updated (custom SDK) Post #347817

Half-Life Updated release candidates released

Half-Life Updated, Half-Life: Opposing Force Updated and Half-Life: Blue Shift Updated release candidates have been released:
Half-Life Updated: https://github.com/SamVanheer/halflife-updated/releases/tag/HLU-V1.0.0-RC002
Half-Life: Opposing Force Updated: https://github.com/SamVanheer/halflife-op4-updated/releases/tag/HLOP4U-V1.0.0-RC002
Half-Life: Blue Shift Updated: https://github.com/SamVanheer/halflife-bs-updated/releases/tag/HLBSU-V1.0.0-RC002

Notable changes for all games:
  • Fixed hand grenade model not animating
  • Added cvar sv_allowbunnyhopping to control whether the bunny hopping limiter is enabled
  • Fixed mouse cursor being invisible in VGUI1 menus when raw input is enabled
  • Fixed RPG being flagged as unusable while a rocket is loaded
  • Copy delta.lst when building client or server to ensure mods have correct delta.lst file (defines networking properties for data types)
  • Fixed item history HUD not resetting the vertical position used for new items added to the list when loading save games
  • Fixed Gauss gun dealing full damage when saving and loading right after starting a charged shot
  • Prevent breakables from spawning multiple items when destroyed by gunfire and explosives at the same time
  • Properly fixed mouse movement in main menu affecting in-game angles
Notable changes for Opposing Force:
  • Fixed electrified wire damage being frametime-dependent causing players to die almost instantly at high framerates
  • Fixed func_tank_of and other OF tank entities firing many attacks at the same time at players if they hide behind obstacles for a few seconds
  • Fixed Geneworm not lighting up its eyes

Progress on the Unified SDK

Release candidate 2 is now available: https://github.com/SamVanheer/halflife-unified-sdk/releases/tag/UNIFIED-V1.0.0-RC002

SDK Changes

  • Fixed incorrect attribute order on a couple functions
  • Optimized debug & project info huds to avoid unnecessary memory allocations
  • Fixed third person view not using correct camera offset
  • Set Drill Sergeant accessories bodygroup to blank
  • Added Natvis types for Schedule_t, CBaseMonster & CCineMonster to make it easier to debug NPCs and scripts using the Visual Studio debugger
  • Move mouth when playing regular sounds as well as when playing sentences
  • Fixed not being able to select weapons if they do not have sequential positions in the weapon bucket
  • Hardened HUD code against missing configuration data
  • Added check to prevent out of range access in entity classification code
  • Fixed func_tank entities not respecting persistence and not being able to switch targets properly if target is behind cover
  • Fixed func_tank and other tank entities firing many attacks at the same time at players if they hide behind obstacles for a few seconds (same fix as in Opposing Force, applies to regular tank entities here)
  • Make sure loader NPC stops playing looping sounds on death
  • Fixed rats having alien gibs instead of human gibs
  • Fixed turrets and tanks continuing to target players after enabling notarget
  • Fixed baby voltigores using adult sized gibs
  • Fixed Baby Voltigores playing attack sounds at wrong pitch
  • Fixed Hornet gun not playing attack animation when firing after recharging the only available ammo
  • Implemented cvar change callbacks to simplify syncing cvar changes with other systems
  • Added cvars sv_infinite_ammo & sv_bottomless_magazines to override skill variables
  • Made crosshair color separately configurable

C# Changes

  • Removed classname validation on map load to allow TFC's flagrun map to load (contains an entity with an empty classname)
  • Missing game content is now logged as a warning instead of an error
  • A missing Half-Life Uplink installation is no longer logged as an error or a warning
  • Fixed Osprey falling through the ground and reverting to the flying animation in ofboot1 after loading a save game
  • Fixed Op4 func_tank entities using persistence keyvalue (func_tank_of entities do not use this keyvalue and act as though it is set to 0)
  • Added missing wav extension to sound in of6a5 (portal sound when Geneworm arrives)
  • Removed redundant chaptertitle key from ba_power2
  • Fixed bullsquids in of5a2 not playing eat scripts (Xen area reached via Displacer)
  • Fixed grunts in ba_outro having wrong body groups

Asset Changes

  • Reverted the LD Opposing Force Crowbar model to the original model
  • Fixed Snark viewmodel fidgetnip animation leaving the left hand in an awkward position at the end of the animation
  • Use correct hud sprite for Opposing Force scanline digits
  • Fixed scientist portal animation cutting off dialogue due to sounds played on voice channel (affects c3a2d, final Lambda Core level)
  • Fixed deadhaz.mdl helmet submodel including Gordon's head causing his glasses and ponytail to clip through the helmet
  • Added crosshair color setting to cfgs, added player_setcrosshaircolor to fgd, updated test_sethudcolor with tests for crosshair color

Remaining work to be done

  • Update changelog to include all changes (done)
  • MIT license all community-written Updated & Unified SDK code
Thanks to everybody for testing these out and giving feedback, this has allowed a lot of issues to be fixed and improvements to be made.

The documentation has also been updated to include new additions.

These releases are mainly bug fixes but in the Unified SDK a few new features were added based on feedback:
  • The infinite ammo and bottomless magazines skill variables now have associated cvars to override the skill settings
  • Crosshair color is now independent of hud color and Blue Shift's crosshair color now matches the original game's color (blue was harder to see as well)
All projects are feature complete so no new features will be added. These were added because they are simple enough and somewhat required for the existing features to work well.

Do remember to follow the installation instructions to ensure that all game assets are installed and upgraded properly so as to avoid glitches and bugs!

There are some more changes that will be made for a third release candidate but nothing involving bug fixes at this time.

Try out the new release candidates and let me know what you think!
Posted 7 months ago2023-08-26 17:47:53 UTC
in Half-Life Updated (custom SDK) Post #347796
I'd hold off for a couple more weeks. We're still testing things and fixing bugs.

There should be another release candidate in the coming days to make all of the fixes available.
Posted 8 months ago2023-08-20 19:06:12 UTC
in Half-Life Asset Manager Post #347790

Half-Life Asset Manager V2 Beta 10 released

Half-life Asset Manager V2 Beta 10 has been released: https://github.com/SamVanheer/HalfLifeAssetManager/releases/tag/HLAM-V2.0.0-beta010

Changes:
  • All mouth bone controllers now work properly and synchronize their controller value
  • Mouth controller value range matches the internal range used by the game
  • Mouth controllers can have a negative starting range
  • Fixed shadows drawing at wrong height when models are moved up or down
  • The "Highlight Hitbox" option now uses a different configurable set of colors than hitboxes drawn with "Show Hitboxes"
  • Added known issues to the manual
  • Numeric edit widgets now use the shortest possible representation to reduce the width of the text
  • Miscellaneous code cleanup
Posted 8 months ago2023-08-20 10:12:57 UTC
in Half-Life Updated (custom SDK) Post #347789

Map Decompiler beta 11

Map Decompiler beta 11 has been released: https://github.com/SamVanheer/HalfLife.UnifiedSdk.MapDecompiler/releases/tag/V0.11.0.0-beta011

Changes:
  • Added checks to log a proper error if BSP version is not supported
  • Show messagebox if any errors occur when saving settings (e.g. file is read-only)
  • Reworked parallelization to improve throughput when decompilation takes a while
  • Fixed job time elapsed being incorrect
This should improve CPU core usage without causing any performance issues. Testing shows that decompiling 125 maps takes 31 seconds with beta 10 and 29 seconds with beta 11.

If you encounter any issues with stuttering or freezing do make sure to let me know.
Posted 8 months ago2023-08-18 17:28:48 UTC
in Problem with sprites Post #347784
Try using the TE_PLAYERATTACHMENT message instead. It creates a temporary entity attached to the player that sticks around for a specific amount of time.

It works by using the clientIndex variable in TEMPENTITY along with the flags FTENT_PLYRATTACHMENT and FTENT_PERSIST, so if this message doesn't do the trick you can make your own. The rest of TEMPENTITY's variables you should be able to set up like you would a server side entity.
Posted 8 months ago2023-08-16 11:30:59 UTC
in Half-Life Asset Manager Post #347776

Half-Life Asset Manager V2 Beta 9 released

Half-Life Asset Manager V2 Beta 9 has been released: https://github.com/SamVanheer/HalfLifeAssetManager/releases/tag/HLAM-V2.0.0-beta009

Changes:
  • Set default text codec to UTF-8 to fix filenames converting incorrectly in some cases
  • Fixed filenames containing UTF-8 passed on the command line becoming corrupted
  • Rewrote the manual in Markdown to allow it to be read directly when viewing it on Github
  • Allow Vertical Sync setting to be changed on-the-fly
  • Use better check to detect lack of textures in main model (fixes Deleted Scenes' null.mdl failing to load)
  • Fixed incorrect filename being referenced in External texture file "<filename>" does not exist or is currently opened by another program message
  • Clean paths before adding them to recent files list to avoid duplicates differing slightly
  • Ensured settings file cannot add too many recent files
  • Added info to dumped model info about use of external texture file
  • Lazily create asset menus and delay file browser startup until it's opened to speed up initial startup
  • Replaced text-based vector edit widget with 3 spin boxes to improve editing experience
  • Made Transformation dock widget visible by default, added to bottom bar, reduced vertical size
  • Added information about spinboxes to manual (CTRL+Click changes values 10 at a time)
Posted 8 months ago2023-08-15 11:53:47 UTC
in Half-Life Updated (custom SDK) Post #347773
Ahhh I see. That's a darn shame, I loved that sound lol. And you're once again an absolute legend for adding that bunnyhop cvar. I made a video about your unified SDK btw, just released it today. https://www.youtube.com/watch?v=EzvoI6nFvf8
That's nice. Thanks for making a presentation of what the project does.

I should stress given some of the comments that this is an SDK first and a mod second, intended to allow others to build on it.

Once the project has moved to the TWHL Community organization people can add more features if they want to, like Decay features and map support but that's out of scope for V1.0.0.

Mr Floyd is currently making a Decay solo campaign mod so they can ask him about possibly porting the campaign but that's not something i have planned myself. The asset sources are going to be made available at some point so it should be possible for anyone to do that.

I've fixed the invisible mouse cursor issue that several people have reported. The next release candidate will have that fix along with a couple others.
Posted 8 months ago2023-08-14 11:23:43 UTC
in Half-Life Updated (custom SDK) Post #347771
So even with all these changes to the code, there's still no way to bring back gunshot impact sounds for the player's bullets? And a cvar to enable / disable bhop cap would be very welcome for someone like myself
I've added a cvar sv_allowbunnyhopping to control the bunny hopping limiter. That can be used to allow unconstrained movement speed.

I haven't actually managed to bunny hop to see if it's possible to accelerate but the code that limits it won't execute so it should work.

Gunshot impacts aren't possible without removing weapon prediction. This is because the impact sounds are handled by client side events, and those events can't detect corpses.

The reason why corpses are undetectable is because the client operates on the list of solid entities that's also used by the player physics code. This list is populated with entities the client is told about by the server but it explicitly filters out some entities, corpses among them. They are quite literally invisible to that part of the game.

Unfortunately there's no way to detect this so it's not even possible to let the server handle it.
Posted 8 months ago2023-08-02 14:10:03 UTC
in Half-Life Updated (custom SDK) Post #347748

Map Decompiler beta 10

Map Decompiler beta 10 has been released: https://github.com/SamVanheer/HalfLife.UnifiedSdk.MapDecompiler/releases/tag/V0.10.0.0-beta010

Changes:
  • Added Windows version requirement to README
  • Added failsafes to prevent empty or invalid configuration files from crashing the program
This fixes the program failing to start if the configuration file is empty, which some users have experienced.
Posted 8 months ago2023-07-31 17:37:18 UTC
in Half-Life Updated (custom SDK) Post #347742

Map Decompiler beta 9

Map Decompiler beta 9 has been released: https://github.com/SamVanheer/HalfLife.UnifiedSdk.MapDecompiler/releases/tag/V0.9.0.0-beta009

Changes:
  • Renamed executables to user shorter names
  • Increased plane hashes array size to match BSP file format's MAX_MAP_PLANES limit
  • Fixed plane normals being rounded incorrectly resulting in some map geometry being misshapen
  • Updated Sledge.Formats libraries to latest version, upgraded code to match library changes
  • Updated Serilog, Newtonsoft.Json and SILK.NET.Maths libraries to latest versions
  • Upgraded to Avalonia 11.0.2, upgraded code to match library changes
  • Replaced deprecated file and folder dialog code with StorageProvider API
I'm waiting for this bug to be fixed before releasing Release Candidate 1. This bug causes the text in the top right corner to become invisible until clicked on after changing the theme from Light to Dark or vice versa.
Posted 8 months ago2023-07-31 17:33:27 UTC
in Half-Life Updated (custom SDK) Post #347741
Thanks, i do my best :)
Posted 8 months ago2023-07-30 18:28:50 UTC
in Half-Life Updated (custom SDK) Post #347738

Half-Life Updated release candidates released

Half-Life Updated, Half-Life: Opposing Force Updated and Half-Life: Blue Shift Updated release candidates have been released:
Half-Life Updated: https://github.com/SamVanheer/halflife-updated/releases/tag/HLU-V1.0.0-RC001
Half-Life: Opposing Force Updated: https://github.com/SamVanheer/halflife-op4-updated/releases/tag/HLOP4U-V1.0.0-RC001
Half-Life: Blue Shift Updated: https://github.com/SamVanheer/halflife-bs-updated/releases/tag/HLBSU-V1.0.0-RC001

Notable changes for all games:
  • Fixed tripmines not detonating if placed on breakable and a save game is loaded
  • Fixed func_friction not working properly in multiplayer
  • Fixed Gauss gun sometimes settting player uranium ammo to -1
  • Fixed user interface coordinates and sizes being incorrectly adjusted for resolution
  • Fixed player weapons still receiving input when starting to use a func_tank
  • Fixed alien slave beams staying forever if they exist during a level change
  • Fixed limit in world weapons (e.g. Hand Grenade) respawning at wrong time if server is near edict limit
  • Fixed Human Grunts dropping weapons again if the game is saved and loaded while the grunt is dying
  • Fixed mouse movement during map load affecting initial view angles
  • Fixed being able to break scripted_sequence by +using friendly NPCs to make them follow player
  • Fixed potential incorrect facing in scripted sequence
  • Fixed Egon not stopping its attack animation if the attack button is held down and ammo runs out
  • Fixed scientists crashing when speaking fear dialogue when enemy has been removed
  • Disabled fall think function for weapons when the player picks it up to prevent possible double-pickup which removes the weapon and crashes the game
  • Disabled jump sounds while player is frozen (e.g. trigger_camera, trigger_playerfreeze)
  • Fixed node graph code incorrectly flagging node graphs as out of date if an outdated graph exists in a search path other than the mod directory (e.g. a graph in halflife_updated_addon/map/graphs)
Notable changes for Opposing Force:
  • Force Pitworm animations to interpolate to fix stuttering movement
  • Implemented snow footsteps and impact sounds, changed snow material type ID to O to match Opposing Force
  • Added missing EXPORT to a few Opposing Force entities
  • Fixed M249 using wrong spread in singleplayer when standing still and ducking
  • Fixed Capture The Flag items crashing on respawn
  • Fixed Health Charger recharge time not using the correct value in Co-op
  • Fixed Desert Eagle laser position not updating when holding down reload button
  • Fixed Voltigore creating beams on death connecting to wrong entity
  • Fixed ropes breaking at high framerates
  • Fixed allied human grunts continuing to fire for a few seconds after killing the last enemy in an area

Progress on the Unified SDK

The first release candidate is available: https://github.com/SamVanheer/halflife-unified-sdk/releases/tag/UNIFIED-V1.0.0-RC001

SDK Changes

  • Disabled following by default for monster_generic
  • Create smell sound when spawning client-side gibs so NPCs can comment on it
  • Only allow monster following if it's actually a monster (stops entities inheriting from CBaseMonster from being +USEable)
  • Removed json_debug cvar (redundant, server commands require rcon access)
  • Updated documentation & changelog to fix some issues, add remaining code changes and make them easier to navigate

Asset Changes

  • Fixed Spore Launcher spore appearing on the side of the screen when reloading
  • Fixed HEV sounds playing when taking damage in Opposing Force

The future of Half-Life Updated and the Unified SDK

With the first versions of these projects coming close to completion a plan for post-launch support is being worked out to allow these projects to continue receiving updates.

I previously announced that the three Updated projects would be archived upon the release of version 1.0.0. Some have indicated a desire to keep updating them afterwards to incorporate changes from the Unified SDK, so i've been working out a way to handle this.

So far i've been managing these projects mostly on my own, merging in changes contributed by others as needed. The Git repositories are part of my Github account, and i can add collaborators to allow direct commit access.

To allow the community to support these projects we've created a new Github organization called TWHL Community

The Updated projects as well as the Unified SDK and others i have on my account will be moved to this organization to allow development to continue there. Github will automatically redirect existing links to the new locations so everything should keep working as before, though links will still be updated for clarity.

Members of the organization as well as collaborators added to the individual repositories can commit to these repositories and merge pull requests.

The move of these projects to an organization managed by TWHL makes these projects officially an extension of the community and should allow development to continue as long as the community remains active. It also ensures that projects referenced by tutorials on the website remain available.

Remaining work to be done

  • Update changelog to include all changes (mostly complete)
  • Write documentation for all new features (done)
  • Stress test the four campaigns and fix issues that show up (third test done)
  • First release candidate build (done)
  • MIT license all community-written Updated & Unified SDK code
With the release of release candidate builds for all 4 projects most of the work is now done. Some small changes may still be made to wrap up some work and fix issues but everything's ready for testing now.

This means no more large changes are going to be made for V1.0.0. Stability, correctness and performance are the priority now.

If anybody wants to try them out, just download them and follow the instructions. Report bugs and other problems on the issue tracker for the relevant project. Make sure to provide as much information as possible.

Thanks and have fun!
Posted 9 months ago2023-07-23 18:33:11 UTC
in Half-Life Updated (custom SDK) Post #347724

Progress on the Unified SDK

SDK Changes

  • Added checks to prevent entities with class none from becoming hostile to player (e.g. if a scientist is killed near the G-Man the G-Man is marked as suspicious which makes him hostile. He'll try to attack the player but, lacking weapons, resorts to stalking the player like a Terminator instead)
  • Prevent allow_follow being set on script entities
  • Added check to prevent level changes from breaking if they are too close to each-other in relative space. The game will instead notify players who touch broken level changes that the level change is incorrectly placed
  • Reduced size of fixed size containers to optimize memory usage in sentence system
  • Use lookup table to get sounds to speed up lookup
  • Eliminated unnecessary conversion from sound index to name and back again when starting sounds
  • Clamp health before conversion to int when showing entity info (prevents entities with huge health values from showing up as having negative health)
  • Properly set scientist head when using random head setting to prevent other body groups from being changed
  • Fixed allied human grunts continuing to fire for a few seconds after killing the last enemy in an area

C# Changes

  • Update env_spritetrain sounds when upgrading maps (same as func_train)
  • Added hack to install default config.cfg file with correct key bindings
  • Added MapUpgraderDocGenerator: converts XML documentation generated by C# compiler for the MapUpgrader.Upgrades library to Markdown for use in documentation

Asset Changes

  • Added polygons under bigrat paws
  • Create valid sequences for unused HD zombie sequences
  • Added test maps to test level changes being too close to each-other
  • Added studio property to a few entities in fgd file
  • Added files used by prototype scripting system

Broken level change detection

If you go through a level change and you're touching a level change immediately after loading into the next map then all level changes will break. This has been fixed so that the level change responsible is instead disabled and a warning is shown to make this clear:
User posted image

Memory and performance optimizations

The new sound system had some performance issues that have been fixed:
  • The memory used by the client-side sentences list has been reduced by about 3/4th from 2 MiB to just under 600 KiB. This was done by reducing the size of the fixed size buffer used to store sentence names and the list of sentence words. For names and word counts that exceed the buffer size additional memory will be allocated. The new buffer sizes were chosen based on the minimum, maximum, average and median counts for both to minimize waste of memory
  • Sound lookup on the client side was too inefficient due to having to compare sound names against every sound used by sentences before regular sounds precached by the server were checked. This now uses a lookup table to dramatically reduce lookup time
  • Sounds and sentences started on the server side are no longer converted from an index back to a name and then back to an index again, which eliminates the need to perform a lookup altogether
These were the only outliers in SDK code that showed up when checking the game with a performance profiler. Most of the game's CPU time is spent in the engine which can't be analyzed more thoroughly due to a lack of access. Memory usage is pretty good with no notable outliers.

Prototype scripting system

The prototype Angelscript-based scripting system has been made available in the Git branch nonfunctional-prototype-scripting.

This prototype implements a number of features that can be used as a starting point for a more complete and functional scripting system:
  • Plugins and map scripts
  • trigger_script
  • Event System
  • Scheduler
  • Call functions from C++ using helper functions and types
  • Entity APIs
  • Custom Entities
  • Per-Entity User Data
  • Console Commands
A more complete overview is included in the documentation. The documentation explains the concepts behind these features, how they work and where the design can be improved.

I updated the prototype to include all changes made to the project and i added a couple more features i thought people might need an example for but as noted in the documentation this prototype is nowhere near ready for use. You'll need to put in a fair amount of effort to get it working.

As i noted in the Closing Thoughts you should evaluate other scripting languages to choose the right one for the job. Angelscript is powerful but that also makes integrating it into a program difficult, and when something goes wrong (and it will) you'll need advanced level C++ knowledge to understand what's happening.

Documentation and changelog

I've added documentation for as much as i can. The documentation covers everything from new features, new, modified and removed entities, tools, scripts and prototypes.

I've also added a changelog listing all changes made in the Unified SDK project (not including changes made in the Updated projects): https://github.com/SamVanheer/halflife-unified-sdk/blob/master/UNIFIED_CHANGELOG.md

The changelog is about 13 A4 pages when exported to PDF.

The main documentation readme acts as a hub for the documentation to allow navigation to the documentation and links to other projects related to this one.

Potential Upgrades

Remaining open Github issues have been moved to a "Potential Upgrades" project. I've also added issues from my TODO list to this project.

These are issues that could be worth investigating and cover bug fixes, API changes and new features. They are by no means required to be added at any point, they're just things that are worth investigating.

Remaining work to be done

  • Update changelog to include all changes (mostly complete)
  • Write documentation for all new features (mostly complete)
  • Review all changes (done)
  • Stress test the four campaigns and fix issues that show up (second test done)
  • First release candidate build
There are a couple things left to be done before development is wrapped up, mostly testing the four campaigns again to check for any issues worth fixing.

I'd like to thank malortie for helping to get the project ready for release. He's done a lot of good work on the project and helping to test the game. The project would not have gotten to this point without him.
Posted 9 months ago2023-07-03 12:20:01 UTC
in Wiki enhancment thread Post #347683
The tutorial for setting up level changes has been updated to cover a common issue where level changes break if set up incorrectly: https://twhl.info/wiki/page/Tutorial%3A_Changing_Levels

This information was missing and it often happens to beginners so this should help.
Posted 9 months ago2023-06-27 12:36:53 UTC
in Wiki enhancment thread Post #347654
I've split the tutorial for setting up a mod directory into WON and Steam versions and i've added links to the main tutorials page to point to these tutorials: https://twhl.info/wiki/page/category%3AGoldsource_Tutorials

I've also added some extra info about the use of unrelated client and server dlls and changes in how the game uses the multiplayer_only option.
Posted 9 months ago2023-06-27 12:34:07 UTC
in Half-Life Updated (custom SDK) Post #347653
I'd suggest asking for help on the Discord server, they can help you with that.
Posted 10 months ago2023-06-25 13:38:05 UTC
in Half-Life Updated (custom SDK) Post #347650

Progress on the Unified SDK

SDK Changes

  • Fixed scientists crashing when speaking fear dialogue when enemy has been removed (e.g. scientist screaming in fear at human grunt that was just gibbed)
  • Fixed serverctrl tool not compiling when built as 64 bit (note: tool is not compatible with Steam Half-Life due to removed engine functionality)
  • Removed procinfo library (obsolete, the Half-Life SDK uses SSE2 by default which is only available with CPUs newer than what this library tests for)
  • Tools now obtain SDL2 using vcpkg instead of relying on the SDL2 library included with the SDK (allows 64 bit builds to be made)
  • Fixed qcsg & qrad crashing due to pointer-to-int downconversion in 64 bit builds
  • Disabled fall think function for weapons when the player picks it up to prevent possible double-pickup which removes the weapon and crashes the game
  • Implemented cheat_jetpack: When enabled, players can fly by holding down the jump button and accelerate forward when holding the forward movement button
  • Give maximum ammo when giving weapons with impulse 101 (MP5 gets full magazine)
  • Fixed Egon gun resetting animation when another weapon has just been deployed
  • Added checks to ensure talk monsters (scientists, security guards, friendly grunts) only talk to other talk monsters when idle chatting or getting shot by friends
  • Added missing call to PostRestore in weapons code (caused weapons dropped in the world to change models when going through level changes)
  • Allow CBaseMonster::DropItem to drop any entity (fixes Shock Troopers not dropping roaches)
  • Disabled jump sounds while player is frozen
  • Fixed node graph code incorrectly flagging node graphs as out of date if an outdated graph exists in a search path other than the mod directory
  • Ensure auto weapon switch setting is always initialized (fixes not switching to picked up weapons in singleplayer)

C# Changes

  • Removed globalname from crates next to the Dam in c2a5 to stop them from disappearing when entering through level change
  • Removed unnecessary sentence replacements (now handled by bs_sentences.json)
  • Removed dialogue in ba_tram2 that references Freeman and HEV suit in error

Asset Changes

  • Fixed allied grunt sentence using wrong filename ("Ok, check in!" dialogue)
  • Stop looping turretrot1.wav sound played by loader model

cheat_jetpack

This cheat was added to make it easier to traverse maps more quickly and to allow players to reach ledges that are just out of reach when testing maps:

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Review all changes
  • Stress test the four campaigns and fix issues that show up (second test done)
  • First release candidate build
I've tested all campaigns and training courses. All of the above changes are fixes for bugs encountered during these tests.

The next step now is to write the changelog and documentation. Features will be tested to verify that documented behavior works as expected. Any bugs found along the way will be fixed.

Once this process is complete the first release candidate builds for all projects will be released.
Posted 10 months ago2023-06-21 13:52:27 UTC
in Half-Life Decay HUD Problems Post #347637
READ_BYTE is used to read data from an incoming network message. It's only valid inside the message handler for the message. You can't just call it whenever and get the value you want; you'll get -1 instead since there's no data to read. There are plenty of examples on how to cache the values received in a message in existing handlers, so look at those to get an idea on how to do that.
Posted 10 months ago2023-06-17 08:14:53 UTC
in Is there any way to preview "p_" models? Post #347630
Sounds like your computer itself has a problem. Maybe your operating system installation is corrupted somehow?
Posted 10 months ago2023-06-16 18:38:32 UTC
in Half-Life Updated (custom SDK) Post #347628

Progress on the Unified SDK

A new pre-alpha build is available: https://github.com/SamVanheer/halflife-unified-sdk/releases/tag/dev-2023-06-16
Note: pre-alpha builds are not intended for general testing. As the wiki article on software life cycles explains the first versions intended for this kind of testing are alpha builds. Pre-alpha builds are for testing specific features by request to verify that they work as expected based on bug reports and feature requests.

Since this project is still in the midst of development (essentially this is the game engine development part of the project) it's expected that there are bugs and features not working as expected (or at all). Once all required features have been implemented the project can move to the alpha testing stage where verifying the proper behavior is the main goal.

SDK Changes

  • Added cl_custom_message_text cvar to display a custom message on-screen, along with cl_custom_message_x and cl_custom_message_y to control the position on-screen (works like game_text)
  • Fixed ropes breaking at high framerates
  • Added documentation to the engine's server interface
  • Marked a few more engine functions as deprecated
  • Fixed code analysis warnings
  • Reworked the music system to use a separate OpenAL device to prevent the HRTF setting from affecting music playback
  • Added option to use Link-time optimizations (C++ compiler setting)
  • Reworked HEV suit sentence playback to no longer store group and sentence indices in save games (indices are not guaranteed to be stable)
  • Reworked sentence groups to allow sentences to be non-sequential, removed bad sentence group index diagnostic message
  • Redesigned sentences system to use JSON instead
  • Removed sv_snd_openal and cl_snd_openal cvars (sound is played through the OpenAL sound system only now)
  • Disabled follower logic for (ai)scripted_sequence to prevent players from activating them with +USE (scripts share code with NPCs, including follower code)
  • Converted documentation for server and client interfaces to Doxygen format, fixed swapped documentation for HUD_Init and HUD_VidInit

C# Changes

  • Added Sentences2Json: tool to convert sentences.txt to sentences.json

Asset Changes

  • Replaced sentences.txt with sentences.json
  • Removed sentence groups that aren't actual groups
  • Fixed bad sentence replacements used in the Opposing Force & Blue Shift replacement files
  • Reworked sentences so game-specific sentences replace originals

Framerate-independent rope physics

Ropes in Opposing Force don't account for the framerate so higher framerates cause players to apply more force to ropes, and ropes will eventually stop moving if the framerate gets high enough.

This has been fixed. Rope physics has been reworked to behave as it did at 30 FPS.

Sentences changes

The HEV suit's playback list used to store group and sentence names using their index which can change between maps in this mod because it supports custom sentences files. The list now stores the names instead. This also simplifies the API used to play sounds since it can deduce what is being played using the name. It previously required you to tell it whether it was a sentence or a group.

The switch to JSON means the engine can no longer load the mod's sentences files so support for using the engine's sound system has been removed. The OpenAL sound system handles everything just fine with the sole exception of the bell sound in the Hazard Course map. That single case can be fixed by manually adjusting the sound to play as it does under the original sound system.

The new file syntax looks like this:
{
    "Sentences": [
        // Grenade Warning
        "HG_GREN0 hgrunt/clik(p120) grenade! clik",
        "HG_GREN1 hgrunt/(t30) clik take!(e75) cover!(s5) clik",
        "HG_GREN2 hgrunt/clik clik oh! shit! clik",
        "HG_GREN3 hgrunt/(p110 t40) clik(p120) get!(e78) down!(t30) clik",
        "HG_GREN4 hgrunt/clik(p110) (t40) of!(e75) god! clik(p110)",
        "HG_GREN5 hgrunt/clik no! clik",
        "HG_GREN6 hgrunt/clik move! clik(p120)"
    ],
    "Groups": {
        "HG_GREN": [
            "HG_GREN0",
            "HG_GREN1",
            "HG_GREN2",
            "HG_GREN3",
            "HG_GREN4",
            "HG_GREN5",
            "HG_GREN6"
        ]
    }
}
Sentences is a list of strings containing the sentences, just like before.
Groups is an object of group names to lists of sentences that are in that group.

It is no longer required for sentences to start with the group name and it doesn't have to end with a digit either.
This allows another sentences file to replace groups and arbitrarily combine sentences.

A tool called Sentences2Json has been added that can convert the old format to the new. It also prints warnings if invalid or duplicate sentences are encountered. The default file has a few of those.

Here's an example of the BA_POK group being replaced, which is played when you +USE a pre-disaster Barney, as well as the scripted sentence BA_SEC2_NOPASS which plays when trying to continue in the Insecurity chapter before you've got your armor:
{
    "Sentences": [
        "BA_POK0 hgrunt/clik(p110) (t40) freeman you are lay!(e90) team!(e20) clik(p120) clik",
        "BA_SEC2_NOPASS barney/c2a4_ba_longnite"
    ],
    "Groups": {
        "BA_POK": [
            "BA_POK0"
        ]
    }
}
This becomes:
Note that you can reload the map to test changes as opposed to the original game which requires a full restart.

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Implement as much of the work scheduled on the issue tracker as possible (done)
  • Review all changes
  • First alpha build
  • Stress test the four campaigns and fix issues that show up (first test done)
  • First beta build
These changes represent the last programming work that had to be completed for V1.0.0. Code-wise this project is now feature complete, which means it's now time to test it and finish the documentation.

This also includes testing the 3 Updated projects independently to make sure they work on their own. That means 7 full campaign playthroughs are required to verify that they work as intended: once in each Updated project and once in the Unified SDK.

New beta builds for the Updated projects will be made available once i've done these tests.

That's about it for now, until next time.
Posted 10 months ago2023-06-16 08:38:07 UTC
in Is there any way to preview "p_" models? Post #347627
If possible, configure HLAM to log OpenGL info and show what's in the log file. See this page for more information: https://github.com/SamVanheer/HalfLifeAssetManager/blob/dev/docs/configuring-log-output.md

This should shed some light on why it fails to work.

Also note if it's not working due to an error or if it's crashing.
Posted 10 months ago2023-06-11 15:22:56 UTC
in Half-Life Updated (custom SDK) Post #347600

Progress on the Unified SDK

A new pre-alpha build is available: https://github.com/SamVanheer/halflife-unified-sdk/releases/tag/dev-2023-06-11
Note: pre-alpha builds are not intended for general testing. As the wiki article on software life cycles explains the first versions intended for this kind of testing are alpha builds. Pre-alpha builds are for testing specific features by request to verify that they work as expected based on bug reports and feature requests.

Since this project is still in the midst of development (essentially this is the game engine development part of the project) it's expected that there are bugs and features not working as expected (or at all). Once all required features have been implemented the project can move to the alpha testing stage where verifying the proper behavior is the main goal.

SDK Changes

  • Simplified talk monster friendly check and use/unuse sentence configuration. Friendly NPCs like scientists and security guards will no longer follow players if their classification treats players as anything other than allies (i.e. as if the player has shot them while not in combat)
  • Made it possible to for any NPC to follow players if they are friendly to the player (barebones support only)
    • Disabled following for some NPCs
  • Removed some obsolete HUD sprite functionality
  • Removed unused CHealthPanel class (non-functional VGUI1 version of the health HUD)
  • Reworked UI code to no longer use resolution size specifier
  • Reworked some string buffers & operations to avoid buffer overflows or truncations (fixes GCC compiler warnings)
  • Removed option to print list of all entities with ent_list client command to avoid network buffer overflows
  • Reworked weapons functions that start animations to use pev->body instead of a separate body parameter
  • Fixed Egon gun not stopping its attack animation if the attack button is held down and ammo runs out
  • Implemented chainsaw_melee skill variable: enables buggy melee attack behavior causing corpses to be damaged much faster
  • Changed client-side fog code to update fog parameters before the game frame is drawn to avoid edge cases that cause black screens
  • Clear global state when game_end is used to end multiplayer game (allows Co-op maps to clear state that may affect other maps)
  • Fixed various compiler warnings that occur at warning level 4. 3 warnings remain involving lambdas that have unreachable return statements. This is probably a code analysis bug, not incorrect user code
  • Fixed a bug in the text-based scoreboard that causes it to search for empty teams incorrectly. This code is not used and the VGUI1-based scoreboard does not have this bug
  • Optimized sound system to avoid a potentially expensive call when starting sounds
  • Reworked HUD message drawing to allow for unlimited-length lines
  • Prevent paths passed to filesystem functions from containing .. (parent directory)
  • Fixed Doxygen comments that contain bad syntax
  • Added child_classification keyvalue to allow NPCs that spawn NPCs (e.g. Big Momma, Osprey) to pass on classifications
  • Added unkillable keyvalue & cheat_unkillable: Makes NPCs and players unkillable, respectively. Not all NPCs support this setting
  • Mark monster_*_dead NPCs that should use human gibs as such so they spawn gibs
  • Play predicated sounds through OpenAL sound system as well (footsteps, weapon empty sounds)
  • Added sv_load_all_maps command to load all maps and generate node graph for them (allows leaving the game running on its own, can also be used to generate a log containing any errors logged by the game)
  • Don't switch weapons when using impulse 101 if the player has a weapon equipped already
  • Merged armor HUD into health HUD, draw armor next to health regardless of resolution (matches original game behavior at 640x480 resolution)
  • Fixed bug in sound loading code that caused it to calculate cue point positions incorrectly for stereo sounds
  • Fixed turrets and spore ammo entities not playing sounds in multiplayer in some cases
  • Reworked Nihilanth and Gene Worm death logic to not teleport players in multiplayer (used to trigger the end-of-map script)
  • Reworked Medic Grunt follower logic to follow player that used it instead of the local player
  • Removed invalid cast in Torch Grunt death logic

Asset Changes

  • Cleaned up fgd some more
  • Added keyvalues for new features to the fgd
  • Added test maps for some features
  • Added information about how to compile, package and copy models from source to a game installation using provided scripts
  • Changed hitgroup values for NPC models back to 0 to ensure game balance (i.e. damage required to kill) is identical to the original games
  • Fixed Rat NPC jump and death animations so they don't loop and end on the right frame
  • Fixed MP5 model so the arm vertices aren't attached to the weapon

NPC following behavior

Barebones support allowing NPCs to follow the player has been added:
NPCs don't have default start and stop sentences yet and may not always follow players as expected.

I implemented the essentials needed for this to work so others can expand on it as needed. This covers the AI schedule aspect of things and moving logic from a more specialized C++ class to the general NPC class.

Chainsaw melee

Chainsaw melee is a bug that causes melee weapons to attack corpses very quickly. It was fixed in this project, but i've added the option to enable it again:

Unkillable characters

NPCs can be set to be unkillable. Not all NPCs allow this since some have their own damage logic, but support can be added there as needed.

Players can also enable this for themselves using a cheat.
This feature is based on Source's buddha cheat.

Sounds in multiplayer

Some sounds didn't play in multiplayer. This happens with entities whose origins is in a brush or on the plane of a brush face. The calculations used to determine if a sound emitted at that position can be heard can produce false negatives causing the entity to be silent.

This was fixed by allowing entities to provide an offset to push the sound origin out of brushes. This fix can only be used with the new sound system since the original sound system has this code in the engine.

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Implement as much of the work scheduled on the issue tracker as possible (in progress)
  • Review all changes
  • First alpha build
  • Stress test the four campaigns and fix issues that show up (first test done)
  • First beta build
This completes more of what's becoming a small TODO list. There are only a few issues left on the issue tracker that will be handled for the first release.

I've tested the sound system with these high quality sound packs: Stereo sounds play without 3D spatialization, essentially they sound as if they're coming from the player entity. Mono sounds play just fine.
There was an issue with cue points not loading correctly but that was fixed. No other issues were found.

The previous dev build included outdated tools that would fail to run due to relying on an older version of the bundled Utilities library. All tools have been updated so that shouldn't be an issue now.

I'm writing documentation for some engine functions to make it easier to work with them. Note that Doxygen's UI program currently freezes when processing this codebase due to a problem with the doxywizard program. The problem has been dealt with so the next release should work fine.

That's about it for now, expect the next progress update to be smaller than this one.
Posted 10 months ago2023-06-04 08:44:19 UTC
in [Help] Sparks Above NPCs Heads Post #347579
This only shows up if you use debug builds. Make a release build and it won't happen.

It's also vanilla HL SDK behavior, not specific to HL Updated.
Posted 10 months ago2023-06-03 14:21:35 UTC
in Half-Life Updated (custom SDK) Post #347576

Progress on the Unified SDK

A new pre-alpha build is available: https://github.com/SamVanheer/halflife-unified-sdk/releases/tag/dev-2023-06-03
Note: pre-alpha builds are not intended for general testing. As the wiki article on software life cycles explains the first versions intended for this kind of testing are alpha builds. Pre-alpha builds are for testing specific features by request to verify that they work as expected based on bug reports and feature requests.

Since this project is still in the midst of development (essentially this is the game engine development part of the project) it's expected that there are bugs and features not working as expected (or at all). Once all required features have been implemented the project can move to the alpha testing stage where verifying the proper behavior is the main goal.

SDK Changes

  • The name of the renderer (Software or OpenGL) is now shown in the debug overlay. It also recognizes Direct3D but the engine does not support it anymore and does not include the code for it to work
  • The weapon deploy animation is now always sent to clients when calling EquipWeapon to ensure it plays when the player stops using func_tank entities
  • Renamed allow_weapon_dropping skill var to allow_player_weapon_dropping, added allow_npc_item_dropping to globally control whether NPCs can drop items on death
  • Added null check to scientist fear task to prevent potential crashes
  • Stop func_train move sound when triggered off (fixes sound looping issue in c1a0c (first Unforeseen Consequences map))
  • Fixed Desert Eagle laser position not updating when holding down reload button
  • Fixed Voltigore beams created on death connecting to the wrong entity, causing them to appear to connect to the world origin
  • Fixed being able to break scripted_sequence by +using friendly NPCs to make them follow player
  • Fixed potential incorrect facing in scripted_sequence
  • Fixed female assassin footsteps always playing every 0.2 seconds when walking and running (now uses the same intervals as player, but may differ somewhat because NPCs only think 10 times a second)
  • Fixed female assassins not resetting their movetype if they jump and land while not in combat (resulted in stuttering movement because they were considered to still be in the air)
  • Added ent.io trace logging for multi_manager start
  • Precache monstermaker entities using provided keyvalues
  • Added diagnostics to entity templates for classname key
  • Simplified trigger_changekeyvalue logic
  • Increased maximum number of multi_manager targets from 16 to 64
  • Fixed env_blowercannon crashing if target does not exist, simplified spore creation
  • Implemented logic_random: triggers a randomly selected target out of up to 16 targets
  • Don't draw the beam sprite for the night vision HUD icon
  • Reworked armor HUD to avoid depending on relative positions of the full and empty icons in the sprite sheet
  • Increased maximum number of weapon slots to 10
  • Reworked train control & pain sprites to use hud.json entry for name mapping to enable an Opposing Force-specific version to be used
  • Added barebones bot system for multiplayer testing (see below)
  • Implemented new temporary entity list; increased maximum number from 500 to 2048 (see below)
  • Limited Overflow 2048 temporary ents! message to only print once per frame (excessive logging caused framerate drops to < 30 FPS)
  • Reworked NPC-spawned gibs to be created as temporary entities to eliminate problems with ED_Alloc: out of edicts errors, crashes, entity rendering issues (see below)

C# Changes

  • Fixed c3a2b (Lambda Core map 3) valves soft) locking if turned too quickly in succession. The second valve now locks until it is safe to use it
  • Fixed game over text being cut off in c3a2 (killing retinal scanner scientist in Lambda Core map 1)
  • Fixed some sounds restarting on save load
  • Fixed Nihilanth dialogue on c4a2 (Gonarch's Lair map 1) not playing ("Win, you cannot win")
  • Reworked upgrade tool classes to improve consistency in API design
  • Renamed Installer to ContentInstaller
  • Renamed executables to remove the HalfLife.UnifiedSdk prefix (the Map Decompiler executables have also been renamed)
  • Added flag matching to KeyValueMatcher to filter results by spawnflags or other flag keyvalues
  • Fixed c2a5 (Surface Tension map 1) barrel not flying up if destroyed using radius damage attack
  • Updated Sledge libraries to latest version
  • Reworked Entity class to store keyvalues as lists instead of dictionaries (matches map compile tools behavior)
  • Prune excess multi_manager keyvalues (affects retinal scanner scripts that had too many keys)
  • Reworked Asset Synchronizer to minimize time spent in event handlers to avoid Too many changes at once in directory errors

Asset Changes

  • Various updates to zoo_npcs to improve map performance, stability and behavior
  • Added test maps for features and bug fixes
  • FGD changes:
    • Added Contents choices to func_train (allows trains to be made out of water, slime or lava)
    • Removed redundant and unused keyvalues
    • Fixed incorrect uses of target_source keyvalue type
    • Added missing master keyvalue to game_zone_player
    • Added ReplacementFiles base class to entities that use sounds or sentences
    • Added logic_random
  • Added HUD sprites for Half-Life & Opposing Force HUDs, updated HUD config files to use the new sprites
  • Updated hud.json entries used by entities whose names have changed
  • Added hud.json entries for the Blue Shift helmet & armor vest pickup items
  • Removed hud.json entries for unused train icons, added train_controls & pain_directions entries to allow the HUD to locate the right files at runtime
  • Hide Change Game button when launching the game directly (as opposed to launching through Steam)
  • Updated OpenAL library name in the package manifest so the right file is packaged

Half-Life and Opposing Force HUDs

The HUD is now capable of being switched between the Half-Life and Opposing Force icons:
This was made possible by the creation of new HUD sprites by malortie. Many thanks for the great work you've done!

Bots

A barebones bot system has been added to enable testing multiplayer. These bots are capable only of spawning and respawning when killed and do not know how to select teams and classes so they can't be used in the Capture The Flag gamemode.

New temporary entity list

The client-side temporary entity list has been replaced with a new one that has a higher limit. The engine's list has a maximum of 500 entities, whereas this one has 2048.

This limit is pretty arbitrary. Technically it can even be made unlimited, but it won't increase the number of visible temporary entities because the engine can only render 512 entities in a single frame. Without raising that limit first increasing the temporary entity limit will not have much of an effect. This would require a custom renderer which is out of scope for this project.

A performance issue in the printing of Overflow 2048 temporary ents! has also been addressed.

Client-side gibs

Gibs spawned by NPCs are now handled on the client side. Previously gibs were server side, causing them to count towards the server-side entity limit. Spawning a lot of them could cause the game to shut down or crash, and often caused other entities to disappear because they also count towards the server-side visible entity limit (max 255).

Gibs are now temporary entities and can be spawned en masse without causing errors or crashes:
The cvars cl_gibcount, cl_giblife and cl_gibvelscale control how many are spawned, how long they exist once they stop moving and how much their velocity is affected (the settings in the video are 100, 1 and -10000 respectively).

Some NPCs override the gib count since they want to spawn a specific number of gibs but for most NPCs the cvar is taken into account.

The gibshooter entity still uses server-side gibs but this can be changed if necessary.

Project merging status

Project merging is complete. While there are still some useful changes that could be merged none of them are user-facing and are mostly about fixing minor bugs and making things a bit easier for programmers to use.

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Networking system (other immutable data) (done)
  • Versions of Opposing Force-only HUD images that have the scanline effect removed (done)
  • Merge in remaining useful functionality from other projects (done)
  • Implement as much of the work scheduled on the issue tracker as possible (in progress)
  • Review all changes
  • First alpha build
  • Stress test the four campaigns and fix issues that show up (first test done)
  • First beta build
Quite a bit of work is completed now, most of what's left are open issues on the issue tracker and things on my TODO list.

Many thanks to malortie for making the new HUD sprites. With the completion of that feature this SDK can now be used to play all 4 campaigns with the look and feel of each game, which is the main goal for the project.

Thanks to Ronin4862, LambdaLuke87, Oxofemple, FreeSlave and Shepard for helping with bug reporting and fixing.

Special thanks to Penguinboy for updating the Sledge libraries to provide keyvalues as lists to allow for more accurate modification of maps using the map upgrade tool.

This project is in the home stretch now, now it's just a matter of wrapping up remaining work, testing everything and documenting it.
Posted 11 months ago2023-05-21 17:26:16 UTC
in Half-Life Updated (custom SDK) Post #347537
<-- Continued from previous post

zoo_npcs test map

The zoo_npcs test map has been added and includes functionality to test most of the non-scripted NPCs as well as weapons, items, ammo and other new features.
As you can see there is still work needed for the classification changes to work properly. Additional features are needed to help reduce the number of entities created since it exceeds the server-side maximum visible entities limit at times (255).

Note that the turrets float up when the fuel and vent buttons are enabled because both apply trigger_push (fuel to force entities to move and touch trigger_hurt) to all entities in the arena. Since the turrets aren't meant to move they aren't set up to handle this properly.

New features used in the map (not an exhaustive list):
  • trigger_changekeyvalue: used to configure NPCs after spawning to set the classification and is_player_ally keyvalues
  • point_teleport: Used to teleport the player at the push of a button
  • Health & HEV chargers: infinite capacity, recharge 5 units per tick instead of 1
  • All item entities: float item to retain designer-configured angles, stay visible during respawn, sound replacement file to silence respawn sound, respawn in singleplayer, give max ammo on pickup
  • ammo_all: Resupply point outside Displacement field lab
  • env_warpball: Teleport target for Displacement field lab teleporters, creates teleport effect
  • trigger_teleport: fire_on_teleport triggers warpball entity on teleport
  • ´!activator´: Used to kill destroyed turrets (a func_button in a room under the map is used for this, since trigger_relay doesn't preserve the activator)
  • monstermaker: Pass initial path_corner target name to Apache and Osprey NPCs
  • func_tank: target lasers

Project merging status

Current status:
  • Half-Life Updated (up-to-date)
  • Half-Life: Opposing Force Updated (up-to-date)
  • Half-Life: Blue Shift Updated (up-to-date)
  • Half-Life Updated CMake (done)
  • HLEnhanced (in progress)
  • Enhanced Half-Life (almost done)
  • Half-Life Better Weapons (done)
  • Condition Zero: Deleted Scenes SDK (done)
Some of the changes listed above involved integrating features that exist in HLEnhanced, the list of features left to merge is getting very small now.

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Networking system (other immutable data): Networking system is implemented, new and existing features are being updated to use it
  • Versions of Opposing Force-only HUD images that have the scanline effect removed: in progress
  • Merge in remaining useful functionality from other projects (in progress)
  • Implement as much of the work scheduled on the issue tracker as possible (in progress)
  • Review all changes
  • First alpha build
  • Stress test the four campaigns and fix issues that show up (first test done)
  • First beta build
The Half-Life Uplink demo maps are included with the game installation now since it's a free demo, and setting it up to copy the maps is non-trivial (Uplink uses the same mod directory name so it has to be renamed, and the maps have to be extracted from the pak0.pak file). The demo works fine aside from a couple scripted events that glitch out, but that also seems to happen in the original so i don't consider those to be worth fixing.

The remaining work required for classifications isn't too much so that should be done soon. After that there's a bunch of smaller stuff i need to check out.

The list of remaining work is getting smaller. There are only a few remaining issues on the issue tracker, not all of which will be implemented.
After that i have to go through my TODO list which includes remaining project merging work.

With a bit of effort the implementation work should be done soon.
Posted 11 months ago2023-05-21 17:26:12 UTC
in Half-Life Updated (custom SDK) Post #347536

Progress on the Unified SDK

SDK Changes

  • Fixed mouse movement during map load affecting initial view angles (caused the player to look to the side instead of straight ahead)
  • Set monster_rosenberg model to correct default (was still using scientist.mdl)
  • Overhauled entity classification system (see below)
    • Implemented is_player_ally keyvalue
  • Fire monstermaker target after NPC spawning is done instead of after NPC creation and before spawning
  • Re-implemented UTIL_FindEntityBy* functions to avoid calling engine function (see below)
    • Implemented wildcard matching for entity classname, targetname & target searches
  • Implemented point_teleport
  • Added initial_capacity keyvalue to Osprey NPCs to allow specifying how many grunts/assassins to deploy instead of relying on existing NPCs in the map to influence calculations (max 24)
  • Implemented targeting laser in all func_tank entities
  • Fixed func_tank entities not returning player weapon control when killtargeted
  • Prevent engine precache limit from being reached (game will no longer tell engine to precache a resource if doing so would cause the limit to be exceeded)
  • Implemented target selector support for target, killtarget & point_teleport (see below)
  • Always store activator on delay trigger to allow access to initial activator entity in delayed trigger setups
  • Ensure turret NPCs finish dying so they don't keep running dying logic forever if killed during first activation
  • Fire Death trigger condition when turret NPCs are destroyed
  • Install additional 32 bit Linux dependencies when running Linux CI (needed because Github Actions has updated its default Linux environment)
  • Implemented Counter-Strike style env_fog
  • Play hud & geiger sounds on unique channels to avoid preempting game sounds (geiger used to cause sounds to cut out)

Asset changes

  • Add default entity classifications config file
  • Added new keyvalues to fgd
  • Added point_teleport and env_fog entities to fgd
  • Cleaned up fgd a bit to remove non-existent functionaltiy and properly hint to level editor how to use certain keyvalues
  • Added source files for class_signs.wad (contains textures stating NPC names)
  • Added zoo_npcs map
  • Added Half-Life Uplink demo sentences & titles entries

C# Changes

  • Fixed flare sprites in c4a3 (Nihilanth boss battle death script) using wrong render mode
  • Fixed grunt on stretcher holding gun in of1a1 (Opposing Force "Welcome To Black Mesa" map)
  • Clear model keyvalue for monster_rosenberg (defaults to correct model in code now)
  • Copy Uplink maps from valve_uplink directory

Entity classification changes

The entity classification system has been redesigned for comfort and utility. Previously this was a hard-coded table defining the relationship between entity classifications.

You can think of a classification as a faction. The human_passive classification (Black Mesa scientists) fears human_military (Human Grunts) and will run away from them. human_military dislikes human_passive and will attack them.

This is now defined in a configuration file:
{
    // Class none is always added and should only have relationship "none" (default) to all classes.
    "none": {},
    "machine": {
        "Relationships": {
            "player": "dislike",
            "human_passive": "dislike",
            "human_military": "none",
            "alien_military": "dislike",
            "alien_passive": "dislike",
            "alien_monster": "dislike",
            "alien_prey": "dislike",
            "alien_predator": "dislike",
            "player_ally": "dislike",
            "player_bioweapon": "dislike",
            "alien_bioweapon": "dislike",
            "human_military_ally": "dislike",
            "race_x": "dislike"
        }
    },
    "player": {
        "Relationships": {
            "machine": "dislike",
            "human_military": "dislike",
            "alien_military": "dislike",
            "alien_passive": "dislike",
            "alien_monster": "dislike",
            "alien_prey": "dislike",
            "alien_predator": "dislike",
            "player_bioweapon": "dislike",
            "alien_bioweapon": "dislike",
            "race_x": "dislike"
        }
    },
    "human_passive": {
        "Relationships": {
            "player": "ally",
            "human_passive": "ally",
            "human_military": "hate",
            "alien_military": "hate",
            "alien_monster": "hate",
            "alien_prey": "dislike",
            "alien_predator": "dislike",
            "player_ally": "ally",
            "human_military_ally": "dislike",
            "race_x": "hate"
        }
    },
    // More classifications here
}
As usual it can be overridden on a per-map basis, though it only supports a single file per map.

The default classification used by NPCs now uses these names instead of a hard-coded index.

Notable changes to existing classifications:
  • added alien_flora classification for Xen trees and large spores (replaces CLASS_BARNACLE which wasn't used by barnacles and was never used because it would cause the class table to be accessed out of bounds)
  • Added IsMachine method to determine whether an entity is a machine of some kind (e.g. Osprey, turrets)
  • Added IsBioWeapon method to determine whether an entity is a bioweapon of some kind (e.g. Snarks, Penguins, Hornets)
  • Changed RadiusDamage and FlameDamage methods to take ignore class as last parameter to allow it to be defaulted to "none"
  • Changed squad monster code to use CanRecruit function to determine whether a candidate entity can be recruited into the current squad monster's squad
  • Changed human grunts, allied human grunts and shock trooper squad dialogue to only identify enemies as monsters if they have alien gibs (previously entities that are not players, player allies, human passive or machines were considered to be monsters)
  • Changed Snarks and Penguins to change their classification when they update their enemy instead of doing so when their classification is requested (avoids possible recursion). They will not do so if they are using a custom classification.
Two new keyvalues have been added:
  • classification: If defined, changes the NPC's classification to the specified class (must be one named in the map's classification config file). The new entity templates feature can be used to apply this to every instance of a specific type of NPC in a map. The new target selector feature (see below) can be used to change the player's classification.
  • is_player_ally: Has three possible values: Default, No and Yes. Default uses the relationship from the NPC's class to the player's class defined in the map's classification config file. No equals dislike (will attack), Yes equals ally.
The classification system changes are not done yet. More work is needed before it works as intended but this covers the majority of the work required.

Entity lookup changes

The functions used to look up entities by classname, targetname and target have been re-implemented in game code. Previously they asked the engine to find entities.

Doing so makes these functions more efficient, not only by eliminating a function pointer call but also because the engine uses an inefficient lookup method. Every time the engine is asked it first looks up the address of the variable used to perform comparisons which slows things down.

The new implementation uses a callback to indicate which variable to use. Analysis of compiled release builds shows that the callback does not exist at all so there is no overhead involved with selecting the variable anymore.

In addition these functions now accept wildcards just like source. So you can for instance trigger all entities that start with a specific prefix:
"target" "class_sprite_*"

Just like Source it only accepts wildcards at the end.

It is now also possible to use target selectors in some cases. For example you can kill the activator of a trigger like this:
"killtarget" "!activator"

Unfortunately some entities don't pass activators along properly, like trigger_relay which passes itself instead.

Two target selectors are supported:
  • !activator: The entity that started the current trigger execution
  • !caller: The last entity in the trigger execution chain

Teleport entities changes

trigger_teleport now has a fire_on_teleport target fired whenever it teleports an entity. Useful for triggering effects and whatnot.

The new point_teleport entity can be used to teleport a targeted entity to the point_teleport entity's position. To teleport the entity that activated it (like a player pressing a button that triggers the teleport entity) the !activator target selector can be used.

It also has a fire_on_teleport keyvalue.

func_tank changes

All tank entities now correctly restore the player's weapon if they are killtargeted. Previously this left the player in an invalid state where the weapon HUD was disabled.

Tanks now also have a target laser visible only to the player that is currently using it.

This laser is enabled only if turned on with the enable_target_laser keyvalue and can use a designer-configured sprite, width and color.

env_fog

Counter-Strike's env_fog entity has been implemented here as well. This entity allows the addition of fog with configurable density, start and stop distances, color and the option to also affect the skybox.

The TWHL and VDC wikis have been updated to include missing keyvalues and spawnflags for this entity.

Note that fog only renders when using the OpenGL renderer. This uses the engine's fog rendering code, not custom OpenGL code.

Hud & geiger sound changes

HUD sounds (weapon selection HUD & chat text) now play on a dedicated sound channel, as do geiger sounds. Previously these played on the player's item channel which is also used for things like weapon reloading. Since the geiger plays very often when near a radiation source it kept cutting off the sounds. This is no longer the case.
--> Continued in next post
Posted 11 months ago2023-05-21 15:44:01 UTC
in Half-Life Updated (custom SDK) Post #347535
And did you learn about modern delegate unmanagable pointers and you would like to port whole Half-Life into C# if Valve Software would like to be happy if many coders write in C# and develop own game better then Xash.
No, i stopped working on SharpLife because that project is way too big to be completed in a reasonable amount of time and recreating game behavior is too difficult to do with available resources.

Like i said on Discord SDL3 is not backwards compatible with SDL2. If you intend to interface with existing mods then you will have to use SDL2 for it to work.

Since native libraries have platform-specific behavior you may run into problems if you try to load multiple versions of the same library into memory. In my experience the Linux runtime linker will try to merge identical symbols even if they exist in different dynamic libraries so it may try to merge SDL2 and SDL3 APIs into a single one.

This happened when i converted some globals to use C++17 inline declarations so i had to change the default symbol visibility to hidden, which you can't do with exported symbols like SDL2's API since those must have default (public) visibility to be directly accessible from other binaries. I also had to make a custom SDL2 build to load it side-by-side since it creates process-global objects managed at the operating system level. That was on Windows but Linux likely has something similar.
Posted 11 months ago2023-04-30 22:21:59 UTC
in Half-Life Updated (custom SDK) Post #347492
That's an avi file. The engine doesn't have any support for video playback, and that was done on the main menu. This menu is done using VGUI1, it's an in-game menu. Rendering a video in that is impractical at best and a lot of work either way.
Posted 11 months ago2023-04-30 14:04:50 UTC
in Half-Life Updated (custom SDK) Post #347490

Progress on the Unified SDK

SDK Changes

  • Made config system code server only to avoid spending time building this code for the client dll
  • Reworked entity creation and destruction to allow additional logic to be added in around the OnCreate and OnDestroy function calls
  • Implemented entity templates (see below)
  • Reworked weapon_rpg and ammo_rpgclip to use entity templates for multiplayer-only ammo doubling
  • Sync client with server gauss charge time value so spin sound pitch is correct after level change
  • Fixed sounds played on current view entity lagging behind in multiplayer (they now always sound like they originate at the current view position)
  • Reworked casts to CBasePlayer to use ToBasePlayer (extra safety checks and runtime type validation in debug builds)
  • Reworked utility functions involving players to take CBasePlayer* (avoids passing non-player entities to these functions and simplifies function calls)
  • Don't use entvars_t::enemy if it can be avoided (the engine uses this variable in NPC movement code but it doesn't seem to actually be used, needs more investigation)
  • Use UTIL_FindEntityByTargetname when searching by targetname instead of UTIL_FindEntityByString
  • Disable trigger_teleport when target is an empty string (prevents teleportation to seemingly random locations)
  • Added missing monster state name to ReportAIState function (HL Updated change, already done in Unified before)
  • Implemented HUD replacement system (see below)
  • Fixed VGUI1 CListBox class setting scrollbar range to incorrect maximum (off by one issue, last line was always empty as a result)
  • Implemented Campaign selection menu (replaces New Game dialog) (see below)
  • Reworked CTF item detection to avoid use of entity classification (uses MyCTFItemPointer() function now)
  • Reworked how the game determines which kind of gibs to spawn (human or alien gibs, relied on the entity classification before which isn't always accurate)
  • Fixed entities notifying their owner of death multiple times in some cases (this broke monstermaker)

Asset Changes

  • Added entity template for MP5 to set default ammo amount to full magazine (50 rounds) for Opposing Force
  • Set weapon_rpg and ammo_rpgclip ammo amounts to 2 for multiplayer (was previously hard-coded)
  • Added GameMenu.res and gameui_english.txt
  • Disabled New Game menu button, added new Start Campaign... menu button that opens the campaign selection menu
  • Added campaign configs for Half-Life, Opposing Force, Blue Shift and the Uplink demo (Uplink has not been updated to account for code changes, needs more work)
  • Added campaign selection map
  • Updated the localization files

Entity Templates

Entity templates is a feature added to allow the MP5 to have a full magazine by default in Opposing Force (50 rounds instead of 25 as in all other HL games).

Entity templates work by allowing level designers to change the default value of a keyvalue for a specific type of entity. Here's how the MP5's is done:

cfg/entitytemplates/op4/weapon_9mmar.json:
{
    "default_ammo": "50" // Full magazine
}
cfg/OpposingForceConfig.json:
// Rest of file omitted
{
    "SectionGroups": [
        {
            "Sections": {
                "EntityTemplates": {
                    "weapon_9mmar": "cfg/entitytemplates/op4/weapon_9mmar.json"
                }
            }
        }
    ]
}
The map config specifies which template to use; the template itself is a collection of keyvalues to apply.

The template is applied after the entity is created (after OnCreate has finished) but before level designer-set keyvalues are applied. All entities with the specified classname are affected, even if created by a monstermaker or when transitioned from another map.

This is only a simple use of a very powerful feature. You can use this to do things like changing the health of all security guards, change the default model of all grunts to that of the Male Assassin, set the sentence/sound/model replacement file for all zombies, pretty much anything you'd want to do to every instance of a specific entity whose keyvalues aren't always set by designer-placed versions (i.e. if the fgd sets a default value that will always take precedence over the template).

HUD replacement system

It's now possible to replace the HUD on a per-map basis by changing the HUD config files used for the HUD itself and for each weapon.
// Rest of file omitted
{
    "SectionGroups": [
        {
            "Sections": {
                "HudReplacement": {
                    "HudReplacementFile": "sprites/op4/hud.json",
                    "Weapons": {
                        "weapon_9mmar": "sprites/op4/weapon_9mmar.json"
                    }
                }
            }
        }
    ]
}
This overrides the default files used (sprites/hud.json and sprites/weapon_9mmar.json respectively) and causes the client to use the sprites specified therein instead.

This feature does not take effect yet because the art assets have not been completed. malortie is working on those and has been making good progress.

Campaign selection menu

The New Game dialog has been replaced with the Campaign selection menu. This menu allows you to select a campaign from a list and start either its campaign or training map.
This menu works by loading a map that opens a menu. That menu loads the list of campaigns by scanning the campaigns directory for JSON files.

JSON file structure:
{
    "Label": "Half-Life",
    "Description": "The Half-Life campaign.\n\nRelease date: 1998.",
    "CampaignMap": "c0a0",
    "TrainingMap": "t0a0"
}
Either the campaign or training map name can be omitted, in which case the option is disabled. If both are omitted or the file doesn't contain the expected data the file is ignored.

Campaigns are ordered based on their filename. The 4 campaigns shown have these names:
  • 001HalfLife.json
  • 002OpposingForce.json
  • 003BlueShift.json
  • 004Uplink.json
All search paths are scanned so these files can be in <moddir>/campaigns, <moddir_addon>/campaigns, <moddir_downloads>/campaigns or other directories usually checked by the filesystem.

There's no extra work needed to list them, no manifest or anything. This means the same mod can be used as a base for unrelated mods/map packs to allow them to launch through the same menu.

This menu is for singleplayer campaigns only, not multiplayer. Though it can be modified to allow the launching of multiplayer games it isn't recommended since this menu works by loading a singleplayer map.

It's not meant to be anything fancy, it's just a quick and easy way to start a campaign map.

Project merging status

Current status:
  • Half-Life Updated (up-to-date)
  • Half-Life: Opposing Force Updated (up-to-date)
  • Half-Life: Blue Shift Updated (up-to-date)
  • Half-Life Updated CMake (done, project has been archived)
  • HLEnhanced (in progress)
  • Enhanced Half-Life (almost done)
  • Half-Life Better Weapons (done)
  • Condition Zero: Deleted Scenes SDK (done)
No changes since the last progress update, but there are work in progress branches that cover the merging of some of the last features that need to be merged. Some of the work listed above was done in preparation for this work.

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Networking system (other immutable data): Networking system is implemented, new and existing features are being updated to use it
  • HUD image replacement for Opposing Force: HUD replacement system has been implemented (complete)
  • Versions of Opposing Force-only HUD images that have the scanline effect removed: in progress
  • A way to start all three campaigns from the main menu: Done, plus ability to start Half-Life: Uplink and add more campaigns with minimal work (complete)
  • Merge in remaining useful functionality from other projects (in progress)
  • Implement as much of the work scheduled on the issue tracker as possible (in progress)
  • Review all changes
  • First alpha build
  • Stress test the four campaigns and fix issues that show up: now includes Uplink as well, once it has been converted (first test done)
  • First beta build
A fair amount of work got done in just a week, but that's because these features build on work that was done before. Entity templates required the item overhaul to be merged in from EHL first since that added the keyvalues to control weapon and ammo amounts; HUD replacement required the switch to JSON files to be done first.

I'd have preferred to overhaul the UI for campaign selection to make it look a little nicer but it would take a lot of work to do that, and this project has been in development for long enough. The focus now is on completing remaining work that's small and useful.

In practice this means most of the open issues on the issue tracker as well as a lot of small things to check that i've got on my TODO list. I'm holding off on going into detail about these because i want to sure about the viability of the remaining work before discussing it.

Once more of the ingoing work is complete i will make another dev build available. That may be as soon as next week but we'll see.
Posted 11 months ago2023-04-28 12:51:05 UTC
in Func_Button trouble Post #347486
The toggle flag should do that but depending on other keyvalues its behavior may change. Maybe create a small test map that illustrates what you're trying to do and what isn't working.
Posted 1 year ago2023-04-22 16:29:17 UTC
in Half-Life Updated (custom SDK) Post #347473
<-- Continued from previous post

Asset Changes

  • Updated fgd to account for code changes
  • Added test maps for new features
  • Removed DefaultGameData.json (now defined in game code)
  • Updated Create Server config to account for code changes
  • Added dummy mapcycle.txt and default mapcycle.json
  • Added default Spawn Inventory for multiplayer and CTF (was previously hard-coded)

Map configuration file changes

The map change config file has been removed. It had been added as a counterpart to the engine's mapchange cfg file but in practice it doesn't have any value since it can only change cvars after the game has already started which has the potential to break things.

The server config can now only echo text to the console and execute commands. Default configurations are now hard-coded again to help avoid the case where a server operator modifies the default config, players download a custom map and are then unable to play it due to those changes being missing.

If a map doesn't have a configuration file the game will use the default map configuration file cfg/DefaultMapConfig.json instead.

Game mode selection

Game mode selection has been completely reworked. Previously the game mode used in multiplayer depended on whether the map enables co-op and the value of mp_teamplay. Now maps can specify the default game mode and lock it to that in the map cfg:
{
    "Includes": [
        "cfg/OpposingForceConfig.json"
    ],
    "GameMode": "ctf",
    "LockGameMode": true
}
The server can choose a game mode using the mp_gamemode cvar which contains the name of the game mode to use (deathmatch, teamplay, ctf, coop).

The Create Server dialog also lets you choose one, unfortunately due to engine limitations this had to be done using a separate cvar mp_createserver_gamemode. That cvar overrides the value of mp_gamemode so the method used is slightly different when starting a server that way.

Since engine bugs cause cvars to be updated too late when starting a second local server through the main menu the game now brute forces the engine to execute remaining cvar changes. Due to engine bugs this can cause multiple map changes to occur which the game now responds to by returning you to the main menu. This should never happen since it requires a specially crafted set of console commands to be executed.

The co-op gamemode is now mostly playable. Some entities still need changes to work correctly in a multiplayer environment but for the most part they now behave as they should. Some game logic and features need updating to handle co-op specific requirements as well.

Mapcycle changes

The map cycle is now JSON instead of the original custom format. I don't think many people are aware that the original map cycle format has optional attributes:
// Example/Default mapcycle for Deathmatch Maps
// Copy to mapcycle.txt to use :)
//
op4_bootcamp   "\minplayers\0\maxplayers\32\mp_weaponstay\1\"
op4_datacore   "\minplayers\0\maxplayers\32\mp_weaponstay\1\"
op4_demise     "\minplayers\0\maxplayers\32\mp_weaponstay\1\"
op4_disposal   "\minplayers\0\maxplayers\32\mp_weaponstay\1\"
(from WON Opposing Force)

The original version allows maps to be restricted to certain player counts and also to set cvars. Since the Unified SDK has map configs the ability to change cvars is rather useless and the syntax is pretty confusing, so it's now JSON:
[
    "undertow",
    {
        "Name": "snark_pit",
        "MinPlayers": 0,
        "MaxPlayers": 32
    },
    "boot_camp",
    "lambda_bunker",
    "datacore",
    "stalkyard"
]
It works the same way but it's a lot easier to understand.

The map cycle code is also a lot simpler so it's easier to modify if you wanted to say, modify it for co-op to handle map packs that are chained together using trigger_changelevel. You wouldn't include all maps in the map cycle file so you'd have to keep track of the last map that was in the file so you can skip to the next one.

In most cases you'll only have a list of map names so the syntax barely changes.

Spawn Inventory and Persistent Inventory

Two new features have been added to remove hard-coded functionality, fix bugs and improve co-op.

The Spawn Inventory is a configuration feature that lets you define what the player's inventory is like when they spawn in the game. In singleplayer this is the inventory they start with when a map is loaded using the map command, so when playing through a campaign you'll only get it in the first map, never in subsequent maps.

In multiplayer this is the inventory each player starts with when they respawn. Gamemode-specific inventories are handled through conditional sections in the map config. A new config file called cfg/BaseGameConfig.json has been added that defines the defaults:
{
    "SectionGroups": [
        {
            "Condition": "Multiplayer",
            "Sections": {
                "SpawnInventory": {
                    "HasSuit": true,
                    "Weapons": {
                        "weapon_crowbar": {},
                        "weapon_9mmhandgun": {}
                    },
                    "Ammo": {
                        "9mm": 68
                    },
                    "WeaponToSelect": "weapon_9mmhandgun"
                }
            }
        },
        {
            // Override default multiplayer inventory for CTF.
            "Condition": "Multiplayer && GameMode == \"ctf\"",
            "Sections": {
                "SpawnInventory": {
                    "Reset": true,
                    "HasSuit": true,
                    "Weapons": {
                        "weapon_pipewrench": {},
                        "weapon_eagle": {},
                        "weapon_grapple": {}
                    },
                    "Ammo": {
                        "357": 21
                    },
                    "WeaponToSelect": "weapon_grapple"
                }
            }
        }
    ]
}
You can control whether the player is given the following:
  • HEV suit
  • Long jump module
  • weapons
  • ammo
And set health and armor to any valid value.

And you can choose which weapon is selected by default.

You can also specify the default ammo in a weapon:
"Weapons": {
    "weapon_crowbar": {},
    "weapon_9mmhandgun": {
        "DefaultAmmo": 34 // Two magazines by default
    }
}
So you can give players empty weapons, make them injured by default, or give them a full loadout.

This feature is also used in Blue Shift to replace the original method used to give the HEV suit since it no longer works (it depended on the player touching the suit before touching a teleport trigger). This also allows players to get the HEV suit if they join a co-op game after it has started on that map, though they'll spawn in the wrong location (campaign maps need a lot of adjustments for co-op, which is out of scope for this project).

Building on the backend functionality used by this feature is Persistent Inventory, a feature exclusive to co-op that allows players to carry their inventory state to the next map. All of the above is carried over along with the weapon's current magazine count.

A skill variable coop_persistent_inventory_grace_period controls how long this persistent inventory is given when respawning. A trigger_changelevel keyvalue controls whether the inventory is persisted or not.

Here's a video showing co-op and persistent inventory:
Note that some sounds aren't playing due to an engine bug. I am working on a solution for that.

Project merging status

Current status:
  • Half-Life Updated (up-to-date)
  • Half-Life: Opposing Force Updated (up-to-date)
  • Half-Life: Blue Shift Updated (up-to-date)
  • Half-Life Updated CMake (done, project has been archived)
  • HLEnhanced (in progress)
  • Enhanced Half-Life (almost done)
  • Half-Life Better Weapons (done)
  • Condition Zero: Deleted Scenes SDK (done)
Merging continues along with planned features being finished. This shouldn't take much longer.

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Networking system (other immutable data): Networking system is implemented, new and existing features are being updated to use it
  • HUD image replacement for Opposing Force: basic hud sprite name replacement test done and functional; more complete implementation will be added to implement this feature
  • Versions of Opposing Force-only HUD images that have the scanline effect removed: in progress
  • A way to start all three campaigns from the main menu. Probably the same solution as used in Condition Zero Deleted Scenes (menu button that starts a map that opens an SDK-level menu that enables campaign and training selection)
  • Merge in remaining useful functionality from other projects (in progress)
  • Implement as much of the work scheduled on the issue tracker as possible (in progress)
  • Review all changes
  • First alpha build
  • Stress test the three campaigns and fix issues that show up (first test done)
  • First beta build
Most of the work done the past few weeks has been completing work that was listed on the issue tracker. That's quickly getting done and some of those also involve merging other projects (e.g. HLEnhanced weather effects code).

One by one major features are getting implemented, co-op is mostly finished now (you can actually make map packs now that level changes work) so it's going pretty smoothly.

I will end this progress update with a couple videos showing new features:
Posted 1 year ago2023-04-22 16:29:06 UTC
in Half-Life Updated (custom SDK) Post #347472

Progress on the Unified SDK

SDK Changes

  • Optimized build times a bit (possibly up to half the build time depending on the machine)
  • Fixed game_text messages not resetting time value correctly causing messages that reuse channels to use the wrong start time
  • Fixed sounds set to play everywhere (e.g. scripted_sentence) still setting an origin and having directional audio (a previous change intended to fix this bug as it occurred in the original engine, this accounts for an edge case that was missed)
  • Fixed sounds that have bad loop length data passing this on to OpenAL (now works like the original sound system does)
  • Fixed Apache and Osprey not playing rotor sounds correctly in multiplayer (they use singleplayer-only pitch modulation logic that depends on the local player entity)
  • Reworked func_breakable and func_pushable to require level designers to specify the classname of the entity to spawn on break. This allows both entities to spawn any item in the game aside from CTF items without needing code changes to support newly added items
  • Added natvis definition for EntityHandle to make it easier to see which entity a handle points to
  • Overhauled NPC schedule list code to use a simpler solution
  • Reworked client side message parsing to use a class instead of global variables (saves a little memory and eliminates edge cases from leftover parsing state and missing parse initialization)
  • Marked engine functions as deprecated if they do nothing, nothing useful or if a local function does the same (will produce compiler warning if you try to use such a function)
  • Streamlined usages of edict_t*, entvars_t* and CBaseEntity* to make code more consistent (ongoing effort)
  • Updated most uses of UTIL_GetLocalPlayer to work in multiplayer (ongoing effort)
  • Use more consistent method to check if the game is multiplayer or singleplayer and whether it's a teamplay gamemode
  • Implemented entities:
    • player_hasweapon
    • logic_isskill: fires a target matching the current skill level
    • logic_setskill: Changes the skill level setting. Due to how the skill system works some changes will only take effect after a map change. This entity is the equivalent of Quake 1's trigger_setskill but is a point entity that needs to be triggered. Its intended purpose is to be used in a campaign selection map
    • logic_setskillvar: Sets a specific skill variable to a value. Intended for multiplayer only because skill variables are not saved and restored, and are reset on map load based on specified skill config files
  • Fixed M249 using wrong spread in singleplayer when standing still and ducking (values were swapped)
  • Fixed shotgun starting idle animations too quickly after exhausting all ammo using primary attack, causing the shoot animation to cut off
  • Fixed RPG not playing empty sound when attempting to fire with no ammo left
  • Reworked how the player's reserve ammo and each weapon's magazine is accessed to centralize the logic
  • Fixed Human Grunts dropping weapons again if the game is saved and loaded while the grunt is dying
  • Fixed Health Charger recharge time not using the correct value in Co-op when using mp_coopweprespawn 1
  • Removed cycler_weapon (not very useful, tends to cause problems when weapons code is changed)
  • Made impulse 101 give all weapons using the weapons dictionary, give the suit without playing the login sound and give max ammo without creating ammo entities
  • Disabled the ability to pick up items when in observer/spectator mode
  • Fixed Capture The Flag items crashing on respawn due to faulty respawn point detection logic (error in recreation, not in Opposing Force itself)
  • Removed conditional evaluation from skill config files. This is now handled by map configuration files only to centralize the configuration logic
  • Implemented support for constraining (treat as integer, clamp to minimum and/or maximum value) and networking skill variables to clients
  • Reworked the weapons code to use skill variables to control multiplayer behavior (allows alternate weapon behavior to be controlled in any game mode on a case-by-case basis)
  • Reworked gamerules to rely more on configurable behavior instead of hard-coding gamemode-specific rules (e.g. item respawn rules are now configured in skill files, not in the gamemode-specific gamerules class)
  • Removed mapchange cfg file (superfluous), restricted the server configuration file to the Echo and Command sections, moved default config file names to hardcoded list (see below)
  • Added default map config file used if the map doesn't have a file of its own
  • Made the Echo config section log as info instead of debug/trace
  • Reworked game mode selection (see below)
  • Reworked the map cycle to use JSON (see below)
  • Implemented Spawn Inventory feature (see below)
  • Implemented Persistent Inventory feature in co-op (see below)
  • Disabled the use of landmarks in multiplayer (was recently added, only caused landmarks to act as spawnpoints which causes players to get stuck in level geometry)
  • Fixed ammo updates not being resent after a hud reset has occurred
  • Fixed game_playeractivate target being triggered multiple times in some game modes
  • The gamemode name is sent to clients using the serverinfo buffer and is displayed when using cl_debuginfo_show 1
  • The current in-game time is now displayed when using cl_debuginfo_show 1
  • Mark player as spawning when choosing a class (hides weapon pickup HUD icons for weapons given on spawn)
  • Removed sv_oldgrapple cvar (leftover from an old Opposing Force update)
  • Made the Knife backstab attack work against NPCs
  • Added master support to trigger_relay
  • ent_create and npc_create now only inherit the yaw angle from the player that is executing the command
  • Added new skill variables:
    • allow_use_while_busy: Allows players to +USE entities while their character is busy with a weapon (e.g. reloading)
    • allow_flashlight: Whether to allow the flashlight (replaces mp_flashlight cvar)
    • allow_monsters: Whether to allow monsters to spawn (replaces mp_allowmonsters cvar)
    • falldamagemode: Controls the fall damage mode (0: fixed at 10 damage, 1: progressive: longer falls deal more damage) (replaces mp_falldamage cvar)
    • healthcharger_recharge_time and hevcharger_recharge_time: Controls how long it takes to recharge both charger types (-1 == never recharge) (Replace hard-coded values)
    • weapon_respawn_time, ammo_respawn_time and pickupitem_respawn_time: Controls how long it takes to respawn the three item types (-1 == never respawn) (Replaces hard-coded values)
    • weapon_instant_respawn: If set to 1, weapons not flagged to be limited in world (i.e. hand grenades, satchels, etc) will respawn immediately (Replaces mp_weaponstay cvar)
    • allow_weapon_dropping: Controls whether players can drop weapons. Does not affect singleplayer (Also replaces mp_weaponstay cvar)
    • infinite_ammo: All players have infinite ammo. The game acts as though players have maximum reserve ammo
    • bottomless_magazines: Player reserve ammo is used before the weapon's magazine is used. When used in combination with infinite_ammo the player can fire forever
    • coop_persistent_inventory_grace_period: Amount of time in seconds after joining the server that players are able to spawn with their persisted inventory
    • crowbar_full_damage and pipewrench_full_damage: Whether the crowbar/pipe wrench should deal full damage on each swing. In singleplayer only the first swing deals full damage
    • revolver_laser_sight: Whether to enable the revolver's laser sight (zoom)
    • smg_wide_spread: Whether to use a wider spread
    • shotgun_single_tight_spread: Whether to tighten the single shot spread
    • shotgun_double_wide_spread: Whether to widen the double shot spread
    • crossbow_sniper_bolt: Whether zoomed in shots use sniper bolts (hitscan instead of physical projectile)
    • crossbow_explosive_bolt: Whether bolts explode if they don't hit an object that can be damaged (sniper bolts will never explode)
    • gauss_charge_time: Controls the Gauss gun's charge time. Clamped to the range [0.1, 10]. The Gauss gun overcharges at 10 seconds
    • gauss_fast_ammo_use: Whether to consume ammo quickly
    • gauss_vertical_force: Whether to apply vertical knockback when using secondary attack (Gauss jumping)
    • gauss_damage_radius: Damage radius multiplayer for secondary attack pierced shots. Due to how radius damage is applied this does not turn such attacks into nuclear blasts when the radius is increased
    • egon_narrow_ammo_per_second: Ammo usage per second for narrow mode (minimum 0) (note: narrow mode is never used)
    • egon_wide_ammo_per_second: Ammo usage per second for wide mode (minimum 0)
    • knife_allow_backstab: Whether to treat attacks from behind as a backstab (backstabs deal 100 times normal damage but will never gib its target)
    • grapple_fast: Whether to allow the Barnacle grapple to launch again quickly
    • m249_wide_spread: Whether to use wide spread for M249 shots
    • shockrifle_fast: Whether to allow the Shock Rifle to fire and regenerate ammo faster

C# Changes

  • Fixed ba_outro player freeze breaking if the game is saved and loaded while frozen
  • Reworked skill converter to emit simplified format
  • Converted MapCfgGenerator script to an executable
  • Reworked map cfg generation to use JsonTextWriter
  • Removed Op4 gamemode settings from worldspawn, rely on map cfg to specify the gamemode instead
  • Updated renamed entity classnames in game_player_equip as well
  • Configure maps that use game_player_equip to not give default spawn inventory
  • Added Spawn Inventory for ba_tram1 to give players the HEV suit instead of relying on buggy game behavior to make players pick it up
--> Continued in next post
Posted 1 year ago2023-04-06 19:54:33 UTC
in Half-Life Updated (custom SDK) Post #347428
<-- Continued from previous post

Debug HUD

A new HUD element has been added that shows some debug info:
User posted image
The current map, player origin and angles are shown. This makes it easier to diagnose issues by including this information in screenshots and helps to note down specific locations in maps.

Enabled with the cl_debuginfo_show cvar.

Chat input position

Chat input is now shown directly above the chat text area instead of in the top-left corner of the screen:
User posted image

New item and charger features

Weapons, ammo and all items other than Opposing Force CTF items now have the following features:
  • Custom respawn delay (works in singleplayer as well)
  • Option to stay visible during respawn
  • Flash on respawn (uses muzzleflash effect)
  • Can disable the pickup sound
  • Can set item to float instead of falling to the ground (items also no longer fall through entities in some cases, though they can still phase through entities if they clip into them)
  • Can trigger entities on spawn and despawn
Ammo entities additionally have these features:
  • Can specify the amount of ammo to give (-1 == maximum)
  • ammo_generic: Can change the ammo type given using trigger_changekeyvalue
  • ammo_all: Give specified amount of all ammo types
Weapon entities additionally have these features:
  • Can specify the amount of ammo in newly spawned weapons
Health kits, battery and guard helmet and vest allow specifying custom capacities as well.

The Health and HEV chargers now have the following features:
  • Can trigger entities on recharge and empty
  • Can change the total capacity (-1 == unlimited)
  • Custom respawn delay
  • Amount of juice to charge per us
This video shows many of these new features:

Monstermaker keyvalue passthrough and proper entity cleanup

monstermaker now passes up to 64 keyvalues to the entities it spawns. This is done by prefixing keyvalues with #:
#TriggerCondition 4
#TriggerTarget death
Killtargeting entities now also correctly cleans up entities spawned by them (if the entity is intended to be killtargeted, not all entities do this). This fixes monstermaker breaking if the spawned entities are killtargeted and certain NPCs and entities leaving effects behind.

Project merging status

Current status:
  • Half-Life Updated (up-to-date)
  • Half-Life: Opposing Force Updated (up-to-date)
  • Half-Life: Blue Shift Updated (up-to-date)
  • Half-Life Updated CMake (done, project has been archived)
  • HLEnhanced (in progress)
  • Enhanced Half-Life (almost done)
  • Half-Life Better Weapons (done)
  • Condition Zero: Deleted Scenes SDK (done)
Enhanced Half-Life's features are almost all merged in. There are a handful of things left to check and then i'll consider that completed.

HLEnhanced features are also being merged in quite quickly and should soon be complete as well.

Many of the changes listed came from these two projects which is why it's going so quickly.

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Networking system (other immutable data): Networking system is implemented, new and existing features are being updated to use it
  • HUD image replacement for Opposing Force: basic hud sprite name replacement test done and functional; more complete implementation will be added to implement this feature
  • Versions of Opposing Force-only HUD images that have the scanline effect removed: in progress
  • A way to start all three campaigns from the main menu. Probably the same solution as used in Condition Zero Deleted Scenes (menu button that starts a map that opens an SDK-level menu that enables campaign and training selection)
  • Merge in remaining useful functionality from other projects (in progress)
  • Implement as much of the work scheduled on the issue tracker as possible
  • Review all changes
  • First alpha build
  • Stress test the three campaigns and fix issues that show up (first test done)
  • First beta build
There's a fair amount of work left to be done that's not listed publicly, but i expect to get through that pretty quickly. I've been going through the Github issues, the Git commit histories for EHL and HLE, my old notes and todo lists to see what's left and i'm quickly running out of all of that stuff.

There are some stability issues resulting from changes made that are being fixed as i encounter them. Unfortunately it's not always possible to fix them completely, for example a bug in the engine allows multiple maps to be loaded at the same time and it corrupts the engine and the game's state. I've added code to detect this and kick the player back to the main menu (using another hack in the process) but i'd prefer a proper fix in the engine for that kind of thing.

Until all of the planned features are in place some temporary hacks are needed. I'm working to get this all done ASAP but i can't say how long it'll take.

I can say that Opposing Force and Blue Shift require only 2 more features to allow them to be experienced just like the original: HUD sprite replacement and setting the MP5's default ammo to 50 (is 25 in HL) is all that's left. There is still the need to enable campaign selection but for now the console allows direct control.

I'm leaving all sound system issues until after i've taken care of all of the merging and feature implementation work since those issues are a bit more complicated, and strictly speaking only sentence playback is needed which doesn't require the features that are a bit buggy at the moment. I don't think it'll be a big problem, but i'd prefer to get a bunch of easy stuff out of the way first.

The next update will probably be similar to this one in that it will have loads of smaller changes.

That's all for now.
Posted 1 year ago2023-04-06 19:54:08 UTC
in Half-Life Updated (custom SDK) Post #347427

Progress on the Unified SDK

SDK Changes

  • Cleaned up some redundant constants, added missing constants
  • Fixed spray logo using the wrong decal after a save game load when not using a custom spray (i.e. if you use the default small Lambda spray, not the custom one defined in the Multiplayer options page)
  • Fixed ammo pickup sound playing when picking up a weapon for the first time (bug was introduced in a HL Updated change)
  • Fixed cycler_weapon trying to reload
  • Replaced V_min and V_max with std::min, std::max & std::clamp
  • Centralize server dll functions used by engine to access server dll
  • Added SV_SaveGameComment function: used by the engine to fill in the text shown in the save game description in the Load Game dialog (game uses localized text for this)
  • sv_spamdelay is now ignored in singleplayer (it controls the time before players are allowed to chat again, to limit the amount of chat text allowed at any given time)
  • Reworked the HUD weapon list to allow an unlimited number of weapons in each weapon category (previously limited to 7 weapons total in Opposing Force, 5 in HL)
  • Weapon categories above 5 are only drawn if there are weapons in that category or a category with a greater number (makes HUD look like HL when no Op4 weapons are equipped)
  • Added diagnostic output warning if there are too many multi_manager targets
  • Renamed TakeHealth to GiveHealth because positive amounts give health
  • Refactored game logic to use CBaseEntity wherever possible to make it more consistent and eliminate some older helper functionality
  • Fixed monstermaker with infinite children not spawning an infinite number (will spawn 4,294,967,293 entities and then stops. Ridiculous, i know)
  • Added a way to pass arbitrary keyvalues to monstermaker children (see below)
  • Made sure entities notify their owner if they are killtargeted so they can keep track of how many active children there are
  • Moved chat input position to 2 lines above the chat text area (see below)
  • Fixed entities not removing child entities created by them (see below)
  • Fixed Alien Slave beams staying forever if they exist during a level change
  • Fixed cycler_wreckage storing time value in int instead of float
  • Replaced ´DECLARE_COMMAND´ and HOOK_COMMAND with console command system
  • Install singleplayer gamerules earlier when loading save games so entity initialization and precaching logic can use it
  • Made trigger_changelevel work in multiplayer (non-persistent level changes only)
    • Added the option to use non-persistent level changes in singleplayer
  • Removed monster_vortigaunt classname (never used, breaks Alien Slave code since it searches by classname)
  • Removed game.cfg execution, added safety checks to prevent server state corruption if multiple map change commands occur in the same frame
  • Only allow NPCs to drop items, never respawn dropped items
  • Fixed Gauss gun sometimes setting uranium ammo to -1
  • Fixed Glock not playing empty sound when using secondary attack
  • Fixed player weapons still receiving input when starting to use a func_tank
  • Fixed weapons marked as "limit in world" (e.g. Hand Grenade) respawning at the wrong time if the server is near the entity limit
  • Removed duplicated ammo variables used in prediction code
  • Moved weapon-specific variables from CBaseEntity to their respective classes
  • Store player suit flag in separate variable, removed unused WEAPON_CHAINGUN constant (effectively frees up 2 weapon slots for use)
  • Reworked gib spawning to avoid use of stackalloc
  • Prevent entity classnames from being changed by level designers using entities that can change arbitrary keyvalues
  • Added assert to warn about classnames with uppercase letters, renamed all entities to use lowercase letters (weapon_9mmAR, ammo_9mmAR, ammo_ARgrenades)
  • Changed schedule debug logic (spark effect above NPC's head) to be controlled by sv_schedule_debug cvar
  • Added diagnostic logging to show time required to load server config files
  • Reset sky name to desert to ensure sky name is consistent even after loading other maps that have other sky names (e.g. crossfire does not specify a sky name and uses the last used sky)
  • Implemented strongly typed entity handles
    • Converted existing uses of EHANDLE to use new handle features
    • Reworked func_train and env_spritetrain to use EHANDLE instead of entvars_t* to track the next stop target
    • Use EHANDLE instead of edict_t* to store tripmine owner
  • Reduced project info HUD size
  • Added debug info HUD (see below)
  • Fixed user interface coordinates and sizes being incorrectly adjusted for resolution (caused spectator interface buttons to overlap)
  • Refactored weapons, ammo and pickup items (excluding Op4 CTF items) to use a shared base class
    • Added new features to items (see below)
    • The give and impulse 101 commands now use the item dictionary
  • Reworked func_healthcharger and func_recharge (HEV charger) to use shared base class
    • Added new features to chargers (see below)
  • Added the option to strip the HEV suit and long jump module from players using player_weaponstrip
  • Reworked item_generic to avoid the possibility of the wrong sequence being used if the game saves right between the entity spawning and finishing its initialization
  • Disabled HEV sounds for item_helmet & item_armorvest
  • Removed world_items (obsolete, replaced by individual entities)
  • Removed item_security and unused item types not used by game code
  • Removed trip_beam (debug only, never used)
  • Implemented entities:
    • player_sethealth
    • player_setsuitlighttype
    • player_hassuit
    • logic_setcvar
    • ammo_generic: Gives ammo of a specified ammo type (combine with trigger_changekeyvalue to dynamically change ammo type)
    • ammo_all: Gives all ammo types. Configurable amount
  • Implemented cheats:
    • ent_remove: Remove the first entity matching the given targetname or classname
    • ent_remove_all: Remove all entities matching the given targetname or classname
    • ent_setname: Sets the name of the entity you're looking at or the entity with the given targetname or classname to the given targetname
    • ent_show_origin: Shows the origin of the first entity matching the given targetname or classname by creating a temporary laser dot sprite at its location (note: brush entity origins may be 0 0 0 if they do not have an origin brush)
    • ent_show_center: Shows the center as defined by the first entity matching the given targetname or classname by creating a temporary laser dot sprite at its location
    • ent_show_bbox: Shows the bounding box of the first entity matching the given targetname or classname by drawing blue particle lines (note: the game expands the bounding box by 1 unit in all directions, so the box appears to be larger than the entity)
    • cheat_god: Toggles god mode (even in multiplayer)
    • cheat_notarget: Toggles notarget (even in multiplayer)
    • cheat_noclip: Toggles noclip (even in multiplayer)
    • cheat_givemagazine: Gives a single magazine's worth of ammo for the current weapon to the player. An optional parameter indicates the weapon's attack mode index to allow giving secondary ammo (i.e. MP5 grenades are given with cheat_givemagazine 1)
    • ent_create: Creates an entity at the position you're looking at, passing along additional keyvalues if provided
    • npc_create: Creates an entity at the position you're looking for and adjusts its height to place its bounding box on the ground. If the entity is stuck in an object or can't fall to the ground it is removed
  • Cheats with the cheat_ prefix are autocompleted by the console now
  • Reworked save/restore system to use a datamap to store data
    • Decoupled engine save/restore data from the game's data to allow the game's version to be freely changed
    • Reworked save/restore system to use serializers for each type
    • Fixed arrays of function pointers not saving and restoring correctly
    • Added function table to datamap to store the list of entity functions used as Think/Use/Touch/Blocked in the server dll instead of relying on the engine to look them up (eliminates use of platform-specific functionality)
  • Merged variables used to store the name of an entity's master
  • Moved m_hActivator to CBaseEntity and removed a hack added post-release
  • Reworked Op4 CTF stats menu to use safe format strings and to use a fallback string if the file providing it is missing or contains a bad format strings

Asset Changes

  • Matched changes to the game's code to the fgd
  • Cleaned up master keyvalue definition and made it use the correct data type so editors can auto-complete entity names
  • Removed .wav extension from a couple Op4 sentences
  • Added maps to test new features
  • Added zoo_items map to enable easy testing of all items
  • Added configuration files defining default keyboard bindings & descriptions, changed description for slot 10
  • Removed non-existent PVS flag from monstermaker
  • Updated func_train & env_spritetrain to use new sound name functionality

C# Changes

  • Removed dmdelay keyvalue from charger entities (was always ignored, removed to avoid confusion)
  • Reworked KeyValueMatcher to take maps directory as argument instead of as option, allow multiple directories
  • Reworked KeyValueMatcher to only print a map name if at least one match is found by default and print the number of matches
--> Continued in next post
Posted 1 year ago2023-03-23 17:54:41 UTC
in Need help with modding Post #347415
Decompilers can't produce accurate results because there isn't enough information in a HL1 BSP file to produce something that can be compiled back into a map. You'll always need to touch it up after decompiling so you'll need a good understanding of level design to work with those maps.

I recently made an improved decompiler which should be more accurate: https://github.com/SamVanheer/HalfLife.UnifiedSdk.MapDecompiler/releases

It still requires work to touch up the maps after the fact. This is not something you can skip, no matter which decompiler you use.
There are guides for 2013, you just need to dig a little deeper: https://developer.valvesoftware.com/wiki/Source_SDK_2013
The Valve Developer Community has many articles that cover Source modding: https://developer.valvesoftware.com/wiki/Category:Modding
Posted 1 year ago2023-03-21 15:20:23 UTC
in Half-Life Updated (custom SDK) Post #347408

Unified SDK Pre-alpha build

The previous post didn't include the link to the new pre-alpha build: https://github.com/SamVanheer/halflife-unified-sdk/releases/tag/dev-2023-03-21
Note: pre-alpha builds are not intended for general testing. As the wiki article on software life cycles explains the first versions intended for this kind of testing are alpha builds. Pre-alpha builds are for testing specific features by request to verify that they work as expected based on bug reports and feature requests.

Since this project is still in the midst of development (essentially this is the game engine development part of the project) it's expected that there are bugs and features not working as expected (or at all). Once all required features have been implemented the project can move to the alpha testing stage where verifying the proper behavior is the main goal.
Posted 1 year ago2023-03-21 14:02:47 UTC
in Half-Life Updated (custom SDK) Post #347407
<-- Continued from previous post

Per-entity model, sound and sentence replacement

It is now possible to use model, sound and sentence replacement config files on a per-entity basis. While it doesn't yet apply to entities created programmatically it does work with editor-placed ones:
The scientist is using sentence replacement to play different sentence groups and uses the custom model keyvalue to look like a zombie. The zombie is using model replacement to look like a scientist and uses sound replacement to sound like a scientist.

Sentence replacement is now also used for Otis, the Drill Sergeant, Recruit and Rosenberg to eliminate code duplication that was needed to play the right sentence before.

It is possible to replace these files using trigger_changekeyvalue, though i wouldn't recommend it because the models and sounds need to be precached to work.

Weapon and ammo changes

Weapon and ammo info is now sent to the client using the new networking system, ammo is defined separately to avoid cases where multiple weapons can define the same ammo type with different properties, in which case the properties used depend on precache order.

Overall these changes simplify the weapons and ammo code.

Project merging status

Current status:
  • Half-Life Updated (up-to-date)
  • Half-Life: Opposing Force Updated (up-to-date)
  • Half-Life: Blue Shift Updated (up-to-date)
  • Half-Life Updated CMake (done, project has been archived)
  • HLEnhanced (in progress)
  • Enhanced Half-Life (in progress)
  • Half-Life Better Weapons (done)
  • Condition Zero: Deleted Scenes SDK (done)
The changes made to the weapons code allowed the Better Weapons project to be merged in. The client gets its list of weapon classnames from the weapon dictionary so as long as you include the weapon source file in the client project (done for you since you include these in game_shared.cmake) it'll set it up.

You no longer need to manually precache each weapon, the dictionary is also used to do that automatically.

A lot of these changes involve the merging of features from HLEnhanced and Enhanced Half-Life so both of those projects are merging in quite quickly. I'm working to merge in EHL's features first now which shouldn't take much longer, then i'll start checking HLE.

Several issues on the issue tracker were closed as well because of this merging work.

Remaining work to be done

  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Networking system (other immutable data): Networking system is implemented, new and existing features are being updated to use it
  • HUD image replacement for Opposing Force: basic hud sprite name replacement test done and functional; more complete implementation will be added to implement this feature
  • Versions of Opposing Force-only HUD images that have the scanline effect removed: some preliminary research done, needs more investigation
  • A way to start all three campaigns from the main menu. Probably the same solution as used in Condition Zero Deleted Scenes (menu button that starts a map that opens an SDK-level menu that enables campaign and training selection)
  • Merge in remaining useful functionality from other projects
  • Implement as much of the work scheduled on the issue tracker as possible
  • Review all changes
  • First alpha build
  • Stress test the three campaigns and fix issues that show up (first test done)
  • First beta build
I expect a lot more of these smaller changes to be done now so the progress updates will be long but full of small stuff.

Thanks to hammermaps for contributing code cleanup improvements, that's very useful.

Until next time.
Posted 1 year ago2023-03-21 14:02:23 UTC
in Half-Life Updated (custom SDK) Post #347406

Progress on the Unified SDK

A lot of progress has been made since a lot of smaller things have been done.

A new pre-alpha build is available:
Note: pre-alpha builds are not intended for general testing. As the wiki article on software life cycles explains the first versions intended for this kind of testing are alpha builds. Pre-alpha builds are for testing specific features by request to verify that they work as expected based on bug reports and feature requests.

Since this project is still in the midst of development (essentially this is the game engine development part of the project) it's expected that there are bugs and features not working as expected (or at all). Once all required features have been implemented the project can move to the alpha testing stage where verifying the proper behavior is the main goal.

SDK Changes

  • The global sound replacement dictionary is now sent to the client
  • Reworked global model, sound and sentence replacement to allow multiple files and to allow removing files listed in config files that were checked prior to the current one
  • materials.txt, sentences.txt and skill.json are now specified through the server config file instead of using hard-coded filenames. Note that this may be changed to solve problems related to servers running custom versions of these files since it messes up custom content when downloaded and loaded locally
  • Removed skill sk_reload command (restart the map to see changes)
  • Changed maximum material texture name length to match wad and bsp limit (13->16)
  • Added snow footstep and impact sounds (from Opposing Force Updated, was missing)
  • Converted the material system and hud sprite config files to JSON
  • Removed obsolete alternate entity classnames for weapons
  • Changed weapon precaching to use weapon dictionary, client side code now creates all weapons using this dictionary instead of requiring globals to be added manually
  • Moved weapon class declarations out of weapons.h since they should not be accessed directly
  • Reworked RPG state networking to eliminate use of special case. Nearly all references to WEAPON_* constants are contained in their individual weapons now
  • Disabled MSVC warnings in CMakeLists.txt instead of Platform.h to ensure they are disabled project-wide
  • Removed unused variables and C-style casts
  • Don't assume hud sprites have sequential indices when loaded from hud configs
  • Fixed Penguin grenade not clearing weapon bit correctly
  • Improved user feedback when using JSON console commands
  • Reworked precache diagnostics logging to show the number of precaches known to the server dll when server activation is about to complete
  • Send all project info using network data system, use it to verify mod compatibility, rename cl_showprojectinfo to cl_projectinfo_show
  • Don't rely on cached max entity count on client side (fixes edge case where sounds played on first frame don't play because entity count is 0)
  • Link user messages on server startup instead of after map spawn (fixes edge case where messages are not registered yet when used)
  • Moved print buffering setup to before client init
  • Use separate loggers for sound cache & sentence playback
  • Use engine sound system rules for channel reuse before allocating new channel
  • Set OpenAL reference distance to 0 to match the engine's calculations
  • Disabled OpenAL Doppler effect feature
  • Play regular sounds using OpenAL instead of engine sound system
  • Implemented A3D functionality using HRTF (note: experimental)
  • Make sounds with attenuation 0 play at player's position (should help deal with ambient_generic Play Everywhere sounds still using spatialization; needs more testing)
  • Store sound filenames as lowercase to ensure extension-based lookup works properly (some maps use uppercase extensions)
  • Removed unnecessary global variables in changelevel code
  • Removed unnecessary macros used to mark variables as global and const
  • Fixed typo in spectator overview code
  • Removed redundant weapon slot index data specified by iItemSlot() method, removed duplicate constants for max weapon slots and ammo types
  • Converted as much code as possible to use Vector instead of float arrays/pointers, replaced older vector math functions with Vector operators and helpers
  • Consolidated math functions in mathlib.h/.cpp
  • Use local AngleVectors functions instead of engine function (more efficient, compiler can optimize the calls since it can see the implementation)
  • Merged server and client versions of weapons code when possible
  • Merged CBasePlayerItem and CBasePlayerWeapon (items only work properly when they are weapons anyway, some code assumes all items are weapons and no classes inherit from CBasePlayerItem directly)
  • Moved CWeaponBox to its own file (server only, client doesn't need it, only player accesses the type directly)
  • Reworked ammo type definitions so the types are explicitly defined instead of implicitly through weapons referencing them. The ammo type definition now includes the maximum capacity, code that required the capacity to be passed in now queries the ammo type system for this information instead. The list of ammo types is sent to the client as well
  • Converted functions used to play sounds to be CBaseEntity class members so the edict_t instance can be inferred from the entity, pass CBaseEntity into the sound system and convert to edict only at the very end
  • Implemented per-entity model, sound and sentence replacement (Work In Progress, entities created through code need to inherit these)
  • Reworked the body list to use CBaseEntity and moved it to its own file (body list is used for multiplayer corpses strewn about)
  • Removed EOFFSET type, updated remaining uses to make use of better alternatives
  • Moved spawnpoint logic to its own file and reworked it to use CBaseEntity
  • Replaced FClassnameIs with class member function
  • Reworked code to minimize use of older helper functions and to prefer the use of CBaseEntity when possible
  • Reworked weapon info to be networked to client through the new networking system, WeaponList network message removed
  • HUD now uses weapon and ammo info received from the client
  • Split up gamerules.h so singleplayer & multiplayer gamerules class declarations aren't included (should never be accessed directly)
  • Renamed gamerules filenames to match their class names
  • Moved saverestore implementation to its own file
  • Grouped CTF classes together in the same file (small classes, cuts down on compile time a bit)
  • Consolidate entities related to level changes in the same file, removed wrapper function
  • Use per-entity sentence replacement to handle Otis, Drill Sergeant, Recruit and Rosenberg sentence changes, removed code duplication in these classes
  • Fixed Rosenberg voice pitch being too high
  • Converted much of the entity and gamerules documentation to use Doxygen, remove redundant, obsolete and incorrect documentation

C# Changes

  • Reworked Skill2Json to preserve comments when possible
  • Added Materials2Json tool (with special case to ignore a bad material entry in the HL materials.txt file)
  • Weapons are renamed to use their primary classname if they use an old pre-release name (e.g. weapon_mp5 => weapon_9mmAR)
  • Added Hud2Json
  • Fixed typo in music filename map (Prospero06.mp3 => Prospero05.mp3)

Asset Changes

  • Updated game config files to use lists of replacement files
  • Added cfg file that adds default game data files
  • Changed material texture names to use full names instead of first 12 characters
  • Fixed material texture names that used misspelled names or that included ignored prefixes
  • Removed Op4 snow step sound replacements in sound replacement file (unnecessary, used for all games anyway)
  • Removed duplicate material entries
  • Converted materials.txt to JSON
  • Converted HUD sprite configs to JSON
  • Added script to convert all HUD sprite configs in a directory to JSON
  • Added options to control HRTF to Multiplayer Advanced dialog
  • Added missing Start On spawnflag to func_guntarget
  • Added replacement file keyvalues to fgd, added test map with test files

Replacement file lists

Game configurations now accept a list of files for replacements. The syntax is as follows:
"Sentences": {
    "ResetList": false,
    "FileNames": ["sound/sentences.txt"]
}
If ResetList is true then any files specified by config files loaded before this one are ignored.

Global sentence replacement is unfinished; it requires conversion to JSON and a more explicit way to define sentence groups to solve problems with how sentences and groups are overridden. That can't be done until the sound system is finished.

Materials files now use the full texture name (with prefixes stripped). Along with previous changes this allows for an unlimited number of materials matching specific textures.

HUD sprite configs don't include the resolution since it isn't used anymore.

Sound system changes

All sounds are now played using the new sound system. This works pretty well overall aside from certain sounds that are pitch shifted. The engine handles pitch shifting by stretching or chopping up the samples, whereas OpenAL uses frequency modulation. I'll have to implement the same pitch shifting algorithm to make it sound good.

I've also implemented Head-related transfer function (HRTF) to emulate the original engine's A3D functionality. This is experimental and has some problems, largely performance issues that occur when a lot of sounds are played.

This video shows the new sound system and some of the problems with it:
--> Continued in next post
Posted 1 year ago2023-03-04 16:33:15 UTC
in Half-Life Updated (custom SDK) Post #347375
<-- Continued from previous post

c2a5 barrels fix

This has been requested for some time now.

The cause of this problem was the use of trigger_push to add velocity in a way that was framerate-dependent. Instead of applying the set velocity in one go it applied it over the course of about a second. The higher the framerate is the lower the applied velocity becomes.

Thanks Uncle Mike for pointing to the cause and fix, Streit and rbar1um43 for providing a link to this information.

In development: hud sprite replacement

This is a simple test to see if replacing hud sprites at runtime is possible. This works on the same principle as the other replacement systems:
{
    "number_0": "number_0_hl",
    "number_1": "number_1_hl",
    "number_2": "number_2_hl",
    "number_3": "number_3_hl",
    "number_4": "number_4_hl",
    "number_5": "number_5_hl",
    "number_6": "number_6_hl",
    "number_7": "number_7_hl",
    "number_8": "number_8_hl",
    "number_9": "number_9_hl"
}
The default sprite is substituted for its replacement. In this case the default hud uses Opposing Force sprites so it was substituted with the Half-Life versions.

This is only an initial test to see if it can be done. The actual feature will be developed to be more flexible than this. It isn't available in the current dev build.

Project merging status

Current status:
  • Half-Life Updated (up-to-date)
  • Half-Life: Opposing Force Updated (up-to-date)
  • Half-Life: Blue Shift Updated (up-to-date)
  • Half-Life Updated CMake (complete, project has been archived)
  • HLEnhanced (in progress)
  • Enhanced Half-Life (in progress)
  • Half-Life Better Weapons (in progress)
  • Condition Zero: Deleted Scenes SDK (done)
Some HLEnhanced features have been merged by way of equivalent features being implemented.

Condition Zero Deleted Scenes merging work is done. trigger_changekeyvalue has been implemented.

trigger_sequence 's features will be implemented in another manner. This largely involves map-specific sentences.txt files, the other features are more of a nice-to-have thing and are not as important.

Remaining work to be done

  • Merge pull requests (done)
  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Networking system (transfer contents of replacement files, precache lists, possibly other immutable data): Networking system is implemented, new and existing features are being updated to use it
  • HUD image replacement for Opposing Force: basic hud sprite name replacement test done and functional; more complete implementation will be added to implement this feature
  • Versions of Opposing Force-only HUD images that have the scanline effect removed: some preliminary research done, needs more investigation
  • A way to start all three campaigns from the main menu. Probably the same solution as used in Condition Zero Deleted Scenes (menu button that starts a map that opens an SDK-level menu that enables campaign and training selection)
  • Merge in remaining useful functionality from other projects
  • Implement as much of the work scheduled on the issue tracker as possible
  • Review all changes
  • First alpha build
  • Stress test the three campaigns and fix issues that show up (first test done)
  • First beta build
I am currently working to update features to take advantage of the networking system, so the next progress report will go into more details on that.

Much of this work was done by malortie, whose help cannot be understated. Many thanks to him for his continued work on this project.

Until next time.
Posted 1 year ago2023-03-04 16:33:07 UTC
in Half-Life Updated (custom SDK) Post #347374
<-- Continued from previous post

Network data system

The network data system that i mentioned in a previous post has been implemented. It uses JSON files generated on map start downloaded to clients to transfer large sets of immutable data to allow features to reference said data.

That's a fancy way of saying that the contents of materials.txt and sentences.txt are now sent to clients by copying the contents into a JSON file and making the client download and read the file.

Servers can now modify both files without requiring the same changes on the client side. I still wouldn't recommend doing that, and it won't be necessary once other features have been implemented, but this change was needed to provide the necessary foundation for said other features to be built on.

To make this system work 4 cvars are forced to the value 1:
  • sv_allowdownload
  • sv_send_resources
  • sv_allow_dlfile
  • cl_allowdownload
If the server cvars are detected to be turned off they will be forced on along with a warning to make sure server operators are aware of why it happened (because these cvars are marked to not log changes normally).

The file is always called networkdata/data.json. Using the same name simplifies things and takes advantage of the engine's automatic change detection to regenerate the BZip2 compressed version networkdata/data.json.ztmp which helps to avoid polluting dedicated servers with many old compressed versions. The average compression ratio is about 79% meaning a file with size 100KiB is compressed to a file that's about 21KiB.

The file is deleted by the server prior to generating a new file. The client will also delete both local and downloaded copies to ensure that it can receive a fresh copy. The client will not delete the local file if it is connected to a local server (i.e. singleplayer or listen server).

When running a local server no download is necessary so players are unlikely to notice much impact other than time spent generating and parsing the file.

Two limitations currently exist:
1. You cannot connect to a dedicated server running from the same game installation as the client. This should never be a problem because the dedicated server tool distributed with the client does not work anymore, and dedicated servers should always be installed separately through SteamCMD.
2. If multiple servers share a FastDL server and transfer the generated file to it they will conflict and use the wrong file. If this does become a problem then a possible solution is to store the file in a subdirectory named after the server IP and port: 1.2.3.4_port. This would make the filename unique for each server. The client has the server's IP address so this should work, but whether this will actually work or not remains to be seen.

The file contents are minified JSON and includes metadata to detect when clients connect to servers running a different version.

Average file size is currently about 99-100 KiB. Since features depending on this system are in development this number will change in both directions.

The engine allows a maximum uncompressed file size of 10 MiB, controlled by the sv_filetransfermaxsize cvar. File size shouldn't be a problem but if it does the first thing to do is investigate replacing JSON with a message format like Protobuf.

My estimates show that for the current data, which are lists of strings, using Protobuf will reduce file size by somewhere around 3000 bytes. Once large amounts of structured data are sent over Protobuf will become the more efficient method because of how it works.

Basically JSON contains both data and the message format in text form. Protobuf contains both data and the message format in binary form, using a much more efficient representation. Where a JSON key can be several bytes a Protobuf identifier can be as small as 1 byte and pretty much never gets bigger than that due to lack of complexity in the data being sent.

It's a good first step to optimizing file size, but file size isn't really an issue here. The biggest problem with this system is the download speed. GoldSource's networking system is primitive and slow and can't be made faster. Its default settings send 512 bytes of file data at a time with a minimum of 256 bytes and maximum of 1024 bytes, controlled by the cl_dlmax cvar.

Reducing file size does speed up the download but having to download the file at all will always make it slow enough to be annoying. Unfortunately the file has to be downloaded every time because the data within can change every time it's generated.

The GameNetworkingSockets-based networking system i discussed previously aimed to avoid this problem, but unfortunately it has its own problems that are harder to solve.

That implementation will not be developed further, but its code can be found in this branch: https://github.com/SamVanheer/halflife-unified-sdk/tree/nonfunctional-prototype-networking

Note that Github Actions failed to build this because that branch references older vcpkg dependencies. A limitation inherent in vcpkg's design is responsible for this.

materials.txt and sentences.txt changes

The materials.txt parser now properly handles comments. Previously a line starting with / was treated as a comment instead of any occurence of // as expected.
It also handles the last line properly. Previously if the last material did not end with a newline it was ignored, which is why the last material in HL's file is listed twice.

Last but not least the material limit of 512 has been changed to unlimited.

Both materials.txt and sentences.txt are now sent to the client. This ensures that the client works with the same data as the client.

This is the first step to allowing map-specific versions of both files which will provide `trigger_sequence`'s map-specific sentences support. Other changes are planned to make the most of this new functionality, as well as apply it to other configuration files.

Game configuration system changes

The game configuration system has been reworked to simplify the structure and avoid potential problems when they are updated due to some overly verbose syntax.

Previously a configuration file contained a list of sections like this:
{
    "Sections": [
        {
            "Name": "GlobalModelReplacement",
            "FileName": "cfg/Op4ModelReplacement.json"
        },
        {
            "Name": "GlobalSentenceReplacement",
            "FileName": "cfg/Op4SentenceReplacement.json"
        },
        {
            "Name": "GlobalSoundReplacement",
            "FileName": "cfg/Op4SoundReplacement.json"
        },
        {
            "Name": "HudColor",
            "Color": "0 160 0"
        },
        {
            "Name": "SuitLightType",
            "Type": "nightvision"
        }
    ]
}
This has been changed to this:
{
    "SectionGroups": [
        {
            "Sections": {
                "GlobalModelReplacement": {
                    "FileName": "cfg/Op4ModelReplacement.json"
                },
                "GlobalSentenceReplacement": {
                    "FileName": "cfg/Op4SentenceReplacement.json"
                },
                "GlobalSoundReplacement": {
                    "FileName": "cfg/Op4SoundReplacement.json"
                },
                "HudColor": "0 160 0",
                "SuitLightType": "nightvision"
            }
        }
    ]
}
There is now a list of section groups. A section group pairs a set of sections with an optional Condition key, which previously was available on every section. The section list has been replaced with an object; section names are the key. Section values can now be any JSON object type: object, array, string, etc. This simplifies the trivial sections quite a bit.

Overall these changes reduce the size of config files and make more complex files easier to work with. Since conditionally included sections are now managed by the group condition having multiple sections conditionally included is easier to reason about.

These changes also make it easier to use the JSON Schema for config files in schema-based JSON editors:
User posted image
User posted image
The previous approach confused these editors too much.

--> Continued in next post
Posted 1 year ago2023-03-04 16:32:51 UTC
in Half-Life Updated (custom SDK) Post #347373

Progress on the Unified SDK

A fair amount of progress has been made in the past few weeks.

A new pre-alpha build is available: https://github.com/SamVanheer/halflife-unified-sdk/releases/tag/dev-2023-03-04
Note: pre-alpha builds are not intended for general testing. As the wiki article on software life cycles explains the first versions intended for this kind of testing are alpha builds. Pre-alpha builds are for testing specific features by request to verify that they work as expected based on bug reports and feature requests.

Since this project is still in the midst of development (essentially this is the game engine development part of the project) it's expected that there are bugs and features not working as expected (or at all). Once all required features have been implemented the project can move to the alpha testing stage where verifying the proper behavior is the main goal.

SDK Changes

  • Implemented console print buffering during client startup. This is necessary to allow regular console output to appear since the engine ignores it until the engine has finished initializing itself. Debug output is not ignored which is why that still shows up. The output does appear slightly out-of-order as a result but that's not a problem in most cases.
  • Print OpenAL info during startup (Vendor name, version and renderer [OpenAL Soft]). Note that this information is equivalent to OpenGL info printed in the console. OpenAL uses an API design based on OpenGL so the concepts are the same. That's why it uses the term "renderer" instead of "driver".
  • Set max edicts to 2048 in liblist.gam, log actual max edicts on map start (max edicts is calculated as max_edicts + ((maxplayers - 1) * 15))
  • Included string_view in Platform.h, enabled string view literals everywhere.
  • Added support for custom hull sizes to all entities (probably won't work properly for brush entities). This involved replacing the non-member function UTIL_SetSize with a CBaseEntity::SetSize member function and overriding the entity's bounds during SetModel and SetSize calls. This setting should be used only with entities that use Studio models (files with .mdl extension).
  • Removed unnecessary workaround for custom hull size in monster_generic, now relies on mapper-defined hull sizes for these.
  • Use bit_cast to convert float to int for writing in WRITE_FLOAT.
  • Project info is now always shown in alpha builds, and the meaning of the Work-In-Progress nature and testing expectations is stated more clearly in the on-screen text.
  • Reworked materials.txt parsing to make it easier to change the data source, simplified material storage, fixed parser bugs involving comment handling and correctly parsing the last material entry.
  • Implemented client user messages dispatcher (see below).
  • Initialize all CHud members, store hud elements & sprites in vector (see below).
  • Removed commented out RecCl* function calls. These were part of an old anti-cheat system once used by official Valve games but no longer does anything now other than add visual noise to code.
  • Implemented network data transfer system using files (see below).
    • Some cvars are forced on to make this work. Server operators are warned if a cvar is forced on to alert them to the change.
  • Send sentences list from server to client, don't load sentences.txt on client (see below).
  • Send material list to client, don't load materials.txt on client (see below).
  • Implemented trigger_changekeyvalue.
  • Fixed Barney playing post-disaster use/unuse sentences in training.
  • Studiomdl compiler change: Mark bones that are referenced by attachment as used. This allows bones that have no vertices attached to it to remain in the model if an attachment references it. v_shock.mdl requires this to fix a visual glitch experienced by some players where polygons meant to be invisible were being rendered due to an OpenGL glitch.
  • Fixed grunt not playing MP5 sounds during scripted sequence. Additionally the Male Assassin and allied grunt received the same fix.
  • Fixed func_tank clamping max range to 2048 (affected the Opposing Force Boot Camp live fire exercise).
  • Forced Pitworm animations to interpolate to fix stuttering movement.
  • Added qfont.h back but only for utils use, use header instead of redefining qfont_t type.
  • Fixed SDK mdlviewer program not compiling due to changes made to vector functions.
  • Fixed tripmines not detonating if placed on breakable and a save game is loaded.
  • Reworked game config system to turn sections into separate values with section-specific types, move conditions to section group (see below).
  • Added Git branch nonfunctional-prototype-networking containing the prototype GameNetworkingSockets-based networking system. As the branch name implies this does not work, it has been added to show people how far its development got and which portions were finished and how. There is some useful information to be gained from it, but there are no plans to continue its development since an alternative has been implemented.

C# Changes

  • Fixed c2a5 barrels not flying as high as they are supposed to (see below).
  • Set custom hull size for monster_generic models that use a hard-coded hull.
  • Use Blue Shift grunt alert sentences in ba_power1.
  • Fixed Rosenberg models in Blue Shift maps.
  • Fixed incorrect rendercolor values in some original HL maps. This happened because some original maps incorrectly include commas in rendercolor values; the parsing code was rewritten to allow the use of string_view which made parsing stricter.
  • Fixed grunts using wrong body value in of2a2.
  • Changed Gina model in ba_security2 to use hologram pushcart model.

Asset Changes

  • Added custom hull size keyvalues to fgd.
  • Added trigger_changekeyvalue to fgd.
  • Removed unnecessary polygons from v_shock.
  • Added HD grunt stretcher sequence.
  • Added shared Hologram pushcart model.
  • Updated game configuration files to use new syntax.

Changes in detail

Client user messages dispatcher

This feature reworks client-side user message handling to allow object member functions to be used without requiring a non-member function to forward it using a global variable.

It changes this code:
// In the global scope somewhere
DECLARE_MESSAGE(m_Health, Health)

// In hud element Init function
HOOK_MESSAGE(Health);
To:
g_ClientUserMessages.RegisterHandler("Health", &CHudHealth::MsgFunc_Health, this);
It's probably easier to show how this change affected the codebase: https://github.com/SamVanheer/halflife-unified-sdk/commit/f32cdda028bef544685c16eecf38a861ba329f42

A lot of boilerplate code has been removed. The hooking of message handlers in VGUI1 code has been moved to a better location.

This feature is a re-implementation of a feature that was added in HLEnhanced for the same purpose. That version also supported multiple message handlers for the same handler in order to support multiple huds, which is a feature that will not be added to this project. That is because multiple huds are not useful; only the visual appearance of the hud should be configurable and that's best done another way.

Additionally the return type has been changed from bool to void since it was never checked anyway and was being used inconsistently.

This feature was added now because it allows the client to detect when a user message is being handled so that the networking system can load its data before it is used anywhere.

Hud class changes

All CHud member variables are now initialized to ensure that variables have valid values from the start. This wasn't a problem but helps to avoid problems in the future.

The list of hud elements is now stored in a std::vector and unnecessary null checks have been removed. Enumeration of hud elements is now much simpler:
for (auto hudElement : m_HudList)
{
    hudElement->VidInit();
}
Additionally the VidInit call is now done using the list instead of manually calling each element as is done in the original SDK.

The list of hud sprites is also stored in a std::vector. Previously all three variables representing hud sprites were in separate dynamically allocated arrays:
// the memory for these arrays are allocated in the first call to CHud::VidInit(), when the hud.txt and associated sprites are loaded.
// freed in ~CHud()
HSPRITE* m_rghSprites; /*[HUD_SPRITE_COUNT]*/ // the sprites loaded from hud.txt
Rect* m_rgrcRects;                              /*[HUD_SPRITE_COUNT]*/
char* m_rgszSpriteNames;                      /*[HUD_SPRITE_COUNT][MAX_SPRITE_NAME_LENGTH]*/
These three variables as well as the actual sprite model name are now stored in a structure:
struct HudSprite
{
    eastl::fixed_string<char, MAX_SPRITE_NAME_LENGTH> Name;
    eastl::fixed_string<char, 64> SpriteName;
    HSPRITE Handle = 0;
    Rect Rectangle{0, 0, 0, 0};
};
The sprite list loaded by the engine (m_pSpriteList) is now freed once all sprites have been loaded into the hud sprite list. This fixes a memory leak on Linux that occurs when the engine does a soft restart (due to video setting changes or changes to filesystem configuration like toggling HD models).

There are still memory leaks in the weapon hud since it uses the same engine function but those will be fixed when the hud sprite text files are converted to JSON.

--> Continued in next post
Posted 1 year ago2023-02-09 14:00:19 UTC
in Half-Life Updated (custom SDK) Post #347317

Map decompiler beta 8

Beta 8 has been released: https://github.com/SamVanheer/HalfLife.UnifiedSdk.MapDecompiler/releases/tag/V0.8.0.0-beta008

Changes:
  • Updated Sledge.Formats to fix Wally being unable to correctly open generated wad files
  • Added --apply-null option to command line
  • Added option to always generate origin brushes for brush entities even if the origin is 0 0 0
  • Added wildcard matching to apply AAATRIGGER to brushes lacking any textures (referred to as "trigger entity classname wildcards")
Posted 1 year ago2023-02-09 13:50:41 UTC
in Half-Life Asset Manager Post #347316

Half-Life Asset Manager V2 Beta 8 released

Half-Life Asset Manager V2 Beta 8 has been released: https://github.com/SamVanheer/HalfLifeAssetManager/releases/tag/HLAM-V2.0.0-beta008

Changes:
  • Added explicit conversion from UTF8-encoded std::string to std::filesystem::path to fix sequence files failing to load
  • Fixed arc ball camera distance spinner being limited to 0-99.99 range
  • When launching a default program to open a file, if the file does not exist this will be more clearly indicated (previously file existence and default program checks were reported in a single error message)
Posted 1 year ago2023-02-04 17:32:31 UTC
in Half-Life Updated (custom SDK) Post #347299
<--- Continued from previous post

Networking system

I've done some more work and research on the networking system and the more i think about it, the more complicated this gets. I've already invested quite a bit of time into this and it's looking like a lot more work is required for this to work as intended.

Experience tells me that continuing to work on this is a waste of time. It would take far too much effort and will never work quite right due to the problems that have to be worked around (needing to add a second loading screen, having to treat the player as unconnected while transferring data, accounting for blocked ports) so i've instead opted for plan B:

Sending the data using a precached file generated on-demand.

The concept is simple: the server generates a file containing all of the data that is to be sent to the client. The file is precached so the server will tell the client it needs the file. The client deletes old files when it initiates a connection (also occurs on map change) ensuring that it will redownload it. The server deletes old files right before generating a new file to avoid wasting disk space.

Both the client and server's download cvars are forced on to ensure that the file is downloaded. For listen server hosts the server's file is used, in all other cases the downloaded file is used.

I've already implemented this but it's not quite ready to be merged since i need to stress test it more. So far i've only tested sending the list of sentences (to test large amounts of data being transferred), sending a bit of structured data (list of objects with text and binary data), and sending the list of precached sounds and playing them using the new sound system (works, but not every sound is played directly by server side code).

The data is generated as a JSON object, with each data set being a keyvalue in that object:
{
"SoundList": [
        "filename1.wav",
        "filename2.wav"
    ]
}
The resulting JSON formatted in minified form (no whitespace, newlines or comments) is compressed using Bzip2 to about 1/5th the original size.

This is a great example of Perfect is the enemy of good. It took me about 6 hours to implement the new system, including a basic prototype based on Source's network string table system before being redesigned to eliminate problems with that design (waste of memory, forcing the data to follow a specific structure which didn't always compress well). I've spent quite a bit more time than that on the other system.

Of course it would've been a lot easier to implement the system as intended if it could've been integrated into the engine (i replaced Quake 1's networking system with GameNetworkingSockets in a roughly equal amount of time) but that's not an option here.

Once this system is finished i can use it to send over existing data and use it to finish implementing work-in-progress features. There is some data that i'd like to send over using this system to eliminate some other problems but that remains to be seen.

New UI

Like i said above continuing to focus on perfection can be a problem. The goal with the UI updates was to focus on picking a UI framework first and then fixing things, but that will probably take a lot of time. So instead the immediate problems will be solved first, and the much larger task of implementing a new UI will come after.

In practice this means having a way to replace HUD images on a per-map basis. The simplest solution is to remap one image name to another and requiring the HUD to refresh its cached image indices at least at the start of the map.

The server only needs to know the name of the replacement file to precache it and send the name to the client. The name can be sent over using the networking system to ensure that it's there before anything needs it.

There's also the need to handle starting the hazard course/boot camp and campaigns using a custom UI. That can be done the same way as Condition Zero, just loading the campaign and map names from a JSON file. It won't look very pretty but it will work.

Project merging status

Current status:
  • Half-Life Updated (up-to-date)
  • Half-Life: Opposing Force Updated (up-to-date)
  • Half-Life: Blue Shift Updated (up-to-date)
  • Half-Life Updated CMake (complete, project has been archived)
  • HLEnhanced (in progress)
  • Enhanced Half-Life (in progress)
  • Half-Life Better Weapons (in progress)
  • Condition Zero: Deleted Scenes SDK (not started)
Some of the work from HLEnhanced, Enhanced Half-Life and Better Weapons has already been merged in now. I've been going through my old notes for HLEnhanced and checking the source code for anything that's useful to merge in.

Enhanced Half-Life doesn't have as much useful stuff, it's mostly experimental and fragile changes not suited for long-term use. The CBaseItem changes and related changes are the biggest set of changes that need merging, and portions of those are already covered by existing changes (e.g. sound replacement).

Better Weapons isn't a lot of work, just using the new weapons dictionary to create the weapons on the client side automatically. The same functionality exists in HLEnhanced so this will complete work for both projects.

Condition Zero Deleted Scenes has only two changes to offer: trigger_changekeyvalue and trigger_sequence. The former is easy to add, the latter relies on sequence files which aren't useful since they still use the old sentences system.

It would be better to focus on implementing scripting support using Angelscript or some other language (e.g. Squirrel) since that's more powerful and avoids relying on a feature that is partially in the engine, so only one feature from that SDK needs merging.

All in all the merging process is almost complete. Several of the projects can be merged in with only a small amount of work.

Remaining work to be done

I know this looks like a constantly changing target, but it's getting closer and closer to completion now. Some goals have changed based on new information and the knowledge that whatever the first version is, it's going to be what people start with so it should be stable and realistic.

For now i need to focus on open pull requests. I know at least one of them involves adding a new feature to the sentence replacement system that involves automatically adding replacements for individual sentences when the entire sentence group is marked as replaced since that's been a source of bugs a couple times.
  • Update changelog to include all changes (partially complete)
  • Write documentation for all new features (partially complete)
  • Networking system (transfer contents of replacement files, precache lists, possibly other immutable data): work in progress
  • HUD image replacement for Opposing Force
  • Versions of Opposing Force-only HUD images that have the scanline effect removed: some preliminary research done, needs more investigation
  • A way to start all three campaigns from the main menu. Probably the same solution as used in Condition Zero Deleted Scenes (menu button that starts a map that opens an SDK-level menu that enables campaign and training selection)
  • Merge in remaining useful functionality from other projects
  • Implement as much of the work scheduled on the issue tracker as possible
  • Review all changes
  • First alpha build
  • Stress test the three campaigns and fix issues that show up (first test done)
  • First beta build
It's mostly a matter of getting the work done now, just implementing stuff, not doing research. It's too soon to test anything at this stage because a lot of stuff isn't finished yet, so please don't report stuff as broken because that's expected at this stage.

I think that about covers it for now, the next status update shouldn't take 2 months but we'll see.
Posted 1 year ago2023-02-04 17:32:09 UTC
in Half-Life Updated (custom SDK) Post #347298

Progress on the Unified SDK

It's been a while since i've posted an update about the Unified SDK. This is mainly because i've been focusing on Half-Life Asset Manager 2.0.0 which is in beta and is expected to reach a full release soon.

SDK Changes

  • Added more documentation covering new feature and changes to existing features
  • Added instructions on how to view Markdown documentation locally using Visual Studio Code
  • Streamlined tool and script documentation
  • removed test_effect entity (not used and only partially implemented, did not function)
  • Return CBasePlayer* from UTIL_PlayerByIndex
  • Removed virtual functions in CBaseEntity that are only implemented for players and called by code that knows it's CBasePlayer
  • Added ToBasePlayer function to convert a (possibly null) entity pointer to a player pointer, with debug check to verify that it is actually a player to catch incorrect results returned by CBaseEntity::IsPlayer
  • Applied a bunch of code cleanup that was originally done in HLEnhanced. This reduces the complexity of type declarations, visual noise, the amount of types suggested by Intellisense, generally making the codebase easier to navigate through
  • Replaced some macros with STL functions
  • Fixed scripted_sequence searching for targets incorrectly
  • Use CBaseEntity find functions instead of edict_t versions
  • Added entity dictionary to create entities with
  • Don't try to play sentences through engine if index exceeds engine limit
  • Use script logger for scripted_sentence and scripted_sequence
  • Changed existing functions to use CBaseEntity for entity parameters instead of edict_t or entvars_t
  • Use local port for openal-soft, modified library name to use one that doesn't conflict with one the engine uses
  • Install OpenAL on Linux, create symlink, locate library using $ORIGIN so the library is located next to client.so

C# Changes

  • Improved command line option and argument passing for existing programs
  • Added missing index-to-filename conversions for func_water and func_train sounds
  • Implemented support for copying assets to hd and lv directories to the AssetSynchronizer

Asset changes

  • Changed MapCfgGenerator destination directory argument from Option to Argument
  • Updated AssetManifest.json to use new structure
  • Added asset source files for many models made by malortie

Entity dictionary

The new entity dictionary has allowed for improvements to be made to existing code.

This change required cbase.h to be split up to ensure correct header include order.

The CREATE_NAMED_ENTITY engine function has been rendered obsolete by this change, the game now looks up entities by name locally using this dictionary. string_t no longer implicitly converts to string_t_value because it was only needed to support CREATE_NAMED_ENTITY.

GetClassPtr no longer exists. Creating entities programmatically with specific types is now done in this manner:
CBeam* pBeam = g_EntityDictionary->Create<CBeam>("beam");
If the type doesn't match what you've requested (e.g. g_EntityDictionary->Create<CBasePlayerWeapon>("beam")) then the game will assert in debug builds to warn you.

It is no longer required for the classname string to continue existing since it's automatically allocated from the string pool. Manual classname assignments are rarely needed since all entity creation is done through the dictionary which guarantees classname assignment. Only entities with multiple classnames and those created on the client side still need it (basically just weapons).

In addition to the entity dictionary there is also a second dictionary for weapons only: g_WeaponDictionary

This dictionary only tracks entities that inherit from CBasePlayerWeapon and is currently used by the weapon precache code. In the future this dictionary will be used for more things when HLEnhanced's updated weapon prediction code and the Better Weapons SDK are merged in. It renders the Better Weapons macro used for weapon registration obsolete.

Additional dictionaries can be added for specific sets of classes:
template <typename TEntity>
void RegisterEntityDescriptor(EntityDescriptor<TEntity>* descriptor)
{
    assert(descriptor);

    // This is where each dictionary is initially constructed and built to add all entity classes.
    // Ideally some form of reflection would be used to build these dictionaries after the initial dictionary has been created,
    // but since we don't have reflection available and existing libraries require loads of refactoring this will have to do for now.
    detail::RegisterEntityDescriptorToDictionaries(descriptor,
        EntityDictionaryLocator<CBaseEntity>::Get(),
        EntityDictionaryLocator<CBasePlayerWeapon>::Get());
}
Simply adding another specialization here creates the dictionary. The global variable used to access it is declared just above this function:
// Used at runtime to look up entities of specific types.
inline EntityDictionary<CBaseEntity>* g_EntityDictionary = EntityDictionaryLocator<CBaseEntity>::Get();
inline EntityDictionary<CBasePlayerWeapon>* g_WeaponDictionary = EntityDictionaryLocator<CBasePlayerWeapon>::Get();
The goal is to eventually merge in Enhanced Half-Life's item class refactoring work, at which point a CBaseItem dictionary will be used to handle the giving of items to the player (e.g. using the give console command) to improve the behavior of existing functionality.

Using CBaseEntity instead of edict_t or entvars_t

These changes are intended to standardize the SDK to use CBaseEntity when passing entities around. This reduces the amount of conversions between types and makes it easier to tell which entities are being accessed.

Third party tools that intercept function calls (e.g. AMXMod) will not work properly with these kind of changes, which is why the README states they're not supported. More changes like these are going to be made to improve the quality of the code and to make it easier to work with.

This also means that trying to make a mod with this SDK right now is a bad idea because you'll have to merge in a lot of changes. Once again i must stress that this SDK is not ready to be used for the creation of mods right now. If you do so and you end up with many merge conflicts it'll be up to you to resolve them.

OpenAL-Soft changes

The OpenAL-Soft library is now renamed and installed on both Windows and Linux. This ensures that both platforms are running the same version with the exact same build settings. This also allows the use of extensions added to newer versions.

There are some things i'd like to try using said extensions to improve the accuracy of the new sound system when compared to the original.

---> Continued in next post
Posted 1 year ago2023-02-04 15:39:31 UTC
in Half-Life Updated (custom SDK) Post #347297

Half-Life Updated betas released

Half-Life Updated, Half-Life: Opposing Force Updated and Half-Life: Blue Shift Updated betas have been released:
Half-Life Updated: https://github.com/SamVanheer/halflife-updated/releases/tag/HLU-V1.0.0-beta014
Half-Life: Opposing Force Updated: https://github.com/SamVanheer/halflife-op4-updated/releases/tag/HLOP4U-V1.0.0-beta011
Half-Life: Blue Shift Updated: https://github.com/SamVanheer/halflife-bs-updated/releases/tag/HLBSU-V1.0.0-beta011

Bug fixes

  • Correctly save and restore controller and blending variables
  • Set activity before SetYawSpeed so it has the right activity
  • Fixed animation code accessing invalid sequence descriptor
  • Fixed weapon bits being incorrectly set and checked in HasAnyWeapons
  • Fixed projects with spaces in paths failing to execute post build step
  • Fixed NPCs not being able to speak scripted sentences while in scripted death
  • Removed unnecessary semicolons
  • Updated source file encoding to UTF-8
  • Renamed CWorld::Instance to CWorld::World to avoid conflicting with CBaseEntity::Instance function name
  • Added -flifetime-dse=1 flag to Linux Makefile to disable compiler optimization that removed entity memory zero-initialization, resulting in the game crashing when any entity touches the world
  • Fixed game_player_equip crashing when given a null activator
  • Fixed Hornet gun recharging to full ammo after loading a save game
  • Fixed explosives that impact the underside of a brush dealing damage to entities on the other side of that brush
  • Fixed entities with an index greater than 2047 corrupting the client's heap if sent over the network (these entities are never sent over the network, so they will be invisible and won't be checked in client side physics calculations)

New features

  • Save and restore game_player_equip (this allows the entity to be used in singleplayer)
  • Moved IsFacing function from barney.cpp to h_ai.cpp to help prevent linker errors when copy pasting source file
  • When using impulse 107 to get the name of a texture the texture type (as used in materials.txt) will also be printed
  • Made PM_FindTextureType const correct
  • Added WRITE_FLOAT function corresponding to the client's READ_FLOAT function
  • Set maximum edicts to 2048 in liblist.gam (note: the actual maximum edicts value is 2048 + (15 * (maxplayers - 1)). It is possible to create more than 2048 entities as long as entities with an index exceeding this don't have any physical presence in the world (i.e. no model, non-solid, no movement) but since the entity index cannot be chosen when creating entities this is impractical. The game will crash in the server-side player physics code if solid entities are created, presumably because that system is hard-coded to a maximum of 900 solid/visible entities with no bounds checking

Project changes

  • Added delta.lst to the archive again (was accidentally removed in the previous beta)
  • Added game icons to the archive
I also investigated increasing the maximum map size that game code allows for. I concluded that since some parts of the engine hard-code the limit to 4096 units in all directions it would result in inconsistencies so the limit will remain as-is in the SDK source code. Modders can change this limit if they want to, provided that they also implement custom network messages to bypass the engine's hard-coded limit. See this issue for more information.

Thanks to vasiavasiavasia95, FreeSlave, jay!, Shepard, λλλλλλ, anchurcn and Hezus for helping with this update.
Posted 1 year ago2023-01-28 19:30:22 UTC
in Half-Life Asset Manager Post #347263

Half-Life Asset Manager V2.0.0 Beta 007 released

Half-Life Asset Manager V2.0.0 Beta 7 has been released: https://github.com/SamVanheer/HalfLifeAssetManager/releases/tag/HLAM-V2.0.0-beta007

Changes:
  • Removed the "Use single instance" option. The default behavior is now to always use a single instance. This option was provided to emulate the behavior of older model viewers which could only load one model at a time. Asset Manager can load any number of models and should always use the same instance to share resources
  • Ensured that file logging is initialized after the single instance check to prevent multiple instances from logging to the same file at the same time
  • Updated the installer to use the correct icon for Shell Execute (the icon shown when a file opened through Asset Manager is shown in Windows Explorer)