wiremod / wire

Garry's Mod add-on that allows users to wire up components in order to make more elaborate automatic and user-controlled contraptions.
http://www.wiremod.com
Apache License 2.0
553 stars 332 forks source link

Proposals for a clientside-programmable view controller? #483

Closed AbigailBuccaneer closed 10 years ago

AbigailBuccaneer commented 11 years ago

As originally discussed in #478, the player's view is smoother when calculated with a CalcView hook clientside than any other method, even setting the view entity and letting the engine take care of making the entity's position nice and smooth.

In light of this, I think it probably makes sense to have an entity which uses CalcView to set a player's entity, but can be controlled via a fixed-function pipeline. It could:

Does anybody have ideas for specifics of how this should work? Would we want it to be configurable at runtime (so you could switch between different aiming modes for example)?

Xandaros commented 11 years ago

Would we want it to be configurable at runtime (so you could switch between different aiming modes for example)?

I think that's a pretty good idea - you basically just send a net message to notify the client of the change, so it's not really hard to implement - why not?

AbigailBuccaneer commented 11 years ago

It's not hard in terms of implementation, but it's not nice if an entity has a huge amount of inputs that correspond to options in the tool menu, and nobody ever uses these inputs because changing the options at runtime doesn't make any sense for anybody's contraptions.

I guess in this case it does make sense to be able to change it on the fly, as you may want for example a ship with different views that can be toggled between. (Of course, it could possibly make even more sense to just have multiple view controllers, as the other inputs to them would likely depend on what mode they're set in, so if you switch mode at runtime you'd also want to completely switch what the other wires are connected to.)

AbigailBuccaneer commented 11 years ago

Thinking about this, if the view controller were to store its configuration in DataTables, we could have an entity (or, more likely, an E2 library) that just let you set DataTables vars. And so you could reconfigure it on the fly but you don't need a huge (metaphorically) tangled mess of wires.

Nebual commented 11 years ago

There's nothing ugly about 3 wires, though having an E2 library for datatables is a good idea, ignoring that only 1-2 wire ents use them.

If pos and dir aren't smoother, what is the ideal usage exactly?

If I wanted a third person cam that was usually a local vec directly behind me, which I sometimes pivoted left, how might I do that?

Need examples of function before we can vote on form.

Bubbus commented 11 years ago

I'm working with @shadowscion on something based upon his ent in #478, which could potentially provide flexible camera behaviour for many applications. I figure writing something comprehensive like this might prove useful in future 3D projects ;) Please critique my ideas, hopefully they'll be of use.

I'm planning a chip-focused ent interface: Active, CamModes [ARRAY], CamSettings [TABLE].

CamModes defines a set of compatible camera behaviours for movement, aiming, FOV, smoothing... Example: CAM_AIM_FOCUSENT + CAM_POS_ORBIT would create a camera that points at an ent and allows movement around a radius.

FOV modes can be used for telescopic zoom, maintaining the angular diameter of objects etc. CAM_FOV_NORMAL, CAM_FOV_FOCUSENT, CAM_FOV_VELOCITY...

Smoothing modes allow tweening behaviours. Example: CAM_SMOOTH_NONE sets the camera immediately to the calculated pos, ang, fov... CAM_SMOOTH_PID allows the cam to smoothly catch up to the calculated settings using PID behaviour. Configuration can form a white/blacklist of pos, ang, fov etc.

The modes would form a fixed-order pipeline. Perhaps aim > pos > fov > smooth > calcview.

CamSettings is a lookup-table of CamMode configurations. The following configuration could make a useful third-person racecar camera which focuses forward and allows you to place the view at any point around the car: {PosOffset = vec(0, 0, 50), PosOffsetLocal = 0, PosDistance = 100, PosAllowUserInput = 1, AimOffset = vec(200, 0, 0), AimOffsetLocal = 1}

These settings can be beamed to the client by the net library, using delta updates with SendTable + shared string hashes to reduce bandwidth. In the event of user input, client-to-server comms could use the same system to inform the controller of the current position and angles.

In the event that this interface is not desirable, it could be composed of a union of all possible CamSettings - however this would get very messy.

Questions:

Xandaros commented 11 years ago

Will this be cross-compatible with other chips (starfall, lemongate)?

No idea about lemongate, I don't really like it.(Though I'm pretty sure it is) As for starfall - yes.

For those who don't code, do wire gates have the capability to form arrays and tables?

Yup, though it's a nightmare.

In E2/starfall/lemon, if an array/table is an output and an element within is modified, is that output triggered for connected gates?

I highly doubt it. I'm pretty sure you pass the reference to the table. (It wouldn't be very efficient to create a new table each time a value gets changed) I wouldn't call such an input Clock, though. Maybe Update Settings?


As for the interface you suggested - it's not that bad an idea, actually, I'm not too sure about the exact specification, though. Also, I don't trust @shadowscion s code, sorry :D (That name is hard to spell... omg)

AbigailBuccaneer commented 11 years ago

There's nothing ugly about 3 wires, though having an E2 library for datatables is a good idea, ignoring that only 1-2 wire ents use them.

It would be significantly more than three wires, and these wires would most likely be using ints as enums, which is horrible to deal with from either E2 or gates.

If pos and dir aren't smoother, what is the ideal usage exactly?

The point is that you'd only occasionally set them, and then the more fancy input modes would do the rest. If your view is going to be manually calculated by an E2 every tick then it won't be any smoother, and there's nothing we can do about that.

If I wanted a third person cam that was usually a local vec directly behind me, which I sometimes pivoted left, how might I do that?

You would set the parent, and the local vector (as you currently do), and then it depends what you mean by "I sometimes pivoted left". If you're doing that with keyboard or mouse control, then that'd all be taken care of clientside.

AbigailBuccaneer commented 11 years ago

I'm planning a chip-focused ent interface: Active, CamModes [ARRAY], CamSettings [TABLE]

I'm still not convinced that runtime-configurable modes are that useful (please feel free to convince me).

I think I'd ideally have Active, and whatever inputs are appropriate for the mode that was configured in the tool menu prior to spawning. It's a much simpler interface, and could replace the cam controller.

Nebual commented 11 years ago

If you don't intend an E2 to manually calculate anything each tick (in ideal circumstances), I think it'd be inappropriate to target E2 as the principal interface. If you guys think Enumerations are bad and modes should be handled in the cpanel, I'd encourage the continued consideration of Gates. Especially if a use might be just feeding it a Constant Value vector for initial local offset.

Perhaps one of the cpanel's modes could be "dynamic", allowing wires to dictate settings via the confusing and no doubt poorly documented settings [ARRAY]. On Oct 8, 2013 9:32 AM, "Abigail Buccaneer" notifications@github.com wrote:

I'm planning a chip-focused ent interface: Active, CamModes [ARRAY], CamSettings [TABLE]

I'm still not convinced that runtime-configurable modes are that useful (please feel free to convince me).

I think I'd ideally have Active, and whatever inputs are appropriate for the mode that was configured in the tool menu prior to spawning. It's a much simpler interface, and could replace the cam controller.

— Reply to this email directly or view it on GitHubhttps://github.com/wiremod/wire/issues/483#issuecomment-25905838 .

Bubbus commented 11 years ago

Runtime and chip interfaces would be useful for more advanced behaviours and make the system applicable to more problems. I love @AbigailBuccaneer's tool-configuration idea though, it can care for the non-E2 player by providing an initial configuration. Customizing the inputs to suit the pre-programmed mode is also clever, good de-cluttering.

For runtime though, say my aforementioned racecar has a robotic rocket launcher hidden in the back seat. When it pops up, we can reconfigure the camera with {PosEntity = launcher, AimOffset = PosOffset, AimOffsetLocal = 0} and we end up with an orbiting cam focused on the launcher. If the rocket locks onto a target we can swap camera aim-target with {AimEntity = target, AimOffset = nil}, FOV mode to CAM_FOV_FOCUSENT with {FovEntScreenSize = 0.5} to make it zoom into the target etc. When the rocket is launched we can change camera policies again. If there's a smoothing policy in place during all this, it'd all be nicely tweened with no interruptions, which might occur if we had to use a separate controller for each of these states.

In the whole thing, the clientside policies handle all the per-frame behaviours such as tracking, positioning. All the serverside has to do is define the boundaries of operation when prodded and leave the client to its own devices until the situation changes again. If the server has to constantly calculate parameters then the benefit of the client cam is lost - the modes should be configurable enough to cover many use cases.

That being said, not providing the chip/runtime interface is an easier proposition and makes for a good first stage. @Nebual brings a good point, regardless of presentation these interfaces will need very good documentation.

TomyLobo commented 11 years ago

tl;dr make sure it's hierarchical

TomyLobo commented 11 years ago

How about sending an E2 custom function to the client in some format. After excluding some data types

Divran commented 11 years ago

Starfall can do this. Just sayin'

(EDIT: not yet, but making a library for it shouldn't be hard)

AbigailBuccaneer commented 11 years ago

Perhaps one of the cpanel's modes could be "dynamic", allowing wires to dictate settings via the confusing and no doubt poorly documented settings [ARRAY].

I like this idea a lot, it offers a great compromise between full flexibility and still having a sane interface when possible.

AbigailBuccaneer commented 11 years ago

How about sending an E2 custom function to the client in some format. After excluding some data types

That's a project with a much larger scope that would significantly broaden the attack surface for exploits in multiplayer. (It would definitely be interesting though - clientside EGP HUD programming would be cool. I can't think of many other use cases, though.)

I've been working quite a lot with OpenGL shaders, so I'm naturally terrified of upstream code sending restricted programs to the downstream code.

Xandaros commented 11 years ago

Starfall can do this. Just sayin'

(EDIT: not yet, but making a library for it shouldn't be hard)

Yes, it's no big deal to do this with starfall. With E2 and lemongate, however, it's a whole different story. Actually, it shouldn't be too hard to make a clientside lib that enhances the cam controller even without a specially made one, so there is no reason to target starfall. I expect the integration with starfall to be a lot better than with anything else.

@AbigailBuccaneer Sending code is not really that big a deal, as long as it is not too powerful. Also, you'd only be able to target a player that activated that cam controller, in whichever way. (Entering a vehicle, most likely)

TomyLobo commented 11 years ago

ok, if you're afraid of E2 functions on the client, how about a mini dsl instead?

sin(camParam(1))*2

there could be a Lua code generator attached right to the back of that

AbigailBuccaneer commented 11 years ago

For most common cases, I do think we can achieve what we need to with a fixed-function view controller pipeline.

If we do go with a programmable view controller, I think I'd rather it be E2 (or an E2-ish language). I don't like the E2 language, but consistency is nice.

I need to go read through some of the E2 compiler code, I'm not actually terribly familiar with how it works and how modular it is.

TomyLobo commented 11 years ago

no need to mess with the compiler, @AbigailBuccaneer my last proposal can be achieved with a plain old E2 extension

AbigailBuccaneer commented 10 years ago

Okay, nice simple proposal:

Modify cam controller to have the following checkboxes in the context menu:

Obviously some of these are mutually exclusive.

AbigailBuccaneer commented 10 years ago

@Divran's implemented something snazzy in 8feebff7e8ed61c2b99463bc18cd3a4f19603586.