Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Everything posted by Valoo

  1. Hi, i am trying to find a good (server) architecture and some implementation hints for my indie multiplayer game i'm designing. I have previously worked on as small scale restoration project for an old mmorpg. The intend was not to have thousands of players connect, but to provide a manageable amount of players with a consistent view of the world; with this goal in mind, and because of not having much practical experience in designing such systems, it became a monolithic server that clients directly connected to. It turned out though that the biggest bottleneck was the simulation of thousands of npcs (active regions increasing on players spreading). For my current/own project (a space-sim kind of game) i intend to have similar requirements: small amounts of players (10-100 max), but big amounts of npcs (thousands, moving along paths most of the time, but observing their environment), a basic physics system (mostly queries, no complex simulation), indirect (chat, trading), and direct/spatial interactions (some form of combat) between players and npcs (trading, conversations, some form of combat). Apart from that, i need to be able to implement changes to the game design without too many cascading steps (some of the interactions are not yet mapped out completely). So, trying to learn from the previous project, i now want to find a better architecture for the systems involved in handling this. Having mostly worked with unity before, my basic way of thinking is in loops (or synchronous events), but the more i read about the different server designs, the more i see asynchronous messaging between distributed systems as a way to tackle such problems. I found valuable resources on 'Engines of Delight', but most of them seem to target the challenge of high amounts of players/connections or just a bigger scope in general, so some of their parts 'feel' unnecessary for my goal (a frontend server for example). But splitting the systems into interconnected, and the game world into separately simulated zones, seems like a way to go (with which i have no experience yet, unfortunately). So my questions are: If i intend to separate the game systems, is this reasonable (amount of work/benefits, 'secure enough', iteration-friendly)? : Authserver (login, version check) - public Gameserver (zone management/character transfer, message relay, persistence(DB saving/loading)) - public Zoneservers[] (physics, gameplay, ai, chat? etc) - internal And if so, the questions i'd have were: where does the character data (players/npcs) live (gameserver, zoneserver); do i send relevant data back and forth between them (each has a sliced copy of the data only covering their concerns) or do they each own a synced full copy for easier cross-system communication / zone transfer? Or are there alternative or even better solutions for my requirements?
  2. My situation probably leans more towards the bad/convoluted code wasting cycles scenario. But okay, i think i have a good amount of information now, thanks for the input.
  3. What i meant was the runtime location of player related data. Is it common to have it reside partially in multiple locations; If the services are physically or logically separated, how do they access the same resource, does each load/gets assigned its part of the dataset (maybe just passed along at the point of a request?), or am i approaching a problem from the wrong side? It seems to me that this may be vital in my understanding of 'distributed' (realtime) computing.
  4. That sounds plausible. And for the player data splitting, is it a bad idea, or too dependend on specifics, is there a common route i can take or terminologies i can look up to learn?
  5. Yes, i think some delay here and there will most likely not be a problem for this type of game. I'm not sure i understand what you mean by multi-database though. If this targeted the split player data question, i was under the impression that even for this distributed design i'd still only need one database, but what i was wondering about was, if on login, i should just load, from the db, the player data in parts for each server (i.e. zoneserver receives the realtime-relevant part (transform, skills etc), whereas the world/gameserver the non-time-critical parts (inventory, friendslist etc.) for example. It feels like this could be a setup for headaches, especially if some things have both realtime and non-realtime components (like droppable items/with spells). What would be a common way to go about this, hold everything on a zoneserver and supply the other services with the relevant data only at the time of a request? (this sounds like more load on a zoneserver and more roundtrips for messages)
  6. That already answers a lot of questions, thanks. About the persistence part: My naîve understanding of persistence until now was that the gameserver (or serviceserver) runs a recurring timer that just updates the database with newly piled up changes, but your description sounds like i should handle all corresponding changes (even moving items in an inventory) as transactions with the database where i only let that change apply to the active, simulated data if that transaction succeeded (and not the other way round - updating the db state after it registered as a change in the simulation)? My guess is that this would create longer response times and that the load on the database goes up. But i haven't tested this, so i may just be overreacting here. When you say 'Ephemeral state', does that mean the player data may indeed be split between the servers and a zoneserver only holds the part it needs for its simulation (as in, the inventory items for example are kept on the gameserver as trading etc are handled by one of its services)? A trading request from one player to another would mean, if they are only able to do so in a certain distance to each other, that the gameserver/trading service must hold some positional data too, or should it just query the zoneservers in that case; how to go about this shared data? (I'm thinking that such a request should not need to pass through the gameserver just to become a request from the zoneserver back to the gameserver/its services, meaning in my imagination it should be able to somehow directly be handled by the former, to cut some internal roundtrip time)
  7. Depending on the situation, you maybe could get away with simulating gravity and only interpolating the horizontal movement. I have no idea if this is true, but Guild wars 2 feels like it does this for proxy player characters (with occasional corrections).
  8. Valoo

    12 weights, one is different

    I didn't read any of the above answers, maybe it's already in there, but i think this works:   [spoiler] weight 6 vs 6 if one is heavier, split that into 3 vs 3 split the heavier one into 1/1 and take one away. if the remaining two are equal, it's the one taken away, else the heavier one. [/spoiler]
  9. Hi, i'm writing a dialog system (first serious attempt) and came to a point where i want to make it more 'unspecific'. Each dialog currently has options to specify requirements (List of DialogRequirement objects) for it to be a selectable option, which consist of a target (enum - npc, player, world) and a type (enum -state, logEntry, etc) and a few value fields (int, float, string). When checking the requirements i select the target based on the enum value and pass the requirement object to it. Targets implement an interface (IDialogRelevant) with bool ValidateRequirement(DialogRequirement) and use the value fields for the check. The problem i have is that the requirement has these value fields (int intValue, float floatValue ..) that are bad to read and easy to implement wrong in the DialogRelevant entity and also the RequirementType enum too tied to a specific type of game (the requirementType enum currently has things like QuestLog for example).   What i would want is it to be extensible , like new requirement (sub)classes which then could (and should) be more specific. What i thought, but am confused about is generic interfaces, or an abstract generic baseclass. (But if, how would i 'connect' these to the specific requirement target and pass the required value and what way should i do it, and wouldn't i have to typecheck and cast these before passing them to the specific target as i have to store them in a baseclass type field?)   i'm using unity (c#) and already have a visual interface ready to build the dialogs, but want it to be open to the requirement types that the user can implement, like i think giving them a Draw() method would be the way (as there's currently only this one requirement object i just inlined the drawing of it).   How would i design it?   I hope you can understand what i mean.
  10. I know that it has to be specific to the game, and i hoped to build a system that becomes specialized at the point where the user created his game specific requirements (and/or implemented the associated (generic?)interfaces for the entities). I currently also have a kind of trigger system, not as sophisticated, but involved entities (npc, player, world context) can be notified when a dialog option is selected. AND'ing and OR'ing of the requirements is also already in there. It's just the way the requirement is structured that currently botheres me. But i will see what i can do with all the suggestions i got.
  11. I understand now, thank you for these suggestions.
  12. @Alberth The idea of passing check objects sounds good. I guess that would mean i still keep the base requirement class with the valuetype fields which the specific check object then takes the ones it needs from, kind of like an adapter?   @Servant of the Lord For the strings idea, it seems to me that this means logging all game events in this string format. And that means checking the inventory for example for an item would become a search for "PickedUpItemX" or the surrounding system has to know which specific events to log as a certain keyword which i feel could be a too strong requirement for the system. And to your script idea it sounds to me like you mean it in a similar way to these check objects, no? (if i understood these correctly)
  13. I see, my explanation wasn't that good and it seems missing some information. Each entity that needs dialogs has the dialog component that holds all dialogs for that entity. If the player requests dialogs, the code checks the each root element of the dialogs for its requirements. This means, foreach DialogRoot (and subsequent dialogoptions: if at that point), i pass the dialogrequirements to the entity the req. is targeted at, for it to check them, because i currently have no idea how to kind of externalize them (i hope that word describes it better). In the end, i want to enable the user to create custom requirements specific to his game (and maybe the validation methods, if those are needed?), for example like Requirement_HasItem that i can use in my system without hardcoding them or having a big allround requirement class with all value types as fields and an enum that defines how the values should be handled (what i currently have)
  14. Hi, my game depends on spells that grant the player abilities like leap, charge, levitate and so on. As these hook into the movement i'm not sure whether i should include them in the client side prediction or just wait until the server initiates them. When not including them i imagine i would just pause the prediction part, while 'transitioning' (i'm doing these inside a coroutine in Unity) and resume it after the Transition has finished. but i also imagine this may lead to some prediction problems with the missing part? When including, i guess i would have to rewrite the way these work (and i'm not sure how, as they come from spells, not direct key input).   How do commercial games do it, or is there even a better way?
  15. Shoud i try to predict dodges/leaps and similiar on the client, is this how it's usually done? Guild wars 2 is an example for the types of movement tied to abilities i have and want to have working.
  16. thanks for your answer, i read that article some time ago. i can't see an answer to my question in it, but i guess you mean i should try to predict the outcome of abilty-tied movement too? It came to my mind that for each resimulation step that happens inside the predicted ability movement i kind of have to fire the spell for that move again, or something. I'm completely lost how i could integrate the spell/ability system into the movement prediction (predicted movement is based on key input, but ability movement isn't). Currently the player sends: i want to cast ChargeSpell the server validates, then sends back DoCastBar() after finishing it sends the outcome of the spell, in this case ChargeToEnemy(X) ChargeToEnemy is a coroutine i would run on the server and the client, which disallowed regular movement, while 'charging' (doing its own movement calculation on the player) towards the enemy. after the coroutine finished input movement was allowed again.   But recently i rewrote the movement code to use client side prediction (and not just telling the server where you are) and now i'm unsure how i can make both (spell/-movement + predicted input movement) work together.   Maybe i just have to redesign how spells/abilities work or the coroutine movement. (i still consider myself a newbie, as most of what i code is kind of self-taught)
  17. Edit: i found that the problem was the ground-state not correctly setting when re-simulating from a server sent state. As i dont know how to delete this thread, i have another question: what do i do when the packet containing the jump-action gets lost (snapping back could mean walking off a cliff)?   Hi, i recently tried to create a client side predicted multiplayer sample (with unity/Lidgren, simulated 200ms latency). So far it works ok. But at some points (kind of randomly) it seems to miss a 'jump'-action, gets corrected, thus glitching the token over half the jump. i currently do it like so: client and server start counting up their tick-counter when started. 30times a second client gets its input, sends it to the server (including the tick), applies it on itself and puts it in a list. on the server i shift the tick according to the incoming number ( if difference > big amount: localtick = incoming tick, else tick++/--) and move the server entity with the attached input every 0.1 second i send the state back to the client with the servers (adjusted) tick the client then resimulates from that tick with the inputs from its past-inputs-list.   from debug.logs i often see (on the server's side): -intended tick: 259, current: 260 -intended tick 260, current: 259 (<-because i adjusted it before)   i guess that's where the problem lies. (the jump action is only 1 tick long). Though i'm not sure, and also not, how to handle this. (I still consider myself a newbie)   here's a video which i hope shows what i mean (towards the end):
  18. thanks for your answer, but what i meant was, if the packet gets lost on its way to the server, and the server then skips the jump-action, the player will on his client snap back to the ground where he left and, because he held forward, walk off a cliff he meant to jump over. i had the idea: should i just send the jump and anything alike separately from the normal movement packets (and then reliable) ?
  19. I'm currently doing a similar thing (online rpg kind of game) and i came to the conclusion that, atleast for me, it seems inevitable to have the server not be a Unity instance too, if i want to handle physics server sided. I'm also using Aron Granbergs A* for pathing and skills/spells (teleporting for example, like guild wars 2). I read somewhere that he planned the possibility of it to be run outside unity (Photon i believe), but haven't seen any further mention of that. But for now it works very well inside unity. i send position related data (position, velocity, y-rotation) 5 times a second and the difference on the client is very acceptable (interpolated and halfway extrapolated).   Also, dont let the player control any mob. I have once seen a game doing that where you could pull all mobs in the area towards you using a hack and one-hit kill them. If unsure maybe just do the movement (mob to player) in a straight line (some Wow private servers do that, if pathing is not enabled). The Mob will most likely run through walls and all that but thats better than giving the player an opportunity to cheat for free.
  20. In my game, i spawn creatures from a database and when one dies it notifies the 'zone' about itself the zone then forwards that to a script which handles special circumstances ( if the zone is an instance and/or only certain creatures should respawn for example). If the script doesnt handle the respawn the default routine schedules the respawn with a timer based on the creature template.
  21. I'm about to get an understanding. Your example is very good. I'm just having difficulties translating it to my code. is stepnumber an actual number i increment or Time? If number, would that mean, it is only incremented on changes/in an interval?   You are right, i'm not familiar with this fixed timestep concept. I guess that's why some things break when i build my code on top of that missing base.
  22. Hi, for my multiplayer game i implemented an interpolation/extrapolation mix for movement sync. It works very well between source and server. But i'm not sure when i should update the clients about changes. For now i would just reroute the source packets while also simulating on the server (for validations and so on). But that means the more players i have the more movement packets i will have flowing around randomly. I thought about packing the movement data of all players in a bundled packet and distribute that in certain intervals. But wouldn't that mean i have to sample the data from the simulation on the server? Also, MoveStart and MoveStop packets are sent instantaneous to aid the extrapolation and those would look odd if they didn't arrive until one of those intervalls, i guess. Am i wrong? What would be the best approach for this? P.S. i target around 20-40 concurrent players online at max, movement packet size with header is around 25bytes, 3 times per second
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!