Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discord? #35

Open
Langerz82 opened this issue Oct 2, 2019 · 24 comments
Open

Discord? #35

Langerz82 opened this issue Oct 2, 2019 · 24 comments

Comments

@Langerz82
Copy link

@dgengin do you have a discord to talk about this project. I would be very interested in helping out.

@ghost
Copy link

ghost commented Oct 3, 2019

No, but I can create one if necessary. You can use the issues tab for now to post any questions you have. I'm not always connected, so it works best for me like this.

@Langerz82
Copy link
Author

Langerz82 commented Oct 3, 2019

Well as I said I want to help and got the time to do so. I'd love to work on attacking monsters. If you could do the shell code for Monsters and have a simple formula for damage, I can look at the decompiled versions and make the formulas verbatim.

edit:
Oh yeah also I want to try and tie this in with a game server that can host a large amount of players eventually as well. I already have codes for a decent rpg server engine using websockets I'd have to update the path-finding on the server to include A* diagonal movement, and perhaps modify some of the packet structures, older compiled version of it is here: https://github.com/Langerz82/rro2-server-compiled

@ghost
Copy link

ghost commented Oct 3, 2019

That code isn't done yet. I said about 1 year ago I would do it, but I haven't. Once I have the code to attack, get hit, die when life ends, etc, the engine is nearly done.

Looking at what Diablo does and what DGEngine can do now, here's what's missing:

  1. player state machine for its mechanics (walking, attacking, hit, dead, etc)
  2. missiles - arrows, moving spells, etc
  3. doors and portals - already doable, but not done.
  4. player AI for monsters, etc
    I'm thinking of defining a set of peoperties that are common to all monsters and building a state machine that acts on those properties (ex: walks_step_by_step, runs_when_monster_dies, attack_frequency, attack_radius, can_open_doors, etc)
  5. random maps - already done (there is code support to generate random maps, but you have to build many tiny maps to randomly stitch them together and generate a bigger map from these tiny maps)
  6. spells - finish what's done now
  7. multiplayer - once single player is 100%
  8. small things that build on the above, such as formulas, showing map based on explored map, sounds on things, using SOL flags, etc.
  9. other features not part of Diablo but useful, such as plying with a keyboard/gamepad, loading D2 assets, etc.

As you can see from the list above, the only thing missing to have a playable game is player mechanics and monster AI (a simple one that seeks and attacks). All the others can be done afterwards.

If you search for formula in the gamefiles, you'll see the ones already done. Damage and other things will be done similar to those. There's a Formula class that allows you to write formulas using the player's properties. It might not be able to do all of the formulas, but it's good enough to write similar ones to the original formulas.

I have working formulas for when players use potions, read books (the required magic increases based on a formula), equipped items.

Attacking monsters would be the damage formula for the monster class.
From Warrior's class:

    "formulas": {
      "life": "(2 * vitality) + (2 * vitalityItems) + (2 * level) + lifeItems + 18",
      "mana": "magic + magicItems + level + manaItems - 1",
      "armor": "dexterityNow * 0.2 + armorItems",
      "toHit": "dexterityNow * 0.5 + toHitItems + 50",
      "damage": "strengthNow * level / 100"
    },

I've been getting the formulas from Jarulf's guide as I go along.

I don't know when I'll have player mechanics. I keep putting it off and doing other things. I did D2 assets loading out of laziness towards this. Hopefully soon 😉.

@Langerz82
Copy link
Author

Langerz82 commented Oct 4, 2019

ok man, atm I will work on creating the basic MonsterClass and Monster files. It will be adapted from the Player files and just stripped down to essentials. Should be completed in about 24-hours.

edit:
I've done some work on the Monster files see:
@dgengin #37

edit:
Hey, Just updating damage formula for Scavenger, how do I specify:
"damage": ":rnd(damageMax - damageMin) + damageMin"; ???

@ghost
Copy link

ghost commented Oct 5, 2019

Hi @Langerz82,

I looked at the changes you made. I would rather you wait until I do that code, since I'm doing things differently. I can tell you how I'm thinking of doing monsters, in case you want to give it a go.

One thing you can do now, which is a little boring to do, but esential, is to add all monsters. Right now there are only 2-3.

I want to have Players, Monsters and NPCs all share the same Player class. I'm thinking of adding a team property to both the class (as the class's default for a new player) and the player. for example, using these teams:

  • 0 - NPCs
  • 1 - player (and other players)
  • 2 - monsters

This way, it would be easier to implement monsters who will only attack you after you complete some task (Snotspill, Gharbad the Weak). You just change the team from 0 to 2. The AI would be made to never attack NPCs and attack any team that isn't the same as that Player's. When you click a NPC or a player on the same team, you execute it's action. When you click a player on a different team, you attack it.

This would allow one to make some interesting mods, such as having a small army of allies to control and to play the game in a similar fashion to Age of Empires, change allegiance for certain quests, gather allies (2-5) or create controllable golems to complete more complex missions (go over there, stand here, attack them while I try to kill the boss, etc).

I want AI also to be able to be set for players, so the code for that would be the same for monsters too. So you can set an auto mode, go for a coffee, and have your player attack enemies that are close by while you're drinking it (something simple, you wouldn't solve quests with this AI).

Work on you fork and post here your progress. I can give you hints and if I see something that could be merged, we can work on a pull request. Of course you can continue as you are now, but I would only merge if you were to make some real progress towards what I have now, even if it's not what I had in mind (such as implementing game mechanics with player and monsters separate, as you have now).

@Langerz82
Copy link
Author

What if we had a more generic Character class that has bare bones and animation stuff and contains the AI, then have Monsters and Players as a child of the parent Character class? My reasoning is that having properties that aren't used, 1. takes up more memory (but not a huge concern given modern systems have allot of ram anyway). 2. Is bad OOP practice to have obsolete properties. For example if I want to create a new type of Character that does something completely different like just roam and gives quests but not use a battle system then it would inherit Monster and Player properties which it does not need. It's your decision and I can go either way but I thought I should raise any concerns I have about having an all-rounder chunky class.

@ghost
Copy link

ghost commented Oct 6, 2019

That's an option. As you said, it's not that big a problem. D2 gamefiles are currently loading all of a player's animations (around 50MB) and it's still only using ~160MB after it loads the level. The engine is fairly fast (well, it's recreating a game from 1996). The original always uses a full CPU core and no GPU. DGEngine uses a residual amount of CPU and the GPU (when the framerate is limited to 60fps or less). DGEngine used to be slower. The performance gains (and possible bottleneck) are in the level drawing code, so there's no point in worrying about other parts that aren't impacting Level::draw for now.

the player doesn't have that many unused variables when used as a monster:

	uint32_t currentLevel{ 0 };
	uint32_t experience{ 0 };
	uint32_t expNextLevel{ 0 };
	uint32_t points{ 0 };

	LevelObjValue strength{ 0 };
	LevelObjValue strengthItems{ 0 };
	LevelObjValue magic{ 0 };
	LevelObjValue magicItems{ 0 };
	LevelObjValue dexterity{ 0 };
	LevelObjValue dexterityItems{ 0 };
	LevelObjValue vitality{ 0 };
	LevelObjValue vitalityItems{ 0 };

	LevelObjValue life{ 1 };
	LevelObjValue lifeItems{ 0 };
	LevelObjValue lifeDamage{ 0 };
	LevelObjValue mana{ 0 };
	LevelObjValue manaItems{ 0 };
	LevelObjValue manaDamage{ 0 };

	LevelObjValue armor{ 0 };
	LevelObjValue armorItems{ 0 };
	LevelObjValue toArmor{ 0 };
	LevelObjValue toHit{ 0 };
	LevelObjValue toHitItems{ 0 };
	LevelObjValue damageMin{ 0 };
	LevelObjValue damageMax{ 0 };
	LevelObjValue damageMinItems{ 0 };
	LevelObjValue damageMaxItems{ 0 };
	LevelObjValue toDamage{ 0 };

	LevelObjValue resistMagic{ 0 };
	LevelObjValue resistMagicItems{ 0 };
	LevelObjValue resistFire{ 0 };
	LevelObjValue resistFireItems{ 0 };
	LevelObjValue resistLightning{ 0 };
	LevelObjValue resistLightningItems{ 0 };

	FixedMap<uint16_t, Number32, 8> customProperties;

you have 8 custom properties that you can use for monsters. You might think monsters don't equip items, so they don't need all those properties but if you look at the butcher, when he dies, he drops the cleaver. You can implement his damage formula in many ways. If he's dropping a cleaver, why not create the butcher with an equipped item (the cleaver) instead of just adding his damage formula?

One thing I would like to support in the future is to change a player's class during the game. Suppose you're fighting a boss and when you're close to winning, he transforms the smaller monsters into bigger ones. Or you cast a spell that transforms you into a black knight for 30 seconds.

So it's more about having the option to use them if one wants to.

I do agree with you that Player is too big and it's only going to get bigger. That's why I implemented save as a friend function and I'm thinking of using the same trick for the AI code.

I don't want to hold you back. I'm taking my time in doing these things, so you can work on your fork as you please. If it gets to a point where you have player/monster mechanics working on you fork, I'll be happy to merge your work.

@Langerz82
Copy link
Author

Langerz82 commented Oct 6, 2019

I'm convinced lol. Thinking about it you could also have Server controlled evil players running round with minimal code changes.
I might work on optimizing the screen draw since I'm familiar with doing the same thing for Orthogonal but Isometric is a bit of a new beast. Monsters I will add when the appropriate attack functions are done which shouldn't be too difficult. Do you have parsers for adding Monsters or make the files manually?

@ghost
Copy link

ghost commented Oct 6, 2019

I have Butcher, Diablo and Skeleton King and Scavanger done. I just copy/paste the contents of a monster and modify the imageContainers, etc.

they're in gamefilesd/level/monster.

A trick I do when I'm testing is to change a player's class to use a monster's class (usually I pick the Warrior) and just walk around and stand still to see if the textures are alright. you can kill yourself in the game by pressing F3 repeatedly.

You have to see if the textures are right, so you might change the textureIndexes property of the playerClass to use the attack animation as the walk animation, just to see that it's loaded and the correct one.

As for the drawing code, right now, it's as fast as it can be. Especially when building statically and with profile guided optimizations. It's below 2% on my CPU at 640x480 and slightly more with the automap visible. In contrast, Diablo uses a full core on my PC (but no GPU).

@Langerz82
Copy link
Author

Hey man, do you think you could get a simple sample battle system up and working. If you do then I will work on integrating a simple dedicated server for multiplayer using node and websockets. The server is already done but its for another game so some modifications will have to be made.

@Langerz82
Copy link
Author

Hey tried to make a simple attack system but not working. Am I missing something?
https://gist.github.com/Langerz82/1b1a3557278bde279dec49c6f6b5949b

@ghost
Copy link

ghost commented Nov 18, 2019

Hi. You need to add damage instead of toDamage (which is something else - used in items to add extra damage to the player):

change

plr->LifeDamage(toDamage);

to

plr->LifeDamage(10);

I'm taking a break from coding for now, but what you tried makes sense to me.

@Langerz82
Copy link
Author

@dgengin ok thanks for the heads up will fix it right away. Btw, do you have the PNG map files for example town.png to import into Tiled? I'm gonna try and make one big map for the custom DGEngine, integrated with my Server.

@ghost
Copy link

ghost commented Nov 19, 2019

https://github.com/dgengin/DGEngine/wiki/Level-texture-support

you can export town like this: DGEngine --export-tileset:16 DIABDAT levels/towndata/town.cel . to create town.png on the same folder. That's what I use in Tiled.

@Langerz82
Copy link
Author

Thanks man, I'm trying to create a simple battle system I'll post when I've got something more complete.

@Langerz82
Copy link
Author

@dgengin how would I adjust the life/mana bars on the screen? I'm not sure if there is code for it.

@ghost
Copy link

ghost commented Nov 19, 2019

There's no code for it. search for updateLifeManaOrbs or updateAllPlayerStats in the json files. you can create an event that runs every 50ms that calls this to constantly update the UI. look for event to see the syntax. times in floats are in seconds. Times in ints are in miliseconds. 1.5 = 1.5 second, 50 = 50 miliseconds.

@Langerz82
Copy link
Author

Ok cool, I hope you come back to work on this engine, as it is really good and the potential is awesome. I know it's hard to work on something that isnt that fun because it has no gameplay, but I hope to make a online battle arena with it, and if I can pull it off I think would be lots of fun.
Heres my concept, A large map, players spawn random spots, enemies spawn randomly too, and it's one big massacre. If you die your loot drops too, character progression stays with the player (etc level 10 etc). Perhaps I have maps for Player levels 1-10, 10-20 etc for more even battles.

@Langerz82
Copy link
Author

@dgengin hey man any idea why this isnt working? The orbs arent updating despite me adding an event:

See:
https://gist.github.com/Langerz82/3cdf23cb64e877b373e513493f519726

@ghost
Copy link

ghost commented Nov 19, 2019

Add the event to afterLevelLoad.json, after line 33. Probably there's some other file that's clearing events (loadFull.json) that's being called after loading that file.

@Langerz82
Copy link
Author

Ugh it's not working, the life bar and in character stats the life is not adjusting.

Here is my clean changes:
https://gist.github.com/Langerz82/901e0b977caec1e4080819f4f7be08ad

@ghost
Copy link

ghost commented Nov 20, 2019

try this instead:

  "event": {
    "action": {
      "name": "if.equal",
      "param1": false,
      "param2": true,
      "else": "updateAllPlayerStats"
    },
    "time": 50
  }

I forgot events only repeat if the function called returns false, so you have to force a return false, like this (the if.equal action returns false if the "else" gets executed). Otherwise they get executed once and get deleted.

@Langerz82
Copy link
Author

Is it possible to have a Lua or cut down Javascript parser for files that have logic structures? It might be easier overall if it were possible. I can re-write some of the scripts if that were the case. I know your on a break, it's just a thought for future.

@ghost
Copy link

ghost commented Nov 21, 2019

It's always possible, but not in my plans. I didn't want to have the game logic in a scripting language, but instead have more of in in C++. Debuggers for C++ are better than for an embedded scripting language. You can easily debug most of the JSON by placing breakpoints in actions and the parser for the element you're debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant