Currently the developers are putting their own money into JC2-MP to keep the servers online.

Please take a few seconds of your time and disable your AdBlock plugin for our website.

Ad revenue is not going to developers, it is used purely for covering our hosting costs.

 

You are also free to donate, which removes all ads from our website!

Patch 0.3 was just released! Full changelog here: https://t.co/4A50m6IKen

2 years ago

Advertisement
October 15, 2019, 08:39:08 am

Author Topic: [Beta] Lightsabers  (Read 4095 times)

LordNoob

  • Sr. Member
  • ****
  • Posts: 349
    • View Profile
[Beta] Lightsabers
« on: January 03, 2016, 08:43:17 pm »
Lightsabers is a script that I have made which uses dreadmullet's OBJ importer to import custom models, in order to create an authentic-looking lightsaber. The script uses ClientLights and the Model class to achieve this.

You will start with your lightsaber sheathed. Press G to start using it. Q (or whatever you have melee bound to) will move it, or you can just run at people with it.

Use the commands "/lightsaber blue" or red, or green, to change lightsabers. At the moment, I have models for Luke's lightsaber from ROTJ, Anakin's lightsaber/Luke's first lightsaber, and Darth Vader's lightsaber.

Please note that the lightsabers screenshotted were done so without legacy render, and with bloom on. These settings provide the best results. If you do not have legacy rendering on, depth testing will be turned off and the handles won't look very good.

A simple raycasting call determines whether your lightsaber is about to cut someone's limbs off (or a vehicle's tyres) and damages them accordingly (almost completely client-side, with additional server verification).



Screenshots (click for full size):



"No, Rico, I am your father!"


He will join the Dark Side soon enough...


Guess I'll be rescuing Solo...solo. (⌐■_■)




For scripters/server owners:

The script requires those OBJ files in the base directory. On a client loading the module, the client will request the 6 models in the server directory and cache them, and then use them to construct all models.

Depending on your user's internet connection to the server, the time this takes will vary. From my locally hosted server to me (i.e. 0 ping) the average loading time for models (which will be necessitated on the client of a player joining, or on all clients if the module is reloaded), tends to be from 1.3 seconds to 2 seconds.

The models and data that is transmitted is of a size around 500 KB.

For scripters who want to extend the script:

The script uses a class system to make a lightsaber an object, which has members including position, bound player, angle, hilt and blade model, etc. You can 'construct' a lightsaber like so:

Code: [Select]
Lightsaber(model, lightColor, modelname, player, hilt, bone, bone_s, position, position_s, angle, angle_s)
The properties, in order, are as follows. Bold denotes a required argument.:
  • Model: the Model object that represents the active, unsheathed lightsaber
  • LightColor: the Color object that the ClientLight should be
  • modelname: the filename of the Model's OBJ file, minus extension. Currently not in use, but required anyway, for possible identification purposes.
  • player: The player who's lightsaber this is. Used to index in a table (and so this player will be the one who damages people, and the one who can sheath/unsheath), and to save preferences.
  • hilt: The Model object that will be drawn when the lightsaber is sheathed.
  • Bone: the bone that the lightsaber should be attached to, if no position is given later on. If not given, defaults to left hand.
  • Bone_s: the bone that the lightsaber should be attached to when sheathed.
  • position: the position that the lightsaber should assume by default. The current script modifies this every render frame, from a function outside of the class, using the class' SetPosition method.
  • position_s: the position that the lightsaber should assume, when sheathed, by default. See note above about being changed every frame outside of the class.
  • angle/angle_s: The angle used by default when not sheathed/sheathed, respectively (you get the drill). Also changed every frame outside of the class

The script does require a player to be tied to a lightsaber, so doing something like having a lightsaber on display isn't possible without modifying the class itself. However, custom position means that if you were really willing, you could add things like throwing lightsabers. Or, with some modelling skill and by seperating the blade from the hilt model and using scaled transformaton, you could try making activation animations and dual bladed lightsabers, using angles and postions (n.b. that would be a huge pain in the ass if not impossible)




The class contains a number of methods:

  • SetModel(newModel): takes a Model object as argument, and starts drawing that instead
  • SetLightColor(newColor): takes a Color object and sets the integrated ClientLight to be that color.
  • Remove(): deletes the light and makes the class nil
  • SetPosition(newPos): sets the drawing position of the model and light to the given Vector3
  • GetBone(): returns the bone that the lightsaber was defined to be attached to
  • GetBone_s(): returns the bone that the lightsaber was defined to be attached to when sheathed
  • SetAngle(newAngle): sets the drawing angle to the given Angle object
  • SetPosition_s(newPos): sets the sheathed drawing position to the given Vector3
  • SetAngle_s(newAngle): sets the sheathed drawing angle to the given Angle
  • SetHilt(newModel): sets the sheathed model to the given Model object

Known issues:
  • Some people may experience high loading times for the models if they are far away from the server and/or their internet connection is sub-optimal. If there is enough demand, I may work on an alternative loading method that would allow such users to download the files (outside of the game) and reduce connection delay. This method would check for files in a certain directory, and if they are found, would load from them instead of from the server.

    However, I do not believe that the issue of loading times is great enough to where this is needed.

Credits:

« Last Edit: January 05, 2016, 12:45:51 am by LordNoob »

Dev_34

  • Full Member
  • ***
  • Posts: 158
    • View Profile
Re: [Beta] Lightsabers
« Reply #1 on: January 03, 2016, 09:45:51 pm »
Now in jc-mp  :)


LordNoob

  • Sr. Member
  • ****
  • Posts: 349
    • View Profile
Re: [Beta] Lightsabers
« Reply #2 on: January 03, 2016, 09:57:45 pm »
All you're missing is somehow that fight killing Palpatine who was miles away because of desync :D

Lord_Farquaad

  • Full Member
  • ***
  • Posts: 217
    • View Profile
Re: [Beta] Lightsabers
« Reply #3 on: January 04, 2016, 12:56:36 am »
Oh man this is awesome!  I can't wait to kill all the stormtroopers!

JasonMRC

  • Donator
  • Hero Member
  • *****
  • Posts: 601
    • View Profile
Re: [Beta] Lightsabers
« Reply #4 on: January 04, 2016, 02:29:17 am »
Sweet! Been wondering what exactly you were working on with Lightsabres.

Currently clients request to load a new model for every player, right? And the server has to load from file for each request?

If that is the case, change it to where on ModuleLoad the system loads all the models(Get the hard work out of the way one time). Then when a client needs a new model you don't have to reload it for each request. Keep the model data as a table so that on the client you can just insert it directly into Model.Create.

Once loaded, the loader calls back to a function in your LightsaberManagement right?

The way client side things are usually synced is by player value. You can set a player's value of "LightSaber" with value being a table. That table could store all the data needed to create that lightsabre(you don't need to store the player obj or other things you can get from the player since your creation function will have access to the player). Store the table of light saber model vertices on there so you can just send those into a Model.Create. In your render or tick you check if they have the player value, if so you check if they already have a saber built, if not, operate based on the data in the value, otherwise activate your tick function in the existing lightsabre.

And a tip: On the server, you don't need to set the time to midnight every tick. On load, set the time to midnight and the step to 0 - time won't advance then.

LordNoob

  • Sr. Member
  • ****
  • Posts: 349
    • View Profile
Re: [Beta] Lightsabers
« Reply #5 on: January 04, 2016, 05:44:07 pm »
And a tip: On the server, you don't need to set the time to midnight every tick. On load, set the time to midnight and the step to 0 - time won't advance then.

Whoops. That was a debug thing for me.

I'll remove that and I'll probably just store the table of vertices on a client script.

EDIT: I've implemented what Jason advised as a way to load models, on the experimental branch (because I haven't tested how it syncs, but everything should be fine)

EDIT 2: After some bugfixing, I've merged the experimental branch into master, with some more changes, including an optimization for OBJ filesize that should reduce loadtimes a lot, especially for players with high ping.
« Last Edit: January 04, 2016, 11:52:12 pm by LordNoob »

JasonMRC

  • Donator
  • Hero Member
  • *****
  • Posts: 601
    • View Profile
Re: [Beta] Lightsabers
« Reply #6 on: January 06, 2016, 11:53:39 pm »
@LordNoob,

Looking over your code again,
On Client, is there a reason you use ModulesLoad instead of ModuleLoad (Note the 's')? ModulesLoad fires whenever any module is reloaded on that side of the network. ModuleLoad only fires when that particular module has loaded. Your code appears to be sending 6 new requests each time any module is loaded.

On Client, I see a place where you check for cached requests, but I don't see where you add anything to the table of requests.

On the Server, it appears you are still loading the obj files each time they are requested, rather than caching them the first time. I see OBJLoader.cache is defined once but never used.
Code: [Select]
if cacheData[cachepath] then
      send cacheData[cachepath]
else
      load data
      cacheData[cachepath] = loaded data
end
That's a simplified version of the cache check I am referring to on the server side. You can do essentially the same thing on the client side. Rather than loading all sabers at once, only load them when needed. When a lightsaber needs to be rendered, check if you already have the data for it. If so, load it directly. If not, send to the server for it. The server will then check if the data is cached. If it is, it'll reply, if not it will load it, cache it for the future, and then reply. Once the client receives the data it will then cache it so that it doesn't have to send again the next time it creates that kind of saber.

EDIT: Ideally, on the Server on ModuleLoad you will load all registered obj files into a cache table. Then when a client requests the data you simply check the table for the data. This makes it so that your server only reads files once, on start up rather than randomly. That gets all your heavy load out of the way initially.
« Last Edit: January 06, 2016, 11:56:06 pm by JasonMRC »

LordNoob

  • Sr. Member
  • ****
  • Posts: 349
    • View Profile
Re: [Beta] Lightsabers
« Reply #7 on: January 10, 2016, 09:16:41 pm »
I missed that post, so sorry for the late reply.

I should change that to ModuleLoad, I agree.

I'm not sure I understand what you're saying with this data. You're saying that I should just stop making requests every reload because it introduces additional I/O overhead?

It's about 500KB of data, I don't really consider the I/O to be a bottleneck, rather the bottleneck is in sending this data over and OBJLoader interpreting it.
When I was referring to caching, before the client would request new lightsabers for every player from the server. With my caching, I have implemented a solution where it keeps the data so that network traffic is reduced. I think what you're suggesting is that the server does not send model data to clients on reload if they already have it.

It's possible that this further caching of limiting network traffic and disk I/O as suggested might introduce some issues with customisability (in models).

I'm somewhat reluctant to go back tinkering with this script again, and I have observed that the average download time for models is sub-10 seconds, even when the client is in America connecting to a British server. If there is some demand for this increased efficiency, then I would have to look into it. But I think the script is fine in its current state.

LordNoob

  • Sr. Member
  • ****
  • Posts: 349
    • View Profile
Re: [Beta] Lightsabers
« Reply #8 on: February 01, 2016, 01:39:37 am »
It's been some time, and the script has improved quite a bit.

Now, lightsabers look a lot better:


Impressive. Most impressive.


A certain point of view? Well, I suppose this one makes the lightsaber look nice.


I wish I had the high ground like this earlier...


I also:
  • Wised up and implemented Jason's suggestion of server-side caching
  • Made it so that lightsabers will stream out and in with their owners (on Streamed branch in the repo)
  • Added a player value that dictates whether that player has a lightsaber full stop (also exclusive to Streamed branch)

JasonMRC

  • Donator
  • Hero Member
  • *****
  • Posts: 601
    • View Profile
Re: [Beta] Lightsabers
« Reply #9 on: February 01, 2016, 02:30:44 am »
Very nice.

HoodDestroyer

  • Newbie
  • *
  • Posts: 29
    • View Profile
Re: [Beta] Lightsabers
« Reply #10 on: March 30, 2016, 03:28:50 am »
everything worked fine before but after been a while like 5 minutes later got crashed and then when i logged into the game again i got this error messages
http://images.akamai.steamusercontent.com/ugc/289728107998575183/B75538D2EFDA0FE0762E6ACA8F9D288B75CF8F97/