Jump to content


  • Content count

  • Joined

  • Last visited

  • Days Won


Posts posted by twostars

  1. Knight Online has a lot of quests. Like, a lot. Hundreds, if not thousands.
    In part, this is due to the fact most are doubled up per-nation, but still -- for a game that's praised for its PvP, it has a lot of quests.

    Since their Reign of the Fire Drake expansion, their quest system was changed up considerably. All of their quests are now referenced in the client and a lot of the boilerplate logic has been wrapped up (it's still a horrible system though, but it's an improvement over the original).

    When we got to the point with the server's development where we seriously started considering releasing a server, one of the first things that came to mind was how many quests there were, and how much of a daunting task that would be to implement them. Honestly, at this point I was desperate to find some way of not having to deal with writing these up manually -- because it was a colossal task, which would be prone to introducing bugs.

    We realised that with the information provided, we could use this to automatically generate ~95% of quests automatically. There are outliers (for example, chain quests), but 95% of the hundreds of quests that exist is still huge.

    So Aesteris mocked up the initial implementation of our quest script generator, to give us an idea of how we were approaching it. We ended up rewriting it after that, but now it generates every quest it can (and we fill in the rest), e.g. this simple quest (this one doesn't have class-specific logic; the generated output can get more complex than this):

    -- Quest: Hasten potion
    -- Speed potion vial is awarded for 2 Apples of Moradon.
    function Event314_NotStarted()
    	pUser:SelectMsg(4, 82, 315, 22, 315, 23, -1)
    function Event315_Start()
    	pUser:SaveEvent(82, 1)
    function Event319_PendingReward()
    	if pUser:CanRunQuestExchange(29) then
    		pUser:SelectMsg(5, 82, 315, 10, 317, 27, -1)
    		pUser:SelectMsg(2, 82, 315, 10, -1)
    function Event317_Complete()
    	if byEventStatus == 1 then
    		pUser:SaveEvent(82, 3)
    	elseif byEventStatus == 3 then
    		if pUser:CheckExistEvent(82, 2) then
    		if pUser:RunQuestExchange(29, bySelectedReward) then
    			pUser:SaveEvent(82, 2)
    			pUser:SelectMsg(3, -1, 11, 10, -1)

    Officially there are occasionally some quests which have extra filler text which this can't support (because it knows nothing about these extra steps), but they're often fluff and don't offer anything of importance. Most players probably even skip these, so they're never really a huge priority to support.

    And that's our script generator. The thing that makes our quests possible (because I was never going to write those manually; you can't make me do it. Nope.).

  2. The client we're currently using for ApexKO is the official 2.1xx client with many, many custom improvements patched in.

    Our update process

    Keeping things up-to-date with official seems daunting, but our process works fairly well.

    First, Aesteris unpacks the official client executable. Then we run it through our patcher (see below for more info), and - provided there's no major changes we need to update the patcher for - it patches it up in seconds.

    Then we need to ensure there's no breaking changes with the server, so we hook it back up to our local server, and essentially go bug hunting (needless to say, this part sucks -- USKO needs actual changelogs  :().

    Regarding keeping the .TBLs (main client data) synced, we have a git repository setup to track changes to both our patches, and USKO's. We commit the TBLs in each patch which gives us a nice diff to compare changes.
    This means that we can then use git to merge them, which - although we still have to go over conflicts (with stuff we've added) - saves so much time.

    Barring anything new that needed to be implemented as a result of this patch, that's it -- we're done.

    Our patcher

    From the very start we realised it would be a pain to have to manually patch every single one of our patches in our growing patch collection every time USKO updated their client. So for this reason, we wrote a patcher to 1. find and 2. patch in our patches generically.

    This has definitely paid off, as it has for sure saved us an extraordinary amount of time; it could take us a few days to manually apply all of our patches for a single patch. With the patcher, this happens in mere seconds. Every so often we do need to update our patcher to support new clients, because they change things in major unexpected ways (like the code the patch was fixing was entirely changed, be it because of the compiler or simply because they changed the logic of the method), but even so, this still saves us a ton of time.

    Our patches

    Right now we have 50 odd base patch "groupings" and a considerable amount of patches (and their respective finders) in each of these groups.

    We have patches for all sorts; like increasing limits, fixing broken or inconsistent behaviour (e.g. fixing UI behaviour, the blinding effect, broken premium checks, party list / targeting behaviour, etc, etc, etc), implementing new behaviour (e.g. antialiasing support, saving & loading the party UI's position, logic to allow the client to handle the removal expiration of items correctly, or allowing for our kick behaviour in event parties).

    There's a ton in there; all-in-all, our patches are ~8,000 lines of code. I'm very glad we don't need to patch these manually.

    Patching these things manually is always a tedious task. It essentially involves getting inside mgame's head and figuring out how they'd have implemented it, with the assistance of the leaked client source (~1.06x). From there, using a debugger or disassembler to track down where this particular logic is implemented (which can take hours for more fiddly things), and then reversing how their logic works.

    With an understanding of how the logic is implemented and why the issue exists, we can start to develop a patch for solving it.

    Once the initial patch is written up, we test it until it's working as-intended (without any side-effects), and then write up finders for where the patch needs to go and anything it needs to reference. Finally, we can then rewrite the patch for the patcher, re-patch the client and re-test to be sure the patch is still correct.

    And that's about it...

    There's not a whole lot to say about the client, really. Beyond the custom patches, the client is more or less official -- for now. ^_^

  3. Unlike other servers, we've put a lot of work into our server -- several years worth, in fact. Actually, I can safely say that we're the reason that most people are even using source code to develop servers now, rather than messing with the official binaries.

    This is why I'd like to go into some detail about our server, since it's not something that's usually talked about outside of bug reports and such.

    A brief history

    Our server was initially created as a result of our attempts to push open source development in the Knight Online community, in 2012~2013.

    The project's intent was to update the official C++ source files (for ~1.06x) to a usable state for community learning purposes.

    Although the project ultimately went closed source due to lack of community attention, in the years since then we've made leaps and bounds with the project, rewriting most systems from the ground up to behave in a more logical and optimised fashion, doing our best to respect both DRY (Don't Repeat Yourself) and KISS (Keep It Simple, Stupid) principles, as well as updating to support the latest version of Knight Online (2.1xx at the time of writing).

    It has been a monumental undertaking, but in doing so, we've learned a lot about how the official server works (and even more about how it doesn't), and have always striven to improve upon it (as well as our own implementation).


    While we do deviate in some regards (with good intentions), accuracy is very important to us.

    We have spent a great deal of time reversing official server and client binaries, as well as testing behaviour on official and scouring through its packet logs.

    As-is, we're confident that in most respects that have any importance (e.g. damage calculations, rates, etc.) our implementations behave the same as (or very, very close to) official's.

    Cheat detection

    While official and 99% of private servers rely on client checks to detect cheating, we do not believe in playing this easily-bypassable game of cat and mouse. As such, our server is very proactive in its detection of cheat methods to lock them down permanently, i.e. with no means of bypass.

    From ensuring we deal with client input in a safe manner to things like verifying every step of the skill casting process, or enforcing tight server-side collision and movement speed checks, we always strive to ensure that players have no vector for abuse. Obviously this is always a work-in-progress and isn't perfect or complete (what is?), and we're introducing new logic to prevent more general cheating behaviour as it pops up, but we're proud of how far we've come - and that we've come so far compared to official (and other private servers) in this regard.


    Aesteris and I have both put years into developing this server (and I'm sure there's many more to come), and at this point I'm confident in saying our server performs - in most respects - better than official. On this note, we've found that many official bugs are caused by design flaws or simply their tendency to copy & paste their logic (and miss things).

    During implementation, we are always ever-present of performance concerns, be it in regards to how much time/resources a player request can consume (or anything in general), how costly a database hit will be, or even how much data is being (unnecessarily) sent to players -- performance matters to us, because it matters to players. A server falling under its own weight isn't worth playing.

    Zone instances are one interesting example of this. Officially and in 99% of private servers, "instances" are implemented such that when dealing with anyone in an instance, it still has to deal with all players in that zone (i.e. all instances of that zone). So instead of the 16 people we want to deal with in our Border Defense War instance, we deal with the 200 players across all of them.

    Here, we implement this system fairly logically: each instance is a self-contained unit attached to a zone. When dealing with players (or NPCs/monsters for that matter) in these instances, we only ever deal with the 16 actually in it.

    Similarly, officially we've noticed they tend to scan the entire server when looking for players to affect with skills nearby. As always, this extends to private servers as well, though most will have this (slightly) optimised from when this was open source. Here, of course, we only ever look for those actually near the player.

    This extends even to our database implementation. Beyond optimising the database design to avoid unnecessary or overly intensive lookups, we've also moved away from Microsoft SQL Server as - while it's a decent product - in several situations, it doesn't fit our performance needs (we also mostly moved away from Windows in general, which was another reason for dropping it).

    While not all are, many of our performance improvements are entirely noticeable by players. For example: unlike official or other private servers, there is close to no delay in logging in and selecting your character (the only delay is your own connection latency; officially and on other private servers, these backend requests take quite some time themselves). Additionally, we optimise our outgoing traffic to avoid congestion on the player side -- which saves you (and us) bandwidth, and means the client isn't bogged down as much processing the traffic.

    Events (and timing)

    Although fairly common with most of our systems, I feel that our event system (in no small part because of our timed event system) should be pointed out in particular as it is a colossal improvement over the way official implements events (as well as other private servers).

    Officially (and again, other private servers -- these go hand in hand), events are scheduled based on specific time checks. That is, if an event is scheduled at 01/02/2017 12:30PM, their game timer will check (every 6 seconds) if the current time matches. That is, it'll check if the day is 1, month is 2, year is 2017, hour is 12 and minutes are 30. Every 6 seconds.

    This means that issues with clock changes can easily upset it, not to mention issues with restarts not realising it has yet to run even though the time has passed (because it isn't exactly that time!).

    Here, we have a scheduler for timed events. Times scheduled in the past will run immediately, while times in the future will run once that time has passed. As always, we're ever-present of performance concerns, and scheduling in this manner can be very sensitive performance-wise, but in its present state our scheduling system performs wonderfully.

    Virtually everything timing-related in our server runs via this system in 1 of 2 ways (again, for performance reasons): in a "precise" mode, where we require a higher granularity (e.g. skill timings), or in a general mode for everything else that matters a lot less (e.g. event scheduling).

    From scheduling to running parts of the events, timing is very important with events.

    As I've mentioned previously, our implementations aim to behave logically. We also aim to keep features as self-contained as possible, unlike official, where you have random logic strewn about that exists that doesn't have an obvious use until you determine it's for, say, a specific case in an event.

    Obviously, when your codebase is littered with random things like this, it's very difficult to maintain, and very prone to bugs. We're all familiar with the bugginess of Knight Online; official servers, particularly. This is why.

    In contrast, we keep all of our event logic with the rest of that event's logic. And I don't mean just keeping it in the same source files.

    I mean, as a common example, if we need to handle the death of a player or monster in this event, we implement a specialized zone instance class for this event's instance, and override its OnDeath() event. Meaning, it's only ever handled in this event by design and no other logic needs to be aware of it.

    As previously said: we aim to implement things logically, in an attempt to keep things readily maintainable and avoid bugs.

    Custom behaviour

    While accuracy is important to us, so is an improved player experience.

    For starters, we're perfectly comfortable with taking features and reworking them into something that can be of use. For example: our in-game Class Transfer feature. This feature doesn't exist officially; it uses the official Nation Transfer feature to accomplish this, as the UI provides the ability to change their desired features -- which is the only time a player needs to make a decision (beyond their desired class, which we accomplish by prompting for that in the NPC -- easy!).

    Another example of this is taking their event system and reimplementing the Forgotten Temple and Juraid Mountain events to work with it, so players can now simply use the sign-up feature to access this event, rather than finding and talking to their respective NPCs. This means a much nicer user experience and increased participation to the events.

    And how about our clan banks? Their inn UI was easily repurposed for this custom feature that again, does not exist officially. ^_^

    And to finish this off...

    It's very easy to see this as "another server", but you need to realise that everything implemented in the game -- everything! -- has been written by us, at this point, from scratch. At the beginning of this project (which if memory serves was aiming to get it up and running with 1.8xx), we didn't have things like merchanting, we didn't have upgrades, let alone any type of event (even old events like Forgotten Temple or Bifrost). For a while I personally didn't really think we'd end up getting it anywhere, but continued to work on it in my spare time regardless.

    Now we have a fully-featured, highly optimised server implementing almost everything official has to offer.

    We've come a very, very long way in this time. We have more work to do (as always), but I hope this at least gives a small glimpse into what's actually involved behind-the-scenes in actual server development and why we're different to other servers. :)

  4. Changelog

    • Updated client to be on par with official 2.167.
      • Removed our wing visibility setting, as 2.153+ supports setting this option ingame. The options editor has been updated to use the official setting.
      • This also introduces:
        • HD texture support.
        • Tattoos (although these are for the moment, inaccessible ingame).
        • New configurable HUD for viewing your HP/MP/Stamina, etc. See last menu in the in-game options for tweaking or disabling that.
        • Several UIs have also been cleaned up (e.g. buying merchant UI).
        • And other such features available on USKO.
    • Added the new Castellan capes. These last for 30 days and can be purchased at no cost by the winners of Castle Siege War (with a special voucher they're awarded), or via both CONT and coins for everyone else. Note: subclans can choose to use these in place of their alliance's cape.
    • Added the Castellan dungeon. See this post for more information.
    • The King system has been entirely rewritten in an effort to clean things up so things work in a more straightforward and maintainable manner. This should fix our longstanding bugs with it (but also may introduce new ones, so please make sure to report any issues you come across!). This in particular should address issues with nominations/elections not running for one or the other nation, etc.
    • We have also implemented impeachment.
      • To use this, a senator (one of the top 10 clan leaders at the time the King was elected) will need to pay 30mil coins to initiate an impeachment request.
      • Once an impeachment request is active, the other senators need to vote to push the impeachment request.
      • If a majority vote is reached, everyone may then vote to impeach the King.
      • If the King is impeached, they - and all senators - will be removed from their positions. No new King will be elected in their place.
    • As with official, Kings will now receive 2 scepters -- not 1.
    • Rogues are again fully credited for drains.
    • Fixed some issues with alliance cape behaviour.
      • The clan forming the alliance should no longer lose their cape's colour when forming an alliance.
      • Accredited 5 or higher subclans should always use their own cape colour. Minor caveat: it'll attempt to use one even if they don't have one set (i.e. as soon as they become accredited), but they'll at least be able to reliably set this now.
    • Fixed an issue with players remaining on the Ronark Land rankings board after Nation Transferring (for real, this time).
    • The event signup UI's restoration icon is no longer hidden when a new event signup comes through.
      • Previously, when you closed the signup UI and another event came up, the icon for restoring the UI disappeared, while the UI itself didn't show up. This meant that you couldn't see when future events occurred until you restarted the game.
      • Now, since the icon is no longer removed, you can just click on the icon. This isn't perfectly ideal, because it doesn't necessarily mean you'll be aware of new events, but it's an improvement over previous behaviour (ideally we'd reset the signup UI so it always shows up regardless, but this is a lot more complicated to implement than it would appear).
      • Since there's still a possibility of missing out on knowing when the event's started, we now send announcements to inform you that the event's signup is active.
    • To better address the various d3d9.dll issues that have been reported in the past, we've changed how we extend the client's behaviour. We no longer use d3d9.dll for this, so it can be removed.
    • [Update] Fixed a bug plaguing us for a while related to friendly skill targeting. This should fix things like minor healing and any number of other skill fails caused by this.

  5. 15 minutes ago, Chayni said:

    well the royal clan loses its color atm (that was the issue)


    on usko it works like ->

    Royal clan ally's accredit clan 

    Royal clan has a base black cape with red color

    Accredit ally clan has the same long black cape but they take yellow as color


    they are not allowed to change colors while being in the ally, they gotta set the color right before they get added into ally

    So you're saying it's breaking for the clan forming the alliance (i.e. the alliance leader), not the subclan? If so, that's interesting, because in that case the colour should be the same regardless of which it uses -- the alliance's or their clan's. Huh.

    "they are not allowed to change colors while being in the ally, they gotta set the color right before they get added into ally"
    They could change colours, but it wasn't being used. This part's fixed now (assuming you're talking about the subclan).

    If you're saying it's official behaviour that they're not allowed to, well... whatever. I think it's fine we let them.

    Okay, I see what you mean; this is a similar but different issue. I've fixed this now. Thanks.

  6. See, this is intended behaviour -- apart from allowing you to colour your cape while in an alliance.

    It's designed to override your cape with your alliance's cape.
    In the next patch it will no longer let you attempt to colour your cape, to make it consistent with actually changing your cape.

    Whether or not this behaviour is the same as official, I'm not sure though.


    Okay, after looking into it, this isn't exactly intended. What's meant to happen is you can use your own colouring when you're accredited.
    So I've reverted that patch, meaning you can - again - recolour your capes when you're accredited. But now it should actually use it.

    Right now we don't have any reliable means of determining if the colour was actually set, which I think was where the hiccup was before, so it'll just immediately just switch over after you're promoted to accredited regardless. You'll have to set it. I may change this in a future update, but for now it should behave more accurately.

  7. Okay, after looking into it, this isn't exactly intended and I've tweaked this slightly. What's meant to happen is you can use your own colouring when you're accredited (which we somewhat allowed for).

    Right now we don't have any reliable means of determining if the colour was actually set, which I think was where the hiccup was before, so it'll immediately just switch over after you're promoted to accredited regardless. You'll have to set it. I may change this in a future update, but for now it should behave more accurately (in the next patch).

  8. This has been somewhat fixed in the next patch.

    The problem as-is, is the minimised icon will disappear as it thinks it's trying to open the UI. But that part of it doesn't work because there's multiple UIs for it, and it doesn't implement the correct logic for it.

    Ideally I'd correct this so that it works as intended (it "restores" the UI so you see the new event prompting for you to signup), but for now the best I can do is stop it from hiding the icon. Because when it's minimised... and you lose the icon to restore it, it's not recoverable until you relog.

    So it'll stay minimised until you restore it yourself. As opposed to breaking completely.

    Additionally I'll probably add in notices announcing events are in the signup phase so you can know that they're actually up and you should restore it. 

    Not ideal, but an improvement. :)

  9. Hey guys,

    As you may have noticed, we haven't had any player patches in a couple of weeks (though we have fixed a few things here and there on the server's side). The reason for this is that we've been working on considerably more time-consuming projects than usual.

    Updating the client

    Specifically, one such project is updating the client to be on par with the official USKO client. We've fallen behind a bit with the official USKO client; it's 2.167 now, while we're still at 2.128. The newer USKO client implements things like the new capes, better texture rendering (i.e. "HD textures"), the in-game ability to toggle wings off/on (rendering our own feature useless, but oh well :P), the addition of an inventory slot for tattoos, the addition of a HUD for displaying HP/mana/stamina, and much, much more.

    For a while we'd been keeping on top of updating the same week as USKO, however they updated their protection somewhat (months back) which caused our mostly-automated updated process to have to be updated as well. We'd spent a considerable amount of time (off and on) since then trying to track down what was still causing the new client to very subtly crash after a random period of time (which was usually 15min+), which -- as we've finally determined for sure -- was still parts of their protection, which we can confidently say has all been disabled now (we can't make use of their protection with our own, after all).

    So our patcher was updated, meaning we can deal with newer clients again in a much faster fashion. Which leaves dealing with all of the actual changes in ~40 official version updates (it's going to be a decent-sized client patch!).

    Firstly, the most noticeably breaking change was the addition of the new inventory slot. As this inventory slot is smack-bang in the middle of the inventory, we needed to implement a versioning system for inventories in order to transform and update them. We also needed to figure out what and where this slot is actually used; as far as we can tell, these aren't visible so other players never see them. We, of course, do though. This is contrary to any other cospre slot's behaviour, but what can you do. :P

    Secondly, Castellan capes! This behaviour is kind've odd in the sense that they documented it on their forums, yet everything else indicates their forum post is wrong (in parts). So it's unfortunate that as usual there's no consistent source for accuracy, but realistically it doesn't change too much.

    If you weren't aware, these capes are available -- for free -- by Delos holders (with a token they're given). For us mere mortals, they cost a considerable amount of both CONT and coins. They also last 30 days.

    Having an expiry time is where the logic gets interesting, because of two things: alliance capes (i.e. when to use them and when to not), and dealing with what happens after the cape expires (does your old cape get restored?).

    The way I implemented them has Castellan capes always override alliance capes. Further, after the 30 days is up, your old cape will be restored -- be it your own cape, or your alliance's. This may not be official, but I think it makes sense and isn't that huge a deal either way.

    Additionally, we've made some changes to how the client accesses the Power-Up Store. We're aware that some players tend to have random connectivity issues we can't do much about, so hopefully this should no longer be an issue (or at least, when it is an issue, it's something we can do something about).

    Finally, the new client still requires going through and tracking down anything actually broken because of unknown changes. We're still in the process of doing this, so it won't be released until this is done -- but we're close.

    Castellan dungeon

    We've also been working on implementing the Castellan dungeon. That is, the dungeon Delos holders can access via the old Abyss entry.
    This has taken some time to address because of accuracy concerns; it's been difficult to get into it on USKO.

    We intend to get this out with the next patch. More details will be provided when (or slightly before) that's released.

    Rewriting the King system

    Ah, the King system. The source of many complaints since the beginning of ApexKO.

    The underlying problem with this system was that when I initially implemented it... back in 2013, I think, I decided (in my infinite wisdom) to keep its logic as close to 1:1 with mgame's original logic, i.e. trying to reverse it and handle it perfectly identically with the same database and internal structures, etc.

    The issue with this, however, is that it's extremely vague and handles things in awkward ways. Even the scheduling/timing logic -- as much as it fits with their original system -- doesn't really mesh with ours. Unlike official, we have an actual timed event/scheduling system we use for our events (rather than asking every ~6 seconds, is it the day, hour and minute for this event? and have I started it already -- because it'll run multiple times in the span of that minute?). I'm still not sure what prompted me to implement it like this way back then, when pretty much everything else was implemented how I felt would be best.

    I'm sure that with time the individual issues with the system could've been addressed individually (we fixed many of them already), but honestly, the system was a confusing mess, so it frankly doesn't surprise me that it randomly broke all the time.

    So it's been long overdue for a rewrite (as much as the original system design's ingrained into my brain; was difficult to move away from it). I actually just mostly finished that up last night, though I want to start looking into implementing impeachment logic (has anyone ever actually seen it used? That's fairly impressive if so), as I happened to reverse most of the process while reimplementing elections (unlike last time, where I just ignored it because I considered it a feature that nobody ever used).

    Minor caveat with this though: we no longer update clan rankings before elections, so it's back to using the top 10 clans from the start of the day. The reason we had it do this was to ensure the top 10 clans were still valid, but between ensuring all clans are ranked now (not just top 100), and tweaking the top 10 clan logic to specifically handle the first 10 that are applicable, rather than the first 10, we really don't need this anymore. All it did was slow down the scheduling (waiting on the clan rankings to update), and cause clan rankings to update at weird times. So it's really not needed anymore.

    From my own personal testing it's looking pretty good, so we just need to test this more thoroughly before we can implement this live. And hopefully never have to deal with elections randomly not happening anymore.

    Future goals

    We have several future goals and projects we're working on in the interests of ApexKO.

    One of them is the website. The website is not in a great place right now from an aesthetic standpoint, which doesn't give the best of impressions to newcomers. Its tool functionality is also lacking. We're very much in need of a web designer and/or developer to assist with this (if you think you can help, or know someone who can, please feel free to hit me up!).

    While I'm capable of handling the backend side of things, the frontend/aesthetic side is not really my forté (as you can probably tell).

    I've actually set about updating this twice since; I really should just update our live website to the first. The first set about improving our design choices with the existing template and updating user functionality. The second was with a new template we purchased, however we had to scrap that since midway through development another server released using that template -- ouch.

    Then there's Under the Castle (UTC). Yes, we plan to implement this, but we don't have an ETA for it. What I can say though, is that it's next on our plate after releasing the new client and the Castellan dungeon.

    Another is a project I've been spending quite a lot of time on recently, which is updating the client source. How does this help ApexKO, though?
    Well, for now it doesn't, since the client source was 1.068 and is being updated for 1.298 (as it's less of a gap than jumping straight to, say, 2.1xx). However, in the long run, once it's updated sufficiently, we'll be able to use this instead of relying on USKO for updates and having to awkwardly patch their issues manually (or not at all, because at some point they're not worth the development effort required).

    We also won't be limited by their client's feature-set: we can improve on it. Add new UIs. Change behaviour, provide proper error messages, fix long-standing bugs with the Knight Online client, etc. Additionally, by being able to change systems to work in a more convenient manner, it will enable us to implement even better anticheat prevention than we have currently.

    I'd originally attempted this back in 2014 and 2015, but the project is very time consuming, especially solo. At the time we also had a ton of work to do with the server project, so it wasn't a good time for it.

    With renewed interest in client development via the OpenKO project, and the server being in a very good place right now, I decided to pick this project up again with a few people from this project so as to actually make some progress with it. And we have: we've implemented some of the major systems; the anvil (upgrading items, and compounding accessories), the merchant system, etc. Also things like loot boxes which weren't a thing in the original 1.068 client.

    We have a lot to do with it still (doesn't support transformations, siege weapons, King system, etc -- even the newer character selection screen from 1.298+), but it's definitely making progress. So I hope to be able to use this for ApexKO eventually. ^_^

    In closing...

    With that I should conclude this lengthy status update post. As you can see, we have a lot on our plate we're trying to finish up. Last week I did say we'd probably get this patch out today. However, for testing reasons we need a few more days on that front.

    But it'll be soon, I promise. :)

  10. I think this tends to happen when the Cloudflare server that's closest to you has issues, hence why it only happens to you -- for a time -- and not others.

    We'll be changing this in next week's patch so it hopefully shouldn't be an issue in future, but for now all I can say is it should fix itself soon. For right now, I can't do much more than that unfortunately.

  11. Trainee Soldier
    Defeat 100 Enemy User

    Attack: +10

    Defeat 500 Enemy User

    Attack: +10
    Defense: +20

    Defeat 1,000 Enemy User

    Attack: +13
    Defense: +1

    Defeat 5,000 Enemy User

    Attack: +26

    God of War
    Defeat 10,000 Enemy User

    Dagger resist: +1
    Jamadar resist: +1
    Sword resist: +1

    Over God
    Defeat 20,000 Enemy User

    Defense: +10
    Dagger resist: +1
    Sword resist: +1
    Mace resist: +1
    Axe resist: +1

    Defeat 30,000 Enemy User

    STR: +1
    HP: +2
    DEX: +1
    INT: +1
    MP: +1
    Attack: +13

    Can't Lose
    Succeed in Revenge x 100

    Attack: +20

    Succeed in Revenge x 500

    Defense: +70

    Succeed in Revenge x 1,000

    Attack: +20
    Defense: +40

    Win 100 times against another user at Moradon Duel

    HP: +4
    Attack: +4

    Win 1,000 times against another user at Moradon Duel

    STR: +1
    HP: +3
    DEX: +1
    INT: +1
    MP: +1

    Arena Legend
    Win 10,000 times against another user at Moradon Duel

    STR: +9

    Ardream Veteran
    Defeat 100 Enemy Nation User at Ardream

    Glacier damage: +6

    Ardream's Revenger
    Succeed 100 times of Revenge in Ardream

    STR: +6

    Military Base Veteran
    Defeat Enemy Nation User 100 times in Ronarkland

    HP: +6

    Military Base Revenger
    Succeed 100 times of Revenge in Ronarkland

    DEX: +6

    Ronarkland Soldier
    Defeat Enemy Nation User 100 times in Ronarkland

    HP: +2
    Attack: +5
    Defense: +5

    Ronarkland Warrior
    Defeat Enemy Nation User 500 times in Ronarkland

    HP: +1
    DEX: +5

    Ronarkland Veteran
    Defeat Enemy Nation User 1,000 times in Ronarkland

    Attack: +20
    Defense: +10

    Ronarkland Legend
    Defeat Enemy Nation User 10,000 times in Ronarkland

    Attack: +33

    Ronarkland Revenger
    Succeed in Revenge 100 times in Ronarkland

    MP: +10

    Lunar War Soldier
    Defeat Nation User 100 times in Lunar War

    STR: +4
    HP: +1

    Lunar War Warrior
    Defeat Nation User 500 times in Lunar War

    STR: +5
    HP: +1

    Lunar War Veteran
    Defeat Nation User 1,000 times in Lunar War

    Attack: +15
    Defense: +15
    XP: +1%

    Lunar War Legend
    Defeat Nation User 10,000 times in Lunar War

    INT: +20

    Lunar War Revenger
    Succeed in Revenge 100 times in Lunar War

    DEX: +10

    Win 100 times in Lunar War

    HP: +9

    Win 100 times in Nation Guard Battle

    Defense: +90

    The Best
    Win First Place 10 times in Chaos War

    INT: +2
    MP: +4

    Most Popular
    Win First Palce 100 times in Chaos War

    STR: +5
    HP: +4

    2nd Best
    Win Second Place 10 times in Chaos War

    MP: +7

    3rd Best
    Win Third Place 10 times in Chaos War

    HP: +2
    DEX: +3

    Commander of Chaos
    30 or more kills in Chaos War

    Dagger resist: +1
    Jamadar resist: +1

    Gone Mad
    40 or more kills in Chaos War

    INT: +14

    For better or worse
    50 or more kills in Chaos War

    Attack: +13
    NP: +1

    King of Evil Spirit
    Win 100 times at Juraid War

    HP: +5
    INT: +10

    Crown Prince
    Cumulative Win x 10 at Castle Siege

    NP: +1
    XP: +1%

    Cumulative Win x 50 at Castle Siege

    Attack: +20
    NP: +2

    Cumulative Win x 100 at Castle Siege

    NP: +2

    At Lunar War, defeat #1, #2 Chief Guards

    Flame damage: +1
    Glacier damage: +3
    Lightning damage: +1

    Defeated Enemy General
    Defeat Chief Gate Keeper at Lunar War

    Flame damage: +1
    Glacier damage: +1
    Lightning damage: +3

    Darkness Shadow
    Complete Assassin Expert I and II

    HP: +4
    DEX: +6

    Complete Bulk of Silk

    Defense: +5

    Novice Hunter
    Defeat 100 Ronarkland Monster

    Attack: +3

    Defeat 1,000 Ronarkland Monster

    HP: +2

    Novice Archer
    Defeat 5,000 Ronarkland Monster

    Attack: +5
    Defense: +5
    XP: +1%

    Defeat 10,000 Ronarkland Monster

    MP: +6
    XP: +2%

    Beast Master
    Defeat 30,000 Ronarkland Monster

    Glacier damage: +8

    Previous Life
    Do not get killed and defeat 100 monsters

    Attack: +2
    Defense: +4

    Do not get killed and defeat 1,000 monsters

    INT: +4

    Do not get killed and defeat 10,000 monsters

    Defense: +40

    Four Phases of Life
    Do not get killed and defeat 100,000 monsters

    Attack: +10
    XP: +3%

    Do not get killed and defeat 1,000,000 monsters

    Attack: +25
    Defense: +5

    Defeat 1 Worm in Moradon

    HP: +1

    Street Smart
    Defeat [Chief] Hideous, [Chief] Bandiking in Moradon

    Complete Wings in the Fog 1, and 2 in Moradon

    MP: +3

    Defeat 100 Gliptodont

    STR: +1
    HP: +1

    Wolf Hunter
    Defeat 100 Dire Wolf, Shadow Seeker, Loup-garou, Lycan

    HP: +1
    DEX: +1

    Deadly Poisonus
    Defeat Pincer or Paralyzer or Scorpion

    DEX: +2

    Undead Hunter
    Defeat Rotten Eyes and Undying

    MP: +2

    All Resource Guardian
    Defeat 100 Shadow Cracks

    (Castle) Defeat 200 Gaf or Troll

    (Castle) Abandoned Bones I & II

    DEX: +3

    Goblin's Enemy
    (Castle) Complete Goblin Family I & II

    INT: +6
    MP: +2

    Awesome Expert
    (Castle) Defeat Aif x 2000

    STR: +1
    HP: +1
    DEX: +1
    INT: +2
    MP: +1

    (Castle) Complete Extreme Pain, Flaming Heart

    Flame damage: +4

    Skull King
    (Castle) Defeat 200 Dragon Tooth Commander, 200 Dragon Tooth Skeleton

    HP: +5

    Orc's Enemy
    (Castle) Complete Orc Slayer I & II

    STR: +3

    Defeat 100 Storming Spostle in Eslant

    Lightning damage: +2

    Defeat 100 Balog in Eslant

    Defeat 100 Apostle of Flames in Eslant

    Flame damage: +2

    Defeat 200 Titan or Dark Stone in Eslant

    Defense: +20

    Defeat 100 Apostle of Piercing Cold in Eslant

    Glacier damage: +2

    Blue Skin
    Defeat 100 each for Forwird or Forwird Warrior; Forwird Knight or Captain in Ronark Land Base

    Attack: +3
    Defense: +1

    Defeat 1000 Phantom in Desperation Abyss

    STR: +1
    XP: +1%

    Complete Server of the Queen, For Knights in Hell Abyss

    STR: +2
    HP: +2

    Hate Spider
    Defeat 1000 Taratula in Delos Basement

    DEX: +1
    XP: +1%

    Complete Testing the King and Nightmare of Spiderman in Delos Basement

    HP: +1
    DEX: +3

    Complete Draki's Trace and Tracks in Ronarkland

    INT: +10

    Complete Guardian of the Guardian Tower I and II in Ronarkland

    STR: +4

    Complete Ronarkland Elder I and II in Ronarkland

    HP: +3
    INT: +4

    Task Expert
    Complete Work Procedure I and II in Ronarkland

    HP: +4
    INT: +2

    Dragon Slayer
    Defeat 100 Red Dragon in Ronarkland

    Flame damage: +9

    Most Speedy
    Destroy Chaos Stone 100 Times in Ronarkland

    Attack: +10
    Defense: +60

    Like a Dog
    Defeat 1000 Goloras in Ronarkland

    Flame damage: +5

    Orc Slayer
    Complete In Between the Arrow and Magic and In Between Two Swords in Ronarkland

    Sword resist: +2
    Bow resist: +1

    Not a Sinner
    Complete 4 Sins and 3 Sins in Ronarkland

    Flame resist: +2
    Glacier resist: +1
    Lightning resist: +2
    Magic resist: +1
    Curse resist: +2
    Poison resist: +2

    Chaos Domination
    Complete Monster born in Chaos I and II in Ronarkland

    Flame damage: +2
    Glacier damage: +3
    Lightning damage: +3

    Defeat Red Dragon and Dark Dragon

    HP: +2
    Jamadar resist: +1

    Juraid Knight
    Complete Juraid Monster III and Seed of Evil in Jurad

    Lightning damage: +6

    Defeat Krowaz in Krowaz's Dominion

    Flame resist: +8

    Defeat 100 Minotaur in Krowaz's Dominion

    MP: +1
    XP: +1%

    Treasure Hunter
    Defeat 10 Treasure Boxes in Krowaz's Dominion

    DEX: +4

    Castle Destroyer
    Do not get killed and defeat Mammoth the 3rd to Crashergimmic

    Lightning damage: +7

    Do not get killed and defeat Purious

    DEX: +7
    NP: +1

    Saved from the Flame
    Do not get killed and defeat Mammoth the 3rd to Pluwitoon

    HP: +7
    NP: +1

    Fire Destroyer
    Do not get killed and defeat Mammoth the 3rd and [Destroyer of Flame] Pluwitoon

    STR: +7
    NP: +1

    Castle King
    Complete Immortal of Under the Castle I and II

    HP: +3
    NP: +1

    ¡Ú KNIGHT 11TH ¡Ú
    Complete 11th Anniversary Quest of Julian

    STR: +1
    DEX: +1
    INT: +2
    MP: +1

    2013 Thanksgiving
    Deliver 50 Moon pieces to Magipie Mother for the year 2013.

    HP: +4

    13Th Snow Knight
    13Th Snow Knight

    HP: +3
    Glacier damage: +2
    Glacier resist: +2

    Relic Protector
    Relic Protector

    XP: +5%

    Juraid Protector
    Win 150 times at Juraid War

    Defense: +100

  12. Changelog

    • Fixed a bug causing rankings on the Ronark Land board to persist after a Nation Transfer.
    • Undying now drops [Gold Coins] in Ronark Land.
    • Raised the cost of [Unidentified Potions] from their quest-givers to 10M, and added a [Silver Bar] as reward to compensate the cost.
    • Updated the login screen to match current USKO.
    • Fixed [Opal Earrings] not being shown in the buying merchant search.
    • Added the various [Apex Point vouchers] to the buying merchant search.
    • To avoid cheesing the Kill the GM event, GMs are now immune to most Krowaz curses.

  13. Changelog

    • Multiple vote kicks can now take place in events concurrently. This fixes an issue whereby players would preemptively vote-kick another to avoid them from being vote-kicked themselves.
    • Ultima now also spawns in Ronark Land twice a day. Players will have 30 minutes to kill it, otherwise it will leave.
    • Added more ways to farm [Blessed Upgrade Scrolls] in Ronark Land:
      • Beasts now drop them at the same rate as Blood Seekers.
      • Hob Goblins now drop them.
      • Apostles of Piercing Cold and Dragon Tooth Commanders now have increased BUS drop rates.
    • Adjusted Hepa's weapon drops in Ronark Land:
      • Balrogs now also have a chance of dropping Hepa's Raptor (+8).
      • Booros now also have a chance of dropping Hepa's Shard (+8).
      • Doom Soldiers now also have a chance of dropping Hepa's Iron Bow (+8).
    • Added armour drops to Ronark Land:
      • Titans now drop Dragon Scale and Trial armours.
      • Falcons now drop Mythril armours.
    • Fixed a visual bug with [Wings of Hellfire Dragon Exchange Voucher]: the name now correctly reads 30 days, not 15. Note that it always gave 30 days regardless.