Forum posts

Posted 6 years ago2018-06-22 11:20:25 UTC
in SharpLife - Dot Net Core based modding p Post #339996
I've looked at a few networking libraries and it looks like Lidgren is the one to go for: https://github.com/lidgren/lidgren-network-gen3
It's recommended by most and provides everything that's needed to replicate the original system.

It also supports DotNet Core, albeit requiring a manual build. It should be possible to distribute the NuGet package itself and load it up locally, as i've done. That's relatively simple to do compared to the C++ dependency management approach.

Unlike GoldSource Lidgren doesn't impose any packet size limitations, but hardware and software limitations in the network infrastructure still apply here. Once a packet grows beyond a certain size it will be fragmented and reassembled on the other side, which means high amounts of packet loss can still cause problems. I may have to look into creating something that can send data in discrete packets to limit the effects of packet loss, but that will require further investigation to see if it's a real problem or not. I'm not too familiar with that stuff so it may not be a problem.

In any case it means the "reliable channel overflow" errors should be a non-issue. Timeouts, high ping and excessive packet loss should be the only reason to disconnect clients.

As far as GUI libraries go i've found that Imgui has a .NET Core wrapper: https://github.com/mellinoe/ImGui.NET
This should make implementing debug overlays simple, i know suXin from Facepunch has done this before so it should be simple to implement.

There's also a library for graphics programming: https://github.com/mellinoe/veldrid

It's low-level, cross platform and supports multiple backends, so i think this is a good way to support Vulkan and D3D.
It uses SDL2 for window management, and the library names are the same as Half-Life's so there is a need to modify the source. This is because Half-Life uses an older SDL2 library that may be missing functions. I may need to make a custom build for this to work out. I see that Veldrid uses a library to load native libraries, i may be able to provide a custom SDL2 path to load it.

For keyboard and mouse input i can also use SDL2, but i'll need to use a .NET wrapper here that also works together with Veldrid.
The wrapper i found uses DllImport which may not cooperate with manual library loading: https://github.com/flibitijibibo/SDL2-CS

Normally any given library is loaded once, so the goal will be to make sure the right SDL2 library gets loaded. If i can control where it looks for native libraries i can use a custom one and bypass the entire issue, otherwise i'll need to modify the source code of all involved libraries.

One option is to use this: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.defaultdllimportsearchpathsattribute(v=vs.110).aspx

But that only affects the assemblies that it's applied to. What i'm thinking is i can do this: free the original SDL2 library, load the correct one in the engine assembly, marked with that attribute, and then rely on the other load calls to use that library. This depends on the SDL2 library used by the original engine being freed, which may not be possible since it's a load time linked library. I'll have to verify this, otherwise using renamed libraries is the way to go.

That should cover networking, (debug) graphics and input. Sound can be handled through FMOD, that has a C# wrapper. The engine doesn't use it so there's no problem there.

I already have the filesystem code written up, though some changes are needed here and there. I'll be ditching the registry part of its initialization since that forces it to have Windows only dependencies, it'll be stored in a general purpose engine config file, along with things like the default game directory ("valve").

I've also built a command system, i've taken into account the problems that Valve had with engine upgrades to the classes. The problem there was that the class layout couldn't be altered without breaking mods, i've solved this by not making modders create instances of the classes. Instead, you provide info objects that describe commands, which are then used to construct the classes. Combined with C#'s delegates allowing class member functions and the compatibility between libraries, it should solve all of the problems that the command system has had since Quake.

As an example, here's the alias command:

RegisterConCommand(new ConCommandInfo("alias", arguments =>
{
    if (arguments.Count == 0)
    {
        Console.WriteLine("Current alias commands:");
        foreach (var entry in _aliases)
        {
            Console.WriteLine($"{entry.Key}: {entry.Value}\n");
        }
        return;
    }

    // if the alias already exists, reuse it
    _aliases[arguments[0]] = arguments.ArgumentsAsString(1);
})
.WithHelpInfo("Aliases a command to a name"));
Compare with the original: https://github.com/id-Software/Quake/blob/master/WinQuake/cmd.c#L341

The registration methods return interfaces to the commands to allow you to reference them, add more handlers, directly query variables, etc.
Commands and variables both allow you to add multiple handlers, so for instance if you have your cheat cvar "sv_cheats" defined somewhere, you can do this anywhere:

var svCheats = commandSystem.FindCommand<ConVar>("sv_cheats");

svCheats.OnChange += (ref ConVarChangeEvent conVarChangeEvent) =>
{
    if (!conVarChangeEvent.Boolean)
    {
        players.ForEach(p => p.DisableCheats());
    }
};
This adds a handler that checks if cheats have been disabled, and if so disables cheat properties on all players.

Variables also have filters that are checked before their values are changed. It's a pretty simple thing, if the filter returns false the change is not allowed. Filters can also modify inputs to for instance clamp values to a range, similar to Source's cvars. I've added filters that can do a few basic things, like testing if inputs are in a list, allowing only numbers, inverting filters, etc. For example, sv_cheats can have a boolean filter applied that restricts all inputs to 0 or 1.

Filters can be added and removed as well. Since both filters and change handlers are events, removing handlers you don't have a reference to is impossible, at least unless you use reflection to get the underlying event handler. It is thus difficult to accidentally break existing handlers.

Once all of this stuff is set up, the essentials should all be there. When i can draw stuff onscreen debugging will be easier, and i can start writing libraries that can load the various file formats used by the engine (bsp, mdl, spr). These will be standalone to allow for re-usability, hopefully useful to make new tools with.

If i can find the time i should be able to set this stuff up soonish, but i can't promise anything. I'm hoping there won't be any more unexpected problems, but you never know with these sorts of workarounds.
Posted 6 years ago2018-06-22 06:38:53 UTC
in Gangsta Wars .fgd Post #339994
Turns out the mod he has is called Gangster Wars, not Gangsta Wars. It's not the same mod :/
Posted 6 years ago2018-06-21 07:25:17 UTC
in 6/20 Update Post #339984
No patch notes, but we know HLTV files were updated and at least one bug was fixed: https://github.com/ValveSoftware/halflife/issues/1330#issuecomment-398531651
Posted 6 years ago2018-06-19 14:50:12 UTC
in SharpLife - Dot Net Core based modding p Post #339964
I experimented with Protobuf a bit to see how easily i could make a messaging system:

//Tell the client to change its name to Solokiller
var message = new StuffText
{
    Text = "name \"Solokiller\"\n"
};

//Represents the server's outgoing message buffer for the given client
var outboundPacketStream = new MemoryStream();

//Queues this message for sending to the client
//First we add a list of messages so the receiving end knows what's coming, and how to parse the messages
var messages = new MessageList
{
    Messages =
    {
        new Message
        {
            //The Id is not defined as an enum in a .proto file because we have both server-to-client and client-to-server messages
            //Using the same enum is a waste of bandwidth (variable length encoding would be larger for no reason) and duplicating the message class is wasteful
            //This cast is needed in only 2 or 4 places (sending messages, receiving them) depending on whether we'll use a generic handler type or one that's hardcoded to the Id type
            Id = (int)ClientCommandId.StuffText,
        }
    }
};

//Write the list, then each message
messages.WriteDelimitedTo(outboundPacketStream);
message.WriteDelimitedTo(outboundPacketStream);

//The client's buffer for processing
var inboundPacketStream = new MemoryStream();

//Would be a net packet send to the client, read by the client into a buffer for processing
outboundPacketStream.WriteTo(inboundPacketStream);

//WriteTo sets the position to the end, so this is needed to read from the start
inboundPacketStream.Position = 0;

//Read the message
var messagesResult = MessageList.Parser.ParseDelimitedFrom(inboundPacketStream);

//Process each message
foreach (var messageResult in messagesResult.Messages)
{
    //Could make a dictionary mapping id to a type containing the parser and a handler method to process the incoming message
    switch ((ClientCommandId)messageResult.Id)
    {
        case ClientCommandId.StuffText:
            var result = StuffText.Parser.ParseDelimitedFrom(inboundPacketStream);

            Console.WriteLine($"Command is: {result.Text}");
            break;
    }
}
So this code makes a StuffText message, sends it, parses it on the "client" and gets the text.

The Quake equivalent looks like this:
https://github.com/id-Software/Quake/blob/master/WinQuake/host.c#L322
https://github.com/id-Software/Quake/blob/master/WinQuake/cl_parse.c#L800

This approach is safer and easier to use. Messages are sent with their size so malformed messages will never cause problems (svc_bad is an indicator of this sort of problem), you can also do validation by marking fields in the .proto file.

Protobuf has no overhead, all it sends is the message data. I'm using the delimited write/parse methods here so a variable length integer is prepended to each message, but that's necessary because the parser wouldn't know where messages end otherwise. If you were to convert all network messages to use this it would be more efficient because Protobuf can encode data more efficiently, for instance you can send entity indices with fewer bits if it's a low number since it can use variable length encoding.

You can read more about encoding here: https://developers.google.com/protocol-buffers/docs/encoding

Eventually the idea is to let you send messages to clients by creating these messages and passing them to the engine's networking system, somewhat like this:
Networking.SendMessage(client, myMessage);

Where Networking is an instance of an object that can send messages, SendMessage is a method that can send to a specific client, client is the target client (index or client instance, probably the former) and the message itself.

Adding new messages is easy, the engine's current limitations won't be a problem here (192 byte maximum for user messages).
It would probably look like this:
Networking.AddMessageType(typeof(MyMessage), MyMessageHandler);

Where MyMessage is the generated class that it can get the parser and metadata from, MyNetworkingClass is the class where you handle your incoming messages and MyMessageHandler is a method with this signature:
void MyMessageHandler(MessageData<MyMessage> message)

Where the MessageData type contains the message itself as a member Message, along with anything else that's relevant (probably nothing, but it allows for changes).

The ability to remove and re-add handlers should also be possible to allow for changing the handlers for cases such as multiple HUDs, where some handlers will depend on the current HUD instance to process it.

So the idea behind this is to make networking a lot easier. Variable length encoding and packed fields will reduce message size, optional fields makes it easy to handle messages with multiple options (e.g. SVC_TEMPENTITY has over 100 possible options, some of which have optional members), and because it's based around code generation it's all strongly typed. No more screwing up a temp entity message because you sent a byte as a short or anything like that, it'll tell you if you made a mistake like normal programming.

It's also possible to send messages to programs that use a different language, so this could be used to send messages between C++ and C# if the need arises. I doubt that will actually be needed, but this could be used to send messages between the game and any tools, like Hammer. That's necessary if the tool is running as its own process, in which case inter-process communication is needed, which makes sending data a lot harder since you can't just pass data around like you normally would.
You could for instance serialize objects to protocol buffers to pass them around, though for that JSON might be a better solution.

It's also easy to log entire messages for debugging since the message size is known, as is the list of all messages in a packet. You could use this information to dump an entire packet for analysis if the game detects something is wrong (e.g. svc_bad errors, assuming those can happen with this design).

The next step will be to look into a good networking system to use, then build something that combines these two things.
Posted 6 years ago2018-06-19 13:55:46 UTC
in Gangsta Wars .fgd Post #339963
I know somebody who has the source code, i've linked him this thread. Hopefully he can help you out.
There's a limit of 32 bodygroups, but both bodies and bodygroups count for it. HGrunts have multiple (heads, weapons, etc) so the total is probably exceeding that limit.
I don't think it's a hard limit, so you could use a modified compiler to increase the limit, but i'm not 100% sure about that.
Posted 6 years ago2018-06-09 19:11:39 UTC
in E3 2018 Post #339852
Ok so there is no way to go back in the Youtube live stream, the EA site is unintuitive and the Twitch stream won't even load.
Posted 6 years ago2018-06-09 13:45:16 UTC
in E3 2018 Post #339846
I hope it's a good one, not the dance-like-an-idiot Kinect-fest they've had for several years.
This post was made on a thread that has been deleted.
Posted 6 years ago2018-06-03 15:42:06 UTC
in SharpLife - Dot Net Core based modding p Post #339795
I've implemented enough to load a client game project now, it's using the same player physics code as the server but nothing's rendering now as before.

I'm considering merging the server and client libraries since they'll be sharing a lot of code, including entities. It makes sense to use the same code with server and client specific providers for things like networking to make things easier, it enforces good design and separation.

I know Minecraft does this, mods are both client and server capable but you can tell it whether to enable the interaction on the client and server sides.

If i were to do this i could probably optimize singleplayer servers by not networking anything and using the same entities for both client and server. This would reduce memory usage and time spent "networking" (sending over loopback) things but could cause changes in behavior when data that is not sent at 100% accuracy is accessed on the client.

I'll have to think it over some more, i could just as easily use a library that shares entity code but one library means it's all in one place. That could be very useful for things like tools which could load the library and query for any data that they need, for instance it should be possible to generate FGD files with the metadata present in the server library.

Right now i'm going to add the code needed to render the game world correctly (telling the engine that entities are visible so it renders them), and then making sure input is handled. This code will need to be updated if i move away from the engine's code but having a working implementation should make it easier to convert.
That way any bugs added during conversion can be fixed without needing to look through my own version of the engine's code.

If all goes well i should have a functioning - if bare bones - C# based modding platform by the end of the week.
Posted 6 years ago2018-06-02 18:57:36 UTC
in SharpLife - Dot Net Core based modding p Post #339776
I've been working to get the client operational, i've got everything up until the managed wrapper done, now it's time to get the actual game code ported over.

Unfortunately i've hit a problem: SDL2 names its threads in a way that causes the game to shut down if it's launched with a managed debugger attached.
This behavior can be disabled, but not in the SDL version used by Half-Life. I've contacted Valve and asked them to update the SDL version, but i doubt they'll do anything about this.

This could also explain the seemingly random crashes i've experienced, if a thread is started and named it would cause the game to exit immediately if ran with a managed debugger so there's that. I'll keep an eye on the exit code to verify this.

Fortunately i can avoid the issue on startup by launching without a debugger and then attaching it, but it is a pain in the ass. Eventually i can ignore the engine and then this problem will go away, but for now it's an issue.

When i ran it without the debugger it seemed that it works without crashing, the player's view is stuck at world origin and nothing is rendered because visibility testing and physics isn't present yet, but that should be relatively easy to implement.

Once i've got that done, i can start working to add a networking layer to build on top of. That'll be the basis of the engine replacements, starting with sending large amounts of data, such as weapon and ammo types, sending a copy of the precache lists, etc. I've got some ideas about optimizing networking that could help but that remains to be seen.

I'll also be looking at available Dot Net Core GUI libraries, there aren't many from what i've heard so i may have to build one. It only has to be able to do what VGUI(2) can do, so a custom one wouldn't be that large. As long as it can render to an OpenGL texture/buffer it should be good.
Posted 6 years ago2018-05-26 20:18:25 UTC
in SharpLife - Dot Net Core based modding p Post #339709
I've put the source code for the wrapper and the game on GitHub:
https://github.com/SamVanheer/SharpLife-Wrapper
https://github.com/SamVanheer/SharpLife-Game

There is no documentation on how to use it yet (you'll need it), and it's still in development so it's subject to change.

Here's the list of changes since my last post:
-No more crashes on startup, unknown what caused it but i haven't experienced it anymore. Defender still uses a ton of memory though

-Implemented a bunch of entities, the training map can be loaded and it has triggers, doors, ladders, letting you move to the end of the map. No changelevel yet, that's partially implemented but it's missing the code to transition entities, which is part of the persistence system

-Player physics is implemented and seems to be mostly working, with the exception that movement on ladders seems to have some issues. There might be missing code in some other area, i'll look into that

-Most of the base classes have been implemented, aside from logic that handles bullets in BaseEntity everything up to BaseToggle is finished

-multi_manager and multisource have been implemented and support an unlimited number of targets now

-You can register cvars that are integrated into the engine, it's nothing fancy but it lets you work with it

-Entity data loading works properly and can handle most inputs quite well

-With the exception of networking code nothing accesses EntVars directly, it's all done through properties which will make switching over much easier

-Edict is avoided wherever possible, most references are in code that accesses the engine and some are wrapped to reduce the number of direct uses

-The node graph and func_train use EHandle to reference entities, which makes the code more reliable since it can't refer to other entities by accident

-The materials file is loaded, all supported materials are defined and contain all relevant data defined in one place: https://github.com/SamVanheer/SharpLife-Game/blob/3af4cda9fc5ec3ed74fd0df38268a41cf6883ab8/src/Server/Game/Materials/MaterialsSystem.cs#L29

Currently hard-coded, but this can be updated to load materials data from config files. It eliminates most of the redundant code and simplifies the logic when it's used

-The sentences file is loaded, its behavior is slightly different but should still be compatible with the engine's version. Once the client is implemented i can handle it there and remove some of the backwards compatibility stuff

-Unused code has not been converted, there are unused functions, class members, as well as logic meant to protect against engine behavior that has since changed. This simplifies things a bit

There are random crashes in the engine that happen from time to time, i'll have to debug that and see what exactly is happening.

I've looked into existing persistence support in the Dot Net framework, it seems that the best solution in this case is to use XML serialization. This will be mostly automated and should work like the original, but without the complicated binary logic.

Here's an example of how an entity is defined in the SDK and the C# version:
https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/plats.cpp#L628
https://github.com/SamVanheer/SharpLife-Game/blob/3af4cda9fc5ec3ed74fd0df38268a41cf6883ab8/src/Server/Game/Entities/Plats/FuncTrain.cs#L22

If you look through the code you'll see some patterns. Spawnflags are defined as a static class named SF that contains constants, that makes it easy to find and reference them.

I've looked into the engine's save game code, it looks like i should be able to override it by handling a few key functions, but i'll need to grab an engine data structure to initialize it properly when saved games are loaded.

I've also looked into the physics code, most of it is handled by one function: https://github.com/id-Software/Quake/blob/bf4ac424ce754894ac8f1dae6a3981954bc9852d/WinQuake/sv_phys.c#L1507

I can take the code from Quake and modify it to match what the engine does, then i can start moving properties from EntVars to BaseEntity. That'll improve performance and reduce memory usage a bit.

Key physics code is only referenced outside of that function hierarchy and engine functions in the player physics code, which i can also override.
That code is what converts edicts to physents, so i might be able to convert all of that to BaseEntity as well at some point.

I won't be able to do that until i've got control over the client as well, since it uses the same code.

Once i do have the client done i can make a networking system to override the engine's version. Then i can start overriding the big stuff like precaches and entities. That's probably going to take some time though.

The big question is whether i should focus on framework stuff like that, or implement all of the game's code first. The former lets me get the entire framework up and running, but leaves it unusable as a modding platform until it's complete, the latter gets it operational but limits functionality to what the SDK can do, with a few additions.

I think the former is the best solution, since it lets me get the client done sooner as well, but if anybody has an opinion, i'm all ears.
This post was made on a thread that has been deleted.
This post was made on a thread that has been deleted.
Posted 6 years ago2018-05-24 16:04:55 UTC
in Strange map issues Post #339701
It means a brush has multiple contents. This will usually occur if you have a brush with a regular texture and a special texture like water applied to it.

Either apply water textures to all faces or apply null to all but the visible sides to fix that.
Posted 6 years ago2018-05-24 07:12:31 UTC
in Strange map issues Post #339697
Warning: Ambiguous leafnode content ( EMPTY and SOLID ) at (2297,-704,-928)(-2296,-611,-920) in hull 2 of model 29 (entity: classname "func_wall", origin "", targetname "securitydoor_blastedwall")
There are a bunch of these warnings. Check the brushes in question to see what's wrong and correct the problem.

Also, VIS doesn't appear to be running, possibly as a result of these warnings. You should double check that it's turned on, since with it turned off you'll have visibility issues.
This post was made on a thread that has been deleted.
This post was made on a thread that has been deleted.
This post was made on a thread that has been deleted.
This post was made on a thread that has been deleted.
This post was made on a thread that has been deleted.
This post was made on a thread that has been deleted.
This post was made on a thread that has been deleted.
Posted 6 years ago2018-05-15 16:52:28 UTC
in SharpLife - Dot Net Core based modding p Post #339586
Okay your decision with C# I hope you have to prepare OpenGL-Wrapper like OpenTK ,OpenGL.net etc...

Good luck! Headcrab Basher - :crowbar:
I won't have to touch OpenGL for some time, there seem to be half a dozen libraries available so i'll take a look when it's time to work on it.
Like... I'm struggling to learn and and apply a programming language (currently mainly using Java) to make a living, and many times I feel like an impostor.

But after seeing this...
This is really advanced stuff that most programmers will never have to do, so don't be discouraged by it.
Java and C# are MOSTLY similar when it comes to the syntax, the main differences are the keywords ("final" -> "const", "package" -> "namespace"...) and other minor things. The transition from Java to C# should be fairly easy.
C# can do anything that Java can do, but Java can't do everything that C# can do.

Events, properties, directly calling delegates from native code, Java either can't do it or is much worse at it. I'd much rather be using C# than Java if i had a choice.

I've implemented the Detour framework so i can improve performance in some areas. Entity creation was really slow so i hooked it and re-implemented it in managed code. Mods can now control the entire process, it allows the creation of templates that can be spawned with a point_template like entity.

This means there is no maximum length limit on keys and values, no limit to the number of keyvalues that an entity can have and no limit to how many entities are defined in a map, although the engine's limit still applies during map spawn time.

I've also implemented support for linking classes to their map name, handling multiple names (some weapons need this), and partial support for keyvalues declared as properties, fields or methods.

I'll be implementing engine functions so i can implement the game interface, which will allow networking and such to work. Then i can implement some entities so maps work and i can see what else i need to implement before it's functional.

I'll probably need to detour more engine functions for performance reasons, which means physics will be re-implemented in managed code as well eventually. That also means parenting support.

Saved games will also need to be detoured to avoid problems with saved games being too big since the maximum size is hard-coded, which will allow the game to control all of the data being saved.

I'll get all of this stuff on Github soon so i can show the code. It's not ready for use yet and the framework seems to be triggering Windows Defender in a way that causes it to use up to 6 GB of memory at times. I don't know why this happens but it may be because it detects a custom CLR host.

It also seems to be causing crashes on startup (before my code is even loaded) so i'll have to figure out how to prevent this before it can be released.
Posted 6 years ago2018-05-15 16:29:15 UTC
in Strange error Post #339584
You can have keyvalues with "{" in them since they're in quotes, so they won't be seen as the start of a block.

This error occurs when the compiler can't find a "{" at the start of the entity data string: https://github.com/FreeSlave/vhlt/blob/3dcf197a30595da251d0577e870b33b4ab85c25e/common/bspfile.cpp#L1510

It looks like you're making a map for the WON version, since it's referencing Sierra. I'd suggest using Steam. Also, make sure you're using the latest VHLT compiler tools: https://forums.svencoop.com/showthread.php/40983-Downloads-amp-Changelogs

Try to move Hammer, the compiler tools and the map file to a directory with no spaces in it, you currently have it in "c:\sierra\valve hammer editor" which might cause issues.

If that causes issues, try using Batch Compiler: http://nemesis.thewavelength.net/index.php?p=2

Also make sure you're using the newest version of Hammer, or use another editor like JACK or Sledge. This could be a text encoding issue, since the engine also sometimes has issues with this data.

If that fails, take a look at this thread:
https://forums.svencoop.com/showthread.php/35026-Error-ParseEntity-not-found

If that doesn't help you, you should provide the map source file so somebody can take a look.
Posted 6 years ago2018-05-11 12:07:55 UTC
in SharpLife - Dot Net Core based modding p Post #339555
If you're having issues loading data or rendering it then it's not caused by the language, that's the library you're using or the code you've written. I've had issues with that in C++ as well, it doesn't make C++ crap.

Java's way worse than C#. I've worked with it for years and it is missing a lot that C# has, and i wouldn't use it for something like this. C# has much better native code support than Java which by itself is already a reason to use it here because i need to do a ton of marshalling and native code access.

Package management is pretty much automatic in C#, whereas Java doesn't have that. I wouldn't want people to juggle dependencies all the time, which is a problem that HLE is suffering from due to the CMake based approach requiring a lot of manual building of dependencies.

My college is even switching their courses from Java to C# because it's much better and easier to teach and use.
Posted 6 years ago2018-05-11 09:17:28 UTC
in SharpLife - Dot Net Core based modding p Post #339553
I can just write unsafe code to access model data, worst case scenario i can write my own loader and do what i've done in C++ before. It's not that hard.

Here's what i did to access edict_t: https://pastebin.com/DQ1qeXus

I haven't been able to test it yet, but it should work. This lets me access the native data while still using managed code in the game itself.

C++ actually does have a dependency manager, but as with most things C++ it's new and not terribly widely used yet: https://blogs.msdn.microsoft.com/vcblog/2018/04/24/announcing-a-single-c-library-manager-for-linux-macos-and-windows-vcpkg/

Even so it's still not easy to add dependencies, you still need CMake and old projects like GoldSource aren't built for it so you need ugly hacks to make it work.

I chose C# because it's the best tool for the job. The language itself is very easy to use and lets you design simple interfaces, like you can make a property that returns a string that internally could do a lot of work without exposing that detail. In Java you'd need a method for that.

You could do this:
//In BaseEntity
[Persist]
public string ClassName => pev.ClassName;

//In entvars_t
//Data is a pointer to the native entvars_t instance
//ToString accesses the string pool containing native string data
public string ClassName => Data->classname.ToString();
If i can ever get the engine out of the equation that can be simplified to:
[Persist]
public string ClassName { get; private set; }
In Java you can't do that. They've been playing catch-up to C# for a few years now, but C# is definitely the better language and the tooling support (Visual Studio) is much better than Eclipse/IntelliJ.

Native interop in Java isn't nearly as powerful as it is in C#. I read that they're planning to implement C++/CLI like support in Dot Net Core sometime, so perhaps next year i can simplify the interface even more by writing the native access in C++ instead. That would make things even easier, though by that time i may already have made the native parts obsolete.

That part's a bit tough, since there's a lot of engine code that accesses entvars_t and edict_t. There's 57 known accesses to entvars_t members that represent strings (string_t), the majority of which are classname checks.

Those can be avoided by handling entity creation entirely in managed code, since these calls are part of map spawning, entity creation, etc. If you override specific engine functions using the Detour framework then you can handle this directly in managed code.

If i can do that, and unregister certain console commands the engine won't touch it anymore. Eventually the idea is to not let the engine do anything, at which point the native interface would go away and the managed version would have its own implementation, or would be removed (edict_t and entvars_t really have to go).

I'm designing the game interface to make sense and be sane so most code wouldn't need updating. Direct access to edict_t and entvars_t would be handled in properties in common entity base classes (see example above), making the switchover easy and painless.

edict_t would probably be re-purposed to do what it does in Source, which is to store networking data and provide a way to represent players before their class instance is created (which i can fix if i have control over those particular engine functions).

If i can get this all done i can implement that custom networking i've talked about, which would let me implement uniform entity networking. It would look much like the persistence example:
[Networked]
public float Health { get; set; }
Should this not work and a notify-on-change type be needed, it wouldn't change the public interface:
[quote]
[Networked]
private Networked<float> NetHealth { get; } = new Networked<float>(0);

public float Health
{
get => NetHealth.Value;
set => NetHealth.Value = value;
}
[/quote]

All Networked instances in an entity would be hooked up to notify their owning entity so it can track the changes and network them at the next opportunity.

That would mean networked entities would exist on both the client and server side, could network any amount and type of variables and probably not cause reliable channel overflows anymore. cl_entity_t wouldn't exist anymore, the hacky weapon prediction system would be integrated into the rest of the system and we could actually build some neat things without worrying about engine limits.

Unfortunately this is all a lot of work and i have to finish up the native<->managed interface first, then port the entire server and then make the client version of all this. I can probably speed the client conversion up by writing a code generator for the interfaces, since it's largely the same thing over and over.

I'd still have to write a new GUI library either way since interfacing with VGUI(2) is not an option here. Any OpenGL based library should do here, as long as i can take the result and put it where VGUI goes it'll work, but there aren't many for Dot Net Core right now. I should be able to use the VGUI2 interfaces to render directly to the engine here though.

As far as content development goes, things should be a lot easier for you. I can implement a plugin system that loads assemblies that reference the mod, letting you access the game's code directly so you could add new weapons that way.
That is probably one of the biggest problems with Sven Co-op's scripting system, and one people have asked me about a lot, so i'm happy that this problem is now solved.

If i can implement the server<->client bridge i could add a debug UI that can directly access the server to take care of things that would otherwise be done through restrictive console commands. More expansive AI and scripting debugging would certainly help.

It's a bit too early to go into details about that, but i'm hopeful that this will let me finish the planned features for HLE and beyond.
Posted 6 years ago2018-05-10 09:27:39 UTC
in SharpLife - Dot Net Core based modding p Post #339540
I'm only using Dot Net Core with compatible libraries, and native interop to run under the engine. I do want to eventually implement engine code in managed code to skip the engine entirely but that's not going to happen any time soon.
Posted 6 years ago2018-05-08 18:00:55 UTC
in Half-Life RPG (one for the coders) Post #339524
They use Angelscript, and no. You need to be able to persist data and they don't have that implemented yet, they also don't have any form of client side scripting and control over the inventory and weapons is too limited for what's being discussed here.
This post was made on a thread that has been deleted.
This post was made on a thread that has been deleted.
Posted 6 years ago2018-05-06 19:15:02 UTC
in SharpLife - Dot Net Core based modding p Post #339507
I've been doing some research on porting Half-Life to C# using the Dot Net Core framework. I've got a working prototype that has C# code that can interface with the engine, though it's still far from complete.

I'm calling this SharpLife, since it's implemented using C#. It isn't limited to that language since it uses Dot Net but that is what i'm working with.

The goal is to port the SDK to C# and then upgrade it with Half-Life Enhanced's bug fixes and additions. Once that's done i can complete the planned changes for that.

Here's a diagram showing the overall design of the framework itself:
User posted image
Here are some examples of how it's easier to work with C# than C++:

[quote]
//Save restoring a field in a class in the SDK:
CBaseEntity* m_pGoalEnt;

static TYPEDESCRIPTION m_SaveData[];

TYPEDESCRIPTION CBaseEntity::m_SaveData[] =
{
DEFINE_FIELD( CBaseEntity, m_pGoalEnt, FIELD_CLASSPTR )
};

//Save restoring a field in a class in C#:
[Persist]
public CBaseEntity m_pGoalEnt;
[/quote]
//Getting the name of a class in the SDK:
const char* pszClassName = STRING( pEntity->pev->classname );

//Getting the name of a class in C#:
var className = pEntity.ClassName;
[quote]
//Loading an XML file in HLEnhanced:
https://github.com/SamVanheer/HLEnhanced/blob/346a9889f7da589f72cc66a71ee1202fc434714a/game/shared/CWeaponInfoCache.cpp#L154

//Loading an XML file in C#:
try
{
using (var stream = new FileStream("SharpLife/cfg/SharpLife-Wrapper-Managed.xml", FileMode.Open))
{
    var serializer = new XmlSerializer(typeof(ServerWrapperConfiguration));
var config = (ServerWrapperConfiguration)serializer.Deserialize(stream);
LoadMod(config.ModInfo);
return true;
}
}
catch(Exception e)
{
Log.Message($"{e.GetType().Name} - {e.Message}");
Log.Message(e.StackTrace);
return false;
}
[/quote]

It's much easier to manage dependencies than in C++ as well. To use XercesC in HLE you need to download, extract, compile and install it before referencing it in your CMake configuration.

In C# you only need to reference the NuGet package System.Xml.XmlSerializer. Once that's done everybody who checks out the codebase will be able to get the packages by restoring all NuGet packages for the solution.

For less experienced programmers (most modders) the language is easier to use as well. One mistake i've seen made a lot is string comparisons:
const char* somestring = ...;

if("ON" == somestring )
{
//Do something if ON
}
This compares memory addresses, which will always be false.

In C# it works like it does in most modern languages:
string somestring = ...;

if( "ON" == somestring )
{
//Do something if ON
}
And it does what you'd expect.

For scripting there's no need for Angelscript because you can just load assemblies that can directly access mod code. A simple plugin system would be a list of Dot Net assemblies that are loaded on mod startup that then behave as though they were part of the mod itself.

The language is very similar to Angelscript which is intentional, since Angelscript is based off of both C# and C++.

In addition, there's a scripting language called CSharpScript that is essentially C# code compiled at runtime, much like Angelscript: https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples

By moving to this it'll be easier and faster to continue development, modders can focus on implementing game logic instead of working around language limitations and quirks.

It will take some time to implement, but right now the biggest issue is getting the native<->managed code interop working. I have the necessarily functionality done for that, so it's just getting the interfaces for the server done, then re-implementing everything piece by piece.

The priority is making sure the game can load and run with a minimal codebase, so most entities won't work yet for some time.

I'm hoping once that's done i can implement the physics code re-implementation, which will allow for parenting, and then if i have time and motivation implementing a new networking system to transfer data to clients. The client itself will also need to be converted, but it's a bit smaller than the server so that should be simpler.

Best case scenario i can skip the engine entirely and just do everything in C#, which would really make things easy but that's a lot of work and i don't know if i'll still have time and motivation for that.
Posted 6 years ago2018-05-06 18:35:55 UTC
in Windows XP usage Post #339505
Alright, thanks for the feedback. Looks like i don't have to worry about stuff not working on anything older than W7, which is the oldest OS that Dot Net Core supports.
Posted 6 years ago2018-05-05 12:34:07 UTC
in Windows XP usage Post #339497
How many of you still use Windows XP these days? Which OS do you use now as your gaming environment?

I'm asking because i've noticed that more and more new tech is not capable of running on older systems and i'm wondering if it's still worth supporting XP at this time.
This post was made on a thread that has been deleted.
Posted 6 years ago2018-04-21 11:43:23 UTC
in mod_numforname error Post #339404
Provide the map file so we can check it ourselves. It sounds like you may have misconfigured an entity, if we can check it ourselves it'll be much easier to diagnose.
Posted 6 years ago2018-03-31 18:48:31 UTC
in Quake 2 mod for Xbox Post #339132
Show us what you're doing to cause that error.
Posted 6 years ago2018-03-30 16:33:46 UTC
in Quake 2 mod for Xbox Post #339124
If you can't even make a mod for a game on PC you'll never be able to do so on Xbox. We've been trying to help you for months now but you keep trying to do things well beyond your abilities.
I suggest you stick to PC, and try to get Quake to work on that instead.
Posted 6 years ago2018-03-26 18:13:30 UTC
in Errors when compiling with custom weapon Post #339115
Where else are you including the header?
Posted 6 years ago2018-03-26 15:18:20 UTC
in Errors when compiling with custom weapon Post #339112
Did you include cbase.h, util.h and weapons.h before including your own header?
Posted 6 years ago2018-03-24 18:46:19 UTC
in Make a killabe gman/kingpin... in HL1 Post #339099
If you were to add a cvar named "showtriggers" and set it to a non-zero value it would make some triggers visible in-game.

You can probably use AMXMod to do that easily.
Posted 6 years ago2018-03-24 12:56:45 UTC
in Hammer is unavailable Post #339092
That page tells you not to use the SDK, check the section "Authoring tools currently shipped as beta with their respective games".

Please read that page and check the rest of the wiki first. It will help solve your problems.
Posted 6 years ago2018-03-24 12:18:18 UTC
in Hammer is unavailable Post #339090
Posted 6 years ago2018-03-24 12:01:14 UTC
in Hammer is unavailable Post #339088
Use the Steam version of the game, don't use the Source SDK because that's outdated, the latest version of all tools are located in common/Half-Life 2/bin.

I would advise against mentioning the use of non-Steam tools and games because we can't support that in any way. Use official versions of games only.
Posted 6 years ago2018-03-18 19:58:17 UTC
in (Goldsrc) Locked doors Post #339046
If i'm not mistaken giving doors a name should make them play the locked sound.
Posted 6 years ago2018-03-17 12:28:16 UTC
in Entities disappear ingame Post #339042
Placing entities too close to brushes can cause them to sink through the floor. I suggest decompiling campaign maps to see how it was done there, then see how it differs from your own approach. There may be some tricks used there.
Posted 6 years ago2018-03-10 10:44:58 UTC
in First person camera position Post #338989
That's defined here:
Server only code:
https://github.com/ValveSoftware/halflife/blob/master/dlls/player.cpp#L2911

Shared physics code:
https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/pm_shared/pm_shared.c#L1952
https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/pm_shared/pm_shared.c#L2021

Standing to ducking transition code: https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/pm_shared/pm_shared.c#L2045

When the player is dead it's changed to be on the ground:
Server only code: https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/player.cpp#L1409
https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/player.cpp#L1456

Shared physics code: https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/pm_shared/pm_shared.c#L2892

The constant is defined here for server code: https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/util.h#L420

Physics code:
https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/pm_shared/pm_shared.c#L86
https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/pm_shared/pm_shared.c#L79
https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/pm_shared/pm_shared.c#L80

Note that the server only constant is used by other code as well, so don't change the constant itself, just define a new one.

As usual it's defined twice, you can rework it if you want.
Posted 6 years ago2018-03-08 22:20:43 UTC
in Little Half Life 1 mod... Post #338974
If you're using the Github SDK, that's projects/vs2010/projects.sln.
Posted 6 years ago2018-03-08 11:32:00 UTC
in Little Half Life 1 mod... Post #338968
Get Visual Studio 2017 Community, Sourcetree (Git user interface) and the source code from Valve's Github.

Visual Studio 2017: https://www.visualstudio.com/downloads/
Sourcetree: https://www.sourcetreeapp.com/
Source code: https://github.com/ValveSoftware/halflife

This documentation explains where to get the address used to clone Git repositories: https://help.github.com/articles/which-remote-url-should-i-use/

Here's a Sourcetree tutorial: https://confluence.atlassian.com/sourcetreekb/clone-a-repository-into-sourcetree-780870050.html

Take the HTTPS URL from Valve's Half-Life repository and clone it using Sourcetree, then you can open the project file projects.lsn located in "projects/vs2010". This contains the client and server libraries for Half-Life, Ricochet and DeathMatch Classic. You may remove the latter 2 if you don't want them.

After that it's basically the same as any other C++ project, but you should make sure you understand the basics of the language first, then read tutorials about Half-Life programming.

Here's a good C++ tutorial: http://www.cplusplus.com/doc/tutorial/

Here are some Half-Life tutorials: http://twhl.info/tutorial.php?cat=1

This looks like a lot of work, so take it slow and one at a time. Get Visual Studio installed and follow tutorials for C++ first so you understand it.

You will likely have issues with it, everybody does at first. It's not an easy language to learn but the most important thing is to keep at it. If you don't understand something, just ask.

If you need help with C++ in particular you can ask for help here: https://www.reddit.com/r/cpp_questions/
https://stackoverflow.com/

If you don't have much experience using Google you should try to use it to find answers first. Prefix your searches with "C++" to narrow it down.

Unfortunately there is no easier way to mod Half-Life. Some of us are working to make things easier. What you're trying to do should be possible with HLEnhanced eventually, but it's not ready yet.

If you don't want to learn how to program or can't, one of us can provide you with the necessary changes. It doesn't sound like a lot of work, but i do recommend learning to program if you want to do more advanced modding later on.
Posted 6 years ago2018-03-06 11:48:39 UTC
in New material sounds Post #338952
Looks like that system is even more complicated, existing code still uses materials.txt as in the SDK, but the client uses this new material system for effects like bullet impacts and the like.