Thread: Void - 634

Page 9 of 12 FirstFirst ... 7891011 ... LastLast
Results 81 to 90 of 111
  1. #81  
    Programmer

    Elysian's Avatar
    Join Date
    Dec 2018
    Posts
    157
    Thanks given
    10
    Thanks received
    79
    Rep Power
    694
    Love how this is still active!
    Reply With Quote  
     

  2. #82  
    Registered Member
    Stimulant's Avatar
    Join Date
    Jan 2013
    Age
    27
    Posts
    1,457
    Thanks given
    248
    Thanks received
    187
    Rep Power
    578
    Very impressive work!
    Reply With Quote  
     

  3. #83  
    Renown Programmer
    Greg's Avatar
    Join Date
    Jun 2010
    Posts
    1,179
    Thanks given
    260
    Thanks received
    1,012
    Rep Power
    2003
    Batch updates and performance

    Kris pointed out that I was handling batch updates differently; I had a batch for joining and a batch for those already in a region,
    Where in osrs the batching packet is only for those in an area, those joining get everything sent as individual packets when they enter.
    Which in theory is less efficient but there was a lot of extra complexity and storage used in the way I was doing it, so I opted for the simpler code.

    This had the knock on effect of needing to modify FloorItems and GameObjects, systems which I wasn't overly happy with anyway so I decided to take the opportunity to rewrite those as well. FloorItems isn't that interesting just a tidy up but GameObjects came with a lot of improvements.


    For context, on games first run it loads all the objects and tile data from the cache and writes it to a flat file, this means on subsequent runs it can be read faster, and while the game is running it can load map data for instances/dynamic maps without needing to hold the cache in memory (cache is discarded after startup).

    Prior to recent changes, loading the full map from this flat file into memory would take on average 668.4ms and the server was using 1.1GB ram. This is much faster than using the cache directly, however still quite slow for startup. So I added a toggle which would choose to store only objects which have options, or have data in the server's objects config yaml file. Essentially only objects which are currently have content and are in use.
    That cuts the stored object count from ~3.5m objects down to ~74k, and load times down to an average of 398ms and 454.68MB ram. This was the start point.

    First thing to go was GameObject's as Entity's. They were heavy as each object had an event bus and a temp properties map and lots more unnecessaries, storing them instead as a Long as an inline value.
    Now GameObjects were numbers they could be stored more efficiently too, I figured if you're using the objects location as the storage index you only need to store the objects id, type and rotation which all easily fit into an integer; not unlike how collision flags are stored but with the addition of the object group added to the index.

    I added two implementations for storage, a simple fastutils Int2Int map which has a much lower memory footprint for when loading 75k objects. And a multi dimensional Array<IntArray> which is much faster but uses up a lot more memory, suitable for loading 3.5m objects.

    The flat map file format also had some improvements, before it was storing and loading at a bit level, which is great for storage sizes but no so much for data throughput and complexity. I threw that out in favour of standard readInt/Long's.
    Overall it didn't increase the size too much; the flat file is now 14.87MB instead of 14.1MB but it simplified the code and increased speed a lot.

    And the final changes were making sure that the data loaded goes through transformations as infrequent and as late as possible not only in the object storage but collision storage too, along with some general refactoring and adding a checksum file so that the flat file is always correct.


    Memory Usage
    Total sever usage after startup has completed

    Object Count Before After Memory Saved
    75k 454.68MB 438.01MB 3.6%
    3.5m 1.1GB 677.69MB 38.4%

    Loading speed
    Map loading only, average of 5 cold starts

    Object Count Before Array Init Loading After (Total) Performance Gain
    75k 398ms 30.6ms 139.8ms 170.4ms 57%
    3.5m 668.4ms 29.6ms 202.2ms 231.8ms 65.3%


    Attached image

    Which is really good, as you can see on the optimised version it barely peaks 500mb on startup before dropping to sub 400mb (700/500 with 3.5m objs). It's no longer a significant contributor to startup times and memory overhead although wasn't enough to breach below the 4s mark.
    I'll have to do something about my yaml files if I want that.
    Last edited by Greg; 06-09-2023 at 07:51 PM.
    Attached imageAttached image
    Reply With Quote  
     

  4. Thankful users:


  5. #84  
    Boolean


    Join Date
    Feb 2014
    Posts
    733
    Thanks given
    91
    Thanks received
    22
    Rep Power
    253
    Quote Originally Posted by Greg View Post
    Batch updates and performance

    Kris pointed out that I was handling batch updates differently; I had a batch for joining and a batch for those already in a region,
    Where in osrs the batching packet is only for those in an area, those joining get everything sent as individual packets when they enter.
    Which in theory is less efficient but there was a lot of extra complexity and storage used in the way I was doing it, so I opted for the simpler code.

    This had the knock on effect of needing to modify FloorItems and GameObjects, systems which I wasn't overly happy with anyway so I decided to take the opportunity to rewrite those as well. FloorItems isn't that interesting just a tidy up but GameObjects came with a lot of improvements.


    For context, on games first run it loads all the objects and tile data from the cache and writes it to a flat file, this means on subsequent runs it can be read faster, and while the game is running it can load map data for instances/dynamic maps without needing to hold the cache in memory (cache is discarded after startup).

    Prior to recent changes, loading the full map from this flat file into memory would take on average 668.4ms and the server was using 1.1GB ram. This is much faster than using the cache directly, however still quite slow for startup. So I added a toggle which would choose to store only objects which have options, or have data in the server's objects config yaml file. Essentially only objects which are currently have content and are in use.
    That cuts the stored object count from ~3.5m objects down to ~74k, and load times down to an average of 398ms and 454.68MB ram. This was the start point.

    First thing to go was GameObject's as Entity's. They were heavy as each object had an event bus and a temp properties map and lots more unnecessaries, storing them instead as a Long as an inline value.
    Now GameObjects were numbers they could be stored more efficiently too, I figured if you're using the objects location as the storage index you only need to store the objects id, type and rotation which all easily fit into an integer; not unlike how collision flags are stored but with the addition of the object group added to the index.

    I added two implementations for storage, a simple fastutils Int2Int map which has a much lower memory footprint for when loading 75k objects. And a multi dimensional Array<IntArray> which is much faster but uses up a lot more memory, suitable for loading 3.5m objects.

    The flat map file format also had some improvements, before it was storing and loading at a bit level, which is great for storage sizes but no so much for data throughput and complexity. I threw that out in favour of standard readInt/Long's.
    Overall it didn't increase the size too much; the flat file is now 14.87MB instead of 14.1MB but it simplified the code and increased speed a lot.

    And the final changes were making sure that the data loaded goes through transformations as infrequent and as late as possible not only in the object storage but collision storage too, along with some general refactoring and adding a checksum file so that the flat file is always correct.


    Memory Usage
    Total sever usage after startup has completed

    Object Count Before After Memory Saved
    75k 454.68MB 438.01MB 3.6%
    3.5m 1.1GB 677.69MB 38.4%

    Loading speed
    Map loading only, average of 5 cold starts

    Object Count Before Array Init Loading After (Total) Performance Gain
    75k 398ms 30.6ms 139.8ms 170.4ms 57%
    3.5m 668.4ms 29.6ms 202.2ms 231.8ms 65.3%


    Attached image

    Which is really good, as you can see on the optimised version it barely peaks 500mb on startup before dropping to sub 400mb (700/500 with 3.5m objs). It's no longer a significant contributor to startup times and memory overhead although wasn't enough to breach below the 4s mark.
    I'll have to do something about my yaml files if I want that.
    always doing great work!
    Reply With Quote  
     

  6. #85  
    Registered Member
    Tyluur's Avatar
    Join Date
    Jun 2010
    Age
    26
    Posts
    5,103
    Thanks given
    1,819
    Thanks received
    1,767
    Rep Power
    2438
    Quote Originally Posted by Greg View Post
    Batch updates and performance

    Kris pointed out that I was handling batch updates differently; I had a batch for joining and a batch for those already in a region,
    Where in osrs the batching packet is only for those in an area, those joining get everything sent as individual packets when they enter.
    Which in theory is less efficient but there was a lot of extra complexity and storage used in the way I was doing it, so I opted for the simpler code.

    This had the knock on effect of needing to modify FloorItems and GameObjects, systems which I wasn't overly happy with anyway so I decided to take the opportunity to rewrite those as well. FloorItems isn't that interesting just a tidy up but GameObjects came with a lot of improvements.


    For context, on games first run it loads all the objects and tile data from the cache and writes it to a flat file, this means on subsequent runs it can be read faster, and while the game is running it can load map data for instances/dynamic maps without needing to hold the cache in memory (cache is discarded after startup).

    Prior to recent changes, loading the full map from this flat file into memory would take on average 668.4ms and the server was using 1.1GB ram. This is much faster than using the cache directly, however still quite slow for startup. So I added a toggle which would choose to store only objects which have options, or have data in the server's objects config yaml file. Essentially only objects which are currently have content and are in use.
    That cuts the stored object count from ~3.5m objects down to ~74k, and load times down to an average of 398ms and 454.68MB ram. This was the start point.

    First thing to go was GameObject's as Entity's. They were heavy as each object had an event bus and a temp properties map and lots more unnecessaries, storing them instead as a Long as an inline value.
    Now GameObjects were numbers they could be stored more efficiently too, I figured if you're using the objects location as the storage index you only need to store the objects id, type and rotation which all easily fit into an integer; not unlike how collision flags are stored but with the addition of the object group added to the index.

    I added two implementations for storage, a simple fastutils Int2Int map which has a much lower memory footprint for when loading 75k objects. And a multi dimensional Array<IntArray> which is much faster but uses up a lot more memory, suitable for loading 3.5m objects.

    The flat map file format also had some improvements, before it was storing and loading at a bit level, which is great for storage sizes but no so much for data throughput and complexity. I threw that out in favour of standard readInt/Long's.
    Overall it didn't increase the size too much; the flat file is now 14.87MB instead of 14.1MB but it simplified the code and increased speed a lot.

    And the final changes were making sure that the data loaded goes through transformations as infrequent and as late as possible not only in the object storage but collision storage too, along with some general refactoring and adding a checksum file so that the flat file is always correct.


    Memory Usage
    Total sever usage after startup has completed

    Object Count Before After Memory Saved
    75k 454.68MB 438.01MB 3.6%
    3.5m 1.1GB 677.69MB 38.4%

    Loading speed
    Map loading only, average of 5 cold starts

    Object Count Before Array Init Loading After (Total) Performance Gain
    75k 398ms 30.6ms 139.8ms 170.4ms 57%
    3.5m 668.4ms 29.6ms 202.2ms 231.8ms 65.3%


    Attached image

    Which is really good, as you can see on the optimised version it barely peaks 500mb on startup before dropping to sub 400mb (700/500 with 3.5m objs). It's no longer a significant contributor to startup times and memory overhead although wasn't enough to breach below the 4s mark.
    I'll have to do something about my yaml files if I want that.
    Glad to see you're still going.
    Quote Originally Posted by blakeman8192 View Post
    Keep trying. Quitting is the only true failure.
    Spoiler for skrrrrr:

    Attached image
    Reply With Quote  
     

  7. #86  
    Misthalin where it all began.
    Forzaiken's Avatar
    Join Date
    Dec 2019
    Posts
    60
    Thanks given
    1
    Thanks received
    17
    Rep Power
    12
    I have no idea what it all entails, but I have been watching this project with fascination for a long time. I hope that someday I can also start practicing with Java and everything related to it!
    Reply With Quote  
     

  8. Thankful user:


  9. #87  
    Registered Member
    Join Date
    Mar 2010
    Posts
    146
    Thanks given
    1
    Thanks received
    15
    Rep Power
    2
    Reply With Quote  
     

  10. Thankful user:


  11. #88  
    Renown Programmer
    Greg's Avatar
    Join Date
    Jun 2010
    Posts
    1,179
    Thanks given
    260
    Thanks received
    1,012
    Rep Power
    2003
    Yaml parser

    The majority of the games content data I store in yaml files and they've slowly been growing in size; currently 30 files at 3.2mb. Loading them all on start up was starting to become noticable; taking between 50-500ms per file.

    The second issue was Jackson doesn't support yaml anchors which are a very neat and useful feature which allow you to reuse data in multiple places.

    Code:
    duck_grey:
      &duck_grey
      id: 6113
      hitpoints: 30
      race: duck
      examine: "Waddle waddle waddle quack."
    duck_swim:
      <<: *duck_grey
      id: 46
      swim: true
      examine: "Quackers."
    & marks an item with a name, in this case: Map<String, Any>
    << is merge key which combines the two maps (while overriding ids, examines)
    * marks an alias which gets replaced with the anchor item when parsed

    SnakeYAML supports anchors but it's a bit slow so I was using a mix of both libraries

    So naturally I wrote my own yaml parser.

    It only supports a subset of the yaml specification but has all the important parts, more importantly it's fast. This is mainly because it doesn't have any reflection usage, the downside of which is converting values to objects you have to do with a manual bit of code in a configuration class. This is an acceptable tradeoff imo.

    A basic config which converts direction strings to enums during parsing:
    Code:
    val config = object : YamlReaderConfiguration() {
        override fun set(map: MutableMap<String, Any>, key: String, value: Any, indent: Int, parentMap: String?) {
            super.set(map, key, if (key == "direction") Direction.valueOf(value as String) else value, indent, parentMap)
        }
    }
    Read speed
    Average of 1k runs after 10 warmups loading all the config files before/after they used anchors

    Parser Without anchors With anchors Json**
    SnakeYAML 206ms 201ms 3404ms
    Jackson 109ms * 130ms
    Mine 14ms 13ms 84ms

    * Jackson doesn't support anchors
    ** YAML is a superset of JSON so I included the 58MB US gov electric vehicle population dataset too

    The write speed is probably as equally as fast but I haven't benchmarked it as it's not as important.

    7-8x faster than Jackson and over 14x faster than SnakeYAML


    Switching over decreased server load times from 4.2s down to 2.9s. and has knocked off an extra 11MB ram overhead which is a nice unexpected consequence, probably due to using more efficient maps.
    There's a few other places I can improve to get load times down to ~2s, not that it's really necessary but optimising stuff is fun


    A few other changes; refactored a bunch of stuff to make naming more consistent (and closer to jagex), added book interfaces for quests, and jerry has added stairs for the majority of f2p areas.

    Attached image
    Attached imageAttached image
    Reply With Quote  
     

  12. Thankful users:


  13. #89  
    Renown Programmer
    Greg's Avatar
    Join Date
    Jun 2010
    Posts
    1,179
    Thanks given
    260
    Thanks received
    1,012
    Rep Power
    2003
    Smithing, Hunt modes & Knights Sword

    I've been working on Hunt Modes as Mod Ash described on twitter, it's quite possibly the or one of the last engine features that was missing. It allows for mechnics like aggression, hunter, and even the ash sweeper in varrock whom I added.

    Attached image


    And then back to some content again; I've added smithing, smelting and superheat item spell along with bots and a number of bot bug fixes and improvements.

    Attached image

    While Jarry has added The Knight's Sword quest

    Attached image


    The content is adding up nicely and while there's still a number of skills left to do the only thing which really seems to be missing mechanics wise is bosses/combat scripts so I think that's what I'll focus on over the next few months
    Last edited by Greg; 08-09-2023 at 04:03 PM.
    Attached imageAttached image
    Reply With Quote  
     

  14. Thankful users:


  15. #90  
    Registered Member
    Tyluur's Avatar
    Join Date
    Jun 2010
    Age
    26
    Posts
    5,103
    Thanks given
    1,819
    Thanks received
    1,767
    Rep Power
    2438
    Looking good.
    Quote Originally Posted by blakeman8192 View Post
    Keep trying. Quitting is the only true failure.
    Spoiler for skrrrrr:

    Attached image
    Reply With Quote  
     

Page 9 of 12 FirstFirst ... 7891011 ... LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Replies: 33
    Last Post: 04-19-2008, 05:48 AM
  2. Replies: 8
    Last Post: 12-13-2007, 06:47 PM
  3. Rune-Void v2.0 No Hamachi
    By haz425 in forum RS2 Server
    Replies: 0
    Last Post: 11-11-2007, 05:28 PM
  4. adding a void for runecrafting
    By fabjan in forum Tutorials
    Replies: 6
    Last Post: 10-20-2007, 06:08 PM
  5. Message to Mods and Admins Void!
    By Pkitten in forum Tutorials
    Replies: 6
    Last Post: 08-14-2007, 10:31 PM
Tags for this Thread

View Tag Cloud

Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •