SharpLife - Dot Net Core based modding p Created 8 months ago2018-05-06 19:15:02 UTC by Solokiller Solokiller

Created 8 months ago2018-05-06 19:15:02 UTC by Solokiller Solokiller

Posted 2 days ago2019-01-15 20:08:10 UTC Post #341679
In my opinion, it may do the opposite. It may encourage people. I've never used C#, but from what I hear and see here, it seems easier than C++
It is, in high programming languages (C#/Java), you don't have to deal with pointers (but you still need to worry about "null references"), memory allocations, memory leaks and more, the language does that for you. The only problems (which aren't really problems if you ask me) is you need a "Common Language Runtime" (.NET Core Runtime in the case of Sharp-Life) to run the code and it can be easily reverse engineered (yeah I know about obfuscation). C/C++ being low level programming languages are "closer to the machine", it's the opposite.
Then there's the question of doing it from scratch. If the HL SDK is ported to C#, do we replicate the changes which we made to our C++ HL SDK code over to the C# HL SDK, or something else?
My guess is that you will need to start from scratch, there are already so many differences that you can't just move your C++ code over to C#. Let's take an example: to save/restore entities data, the C/C++ way is to declare and use a save/restore table. Sharp-Life through the power of C#'s annotations handles the save/restore table already for you and you just need to annotate the variables you want to be saved/restore.

C/C++:
// Might be wrong here
TYPEDESCRIPTION CTWHL::m_SaveData[] =
{
    DECLARE_FIELD( FIELD_BOOLEAN, CTWHL, m_bStatusSent )
};
IMPLEMENT_SAVERESTORE( CTWHL, CBaseEntity );
C# (Sharp-Life):
// Might be wrong here too (feel free to correct me Solokiller if I messed up)
class CTWHL
{
    [Persist]
    bool StatusSent;
}
Shepard62700FR Shepard62700FRHalf-Cat is watching...
Posted 2 days ago2019-01-15 20:19:19 UTC Post #341680
Yeah your example is pretty much how save/restore should work.

C# is much easier to use than C++. I'll show a couple SDK examples to show this.

This is some code that shows up a lot in gamerules classes:
UTIL_LogPrintf(
	"\"%s<%i><%u><spectator>\" joined team \"spectator\"\n",
	STRING( pPlayer->pev->netname ),
	g_engfuncs.pfnGetPlayerUserId( pPlayer->edict() ),
	g_engfuncs.pfnGetPlayerWONId( pPlayer->edict() ) );
The equivalent in SharpLife would be:
_logger.Information( "\"{PlayerName}<{UserId}><{SteamId}><spectator>\" joined team \"spectator\"", player.PlayerName, player.UserId, player.SteamId );
Changing WONId to SteamId since WONId is always -1 now.

This is for logging, for normal string formatting you can just use string interpolation:
sprintf( text, "* you are on team '%s'\n", team_names[ ( int ) pPlayer->m_iTeamNum - 1 ] );
var text = $"* you are on team '{TeamNames[(int) player.TeamNumber]}'\n";
No possibility of buffer overflows here.

EHandles can also be made safer:
CTFGoalFlag pFlag = ( CTFGoalFlag* ) ( CBaseEntity* ) pPlayer->m_pFlag;

if( pFlag )
{
	pFlag->ReturnFlag();
}
Becomes:
EntityList.GetEntity<CTFGoalFlag>(player.Flag)?.ReturnFlag();
You don't have to do the double cast anymore (needed since EHANDLE can only be cast to CBaseEntity through its conversion operator), and the cast is safe instead of potentially creating an invalid object that can crash the game when used. Use of ? here is the same as the if check, if the object is not null call this method.

I've also had to write this code recently:
edict_t* pKiller = INDEXENT( 0 );

entvars_t* pEntKiller = pKiller ? &pKiller->v : nullptr;
None of that is needed in SharpLife, you can just use BaseEntity directly:
var killer = EntityList.GetEntityByIndex( 0 );
Since this just gets the world you can also get it through Context.Entities.World.

This is all pretty basic stuff, it gets easier once you deal with entities more:
pPlayer->pev->effects |= EF_NODRAW;
pPlayer->pev->flags |= FL_SPECTATOR;
pPlayer->pev->solid = SOLID_NOT;
pPlayer->pev->movetype = MOVETYPE_NOCLIP;
pPlayer->pev->takedamage = DAMAGE_NO;
pPlayer->m_iHideHUD |= HIDEHUD_HEALTH | HIDEHUD_WEAPONS;
pPlayer->m_afPhysicsFlags |= PFLAG_OBSERVER;
pPlayer->m_iNewTeamNum = CTFTeam::None;
pPlayer->m_iCurrentMenu = 0;
pPlayer->m_iTeamNum = CTFTeam::None;
player.Effects |= Effect.Nodraw;
player.Flags |= EntityFlag.Spectator;
player.Solid = Solid.Not;
player.Movetype = Movetype.Noclip;
player.Takedamage = TakeDamageMode.No;
player.HideHUD |= HideHud.Health | HideHud.Weapons;
player.PhysicsFlags |= PhysicsFlag.Observer;
player.NewTeamNumber = CTFTeam.None;
player.CurrentMenu = Menu.None;
player.TeamNum = CTFTeam.None;
Though i expect some of these variables will become obsolete since they're used for networking physics specific stuff. There's overlap here and there that can be eliminated.

Network messages will also be easier to use, right now they're just Protobuf messages so you can easily create and send them without having to worry about getting it wrong.

Debugging is also much easier since it'll tell you where a problem occurred, for example here's the log entry for a fatal error where it failed to load a sprite:
2019-01-10 00:34:47.640 +01:00 [ERR] A fatal error occurred
System.IO.FileNotFoundException: Could not resolve absolute path
File name: 'sprites\sewerfog.spr'
   at SharpLife.FileSystem.DiskFileSystem.GetAbsolutePath(String relativePath, String pathID) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.FileSystem\DiskFileSystem.cs:line 134
   at SharpLife.FileSystem.DiskFileSystem.Open(String relativePath, FileMode mode, FileAccess access, FileShare share, String pathID) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.FileSystem\DiskFileSystem.cs:line 222
   at SharpLife.FileSystem.FileSystemExtensions.OpenRead(IFileSystem self, String relativePath, String pathID) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.FileSystem\FileSystemExtensions.cs:line 254
   at SharpLife.Models.ModelManager.LoadModel(String modelName) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Models\ModelManager.cs:line 65
   at SharpLife.Models.ModelManager.InternalLoad(String modelName, Boolean throwOnFailure) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Models\ModelManager.cs:line 87
   at SharpLife.Models.ModelManager.Load(String modelName) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Models\ModelManager.cs:line 119
   at SharpLife.Engine.Server.Resources.ServerModels.LoadModel(String modelName) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine.Server\Resources\ServerModels.cs:line 75
   at SharpLife.Game.Server.Entities.BaseEntity.KeyValue(String key, String value) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\BaseEntity.cs:line 228
   at SharpLife.Game.Server.Entities.Effects.EnvSprite.KeyValue(String key, String value) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\Effects\EnvSprite.cs:line 45
   at SharpLife.Game.Server.Entities.ServerEntities.LoadEntity(List`1 block, Int32 index) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\ServerEntities.cs:line 267
   at SharpLife.Game.Server.Entities.ServerEntities.LoadEntities(String entityData) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\ServerEntities.cs:line 197
   at SharpLife.Game.Server.Entities.ServerEntities.MapLoadBegin(ITime gameTime, IMapInfo mapInfo, GamePhysics gamePhysics, String entityData, Boolean loadGame) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\Entities\ServerEntities.cs:line 170
   at SharpLife.Game.Server.API.GameServer.MapLoadContinue(Boolean loadGame) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Game.Server\API\GameServer.cs:line 207
   at SharpLife.Engine.Server.Host.EngineServerHost.InitializeMap(ServerStartFlags flags) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine.Server\Host\EngineServerHost.cs:line 240
   at SharpLife.Engine.Engines.ClientServerEngine.FinishLoadMap(String startSpot, ServerStartFlags flags) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Engines\ClientServerEngine.cs:line 442
   at SharpLife.Engine.Engines.ClientServerEngine.StartNewMap(ICommandArgs command) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Engines\ClientServerEngine.cs:line 426
   at SharpLife.CommandSystem.Commands.Command.OnCommand(ICommandArgs command) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.CommandSystem\Commands\Command.cs:line 43
   at SharpLife.CommandSystem.CommandQueue.Execute() in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.CommandSystem\CommandQueue.cs:line 95
   at SharpLife.CommandSystem.CommandSystem.Execute() in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.CommandSystem\CommandSystem.cs:line 103
   at SharpLife.Engine.Engines.ClientServerEngine.Update(Single deltaSeconds) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Engines\ClientServerEngine.cs:line 196
   at SharpLife.Engine.Engines.ClientServerEngine.Run(String[] args, HostType hostType) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Engines\ClientServerEngine.cs:line 181
   at SharpLife.Engine.Host.EngineHost.Start(String[] args, HostType type) in C:\Users\Sam\Documents\GitHub\SharpLife_full_dev\SharpLife-Engine\src\SharpLife.Engine\Host\EngineHost.cs:line 36
It's a bit much but you get everything you need to know.

Compare this with GoldSource or even just C++ debugging where something like this is little more than a message box telling you there was a fatal error, without actually pointing you at the code that triggered it.

Once you get used to the language you'll find it's much easier, you won't want to go back to C++ after this.
Posted 2 days ago2019-01-15 20:23:38 UTC Post #341681
So, it is not a question of doing anything from scratch, just knowing the "sintaxis" and "translating" waht´s already done to C#, right?. So, Solokiller is doing a "translation" of the HLSDK if I am not wrong, applying of course updates and making the code cleaner and optimized. :\

Well, what´s your advice for people like us who´re searching for a GoldSource compatible engine capable of more "horsepower" to move bigger and complex mods? I mean that if we could use, as Solokiller said, his engine to move GS mods or it is oriented to newer mods created on the SL plataform. Probably my explanations are not accurate, but I think from the perspective of a car user with little knowledge about car maintenace, and you are car´s motor and electronics designers, Idk if you catch the idea. :crowbar:
Posted 2 days ago2019-01-15 20:36:26 UTC Post #341682
I'm not translating it, i'm making a new engine that's also a mod that lets you make Half-Life mods and load original content.

If you want a better engine other than Xash then you'll have to wait.
Posted 2 days ago2019-01-15 23:37:44 UTC Post #341685
If you want a better engine other than Xash then you'll have to wait.
You caught me!! ;) But, If it can load original content like the original HL does I will wait for sure. Also It appears to work without vgui.dll, which´s the major limitation of Xash when it comes to go greenlightened on STEAM, right? , I´m with ZWC for the last 14 years, one more will not harm me. :crowbar: :D

In what a media playing is about, can we use other formats than AVI for the intro and sierra videos? also, I remember that in EHL you wanted to add background maps for the game menus, is this still present in SL?
Posted 2 days ago2019-01-16 00:11:22 UTC Post #341686
I am surprised. Keep work! Congratulations my dear! I wait also for your SL.
Posted 1 day ago2019-01-16 10:01:38 UTC Post #341690
You caught me!! ;) But, If it can load original content like the original HL does I will wait for sure. Also It appears to work without vgui.dll, which´s the major limitation of Xash when it comes to go greenlightened on STEAM, right? , I´m with ZWC for the last 14 years, one more will not harm me. :crowbar: :D
The original engine references vgui.dll, but my code doesn't use it.
In what a media playing is about, can we use other formats than AVI for the intro and sierra videos? also, I remember that in EHL you wanted to add background maps for the game menus, is this still present in SL?
The original engine can't play any videos, and SharpLife can't do it either. I'm not going to look into that any time soon either.
Background maps will be a thing for later, when the engine is stable.
Posted 1 day ago2019-01-16 12:52:09 UTC Post #341691
is it posible to use alternative algorithms over csg, bsp, vis and rad?

because map leaks and, convex and simple brush only mapping is very hard and bottlenecking on map design.

and rad compilings learning curve is too steep. I still dont know how to use expert compiling

so more modern collision dedection and more modern visibility calculation would be nice :D

i hope your sharp lifes mapping learning curve would be less steep too. as less as coding side :)

edit: i mean polygon based mapping rather than brush based mapping, is more powerful.

edit2:lightmaps have too low resolution
Posted 1 day ago2019-01-16 13:21:06 UTC Post #341692
While I think it is possible to have different map formats, I believe you are missing the point. The idea is to have a drop in replacement engine that is compatible with existing assets and later build on top of it as Solokiller said, so having legacy compatibility is the main focus now.

What you are suggesting is having completely different formats and methods for rendering, basically requiring making an engine completely from scratch.

GS mapping is pretty simple for new people to get going with, but as with everything it takes time to master. Same with Source and any other engine (the newer the more complex it is).
rufee rufeeSledge fanboy
Posted 1 day ago2019-01-16 13:24:48 UTC Post #341693
You're getting way ahead of yourself here. SharpLife doesn't even support all of the original engine's features yet, talking about adding a bunch of new stuff now is far too soon. At this rate it'll end up being some mythical super engine that can do anything but doesn't actually work yet.

We can talk about this stuff later on, when the initial version is finished. For now i'd like to focus on getting it all to work as it should.
Posted 1 day ago2019-01-16 14:53:43 UTC Post #341695
Ok, no avi for SL :crowbar:

What are the entities did you tested successfully among, info_player entities, env entities, lights (I saw something about those), scripst,etc.? apart from what´s descibed in Post #339709.

Also, what programs are you using to edit-compile the source?

Sorry for saying the "translation" thing, but, in your experience, what will be the major problems a non expert code will find when trying to "port" his/her code to SL?, many of us use tutorials all written in C++... ;)

Sorry for my too basic questions, I know that maybe this is not the place to ask them because the info here reached a high level, but I am very interested in SL as I was in EHL and PS before, and I want to gather as much info as possible before making the decission to jump from C++ to C#, because if C++ was sometimes like chinese to me, I think I will not be able to learn korean. :glad: :walter:
Posted 1 day ago2019-01-16 16:32:58 UTC Post #341697
@abbadon:
descibed in Post #339709.
heres post #339709

btw can we make another thread for SL v2 for not to forget cool ideas. and not to flood this thread with weird ideas. :D

cause i have one more idea to implement: unbroken coop mode and seamless level transition in multiplayer server. :D

so solokiller dont bother with forwardthinking ideas for now. he can look the other thread when hes ready to implement :D
Posted 1 day ago2019-01-16 16:48:17 UTC Post #341698
What are the entities did you tested successfully among, info_player entities, env entities, lights (I saw something about those), scripst,etc.? apart from what´s descibed in Post #339709.
That's the prototype for SharpLife, which ran under the original engine and only implemented game logic. It was essentially a converted SDK, but i scrapped it in favor of a complete rebuild, so just ignore all that.
Also, what programs are you using to edit-compile the source?
Visual Studio 2017 with C#7.3. The native wrapper uses C++17, but you'll probably never touch it since it's very simple and only does one thing.
Sorry for saying the "translation" thing, but, in your experience, what will be the major problems a non expert code will find when trying to "port" his/her code to SL?, many of us use tutorials all written in C++... ;)
No problems really, you'll just have to know which pev members map to which members in the new version. That's not really hard to figure out.
Sorry for my too basic questions, I know that maybe this is not the place to ask them because the info here reached a high level, but I am very interested in SL as I was in EHL and PS before, and I want to gather as much info as possible before making the decission to jump from C++ to C#, because if C++ was sometimes like chinese to me, I think I will not be able to learn korean. :glad: :walter:
You shouldn't make any decisions yet, this project is far from complete. I'd suggest checking out tutorials for basic Hello World stuff first, then maybe WPF since it requires the use of many language features.

If C++ is chinese then C# is dutch. It's way easier to learn and use. C++ has a lot of complexity and gotcha's that don't exist in C# and IntelliSense and the compiler will tell you how to fix most problems in C#. I'm using extensions that find code that can be improved which also helps out a lot.
btw can we make another thread for SL v2 for not to forget cool ideas. and not to flood this thread with weird ideas. :D
That's probably years away at this point, so i wouldn't bother just yet.
cause i have one more idea to implement: unbroken coop mode and seamless level transition in multiplayer server. :D
I was already going to implement co-op (Opposing Force has a co-op gamemode in it), what do you mean by unbroken?

Seamless level transitions basically revolve around 2 things: not showing the changelevel dialog and transitioning entities, which singleplayer code already does. For multiplayer all that's needed is to track which player is which since they don't remain connected during transitions. That's not very hard to do.
Posted 1 day ago2019-01-16 17:06:30 UTC Post #341699
what do you mean by unbroken?
i was thinking hl's coop mode is broken. i didnt know it wasnt

and i also trying to say, trigger changelevels arent working in singleplayer maps when playing MP, are they?
That's probably years away at this point, so i wouldn't bother just yet.
Then im gonna wait. and i will make projects about my own profession. because time wont pass when waiting something will not be released soon :D
Posted 1 day ago2019-01-16 17:18:32 UTC Post #341701
and i also trying to say, trigger changelevels arent working in singleplayer maps when playing MP, are they?
They're disabled for multiplayer, but it's easy to re-enable them. The hardest part about seamless transitions in the vanilla engine is that it wasn't designed for multiplayer use, so save games don't handle it. Also a fair amount of code in the SDK assumes the first player is in charge of gameplay, so things can break in weird ways. Easy to fix if you know what you're doing though.
i was thinking hl's coop mode is broken. i didnt know it wasnt
Half-Life itself doesn't have co-op at all, beyond an IsCoOp member in gamerules that's only used to find info_player_coop spawn points. Valve didn't finish it in time for Half-Life, but Op4 does seem to have it. Which brings me to: https://twhl.info/thread/view/19673
Posted 1 day ago2019-01-16 17:36:40 UTC Post #341702
You shouldn't make any decisions yet, this project is far from complete. I'd suggest checking out tutorials for basic Hello World stuff first, then maybe WPF since it requires the use of many language features.
Ok. I´ll finish all the graphics left undone (the code is 99,99% done) and I´ll keepseeing how SL grow and evolves. Thanks Solokiller (as always) :)
You must be logged in to post a response.