Jump to content

Recommended Posts

Posted
On 8/10/2023 at 7:56 PM, Blitzkrieg said:

This was always also my desire to do, to create some instances / dungeons where players actually use their heads to progress


That's what I've been trying to do with my brother, on a project we've been working with for many years already, but we're applying it to everything (interactive dungeons, farming, character builds, character classes in general, crafting, alchemy, etc etc etc). At this point you could argue that it's a different game though, but L2 is just monotonous and boring AF right now, hence why most people usually go towards implementing auto farm on their servers instead of making farming interesting.
 

i.e; here's a WIP of a 'randomly generated dungeon' system we've been working on, using catacombs (the red lines are doors, and the dungeon gets bigger and more dificult depending on the amount of people who enters, plus there are multiple objectives to complete in order to advance)
53433.gif

 

 

  • Upvote 1
Posted

Thanks for the support folks! The reality is that I'm most likely not going to build a client that's compatible with existing servers. I'm fully aware of the amount of work such a task entails. Instead, I'm using this project as a way to get my nostalgia kick and to prototype some gameplay ideas.

  • Like 1
  • Upvote 1
  • 1 month later...
  • 3 weeks later...
Posted (edited)

Not render-ready, but re-working all the textures to clean them up and smooth out the ugly pixelation in the originals. Currently reworking Aden and TOI. Image quality stays pretty good even at max compression. Should leave enough room for normal, metallic, and occlusion maps.

 

spacer.png

spacer.png

Edited by cgrahamseven
  • Like 3
Posted
On 10/21/2023 at 11:03 PM, cgrahamseven said:

Not render-ready, but re-working all the textures to clean them up and smooth out the ugly pixelation in the originals. Currently reworking Aden and TOI. Image quality stays pretty good even at max compression. Should leave enough room for normal, metallic, and occlusion maps.

 

spacer.png

spacer.png

Neat. I specifically chose Talking Island first because it doesn't have too much architecture. I find that all buildings are just too low detail, even with texture updates, and would require an artists intervention.

Posted (edited)
On 10/29/2023 at 3:28 PM, Carow said:

Neat. I specifically chose Talking Island first because it doesn't have too much architecture. I find that all buildings are just too low detail, even with texture updates, and would require an artists intervention.

Your last talking island update pic looks gorgeous. Are you working in gamma or linear color space? It almost looks dream-like as if it was gamma. The textures look really good at least from that pic. 

 

I've found that alot of the older areas of the game (talking island, de village, gludio, etc) have textures that are in serious need of improvement. It would definitely be good to have an artist to do it, but you can also tweak them a bit with the right AI models and get some decent enhancements that still hold to the original feel. Definitely takes some experimenting and can be quite time consuming because of the number of textures used. I wish they had used texture atlases instead of having like 10-15 textures per model. I was recently messing around with Lineage 2M and they really made good use of atlases there because it was for mobile but it was so nice to just apply one texture to a material that is used for like 15 different models.

 

At one point I considered trying to bake the lineage 2 textures for certain buildings or towns into one single texture but you run into problems because their existing uv maps are fairly atrocious and they frequently scale the uvs outside of the bounds of some of the textures. 

 

With regards to some of the older art, you can kinda see what I did here in the DE village. They're subtle changes, but much more visible and clean up close. It's not 100% done (carpet and some other pieces/minor uv map updates), but you can see that once I add lighting and normal/metallic maps, you can kind of visualize in your head how it's going to pop with all that metal and rock. Throw in some post processing with bloom effect and it should be really dramatic. 

 

spacer.png

 

spacer.png

 

spacer.png

Edited by cgrahamseven
  • Upvote 1
Posted (edited)
7 hours ago, cgrahamseven said:

Your last talking island update pic looks gorgeous. Are you working in gamma or linear color space? It almost looks dream-like as if it was gamma. The textures look really good at least from that pic. 

 

I'm doing it in linear space since it's the more physically "correct" way of doing things. I'd mostly recommend gamma space if you're going for an old school aesthetic or are targeting really old mobile/WebGL devices.

 

As for atlasing textures, I'm not bothered about it at the moment because it's premature optimisation. Unity's SRP Batcher batches draw calls by shader, rather than material. This already produces great performance. My current performance bottleneck is all the grass I'm drawing anyway. New vid is being finished shortly, so that'll show the progress.

Edited by Carow
Posted
39 minutes ago, Carow said:

Latest video is out 

Its great to see more from this 🙂
About the BSP brushes, honestly, i have no idea how they set up the texture mappings, but there's a simple method to convert BSP brushes to staticmeshes, which can then be extracted using UModel:
Screenshot_1.jpg?ex=655b9495&is=65491f95

Screenshot_2.jpg?ex=655b9510&is=65492010


(It's an integrated function in Unreal Engine 2's editor, so you just need to select the brushes and click a button and voilà)
I don't have much free time these days, but let me know if you wanna try it out, i'll give you a small step by step

 

  • Thanks 1
Posted (edited)
4 hours ago, 911reg said:

Its great to see more from this 🙂
About the BSP brushes, honestly, i have no idea how they set up the texture mappings, but there's a simple method to convert BSP brushes to staticmeshes, which can then be extracted using UModel:
Screenshot_1.jpg?ex=655b9495&is=65491f95

Screenshot_2.jpg?ex=655b9510&is=65492010


(It's an integrated function in Unreal Engine 2's editor, so you just need to select the brushes and click a button and voilà)
I don't have much free time these days, but let me know if you wanna try it out, i'll give you a small step by step

 

Here the brush extractor from .unr maps into .json for unity

https://workupload.com/file/JWseAVdY6pc

 

p.s. original author of this program i think "kisliy" from Gildor's forum.

Edited by deMEV
  • Like 1
Posted (edited)
8 hours ago, Carow said:

Latest video is out 
 

 

Love it. Especially nice job with the lighting in the church. The emission map for the windows really gives a much better feel to that room. I saw some comment on the vid saying they didn’t like the glossiness of the floor. I think it looked more realistic how you did it. 
 

I think I looked at using KWS water solution a while ago but he has some limitations that don’t let you properly mask out certain areas effectively. The problem you will run into with a single water prefab set to infinite water is that there are many spots on the world map that dip below sea level where you would want to just entirely mask out the water. I think I settled on Crest and it was much more configurable and allowed for the creative use of masking and setting water plane heights. 
 

Definitely love the combat changes. The movement and combat really have to be changed. I reworked some animations to include jumping and 8-directional WASD with strafing and it just feels a lot better. Of course it still remains to be seen how well the original skills would look with that kind of free movement where it doesn’t move you to the target and stop you to attack. I think it can be done with avatar masks with upper and lower body masks to do something like still allow you to use skill and attack animations while moving.  
 

Really excellent work overall. Impressed. 

Edited by cgrahamseven
Posted (edited)
8 hours ago, cgrahamseven said:

Love it. Especially nice job with the lighting in the church. The emission map for the windows really gives a much better feel to that room. I saw some comment on the vid saying they didn’t like the glossiness of the floor. I think it looked more realistic how you did it. 
 

I think I looked at using KWS water solution a while ago but he has some limitations that don’t let you properly mask out certain areas effectively. The problem you will run into with a single water prefab set to infinite water is that there are many spots on the world map that dip below sea level where you would want to just entirely mask out the water. I think I settled on Crest and it was much more configurable and allowed for the creative use of masking and setting water plane heights. 
 

Definitely love the combat changes. The movement and combat really have to be changed. I reworked some animations to include jumping and 8-directional WASD with strafing and it just feels a lot better. Of course it still remains to be seen how well the original skills would look with that kind of free movement where it doesn’t move you to the target and stop you to attack. I think it can be done with avatar masks with upper and lower body masks to do something like still allow you to use skill and attack animations while moving.  
 

Really excellent work overall. Impressed. 

 

Honestly, I'm not sure when/if I actually get to all the other areas at this rate. Each one requires a lot of attention to do right. As such, KWS water fits the bill for now. It's also the plugin that had the shore wave system I wanted.

 

As for combat, I'm mostly inspired by Soulsborne games. As such, I expect there to be a decent amount of movement (running attacks, attack based momentum movement, active evasion/blocks, etc.), but not to the point where you can freely navigate while attacking - that always looks and feels extremely floaty to me.

Edited by Carow
Posted

You are not recreating L2 in Unity. You are recreating the MAPS.

 

What you are doing is PoC and will remain unfished forever, and simply because recreating Lineage 2 is much more than importing / improving maps in Unity.

 

Think of client side code, networking, game data, effects, sounds which is truly A LOT, trust me.

 

To do all this in Unity will require an enormous man-hour waste to script, with probably inferior performance to the good old native L2 binaries.

 

I will not even discuss about incompatibility with L2J/L2OFF networking, you will also have to remake the server because scripting the current networking would be a dumb idea on such a project.

 

Overall, yeah nice effort / graphics.

  • Upvote 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



  • Posts

    • what pack you use  send me on discord for it
    • package custom.events.RandomZoneEvent; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.ScheduledFuture; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.l2jmobius.commons.threads.ThreadPool; import org.l2jmobius.commons.time.SchedulingPattern; import org.l2jmobius.commons.time.TimeUtil; import org.l2jmobius.commons.util.IXmlReader; import org.l2jmobius.gameserver.managers.ZoneManager; import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Npc; import org.l2jmobius.gameserver.model.actor.Player; import org.l2jmobius.gameserver.model.quest.Event; import org.l2jmobius.gameserver.model.zone.ZoneId; import org.l2jmobius.gameserver.model.zone.ZoneType; import org.l2jmobius.gameserver.model.zone.type.RandomZone; import org.l2jmobius.gameserver.util.Broadcast; /** * Random Zone Event - Activates one random PvP zone temporarily. No modifica la clase de la zona: usa flags PvP en runtime. * @author Juan */ public class RandomZoneEvent extends Event { private static final String CONFIG_FILE = "data/scripts/custom/events/RandomZoneEvent/config.xml"; private static int EVENT_DURATION_MINUTES = 15; private static boolean _isActive = false; private ScheduledFuture<?> _eventTask = null; private final List<ZoneType> _availableZones = new ArrayList<>(); private ZoneType _activeZone = null; public RandomZoneEvent() { loadConfig(); loadZones(); registerZoneListeners(); } /** * Registra listeners a TODAS LAS ZONAS random */ private void registerZoneListeners() { for (ZoneType zone : _availableZones) { addEnterZoneId(zone.getId()); addExitZoneId(zone.getId()); LOGGER.info("[RandomZoneEvent] Registered listener for zone: " + zone.getName()); } } private void loadConfig() { new IXmlReader() { @Override public void load() { parseDatapackFile(CONFIG_FILE); } @Override public void parseDocument(Document doc, File file) { forEach(doc, "event", eventNode -> { final StatSet att = new StatSet(parseAttributes(eventNode)); final String name = att.getString("name"); for (Node node = eventNode.getFirstChild(); node != null; node = node.getNextSibling()) { if ("schedule".equals(node.getNodeName())) { final StatSet attributes = new StatSet(parseAttributes(node)); final String pattern = attributes.getString("pattern"); final SchedulingPattern schedulingPattern = new SchedulingPattern(pattern); final StatSet params = new StatSet(); params.set("Name", name); params.set("SchedulingPattern", pattern); final long delay = schedulingPattern.getDelayToNextFromNow(); getTimers().addTimer("Schedule_" + name, params, delay + 5000, null, null); LOGGER.info("[RandomZoneEvent] Event " + name + " scheduled at " + TimeUtil.getDateTimeString(System.currentTimeMillis() + delay)); } } }); } }.load(); } private void loadZones() { for (ZoneType zone : ZoneManager.getInstance().getAllZones(RandomZone.class)) { if ((zone.getName() != null) && zone.getName().toLowerCase().startsWith("random_zone")) { _availableZones.add(zone); LOGGER.info("[RandomZoneEvent] Loaded zone: " + zone.getName() + " (id=" + zone.getId() + ")"); } } LOGGER.info("[RandomZoneEvent] Total random zones loaded: " + _availableZones.size()); } @Override public void onTimerEvent(String event, StatSet params, Npc npc, Player player) { if (event.startsWith("Schedule_")) { eventStart(null); final SchedulingPattern schedulingPattern = new SchedulingPattern(params.getString("SchedulingPattern")); final long delay = schedulingPattern.getDelayToNextFromNow(); getTimers().addTimer(event, params, delay + 5000, null, null); LOGGER.info("[RandomZoneEvent] Rescheduled for " + TimeUtil.getDateTimeString(System.currentTimeMillis() + delay)); } } @Override public boolean eventStart(Player eventMaker) { if (_isActive) { if (eventMaker != null) { eventMaker.sendMessage("RandomZoneEvent already active."); } return false; } if (_availableZones.isEmpty()) { Broadcast.toAllOnlinePlayers("[RandomZoneEvent] No zones configured."); return false; } _isActive = true; Broadcast.toAllOnlinePlayers("⚔️ Random Zone Event has started!"); _eventTask = ThreadPool.schedule(this::activateRandomZone, 5_000); return true; } private void activateRandomZone() { _activeZone = _availableZones.get(new Random().nextInt(_availableZones.size())); _activeZone.setEnabled(true); Broadcast.toAllOnlinePlayers("🔥 Random Zone Event: " + _activeZone.getName() + " is now PvP for " + EVENT_DURATION_MINUTES + " minutes!"); _eventTask = ThreadPool.schedule(this::eventStop, EVENT_DURATION_MINUTES * 60 * 1000L); } @Override public boolean eventStop() { if (!_isActive) { return false; } _isActive = false; if (_eventTask != null) { _eventTask.cancel(true); _eventTask = null; } if (_activeZone != null) { _activeZone.setEnabled(false); Broadcast.toAllOnlinePlayers("🏁 Random Zone Event ended. " + _activeZone.getName() + " is back to normal."); _activeZone = null; } else { Broadcast.toAllOnlinePlayers("🏁 Random Zone Event ended."); } return true; } @Override public void onEnterZone(Creature creature, ZoneType zone) { if (!_isActive || (_activeZone == null)) { return; } if ((zone == _activeZone) && creature.isPlayable()) { creature.setInsideZone(ZoneId.PVP, true); if (creature.isPlayer()) { creature.sendMessage("Esta zona está en modo PvP temporalmente."); } } } @Override public void onExitZone(Creature creature, ZoneType zone) { if (!_isActive || (_activeZone == null)) { return; } if ((zone == _activeZone) && creature.isPlayable()) { creature.setInsideZone(ZoneId.PVP, false); if (creature.isPlayer()) { creature.sendMessage("Abandonaste la zona PvP temporal."); } } } @Override public boolean eventBypass(Player player, String bypass) { return true; } @Override public String onEvent(String event, Npc npc, Player player) { return super.onEvent(event, npc, player); } @Override public String onFirstTalk(Npc npc, Player player) { return null; } public static void main(String[] args) { new RandomZoneEvent(); } } i have this but its not working
    • ZonePvPSpawnBossRadio=0 ZonePvPSpawnBossBarakiel=0 at the Customs.ini in L2Server folder. Im prety sure this is it because i had the same problem with you in cruma 1 floor for example and i couldn't fix it but i fixed it finally by changing these 2 lines
  • Topics

×
×
  • Create New...

AdBlock Extension Detected!

Our website is made possible by displaying online advertisements to our members.

Please disable AdBlock browser extension first, to be able to use our community.

I've Disabled AdBlock