Forum posts

This post was made on a thread that has been deleted.
Posted 6 years ago2018-11-03 20:29:43 UTC
in TWHL Modded Minecraft Server Post #341163
I'm using the seed that you posted with the mods you posted yesterday. I haven't changed it at all, and everything else is generating properly.

Also see this: https://twitter.com/voxcpw/status/1058816540659867648
Posted 6 years ago2018-11-03 19:56:55 UTC
in TWHL Modded Minecraft Server Post #341160
You should try to install it using the Twitch client, it looks like it downloads Forge from its own servers.

EDIT:

I was looking around the world a bit and found this:
User posted image
A perfect square going down quite a bit, there's gravel at the bottom.
Posted 6 years ago2018-11-03 15:49:15 UTC
in TWHL Modded Minecraft Server Post #341156
Give or take 100 mods :P
Posted 6 years ago2018-11-03 15:32:00 UTC
in TWHL Modded Minecraft Server Post #341154
I don't think it can mine stones, sand definitely isn't affected, but gravel is. You can configure it through the mod settings in the menu.
Posted 6 years ago2018-11-03 15:24:12 UTC
in TWHL Modded Minecraft Server Post #341152
VeinMiner lets you mine every block of the same type that's within one block of a group you're mining. It only works on blocks that are whitelisted, like clay. It also uses up your tool's durability, so all it really does it let you mine groups of ores or resources more quickly.

It's not a big deal if it's not there, but it's a nice to have type mod.
Posted 6 years ago2018-11-03 15:07:32 UTC
in TWHL Modded Minecraft Server Post #341150
If you're adding more mods, could you also add VeinMiner to it?

I'll update the Twitch profile once we're sure it's all locked in.

My username is _Solokiller_.
Posted 6 years ago2018-11-03 12:50:26 UTC
in TWHL Modded Minecraft Server Post #341146
I made a Twitch mod profile that you can import: https://www.dropbox.com/s/0s21tbt9y1dxs7p/TWHL%20ModPack-1.0.zip?dl=0

It includes the same directories as the mod pack archive, same Minecraft version, same Forge version. I hope it's compatible.
Posted 6 years ago2018-11-03 12:15:55 UTC
in TWHL Modded Minecraft Server Post #341144
It would probably be easier to make a Twitch mod profile and import it there, but i don't know if it would be compatible with the one that The Mad Carrot made.
Posted 6 years ago2018-11-03 12:03:03 UTC
in TWHL Modded Minecraft Server Post #341142
Take a look at this, it might help: http:/www.minecraftforge.net/forum/topic/62679-forge-1122-these-libraries-failed-to-download-try-again-error
Posted 6 years ago2018-11-03 11:23:44 UTC
in TWHL Modded Minecraft Server Post #341140
I had that error as well, just run it again.
Posted 6 years ago2018-11-03 11:13:07 UTC
in TWHL Modded Minecraft Server Post #341138
I had some trouble with it as well. I use the Twitch client so i initially tried to install Forge to its directory which didn't work. When i installed it into the default directory it worked and it showed up in the profiles list in my Twitch launcher. I changed the game directory after that to point elsewhere.
Posted 6 years ago2018-11-02 19:24:27 UTC
in TWHL Modded Minecraft Server Post #341131
That one looks good. There's swampland and extreme hills to the north-west along with a village.
Looks like there's a desert temple right next to it as well.
Posted 6 years ago2018-11-02 17:04:28 UTC
in TWHL Modded Minecraft Server Post #341128
User posted image
Seed is 7603789325610920724

I don't know why the "Save Map" feature is cutting out part of the map here, it just isn't capturing it.

It has a bunch of different biomes close by. Lots of birch forests, a desert, a couple extreme hills mountains, lots of swampland and plains.

There's a village close by as well.

The spawn point is near the center, in the small plains area between the 3 floating slime islands.
Posted 6 years ago2018-11-01 18:28:24 UTC
in TWHL Modded Minecraft Server Post #341119
Oh it has the mod with the controllable boats?
Posted 6 years ago2018-11-01 18:10:00 UTC
in TWHL Modded Minecraft Server Post #341117
Could be related to this: https://github.com/MrTJP/ProjectRed/issues/1331

Fixed in dev, but not pushed to a release yet from the looks of it.
Posted 6 years ago2018-11-01 17:37:24 UTC
in TWHL Modded Minecraft Server Post #341115
Looks like you're in the middle of a plains biome surrounded by forest. A good starting position, but i prefer to start near an intersection between forest, desert and swamp to get wood, sand and clay in large quantities.
Posted 6 years ago2018-11-01 12:25:40 UTC
in SharpLife - Dot Net Core based modding p Post #341113
Avalonia announced that they can recommend its use in production: http://avaloniaui.net/blog/2018-10-30-avalonia-0.7-release

I'll be taking a look at it sometime soon to see if i can make a model viewer replacement with it. According to some of the comments they don't yet have OpenGL support, but DirectX is supported. Figuring out if and how they support integration with Veldrid will be an important part of determining whether it's suitable for use at this time.
I've made a basic prototype for plugin management. It covers the essentials needed for assembly based plugin loading to work.

The manager loads plugin configuration from a file, much like Sven Co-op's plugin system does and similar to HLE's proposed configuration syntax: https://github.com/SamVanheer/HLEnhanced/wiki/Plugin-manifest-(temp-page)
<?xml version="1.0"?>
<PluginListFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<Plugins>
		<PluginConfiguration>
			<AssemblyName>TestPlugin.dll</AssemblyName>
			<PluginClassName>TestPlugin.TestPlugin</PluginClassName>
			<Arguments>
				<TestPluginArguments>
					<Name>Test Plugin</Name>
				</TestPluginArguments>

				<cvar name="developer" value="2"/>
				<cvar name="sv_cheats" value="1"/>
			</Arguments>
		</PluginConfiguration>
	</Plugins>
</PluginListFile>
A plugin is loaded based on assembly name, the plugin is instantiated based on the given class name.

If the class implements IPlugin, it will create an instance by using dependency injection to provide any objects needed by the plugin.
This could be used to get interfaces like the entity manager, networking, etc. Each plugin can also request the arguments given to it in the config file by specifying a constructor argument of type PluginConfigurationArguments.

Here's a basic example of a plugin:
using PluginHost;
using System.Xml;
using System.Xml.Serialization;

namespace TestPlugin
{
    public sealed class TestPlugin : IPlugin
    {
        public string Name => "TestPlugin";

        public TestPlugin(PluginConfigurationArguments arguments)
        {
            var serializer = new XmlSerializer(typeof(TestPluginArguments));

            var myArguments = serializer.Deserialize(new XmlNodeReader(arguments.Elements[0]));
        }

        public void Initialize()
        {
        }

        public void Shutdown()
        {
        }
    }
}
This plugin takes only the config arguments, and then converts it into an object of type TestPluginArguments, which looks like this:
namespace TestPlugin
{
    public class TestPluginArguments
    {
        public string Name { get; set; }
    }
}
This allows you to specify complex arguments and read it with ease. Note that the example does not do error handling, but that's not hard.

This can easily be used to pass configuration around, like requiring cvars to be set or even created dynamically.

Interface versioning is an important part of supporting plugins properly, breaking changes would require the assembly that provides the interface to change its assembly version, which will cause assembly load to fail with an error noting the version conflict. That makes it relatively easy to avoid cases where plugins rely on interfaces that have changed or have been removed.

For changes that don't break the API, like new methods it won't be necessary to change the version. I'm not 100% sure how C#'s interfaces work in this type of situation, but following the general rule of adding to the end of interfaces might be good enough, or alternatively adding new interfaces that extend from them.

Accessing plugins in game code should only rarely be needed, and can be done in a couple different ways.
Most of the time you won't need to access a single interface, just all of them, so iteration is the common case:
pluginManager.ForEach(plugin => plugin.DoSomething());

foreach (var plugin in pluginManager.GetPlugins())
{
    plugin.DoSomething();
}
The first option is the simplest and won't break easily. It does however create delegates which can add overhead in critical per-frame game logic like RunFrame. The latter option avoids that cost.

Most plugin access in SC revolved around hooks. The way it accesses hooks accounts for the fact that plugins can be reloaded. in C# assemblies can't be unloaded individually, only the app domain in which they've been loaded can be unloaded. Using app domains means direct access to plugins isn't possible, instead it would use proxies which adds too much overhead here, since plugins will define and access entities, among many other things.

This means that once loaded, a plugin will stay loaded.

As such, the hook system is best implemented by extending the event system currently used in the engine. Making each event always pass an Event object around that has properties to support preempting further processing of an event. This is similar to features that exist on most GUI frameworks such as JavaScript's preventDefault.

This would make preemtable hooks such as SayText pretty easy to implement and use, and avoids the direct reference between the code that emits the event and the plugin system.

Registering such an event handler would be done by the plugin:
public sealed class TestPlugin : IPlugin
{
    private readonly IEventSystem _eventSystem;

    public string Name => "TestPlugin";

    public TestPlugin(IEventSystem eventSystem)
    {
        _eventSystem = eventSystem ?? throw new ArgumentNullException(nameof(eventSystem));
    }

    public void Initialize()
    {
        //The event system can deduce the event name from the event object type
        _eventSystem.AddListener(OnSayText);
    }

    public void Shutdown()
    {
        //Remove all listeners registered by this plugin object (but not other objects created by the plugin!)
        _eventSystem.RemoveListener(this);
    }

    private void OnSayText(SayTextEvent @event)
    {
        //Chat text starting with this command is hidden and suppressed from further event handling
        if (@event.CommandLine.FirstOrDefault() == "/hide")
        {
            @event.Visible = false;
            @event.Cancel = true;
        }
    }
}
This way plugins can plug into the engine and game without ever needing to expose the concept of plugins anywhere.

By making it register event handlers in Initialize and removing them in Shutdown plugins and the game itself can be rebooted, which can flush all past state.

In similar fashion plugins can also create and acquire console commands and variables by taking an ICommandContext. The same goes for registering entities; taking the entity factory and registering itself as providing a set of entities that override the normal entities so it can override built-in entities when needed (that isn't implemented yet).

The only downside compared to Sven Co-op and HLE's versions is that you can't reload plugins. To solve that problem CSharpScript based plugins may be used. There is ultimately very little difference between the two once the IPlugin instance has been created, and scripts can be loaded again, although if i understand it correctly the script will stay in-memory even if it isn't used anymore.

CSharpScript does have some downsides but i haven't used it enough to know how much difficulty those add. Handling the difference in the plugin manager is pretty straightforward, and supporting both here means map-specific support can be added by using a map-specific plugin manager. The same config file structure can be reused for everything, the only issue would be that assemblies would stay loaded in-memory.

I don't know how much overhead this adds in memory usage and other costs, but given that the SharpLife assemblies are between 25-80 KB in size when built as Debug, i don't think it's that much. Worst case scenario servers would need to reboot every so often to flush its memory, which they often need to do due to crashes anyway.

Since most maps that use scripts also tend to become popular the memory cost would only have to be paid once, so that does make things better.

This is only a basic prototype of a plugin system, i'll probably rework it to avoid directly depending on XML serialization so it can be used independently.

I would like to use this for HLMV to let people add functionality to it themselves more easily. Since people request all kinds of features, making it possible to easily add it yourself would really open up model customization if you could modify the model data from a plugin.

If anybody has any opinions about this i'd love to hear it.
Posted 6 years ago2018-10-31 18:39:53 UTC
in TWHL Modded Minecraft Server Post #341108
I think you can do that already. What other integration mods do you suggest?
Looks like it isn't necessary anymore these days, it was the case in older versions.

If you want you can add Extreme Reactors to the list, it allows for large scale power generation. It may be better performance wise for the server compared to lots of smaller power generators.

In EnderIO's case, one of the latest updates added the Grains Of Infinity item for crafting, as well as needing to use dyes to craft machines. The recipes can be reverted by using config\enderio\recipes\examples\legacy_recipes.xml. The file explains how to use it, it reverts everything to the old redstone and iron based recipes. Since grains can only be acquired by setting bedrock on fire or using Ex Nihilo/Compressum to grind for them, it can really slow down EnderIO progression.

It's up to you to decide, i personally prefer the old recipes since the mod is already grindy enough when it comes to teching up.
Posted 6 years ago2018-10-31 11:10:42 UTC
in TWHL Modded Minecraft Server Post #341105
Mystical Agriculture is another good one. A good alternative to quarrying holes in the world.
Immersive Engineering also has some good stuff, and lets you make stuff like ziplines.
RFTools has good machines for various tasks.
Tinkers' Construct has tools to make mining go way faster.

You'll probably want integration mods between them too, so you can do stuff like smelt TE metals in a TC smeltery.

Biomes O Plenty adds a bunch of new biomes if you want those.
Posted 6 years ago2018-10-30 20:13:44 UTC
in TWHL Modded Minecraft Server Post #341102
Yeah those are the ones.
Posted 6 years ago2018-10-30 19:53:04 UTC
in TWHL Modded Minecraft Server Post #341100
Nope, those are all 1.12.2 compatible, i'm using them in my custom version of FTB Revelation which is 1.12.2 as well.
The exact names will differ because the ports are usually maintained by somebody else.
Posted 6 years ago2018-10-30 19:10:09 UTC
in TWHL Modded Minecraft Server Post #341098
Thermal Expansion, EnderIO, Ex Nihilo with Ex Compressum, SolarFlux, Refined Storage are all good mods.
If you're using my model viewer to view the result it will incorrectly show the skins as empty. Remove "$externaltextures" to avoid this.

That command isn't really used anymore these days so you don't have to worry about it.
Posted 6 years ago2018-10-25 20:37:28 UTC
in SharpLife - Dot Net Core based modding p Post #341080
Yeah we discussed this, i can add support for different units. It may be best to implement things like CSS styling, margin and padding for flexibility.
Posted 6 years ago2018-10-25 12:38:23 UTC
in SharpLife - Dot Net Core based modding p Post #341078
That's possible, i could make config values take effect for specific ratios. Kinda of like this:
<Property name="Position.X" value="10" condition="AspectRatio == 16/9"/>
The condition could be evaluated using CSharpScript, though in this case a constant value for 16/9 may be preferable. This would make it more flexible, for instance allowing you to support multiple ratios or different conditions (e.g. Game == "Half-Life", but that's pretty hacky).

EDIT: configs could maybe even be whole scripts. Much more efficient, and you can express things more easily by using the actual code. It would unify the GUI code in the game codebase and config files, meaning you can use the same API.
Posted 6 years ago2018-10-25 12:01:48 UTC
in SharpLife - Dot Net Core based modding p Post #341076
Cross posting this bit from the HLE thread:

I estimate it will be at least 6 months before SharpLife can deliver the same functionality as the vanilla SDK, though given that i'm incorporating HLE's features from the start it will provide much of the same at that point in time. This means things like entvars_t members being accessed through properties (SL doesn't have entvars_t), customizable entity relationships, config files, etc will be available as they are for HLE.

How long it takes depends on how difficult it is to implement original functionality.
I'm getting close with physics but it will eventually require both lag compensation and prediction to be implemented, which relies on accessing old data. Easily accessing this will likely require restoring the old state, so i have to make sure non-networked members can be restored as well, which they currently can't.

Once physics is implemented i'll have client input working, which means the user can press their use key, have that converted from +use to a usercmd_t, sent to the server and processed there so it can find and trigger entities. I should also be able to rework the camera movement system to instead use player position in the world at that point.
Everything needed to test physics will be available by that point, so i can verify that it all works.
I also need to make sure the networking system can handle infrequently updated objects properly. Currently it will still send updates for objects that haven't changed so the client can track them, this needs to be improved.
I also started working on a prototype for a GUI, starting by getting the drawing code operational. I studied Doom 3 and ImGui's code for this, they both use a similar method where all drawn primitives are stored as a list of vertices and drawn with a texture. Simple colored primitives use a white texture, text is ultimately also a texture (one character is typically referred to as a "glyph" in this context), so if i can get that working it should be good to go.

VGUI1 can only draw text, filled and outlined rects and textured rects, which my current implementation should be able to handle. Things like rounded corners can be done by using partially transparent textures (alpha channels masking the rounded part), so it shouldn't be that difficult.

The actual widgets like buttons require a good widget management design and class hierarchy, but that's not hard to figure out.
Once this is all working then the engine should be mostly there. Some features are unfinished (brush models don't render water properly, don't do random or animated textures yet, studio models are missing chrome and glow shell, sprites could use some optimizing), but the essentials needed to play a map should be working at that point.
As far as audio goes, my prototype should cover the basics so i can integrate that at some point to do menu music playback and basic per-entity sounds, after that individual features can be implemented.

The stuff that's needed should be there relatively soon if i keep at it, once the engine level stuff is there i can shift my focus to game features. Most of that involves re-implementing SDK code (mostly entities), but i can keep feature requests in mind while i'm doing this.
I do have a request for people wanting to use this for their own mod: if possible could you give me some ideas/feedback on a good way to configure GUI settings? VGUI1 uses resolution specific scheme files, VGUI2 uses resolution independent resource files, so i'd like to make sure i get this part right from the start since the widget design involves getting these values during creation.

Features like interactive building at runtime like VGUI2 does would be nice, so a way to store/update these settings is nice to have. Knowing how the configuration needs to be done plays a big part in designing such an editor.

I know that some people would like to have 3D rendering support in the GUI, i have never done this before but i figure it should be relatively simple by using render-to-texture, which would let it function with the current design for GUI rendering. This is probably a well-known approach but i haven't done any research on it yet.

One good use of this would be in the multiplayer model selection window, which would make the older image based approach obsolete and allow you to view the actual model in real-time.

If anybody has ideas or suggestions i'd love to hear them.
This post was made on a thread that has been deleted.
Posted 6 years ago2018-10-22 17:43:35 UTC
in SharpLife - Dot Net Core based modding p Post #341061
A sound VMT style thing would be perfect as a replacement
I could do something that's similar to Source's soundscripts: https://developer.valvesoftware.com/wiki/Soundscripts

Given that they implemented stuff like operators it may be easier to let these be defined using scripts instead, so you can express properties and events programmatically.
I've been working to implement physics support, so far i've got the majority of regular entity physics implemented, with func_door mostly implemented for testing.

Since there's no entity triggering or user interaction yet i added a feature to the object editor to invoke a named parameterless method so i can trigger the door movement methods directly. It works, but it's choppy so i'll need to figure out why that is. It could be related to the framerate or some value being used as int instead of float, but it could also be a networking issue.
I've also made a small prototype IO system. You can define inputs and outputs, trigger them and pass values just like Source's version. Here's what the code for it looks like:
[Output("OnPass")]
public OutputEvent<float> OnPass { get; } = new OutputEvent<float>();

[Output("OnFail")]
public OutputEvent<float> OnFail { get; } = new OutputEvent<float>();

[Output("OnPrint")]
public OutputEvent OnPrint { get; } = new OutputEvent();

[Input("TestValue")]
public void InputTestValue(in InputData inputData, float value)
{
    Console.WriteLine($"Firing {value}");

    if (value != 0)
    {
        OnPass.Fire(EventQueue, inputData.Activator, this, value);
    }
    else
    {
        OnFail.Fire(EventQueue, inputData.Activator, this, value);
    }
}

[Input("Print")]
public void InputPrint(in InputData inputData)
{
    Console.WriteLine("Print");

    OnPrint.Fire(EventQueue, inputData.Activator, this);
}
Inputs are public methods marked with an Input attribute, which takes the name of the input as used in the map editor or console commands. They can optionally take a single additional parameter that is the value that outputs can pass to it (or the parameter override if specified). Inputs can also access the value as an object instance through the InputData instance passed to the method, which allows for variant type inputs.

If the wrong type is passed to an input and it can't be converted, the input won't be called, just like in Source.

Outputs are public properties or fields marked with an Output attribute, which takes the name of the output as used in the map editor or console commands.

Outputs can optionally return values, in which case you have to specify the type in the member declaration. This also enforces the requirement that you pass the correct type when you fire the output.

Firing outputs is straightforward: you pass the event queue used to track events for entities (there's usually only one), the activator, the caller, and a value to pass to inputs if the output returns a value.

The event queue is similar to Source's version: a linked list sorted by event execution time, designed so that new events are added to the end of the list of events fired a a certain time so that events with delay 0 added while an event is being fired will fire in the same frame.

As far as supported return types goes, if you register a converter it'll work. Converters are subclasses of the C# class TypeConverter with ConvertFrom and CanConvertFrom overridden. This way, the USE_TYPE enum can be directly used without having to add it to a variant type like Source requires (Source uses a hack to pass the USE_TYPE value along instead).

This also means that you can easily add support to convert between types without having to edit a massive Convert method.

I'll be integrating this IO system once i've got physics completely done so i can implement +use support. +use relies on the physics code to pass along which buttons are pressed, finding entities in a sphere and then triggering the entity's Use method.

In SharpLife this will be replaced with the firing of the entity's Use input. It will be largely the same since input parameters can be part of the method signature, unlike Source. It should look like this:
public void Use(BaseEntity activator, BaseEntity caller, UseType useType)
{
    //Value not passed to InputData to avoid cost of boxing
    Use(new InputData(activator, caller, null), useType);
}

//Usage:
entity.Use(this, this, UseType.Toggle);
GoldSource actually uses USE_SET when +using entities, so i'll need to figure that out.
This post was made on a thread that has been deleted.
Posted 6 years ago2018-10-21 08:56:08 UTC
in Now Gaming: ... Post #341056
Posted 6 years ago2018-10-14 10:45:03 UTC
in rendering bounding boxes Post #341037
It sets entvars_t members mins, maxs and size.
Posted 6 years ago2018-10-12 16:39:38 UTC
in SharpLife - Dot Net Core based modding p Post #341026
I was working on the prototype for SharpLife's audio subsystem and i discovered that the engine handles cue points in wav files in a really strange way.

People always assumed that having 2 cue points would cause the sound to be looped between those two cue points after the first loop (which plays the whole file).

In reality only the first cue point is considered and what everybody thought was the second cue point is actually a bug in the engine dating back to Quake 1 that causes the range of a looped sound to be limited when the sound file has more than 8 bits per sample.

It doesn't seem to be possible to use a second cue point. It is however possible to limit loops if the "purpose ID" of the first cue starts with "mark". I don't know if it's actually possible to set the purpose ID using audio editing tools (Audacity can't edit cue points at all from the looks of it).

It's very limited, the Quake source code mentions a program called "cooledit" so that might let you do it.

I can fix this behavior for SharpLife, it's pretty easy to do. But some sounds in Half-life use cue points, like for example sound/doors/doormove6.wav has a cue point named MARK964. I can see in my sound system that it has a purpose ID "mark", and 964 is the "Cue Point ID" used to map the cue elsewhere.

I'm not sure if the name is actually what's used here or if GoldWave is just combining the two IDs, but when i modify it the cue is saved as a label instead of as label text and a label. The label text contains sample length information that controls how long the loop section should last for, but the file i tested has it set to the length of the file.

The cue point ID is set to 0 by GoldWave, and the cue position becomes 964 which seems to indicate that it's supposed to be the offset in the audio file where the cue point is located. I don't know why the file originally had it different, since the position is 0 there. The engine doesn't read the cue point ID at all from what i can tell, so it basically isn't using the cue point for looping at all.

I assume Valve made their sounds using this cooledit program, but it doesn't explain what their intentions were with these looping sounds. Since this design dates back to Quake 1 they may not even have known about the different behavior at all.

I checked another file, sound/plats/rackmove1.wav and it also has a cue point in it, named MARK514. It also doesn't store the actual cue position where it should and so doesn't loop either.

Neither sounds really need a cue point anywhere other than the start (they are needed to loop the sound), so they probably didn't even notice anything was wrong. For anyone modifying the sounds the cue point positions will matter since GoldWave and probably other programs will convert the cue points to correct this mistake.

Does anybody know more about this? I've seen the discussions on the VDC ( https://developer.valvesoftware.com/wiki/Talk:Looping_a_Sound) but those are inconclusive and only apply to Source. I'm sure it's very interesting to know how looping is actually done but if no tools exist to set the sample length property for a cue point then it isn't really useful.

I also found that GoldWave writes an additional LIST chunk that follows a really old (less than 2 months younger than me) spec: https://www.aelius.com/njh/wavemetatools/doc/riffmci.pdf

The List info chunk can contain information such as copyright. it tripped up my loader and probably breaks NAudio as well.
Posted 6 years ago2018-10-05 08:06:59 UTC
in A Barney Model that im fixing isnt walking Post #340987
Looks like the linear movement value is zeroed out.
Posted 6 years ago2018-10-04 13:14:45 UTC
in SharpLife - Dot Net Core based modding p Post #340983
User posted image
User posted image
I've been doing some backend work the past few days, mostly figuring out how the physics code works so i can implement it.

To test settings more easily i've added editable fields for vectors.

Above: Origin, Angles and RenderColor are vectors that use different representations. Origin is a plain edit field, angles is 3 angle edit fields in degrees, and RenderColor is a color picker. The antenna model is rotated to show that it does work.

Below: light_environment's settings can be edited, and are then transmitted to the client. The sky color picker is open, set to bright red. The sky normal is set to a direction that causes most studio models in the scene to use the floor color instead. The model standing on a sky brush and the scaled model use the sky color because the normal is pointing from a sky surface for both of them.

You can use this to move objects around to wherever you want, you can rotate them, change render modes, colors, etc. This means instead of having to adjust the setting in Hammer, recompiling (onlyents or otherwise), restarting the map and moving back to where the entity is you can adjust the setting in real-time and then adjust it back in Hammer.

Two uses that i personally think are really good for this are getting a good rotation angle for func_door_rotating, and movement distance for func_door.

The origin fields should be lined up horizontally, but there's an issue in ImGui.NET that prevents this from being done easily so for now it's vertical.

The sky color and normal don't affect much, as far as i can tell only studio models are affected by controlling the sky color when they're standing in the path of sky lighting. In theory you could disable lightmaps and use this to do real-time lighting, but without light data (light, light_spot, texture lights) anything indoors would be black.

I'm not sure if the compile tools strip unnamed lights, the lights in this map are still in the bsp along with the original color and brightness values, but old maps might not. light_environment handles the case where light data only contains a single color value and no brightness, so really old maps (retail maps probably) might not have all the data needed for this.

Even if that's all there, texture lights would require the original lights.rad to even try to handle them, and i don't know how expensive all this would be to calculate in real-time.

I've been asked if there is a way to modify the values in the level editor; this requires the use of Inter-Process Communication (IPC) and unique identifiers for each entity, so that the entity can be properly identified between the game and the editor. Sledge may get this as a plugin someday, but it's not going to happen any time soon.

Now that this is done i'm going to implement physics for normal entities. Once that's all there entities can move, collide, etc, and trace functions can be implemented on top to finish up some renderer visibility testing code. I'm leaving the rest of the studio model features for later because they're not critical to have right now and i'd prefer to be able to fully interact with the entities to do more testing.

After that, if i can get user input to the server working and player movement physics implemented it should be possible to move around, use and shoot stuff, etc.
Posted 6 years ago2018-09-28 08:58:58 UTC
in SharpLife - Dot Net Core based modding p Post #340960
User posted image
User posted image
User posted image
User posted image
User posted image
From top to bottom:
  1. Testing studio lighting. Only includes lightmap light data & world dynamic lights (dlight). Point entity lights (elights) not yet implemented but should be relatively simple. Different color rooms used to test the effect of different colors, showing that sampling is working correctly.
  2. Testing shadows.
  3. Additive render mode for studio textures. The mask goggles are black but are transparent to allow the green color behind it to be visible. The goggles are chrome, but that isn't implemented yet.
  4. Masked render mode for studio textures. Alpha tested transparency.
  5. All 6 render modes, from left to right: Normal, Color, Texture, Glow, Solid, Additive. Color, Texture and Glow all use the same settings and behave as Texture. The upside down grunt is a test to see if negative model scales work. This is important because Counter-Strike's cl_righthand flips models along the Y axis, and requires culling to be changed.
It's not quite finished yet but it's looking good. This runs at ~400 FPS without optimizations (vis leaf culling and bounding box culling).

To make lighting work i've also implemented light_environment. This is needed because it sets the sky color and normal vector.

What's left to implement is the correct lighting values for all render modes (minor adjustments needed), elights, chrome, glow shell and perhaps flat shading as implemented by glShadeModel(GL_FLAT). This last one is very specific since only normal render mode with additive texture render mode sets it, but only after it has drawn the mesh that uses it. I doubt it's actually required since it seems more like incorrect behavior, but i'll look into it all the same.

Models used:
  • Vanilla hgrunt.mdl
  • Sven Co-op 5 hgrunt.mdl (additive render mode, not included in SharpLife repository)
  • Condition Zero props/antenna_urban.mdl (masked render mode, not included in SharpLife repository)
I've also found a presentation detailing the design of a high performance renderer from Valve: http://on-demand.gputechconf.com/gtc/2016/events/vulkanday/High_Performance_Vulkan.pdf

This could be very useful for designing a threaded renderer.
Posted 6 years ago2018-09-26 09:05:32 UTC
in SharpLife - Dot Net Core based modding p Post #340951
That depends on whether or not i can reproduce the original lighting. I've been looking into it, it seems that lighting uses transformation matrices that are identical to bone matrices for hardware renderers. Since that's already available to the shader it may be as simple as passing along the list of lights to the shader (3 lights maximum for studio models).

I'll know more once i've finished researching the original lighting system.

In the meantime, here are some of the render modes in action:
User posted image
From left to right: Normal, Color, Texture, Glow, Alpha, Additive

Normal and Additive have their own settings, the rest all use Texture's settings.
User posted image
Here you can see scale -1 and masked textures.

Scale -1 requires the cull face to be set to front instead of back, which requires every render mode pipeline to have 2 copies for both sides. This is also needed for Counter-Strike's cl_righthand cvar.

Masked textures require 2 copies of those as well.
User posted image
Here's the additive render mode for textures. The mask's eyeholes are black but due to the use of additive they become transparent, taking on the green color of the face texture behind it.

Not yet implemented are lighting and chrome, render fx, flat shading and matching the logic from the game's renderer exactly.
Posted 6 years ago2018-09-23 11:23:33 UTC
in SharpLife - Dot Net Core based modding p Post #340941
User posted image
Skins and bodies work, i've also implemented the game's frame animation logic so it's smoothly animating now (it wasn't before).

Still need to implement lighting, chrome and modify the bone controller logic a bit to match the original. Render modes and fx is next, that should just about cover studio models.
Posted 6 years ago2018-09-22 16:48:15 UTC
in SharpLife - Dot Net Core based modding p Post #340936
So here's that debugging feature i was talking about:
User posted image
This lets you edit entities directly when you're hosting a listen server. It isn't perfect, but it's good enough to let me test different sequences, frame rates, etc without needing to set up the user input system or use console commands.

It does have some limitations, and i discovered a bug in the networking system where objects that haven't updated in a few frames try to send a delta when they shouldn't, but it's going to make implementing studio models a lot easier. It'll also come in handy down the line when tweaking entities.

I've also finished reworking the renderer so now each model type has its own input data type. This will let me separate out the keyvalues to entities that actually need them, and it avoids having to fill in values that aren't used for some types of models.
Posted 6 years ago2018-09-21 06:39:07 UTC
in SharpLife - Dot Net Core based modding p Post #340928
I tried out Avalonia, it's similar to WPF but it's not quite there yet. The toolbox doesn't show Avalonia controls but other than that it seems to work.
It currently targets NET standard, the problem is that some of NET Core 2.1's features aren't available in standard, and i'm already using them. So regardless of whether i'm using WPF or Core, it won't be able to work out of the box unless i either remove the features or use the OOP packages that contain the newer features and hope it all works out.

EDIT: i'm not 100% sure if Avalonia can use Core libraries or not, will need to check.

Microsoft's post on Core 3 said they were going to release a preview in 2018, so it should be available soon. I'll put something together once that happens so i can try things out, and then upgrade later on.

There's an article released just today that says NET framework is done: https://medium.com/@andy.watt83/the-net-framework-is-done-8aec3bbae12d
So i would assume that MS will eventually focus on cross platform GUI support. I'm guessing Core 4 will bring support, but there's no telling how long that'll take.

For now i'll stay focused on the engine itself, but i could always use ImGui for a basic GUI if a model viewer is needed sooner.
Posted 6 years ago2018-09-20 14:52:19 UTC
in SharpLife - Dot Net Core based modding p Post #340924
I've refactored the code that handles model loading and rendering, each model type is now completely in its own library.
The file format, the code used to convert it into an IModel instance and the code used to load graphics resources and render it is all in it.

This isn't finalized yet, i want to make the graphics part only handle the loading of resources while leaving the rendering up to the user to allow the same code to be used to render models in-game and in separate viewer programs. IModel handling should eventually be moved out to SharpLife.Game.Shared since it's primarily used by the game.

The renderer has been moved into the client, allowing it to control how everything is drawn. This means all graphics related code is now handled by the client game library.

The engine no longer handles specific model types as map loading is fully handled by game code now, so in theory you could completely replace it with new formats without the engine having to know.

These changes make it easier to handle the remainder of the model rendering code since each type should ideally get only the data it needs to render itself. Since the game handles everything it's easier to handle specific types.

I've also refactored the model manager to remove the explicit handling of bsp submodel loading. The bsp loader now does this, though there is still a need to explicitly add the models to the string list later on so they're in the list. I may change this to allow models to specify what their submodels are so it can be handled automatically there as well.

Another important addition is the bridge between the game client and server, which allows them to share data and communicate directly.
Currently it shares a helper object that's used to format bsp filenames, but i have plans to use this to add debugging features. I'll probably be able to show what i have in mind in the next few days. It should be pretty interesting to see, but i'd like to see if it's possible before saying more.

There is more refactoring left to do to move code from the engine to the game. I'd like the map command to be handled as a shared game command, removing the need to reference saved games in the engine as well as removing the need to pass additional state around when changing levels in singleplayer.

The SharpLife.Renderer library contains types that i'd like to move as well, which should turn this library into a utility library containing interfaces and helpers for rendering and managing resources.

I'm also going to rework the object list networking system so that its delta networking system doesn't have any loss in precision, which was an issue when networking the studio model Frame variable.

When all this refactoring is done the model rendering code should be easy to use in a model viewer. A pretty important bug was reported a few days ago about skin families being missing when the model has a separate texture file, so i'd like to get the new model viewer done soon. To that end i've looked into WPF a bit to see if it has what's needed to make a replacement viewer, and it looks like it's good enough, though i did have to get a third party library (https://github.com/xceedsoftware/wpftoolkit) to cover common controls.

Dot Net Core 3.0 will include support for WPF, but that won't be released until 2019, and when it does the library i used above may not be available right away. i'll try to convert the SharpLife libraries from Net Core to Net Standard so they can work in the Net Framework WPF environment, so until WPF on Core is ready to handle everything it can still work like that. Unfortunately this may result in an excessive number of libraries being loaded so that's something to keep an eye on.

We've also been talking about adding an I/O system to SharpLife. This feature would be purely in game code and would allow the same kind of functionality that Source's I/O system has. I've looked into how Source's system works and it looks like the same could be done in SharpLife without requiring changes to the .map and bsp format.

Penguinboy and i have talked about it a bit and if editor level support can be added it should all work fine. Since Sledge is projected to support Source as well the same UI can be used, and the only difference would be in how the data is stored on disk in the .map format.

For backwards compatibility purposes the old trigger system will still be supported, but i have been working on a tool to convert maps that could also convert the old triggers to the new system. This tool is meant to convert older, more limited keyvalues (like func_door's index based sound keyvalues) to a new format, and outputs are stored the same way so this should work out.

For now the focus will be on reworking the model rendering code to use separate data types to pass around rendering data, this will allow me to pass studio model specific data around without the other formats also getting it. After that the debugging tool i mentioned above should be implementable.
Posted 6 years ago2018-09-19 15:12:12 UTC
in Hassassins killing each other Post #340916
That's this code: https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/schedule.cpp#L169

If you're compiling debug builds it turns on spark effects for NPCs that failed to follow a schedule.
Posted 6 years ago2018-09-18 10:00:18 UTC
in Hassassins killing each other Post #340909
You need to make sure your new class is set to be allied with female assassins in this table: https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/monsters.cpp#L2199
Posted 6 years ago2018-09-16 18:14:31 UTC
in SharpLife - Dot Net Core based modding p Post #340901
The first one is in game code, all it needs is a check on material type. A separate material type "none" would be needed to disable effects, that's easy.

Blood color is that way because it's legacy Quake code, i plan to make these use RGB color values instead so that isn't a problem.

Mod support will have to wait until everything else is done, but i'm sure it's possible to add at some point.

I was already going to add 3D skybox support at some point. I don't see why this shouldn't be done since it's fairly simple and can add a lot to a map without costing much.
I've also just implemented fullbright support, since that goes hand in hand with overbright.

I've also added a cvar mat_powerof2textures to disable textures rescaling to power of 2.
Posted 6 years ago2018-09-16 16:47:05 UTC
in SharpLife - Dot Net Core based modding p Post #340899
You mean skyboxes that have a higher resolution? That's already available. It doesn't support TGA skyboxes yet, that's going to have to wait until ImageSharp supports it.
Posted 6 years ago2018-09-16 16:20:02 UTC
in SharpLife - Dot Net Core based modding p Post #340896
Thanks!

I implemented gl_overbright since i was asked about it.

Without overbright:
User posted image
With overbright:
User posted image
Posted 6 years ago2018-09-13 11:35:52 UTC
in SharpLife - Dot Net Core based modding p Post #340867
User posted image
I've implemented gamma correction in sprites now as well.

I've also reworked shader compilation to use glslc instead of glslangvalidator.
This tool is built on top of the other tool, but adds support for #include. I've used this to share gamma correction functionality.
Posted 6 years ago2018-09-12 16:51:09 UTC
in changing NPC walking speed Post #340861
This is the list of activities: https://github.com/ValveSoftware/halflife/blob/master/dlls/activity.h

The game looks up which animation has the activity set for it. Check the QC file for which animations have which activities.

As far as movement goes, each animation defines how far it moves. The root bone is used to determine where the animation starts and ends, end - start (position in last frame - position in first frame) determines how far movement goes, the rotation defined for the animation affects which direction movement will go in.

Movement speed is determined by movement distance * (framerate / number of frames - 1). The fewer frames and the higher the framerate, the faster movement will be.
If there are no frames then movement speed is always 0.

None of the models in the SDK specify rotation, so don't be surprised if it doesn't work properly.

The function used to extract movement speed can be found here: https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/animation.cpp#L226

pflGroundSpeed is movement speed, pflFrameRate is the framerate for the animation, which is independent of the entity framerate. The final framerate is pflFrameRate * entity framerate, so movement speed will be affected by that as well.

The actual movement is performed here: https://github.com/ValveSoftware/halflife/blob/5d761709a31ce1e71488f2668321de05f791b405/dlls/monsters.cpp#L1980

Some entities may override this so check their MoveExecute method. If you wanted to, you could add a keyvalue that overrides the animation movement speed, or that multiplies it to speed up/slow down the entity.
Posted 6 years ago2018-09-12 16:04:29 UTC
in changing NPC walking speed Post #340859
The game looks up animations based on which activity is associated with the animation.
Posted 6 years ago2018-09-12 10:52:22 UTC
in SharpLife - Dot Net Core based modding p Post #340854
User posted image
I've implemented render modes for brushes. From left to right:
  • Normal
  • Color
  • Texture
  • Alpha test (normal on top for comparison)
  • Normal and alpha test side by side
  • Additive
The 4 other brushes are a test to see if rotation works properly.

Here's alpha test up close:
User posted image
To make alpha test work i had to implement texture re-sampling and rescaling during upload. The engine actually does a fair amount of work here, first changing all palette colors by running it through a gamma correction table, then changing the color of invisible pixels so sampling doesn't try to blend black. Otherwise the texture ends up having black borders around the transparent parts.

Finally, the image is rescaled to a power of 2. It isn't necessarily upscaled, the cvar gl_round_down affects this and is used to make texture biased towards scaling down instead of up. For instance, the grate texture seen above is 48x48, but is rescaled down to 32x32.

This affects the look of the texture since the number of pixels for each bar in the grate is reduced. Without scaling, each bar is 3 pixels wide. Scaled up, it's 4, and scaled down it's 2. Combined with the transparency color changes this can drastically change the look of a texture.

Here's the original texture, without any of these changes:
User posted image
The scaling of the image is done for all textures to ensure power of 2 sizes, the alpha color balancing only applies to alpha tested and index alpha textures.

Textures used by models and sprites seem to use yet another scaling algorithm that uses a different code path. Setting fs_perf_warnings to 1 and developer to 1 will print out warnings only for those textures. This path is apparently used for textures that don't use mipmapping. I'll have to replicate that later to make textures for those load properly as well.
I've implemented gamma correction and brightness override to (almost) match the original. Since this is done in the shader the results are slightly different from the original, but you won't notice it unless you're comparing the results.

The settings use cvars, and the values are uploaded to the GPU. This means it's now possible to adjust the values in real-time:
User posted image
I've also added an FPS slider, although ImGui is bugged and doesn't display the value correctly.

As you can see the settings are all dialed up to the maximum, showing how it changes gamma.

Like the original render mode Color brushes are unaffected by gamma correction, and i fixed it using texture colors and lightmap data.