-
Posts
57 -
Joined
-
Last visited
-
Days Won
11
Content Type
Profiles
Forums
Events
Everything posted by Inveteratus
-
So, the rebalancing went through almost as expected. There were a couple of minor hiccups that I hadn't anticipated and, in all honesty, I'm still trying to work out exactly how they happened. Thankfully, neither is damaging to the game. One was a very easy fix; the other... well, I think I'm just going to leave it as-is. It affects a fair few players, certainly, but it's not really a major concern. The rebalancing was potentially a risky one. If you look back at the original MCCodes codebase, there are quite a few design errors that, often through inexperience on the part of owners and admins, have been propagated into many games that are still being played today. Some of those problems were sadly the result of the original developers not fully considering the long-term ramifications of what they were writing. But while blaming them might be easy, it's probably not particularly useful either. They built something that lasted, after all. For a game to really work, a surprising amount of time and investment has to go into it. Code, data, user interface, graphics, setting and story all play crucial roles. They're often the difference between a game that's merely playable and earns a few quid, and one that's actually enjoyable — a game with challenges that keep players engaged and enough depth to give it some longevity. I've only solved a few of those points! The legacy game I took over now has a much better codebase and a far more sensible dataset. The challenges, though... I'm still working on those. Getting the right staff is oddly one of the problems. The current staff are good, but there are probably areas where we're still lacking. The story is almost non-existent, which is something that really needs addressing, and many of the challenges within the game are still relatively minor. Oddly enough, during this whole process I started creating another game — but this time I approached it completely differently. I started with the story, the setting, the graphics and the challenges. The code then fell into place remarkably easily, and the data followed naturally afterwards. It's not released yet, but building it this way has made me wonder whether some of its ideas could be pushed back into the old legacy game. More cooperative play, for example, is something I'd really like to experiment with. I often wonder where this game will eventually go. It earns a small income each month — certainly enough to cover the hosting costs, licence fees, AI subscriptions and the other bits and pieces needed to keep it running. It might even pay the mortgage in due course! But I increasingly find myself asking a different question: Where do I actually want it to go? It has taken an enormous amount of time and effort over the last nine months, and I'm not entirely sure my heart is still in it in quite the same way. What I really need is a few good people who can help run it. People with the vision to generate ideas, keep the players engaged, challenge my decisions and tell me when and where I've got something wrong. But then... if the game is producing a passable income, why not simply accept it for what it is? Maybe this is the point many developers eventually reach. Do we continue developing something that has gradually become more labour and less love? Or do we decide we've taken it as far as we want to and sell it onwards to somebody with fresh enthusiasm? I genuinely don't know how to answer that yet. One thing I do know is that running a game like this will always be an ongoing process. If, as a developer, you neglect the game and simply spend the income, eventually the players will notice. They'll become frustrated, they'll start leaving, and the game will slowly decline. If you're prepared to keep putting that extra effort in, though, perhaps you'll be one of the lucky ones who ends up with a game that survives the test of time. Me? I think I'll take the occasional holiday, keep tinkering with things, and keep the game running for as long as both the players and I still have some interest in it. Hosting is cheap. Licences aren't too painful. The subscriptions... well, hopefully there won't be quite so much need for those in due course. So that leaves just one question: What shall we do next?!
-
I was recently asked to help out with an old MCCodes game that had been running for a good ten years or so. I was quite happy to take it on; it had been a long time since I'd played around with that particular codebase, and I thought it might make a pleasant change to see what had been done with it over the years, particularly after passing through the hands of several different developers. Oh dear. There were problems. Lots of problems. Nothing insurmountable, fortunately, but it quickly became apparent that this wasn't going to be a case of fixing a few bugs and tidying up some CSS. The game was still largely running on the old procedural MCCodes architecture, with pretty much everything sitting in the public directory. Business logic, database queries and presentation were thoroughly intertwined. The first job, therefore, wasn't really to fix anything at all—it was to understand exactly what was there and work out how to drag it into something resembling a modern application without breaking a game people were actively playing. After analysing the codebase, I decided to target the Slim framework. It's small, straightforward to learn, uses PSR request/response interfaces and provides proper middleware support. No, it's certainly not Laravel. There are no bells and whistles and the batteries are most definitely not included. As it turned out, that was actually a good thing. It took a couple of months and a few false starts before I was completely convinced, but eventually it became clear that this was the right approach. Then began the long process of converting the original procedural files into a Controller / Repository / Template structure. That relatively simple architectural change made an enormous difference. Database access was moved into repository classes. Application logic moved into controllers. Presentation moved into templates. Suddenly the different parts of the application had clearly defined responsibilities, and changing the appearance of the game no longer meant risking damage to the underlying game logic. AI helped speed up some of that process considerably, although a surprising amount was still ported by hand. I wanted to retain control over the architecture and, more importantly, make sure the project was moving in the direction I wanted rather than simply translating old code into newer-looking old code. Somewhere along the way, things took another unexpected turn: I ended up buying the game. Being a co-developer is fine. Owning the project yourself is considerably better. That gave me much greater freedom to address some of the deeper problems rather than continually working around them. One of the first major additions was a completely new logging system. Rather than recording only obvious events, it tracks virtually every significant action performed by players. That has proved invaluable for finding those awkward last-minute bugs where somebody reports that "something strange happened" but can't quite remember what they did beforehand. Alongside that came a much more capable multi-account detection system, and that has produced some particularly interesting results. It can identify obvious same-IP transfers, but also patterns involving feeder accounts, indirect transfers through several players, suspicious account relationships and activity hidden behind VPNs. Combining that information with general player activity has made it possible to identify bots, multis, feeders and outright cheating—as well as cases where players weren't necessarily cheating at all, but had discovered and exploited flaws in the game's own logic. And there were plenty of those flaws to discover. The final major addition to the development process was something the original game had never possessed: a comprehensive automated test suite. Code coverage went from effectively zero to approximately 98.5%. That has completely changed the way the game can be developed. Changes that previously required a great deal of manual testing can now be made with considerably more confidence. The tests don't prove that bugs are impossible, of course, but they provide an extremely effective safety net and quickly highlight when a change in one part of the game has unexpectedly affected another. Static analysis also proved invaluable during the early stages. I believe I eventually cleared more than 5,000 warnings, errors and questionable pieces of code from the original codebase. Static analysis is excellent at finding structural problems, dubious assumptions and outright programming mistakes; unit and feature tests then provide confidence that the behaviour of the application remains correct as it continues to evolve. And that brings me to perhaps the biggest problem of all. Ten years is a long time for an online game. Over those years, a considerable number of mistakes had accumulated. Some came from MCCodes itself, whose underlying design is badly flawed in the way it handles several important aspects of the game economy and player progression. Others came from developers with limited experience blindly copying existing ideas or implementing player requests without considering the long-term consequences. Some of those mistakes were relatively harmless. Others allowed enormous and completely unintended gains in experience, skills and money. The result is a game population with a very unusual distribution. The majority of players occupy the lower end of the progression curve, while a relatively small number sit right at the extreme upper limit—sometimes effectively clamped against values that were never sensibly designed to be reached. Simply resetting those players isn't reasonable. Leaving everything untouched isn't particularly viable either. So the next major job is rebalancing the game's statistics and progression system. This is considerably more complicated than merely dividing everyone's stats by ten. There are numerous relationships and dependencies that have to be preserved, along with a large number of checks that need to be performed. The objective is to compress the inflated values while ensuring that players retain their relative positions. Somebody who has legitimately worked their way into the top 1% should remain in approximately that position afterwards. The difference is that they'll once again have somewhere to go. Development testing has shown that this approach works extremely well. Skills, experience and levels return to manageable ranges, while the relative hierarchy between players remains intact. More importantly, it opens up enormous scope for future development. We can introduce more jobs, courses, houses, crimes and other progression systems. Existing high-level players can finally receive meaningful new content, while newer players have a realistic path towards eventually reaching those same heights. And, critically, the underlying mathematics can now be designed so that uncontrolled stat inflation simply cannot happen again. So what have I learned from taking over a decade-old browser game? Never assume the code is the whole story. Analyse the code, certainly, but analyse the data just as carefully. Understand how the game has actually been used rather than merely how its code suggests it should have been used. Understand your players and the economy they've created. Introduce logging early. Get static analysis running. Build unit and feature tests as quickly as possible. Look for inconsistencies and investigate the strange outliers rather than dismissing them. Because sometimes those outliers tell you far more about the health of the game than the code ever will. In my case, one of those investigations revealed that a single player held approximately a quarter of all the money in the entire game. At that point, you stop wondering whether the economy might need a little attention.
- 1 reply
-
- 1
-
-
As I have a project that is rapidly reaching GA, I'd like to improve the incentive voting systems. I currently have 4 sites available only one of which appears to offer a callback providing a guaranteed "voted" mechanism. I'm really looking only for sites that provide a callback mechanism, and for reference, I'm currently using: topgamesites.net, mpogtop.com, mmohub.com, and mmorpg50.net Are these sites still of use, and if so what experiences do you have of them? Any sites you would recommend?
-
lmao - nicely said.
-
One is sorely tempted to respond with simply an image of a bag of humbugs, but at my age, I like a humbug or two! Satan Santa has certainly brought me some gifts which I must admit to being rather pleased with - I hope you all did as well. As for the new year, I hope you all have a decent one - I know I will 😄
-
Stats ? Active Players ? Income ?
-
Actually I never got around to them - was enjoying the 70's vibe of the background too much 😉
-
Looks to be up - albeit a simple and rather loud placeholder! Almost had me reaching for the shades 🙂
-
Melvor Idle Forge of Empires
-
Hmm, 2016 yet apparently no backups. I swear I was making backups in the, admittedly late, 70s - I guess that process must have skipped a generation or two! Mind you, had the most recent poster noticed the date (Sep 2016), perhaps they would not have not been too concerned about demos or images!
-
Well, I considered doing another deep dive into some of the fun bits of Mccodes, maybe looking at the job system and seeing how to improve it, or looking into the very poor casino games and seeing what could be done to turn them around, but I kept hitting stumbling blocks. When the code was open-sourced, I think lots of people including myself have high hopes of many people starting to turn it around, but what we see is very little work on the code if anything. Cronless crons and a role-based access control system, both of which are frankly pretty poor bits of work - I'd suggest ripping them out and returning to the old v2.0.5b base. At least we all know the problems with it! For reference, running static analysis tools on these modules shows a wealth of problems, so much so that I'm not going to examine them in detail. No deep dive, however does not mean the end of my foray into the world of Mccodes, far from it. I've started from the open-source edition, and have: Introduced a full template system using Blade as the template language. Created a front-end controller to direct new code into name-spaced controllers rather than individual files in the public folder. Added repository classes so controllers talk to the database only through the repositories, make it easier to change database back-end, table and field names. Used PDO as the core database driver rather than MySQL(i). Improved the docker stack considerably - though to be fair, it's for local development, not production. Rebuilt a number of pages using the new template system which allows for easy integration with the old code. Used Tailwind CSS as the CSS framework to get up and running quickly. Ensured the controllers are all PSR7 compliant, so dropping middleware in (for guest/auth redirection, and performing cron tasks) will be simplified. Started to flesh out the houses, crimes, jobs, cities, courses and items with fixtures as a "get you started" set of data. Used PHP 8.3 in the docker stack though I aim to get 8.4 in shortly, and MySQL 8 is also present along with Adminer for simple database management. Created a routing system for the front-end controller ensuring that all new code is defined by the routes. Checked the code regularly with static analysis tools to ensure no new bugs (or features as we used to call them) are brought into the system. Used Alpine JS to enhance the site to help with things like tabbed controls, show/hide password controls, modals etc. Stripped out the logging and replaced with Monolog with a database adapter. There's a lot of items on my roadmap: Finish of the core code rewrites to address all the common modules available from the menu and explore screens. Redo the crimes formula system. Refactor the attacking code to simplify it and better address how weapons can be used. Increase the amount of equipment slots for armor - thinking legs, body, hands, feet and head here. Use Alpine JS to enhance the site to help with things like tabbed controls, show/hide password controls, modals etc. Bring in some modules including the stock market, auction rooms foraging, and some as yet unnamed one. Add tests with PestPHP. Ensure where necessary, complex updates are handled within transactions to ensure atomicity. Documentation! Images for the relevant fixtures - cities, houses, etc. Visually, it does look at lot better, the templates allow me to get rid of the one-page lag often seen when committing crimes or training in the gym, but I've tried to retain the original look and feel to a certain extent - at least for now. At some stage, I intend forking my own work to spin up a game, though I pull push what I have online as soon as possible as a playable demo. During development, it will be refreshed on a regular basis until all the modules are rewritten to ensure none of the older code causes problems.
-
- 1
-
-
Making Money .. or rather how to stop players making money
Inveteratus replied to Inveteratus's topic in General Discussion
Some very good suggestions - culling inactive actives is thoroughly recommended though I'd be inclined to mail them 30 days in advance of a cull with the option to opt-out - they may be unable to play temporarily after all. I think I like the idea of only earning interest up to a set amount; it would help keep a cap on games where the interest rate has been set high, which may be deliberate. Charges, I've considered but I've never found a satisfactory mechanism that allows me to bleed funds out as a standalone measure - it seems too much like taxes in real life which I usually try to avoid ... and in real life! I suspect the key point to take from these discussions is that balance is very important. And while you won't manage that with an out-of-the-box system, with careful play-testing and no doubt hours slaving over a few spreadsheets will result in a game that lasts. There will always be areas that need tuning up, but if you get the basics right, the fine tuning can be done over time. -
So what if I told you how to make $135,259 just by sitting on your hands just by giving me $100? Or how about if you give me $100 and I will show you how to make $5,323,942,470,216 again just by sitting on your hands? I've no doubt at this point, you are probably reaching for the "Report Spam" button, but bear with me a moment .. This is how MCCodes games are designed from the get-go. There's no need to play the game, just sit and wait and you will soon be richer than ... well everyone! Okay, some explanation .. lets look at a couple of critical lines in MCCodes in the cron_day.php script. UPDATE users SET bankmoney = bankmoney + bankmoney / 50, cybermoney = cybermoney + cybermoney / 100 * 7 Will that doesn't seem so bad .. or does it? Since MySQL will be rounding the result so if we look at the basic bank to start with given you save $100: After 1 day you will have $102, after 2 days, $104... even after 10 days you will only have $120. Weill again, that doesn't seem to bad. It's not going to introduce too much money into the system - after all $20 in 10 days is peanuts. But wait, after 20 days, it's risen to $147, after 30 $177. After 50 we are up to $265, after 100, $713. In fact, its doubling your initial money every 36 days or so. So after 1 year,. you will have $135,359 in the bank for an outlay of only $100! I wish I got that in the high street! Before we look at the frankly frightening cyber-bank, a little math. $principal = 100; $futureValue = 135359; $annualPercentageRate = $principal * $futureValue / 100 + $principal; Yipes - that's a rate of 135,259% Now for those of you paying mortgages, you may be lucky to have a rate as low as 2.5%, I believe I'm paying around 4.5% at the moment, while my bank is giving me a meager 3.3% rate on my savings. So what about the cyber bank. This one is truly scary. It doubles your money every 10.5 days ish. So in 10 days you will have amassed $197, in 20 days, that's gone up to $388, in 50 days we have a rather nice $2,953, while in 100 days we've got $93,092. These figures a truly scary! And after a year... Well we would have $5,323,942,470,316 but as that overflows the data-type in MySQL (a signed int) we would have the maximum of $2,147,483,647! Phew! Well clearly, the banks calculations are bringing in far too much money into the game, so what can be done about it? Well the first thing I suggest is to shut down the cyber-bank. It might be a nice idea, but it's going to ruin your game in double quick time. Since it's doubling the principal every 10.5 days, then every years, the amount of cash in the game will be fatal. With 10 players not a major problem, but with 10 players joining every month .. you have a financial crisis on your hands in well under a year. Next suggestion is drastic. Remove the bank-money and cyber-money update statements from your daily cron. In fact you don't need crons to work out what your bank value will be - again it's all down to a simple bit of math. (We'll see how to do that in a bit) Now of course you want to reward players for having a bank account - how about 100% APR for premium players and 50% for non-premium players. That's still way more than any of us will ever see in real life from a high-street bank, but it's not introducing too much money into the system. Again .. a little bit of math $principal = 100; $annualPercentageRate = 100; $futureValue = $princial * (1 + $annualPercentageRate / 100); Will let you play with the APR figure to see just what sort of cash you will be bringing into your game. To apply this as a multiplier on a daily basis... $daysInYear = 365; $dailyMultiplier = pow($futureValue / $principal, 1 / $daysInYear); So for 100% APR, this yields a daily multiplier of 1.001900838. If you insist on using crons then you could adjust your daily cron to : UPDATE users SET bankmoney = bankmoney * 1.001900838; Caveat, due to rounding, you won't actually see any interest until you have around a $270 in the bank, but after that it will kick in - maybe that's a good thing! This is a lot more gentle on the amount of money coming into the game and is actually quite manageable - at least from personal experience. If you are feeling brave, then as long as you have the date-time the user deposited money into the bank, and the principal amount, you can compute the present value (I use the term present rather than future here but it means pretty much the same thing) at any point to show them what the have now. For reference: $dailyMultiplier = 1.001900838; $prinicpal = 100; $daysSinceDeposited = 50; $presentValue = pow($dailyMultiplier, $daysSinceDeposited) * $principal; With these calculations, I've never need to use a cron to update my bank, and in fact I can actually claw a little money bank from the player by rounding the number of days down to a whole number (which may be have 3.5 days) so they lose out on a little interest but still get the benefit of an apparent 100% APR interest especially if they leave their money alone! The moral of the story here is ... well I'm not sure. It probably goes a long way to explain why so may MCCodes fail - their inflation turns rampant as smart players bank their money early and often. There are some nice solutions I've found such as variable APRs depending on key stock holdings and/or premium status, limiting the amount of cash that can be deposited by combat level (so the higher combat level you are, the more likely you will have large amounts of cash on you to entice players to PvP). You might also look to variable APRs where it reduces to try and keep the overall interest across all players to a certain value, so as more players join, the global APR reduces slightly. What's your take on it? How do you stop players making money? If you are happy to run an MCCode game with the original SQL in the daily cron - let me know a link to your game! I always enjoy breaking the bank!
-
I've seen some stock markets in MCCodes-based systems, and sadly most fail for a number of reasons. A classic example being one I came across a year or so back. From what I can ascertain from playing it; it had a cron running every 5 or 10 minutes changing the price to a random value with a set range. This meant that any smart player would monitor the market for a few days to determine the lower and upper bounds, then buy when within lowest 10-20% of the price range, and sell in the upper 80-90% of the range. Oddly, I had a mail from the admin/owner asking how I was managing to make so much money so quickly... Despite telling them, they failed to understand the underlying problem, and banned me a day or so later. My fault ? Possibly, I guess it is abusing a bug, but it's a bug that despite explaining it, the owner failed to take steps to address it in a timely manner. There's actually a number of problems here : Random values do not a stock market make. Using crons to update the prices. Failure to log actions on the market. And critically, not play-testing prior to release. So who to we address these ? 1. Use a noise generator There's a number of decent noise generators out there, though I find that Simplex is probably the best for mimicking a stock market. Remember, in a real market, prices are driven by "market forces", which essentially means the amount of stocks that are being bought and sold. As a game simply won't have the number of players to drive this, then using a noise function seems to produce the best result. 2. Crons are unnecessary when you can generate the values via your function in real time. Assume your noise functions is defined as : function noise( float $x ): float then you can pass in a UNIX timestamp scaled by (say) 1/255 (i.e. multiply by 0.003921568627451), then may get a result in the range -0.7888 to 0.6373. Multiple this by (say) 128 and add 127 you would see a range of 26.023 to 208.583. So while the main input into your noise function is essentially a time value you would actually be using it like: $timeScaleFactor = 1 / 255; $rangeFactor = 128; $rangeOffset = 127; $result = noise($time * $timeScaleFactor) * $rangeFactor + $rangeOffset; This gives you plenty of scope to vary the stock prices by changing the input variables, and the best bit is, being deterministic, the $result will always be the same for the same input values - so no need to use crons, you can generate the price at any time on the fly. 3. Logging actions There are multiple options here, probably the simplest is just to store the player-id, the transaction type (buy or sell), the stock-id, the number of stocks, and the price they were bought or sold at. Of course, you may not really need to log transactions assume you follow the next step closely. 4. Play testing This is extremely important, and sadly something that is often missed by owner/admins. Ideally unit and feature tests should be present to ensure the site actually works using either PHPUnit or PestPHP. After that, you can consider acceptance testing or simple just make sure you manually test EVERY page in your project. And that's not just a case of seeing if the page loads - drop in some bad data; i.e. try and buy -1 stocks, or putting string data into numeric fields. There's a number of techniques that people favor here - I tend to rely heavily on feature tests; but they may not pick up everything if you are lazy when writing your tests. Going back to the original example what would these points have addressed? Well for one, using a non-random system makes it more difficult to predict the outcome of the stocks despite being deterministic. Time is one factor, but you still may have to consider limiting the number of stocks available, or perhaps ensure that you cannot sell stocks for maybe 14 days. Without crons, we've got rid of a hidden problem and extra load which simply is no longer needed, though you would need to to do more work to present a stock graph rather than just pulling data out of the db. Logging is of course a simple one to address, and may not be needed if you trust your code and understand any potential pitfalls. Finally testing is probably the biggest one here. Without testing your code, you run the risk of missing something that may seem stable and fits in nicely in your project but suddenly introduces massive amounts of funds making your game highly unstable. If anybody has suggestions in improving the buy/sell experience, let us know - it's a potentially useful module for many games as it can tie up money for long periods of time. Finally, for reference, here's an example but of code you might want to play with: function noise(float $x): float { $permute = [ 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, ]; $i0 = $x > 0 ? (int)$x : (int)$x - 1; $i1 = $i0 + 1; $x0 = $x - $i0; $x1 = $x0 - 1.0; $t0 = 1.0 - $x0 * $x0; $t0 *= $t0; $n0 = $t0 * $t0 * $noiseGradient($permute[$i0 & 0xFF], $x0); $t1 = 1.0 - $x1 * $x1; $t1 *= $t1; $n1 = $t1 * $t1 * $noiseGradient($permute[$i1 & 0xFF], $x1); // The maximum value of this noise is 8 * (3 / 4) ^ 4 = 2.53125 // A factor of 0.395 scales to fit exactly within [-1,1] return 0.395 * ($n0 + $n1); } function noiseGradient(int $hash, float $x): float { $h = $hash & 15; $grad = 1.0 + ($h & 7); if (($h & 8) != 0) { $grad = -$grad; } return $grad * $x; } And just for giggle ... something I was experimenting with -- apologies for the un-formatted dates
-
Why not use something like omnipay? It supports a huge variety of payment gateways - including Paypal, with all the same interface so you can chop and change to suit. It has the added advantage of being free. (Sorry Dave!)
-
Ah, the days of CE - fun was had, money was made, games were written, bugs were rife .. all good stuff! A merry Christmas to you all and here's hoping for a good New Year.
-
I'd argue the point - however there are some valid points. In the old days, when CE was in existence; pun intended, MCCodes was a vibrant product despite its many faults, with plenty of active developers willing to push out some freebies. As time progressed there were other games, and people willing to put their time and effort into helping people get off the ground. These days, of late, we've seen GRPG and MCCodes both turn open-source, though considerable work needs to be done to turn them into viable long-lasting products. But to what end ? It would be nice to see one or both of them brought up to scratch with a decent front-end controller, requests, controllers, validation, templates, unit testing etc, but that's a fair amount of work for anyone. There are a few developers I know or rather knew here that I've worked with, some in real-life that I've enjoyed their company, their insights and indeed their knowledge, but where are these people now? Most have moved on away from IT, the few that I'm aware off are probably too busy with real-life problems to return to what is essentially legacy code-bases that with the best will in world, simply costs too much time to be realistically viable. Hosting these days is simple - and cheap. DO, AWS are both fine environments, there's really nothing to stop developers from grabbing an account on either and getting setup. The marketplace ... well it's no github - and that is what I suspect is needed. Look at the larger open-source products, they have a lot of products in version-control, once there is sufficient mass, then and only then, should a marketplace be considered. There's also no point in having a marketplace for a product until the base issues are sorted out - and ideally, the product is brought kicking and screaming into the current century. So what's the solution ? Well, I'm a developer, I'm not production management, so obviously I would be dusting off an editor and firing up a project ... if I had time. I've enough experience to refactor projects and to maintain them, but it's not really something I'd wish to do alone. There lies a possible solution of course, if somebody were to pickup the mantle of managing pull requests, but it really needs a group of probably 3 people to drive the direction forward, otherwise you run into the age old problem, of mine is better than yours ... I'll create a fork and work on that myself. I'll leave others to draw a conclusion to all of this. As a side note, my apologies to GRPG developers especially if I've maligned the code-base, I'm not fully familiar with it. MCCodes developers... well sorry lads, you probably needed to communicate a bit in the first instance! tl;dr; we need a new open-source game or people willing to spend time bring an existing one up to current standards and be willing to teach the why's and wherefore's as they go.
-
Further to the above ... https://github.com/inveteratus/slim4 Has a small but working demo written using the Slim framework. I may extend it to add in other features in time, however this may give you a leg-up. You will need docker to run it, although it's easy to alter it to run under nginx (or apache), php and mysql natively.
-
With Slim, you really want to install a few extras. You'll need a PSR7 library - sliim/psr7 is perfectly decent. Slim does come with a container, but it's limited, so get yourself php-di/php-di. Drop in twig/twig of course, vlucas/phpdotenv for parsing your .env file and I like to use respect/validation for form validation. monolog/monolog for logging of course and finally, though I often forget about this one, is slim/csrf for CSRF protection though tbf, it's not difficult to do yourself. composer require slim/slim slim/psr7 slim/csrf php-di/php-di vlucas/phpdotenv monolog/monolog twig/twig I could rustle up a bare-bones skeleton, however there are plenty out there that are very decent and probably better than I can produce. Unlike many other frameworks, there are so many ways of booting Slim - you could for example place all the code into your index.php apart from the controller (and presumably repository) code, however I find I tend to split things up a bit. It's really up to you to choose what tools you need. Your container (usually php-di) allows you to instantiate any class and access that via DI, so you could (for example) have both Twig and Smarty in the same project potentially sharing some templates. CSRF, you can do yourself thought there is a package for that. Monolog is probably the standard logger as it supports writing to a huge variety of endpoints - files, databases, etc. Validation, well I tend to use Respect as it seems to fit my needs. and so on. I'd suggest you experiment with some of the basic examples in the Slim docs first have at look at the original author's skeleton akrabat/slim4-starter as it's a great starting point. For databases, use the container to instantiate a PDO instance, and ideally use repository classes that access the PDO instance - it keeps your code nice and clean. As for linking with JavaScript .. your choices are unlimited. It makes no demands whatsoever, on JS or CSS, so that's all up to you. As mentioned above, look into Alpine and Tailwind as both fit nicely and are powerful enough to produce some amazing applications. If you run into trouble or need some advice, give me a shout; I'm always willing to lend a hand. In the meantime, I'll pull apart one of my apps to leave it the basic index/login/register/home/logout endpoints and pop that in a repository for people to play with.
-
Sadly not 200 (I little less anyway) - and hopefully not upsetting anybody. I'm just trying to point out that providing limited code snippets without any context or useful error messages is not always the best way to ask for help. By all means - ask away - if I/we can, I'm sure help will be forthcoming.
-
While I feel it is probably a little too obvious to point out the frankly bleeding obvious, perhaps in this case it is necessary: "text" => 'You successfuly stole a '.$carName.' with '.$carDamage.'% damage.' So that looks like it's setting an element on an associative array, yet you appear to address $text later on. I'd also point out the lack of trailing comma here (not perhaps 100% necessary, however potentially good practice. You could also perhaps use inline variables here, ie "... {$carName} ... {$carDamage} ..." -- both of which will be expanded correctly due to the double-quote. (n.b. ensure both variables are of course correctly escaped). )); ... Closing an array by any chance ? or nested array ? - If so, you probably want to be using the short array syntax these days. - [] $labour = mt_rand(1, 100); Let's use random_int(1, 100); -- it's a lot better at random number generation even at some ranges, something mt_rand() is pretty poor at. foreach ($cars AS $c) { Yeah gods man - use lower case for keywords already! if ($c['C_successText']) { $text = $c['C_successText']; } } Let's just gloss of the use of short variable names .. ( foreach ($cars as $car) would have been a much better choice - even on code this small ). I suspect this could be shortened to .. $text = $c['C_successText'] ?? false .. or similar but where's the code that determines the success? if ($labour) { Where does this come from - it's not referenced above. $text .= " And you earned ".number_format($labour)." Quarter Master"; Okay, so we like mixing single and double quote for no real reason. Stick to single unless you have a replacement variable ( "... {$var} ..." ) - just make sure it is escaped properly! $rewards[] = array( 'val' => number_format($labour), 'name' => 'Quarter Master' ); } Was $rewards initialized above ? And again, what's with the short array syntax ? I have a nasty feeling this is being edited with a simple editor - maybe sublime text, maybe vscode, maybe notepad, or maybe even rped (before your time I image) - Do yourself a favor and get a copy of PhpStorm, it's free for evaluation purposes for a month iirc, (and can be rolled on forever) - it may help point out potential bugs in your code before having to ask for help or run on a production box - and no doubt upsetting a few regular players. It would also be useful to see any error messages your system may be throwing up as well as the original file in full (credentials, if present, masked obviously). If you don't feel happy with presenting the whole file - toss us a function or a method - it makes for so much easier debugging and thus swifter turnaround of problems.
-
I've been experimenting with this for a while now and it seems to have stabilised quite nicely. This particular screenie is from my mccodes project. specifically the new cores editor within the staff console although there are a couple of missing top-level entities. Both the requirements and the benefits fields are essentially simple tag lists, however the code is validated and evaluated enabling any number of skills to be applied to a player, with any number of abilities. I'm using expression evaluation for the requirements, this will mean that to; in this case anyway; start this course, you will need to pass all the requirements. Expression evaluation thankfully works nicely for the benefits here as well and using reflection is able to access any detail connected to the user. Obviously both fields are heavily validated, essentially being whitelisted so nothing untoward can ever creep in. My main goal of this is to bring about the ability to change the game dramatically without touching code as many areas will use the requirements field i.e. entering the travel agent might require you be carrying a passport `user.inventory.has(PASSPORT)`. Simple stuff, but proving very useful
- 1 reply
-
- 2
-
-
Personally, I'd forget income for the moment. Look to your design steps; there's a lot of problems that will need to be solved, a lot of content to be generated, some of which will no doubt lead to further problems and further content. Balances need to be sought to ensure that players cannot get too powerful, in-game currency needs to be carefully tended to prevent runaway economies and only after a lot of play-testing be it with beta testers or with spreadsheets will you see where adjustments can be made which would allow for real-world currency purchases. Of course you then run into problems of how to charge. There's a lot of payment gateways out there, but on mobile's, especially iOS, I suspect you may run into restrictions; ie you may have to use Apple's own payment system. On Android there are probably less restrictions, and of course a PC/Browser is pretty easy going. You may have charge-backs, you may have players who expect items, facilities etc in return for real-money, you may have break-downs in communication between the player, the payment provider and yourself. You may even have server issues where players expect some level of service having ""paid"" to play your game. This brings in some basic but wise-to-have legal protection. There was game I recall that held weekly gang-based challenges; the system relied on people purchasing some form of in-game currency which was used to further their gang's resources. The winner of the competition won either a small token gesture of real cash or occasionally some gizmo, the runners up received some of the in-game currency thus putting them in a slightly better position the following week. It worked extremely well; even a beginner could derive a lot of fun and occasionally some in-game currency if they took the time. Prizes went up quite nicely, I seem to recall iPods at one stage and prize money did reach into the hundreds. So while it's possible, I'd suggest you work out the concepts first, get the first draft of the code in place; get it play-tested and balanced and then and only then should you look to developing an income from it. Sadly very few games make it this far but a few products do survive. Being careful with your design process, and continuous monitoring of the overall balance, is probably key to making something that can last. Best of luck!
-
Some other questions do arise; for example - you say you have 10 years experience, congratulations; but just how far forward are you with the project? For instance do you actually have a specification with wire-frames, clear definitions of the calculations necessary for say gym gains, or how combat works? Without these, there is a lot of core, internal leg-work to be done before you can get of the ground. Sure, you can release and "see-what-happens" which appears to be common in the Mccodes world, but I hope we've grown past that. How about back-end data structures? It's all very well putting together a system (thinking of Mccodes here), that works, until you have more than 20 people playing simultaneously at which point the database grounds to a halt due to poor design. GL is better but still suffers from scalability from what I've encountered (feel free to correct me on this!). Caching? Job queues etc.? Yes it's a lot of open architectural stuff which I don't expect an answer for, but is of interest to the prospective programmer. Angular? seriously? Okay, I must be out of touch (and not the first time). React? not my favourite by any stretch of the imagination, a few here who know me will attest to this! Rest API and sockets; okay I can get behind them, but then I'm much more of a back-end developer! Sockets do run into scalability problems quite quickly, Rest API's not so much; at least with a decent LB in front of them. The offer of part ownership is potentially laughable, but then I've been in the industry for a while (>45 years); and few projects have survived to make this even a viable proposition. I'd hope that your abilities would help create a good working group of people who collectively can combine their efforts towards this. Looking back, I don't think I've ever had ""ownership"" of a site last past a couple of years while the admins drive it into the ground with poor management or just walk off leaving the site to the vagaries of it's users with no DB/code access. The iOS, Android, PC bit ... hmm, there's some interesting problems with that mix. Graphics; don't they need higher resolutions - 2x, 4x, 5x? on iOS which introduces potential bandwidth problems assuming you are hosting this on any sane system (AWS, DO, RS etc). Both Android & iOS marketplaces require some sort of recurring payment just to be able to list; that's going to hurt billing unless you have a cunning plan for a .. and I hesitate to mention it .. "pay to play" or "pay to win" system. PC is easy enough - heck with speeds these days, it's possible to host demos and small sites from home not that I'd recommend it. Responsive websites get around the initial iOS/Android problems which may be a way around the iOS/Android marketplace pricing. And that brings about the question on how the site generates income. Adverts (god forbid), pay to play/win, or are you bankrolling the whole system? I assume some form of bankrolling is in place to begin with - AWS/DO/RS + Github/BitBucket/Gitlab accounts and tool-chains. In the early stages of any game, donations seldom work as the product is not public facing, so the costs mount up. This has to be offset somewhere; I remember an individual here who ""hired"" programmers for a projected income, but was paying a massive amount for an highly over-spec'd development box. I guess it would be useful to know your background as well; 10 years is a decent timescale with one language but these days, programmers need to be savvy in so many fields; there's potential for a lot of overlap which may not be desired. I suppose finally Torn ... I mean ... why? Sure, I play, but by ""play"" I mean I log in once a day, read my messages, commit a few crimes, run a quick gym training session and bugger off. To me, Torn is a social club, with a lack of content. Oh and why crimes? Isn't the market flooded with crime based systems over cooperative play? So here's where you could make a massive difference; by coming up with something fresh; something no-one has seen before - and no, I won't ask you about it here as that's unfair to you. Anyway, my best of luck finding a team to work with you.
-
I'd argue with ags_cs4's suggestion that you need to use PDO to provide an extra layer of protection from injection; as it's not fully correct. It is still possible to perform SQL injection attacks against a site using PDO for it's queries even if they are prepared. And the MySqli library can be perfectly safe if used correctly! Sadly Mccodes has shown us how poor queries can and do result in broken games very quickly. The first point about helping make a site more secure; note "more", not "fully"; is to ensure the data you have is sanitised wherever possible to protect against a number of problems. Passing any request variable to SQL is going to be a recipe for disaster. Check your inputs properly; using for example ctype_digit for positive integers, filter_var for pretty much anything else; there's a decent range of FILTER_VALIDATE_xxx constants with support for options for example integer minimum/maximum values, regular expressions for strings etc. Once you have sanitised the input, you can still have strings which would prove dangerous were they passed directly to SQL, so you need to prepare your queries. The basic concept is very simple: // Assuming $location and $username have been filtered correctly, and $pdo is an instance of PDO: $sql = 'SELECT * FROM users WHERE location = :location AND username LIKE :username'; $stmt = $pdo->prepare($sql); $stmt->execute([ 'location' => $location, 'username' => $username, ]); $data = $stmt->fetchAll(); It is a bit of a contrived query; potentially finding a user in a particular location; however it serves to demonstrate how data can safely be passed to SQL. I suggest some research into filtering and using PDO yourself; it's not difficult. Converting mccode's poorly written database classes into PDO is not difficult; with care you can add a function to the basic database class that uses PDO, then it's just a case of slowly converting each and every page to use that method. As a side note; well worth reading (The only proper) PDO tutorial. I still occasionally find myself referring to it from time to time.