Jump to content
MakeWebGames

Inveteratus

Members
  • Posts

    53
  • Joined

  • Last visited

  • Days Won

    10

Everything posted by Inveteratus

  1. The error message should be sufficient to determine that there is a misplaced ' symbol - and it does point towards the $r['] I suspect the url tag should be [url='viewuser.php?u=" . $r['userid'] . "']" . htmlentities($r['username']) . "[/url] however it would probably be wise to provide more context; i.e. a few lines above and below line 120 in order to provide a more accurate response.
  2. Yes, I just got that message. Seems there's a lot of problems with this game, not least is overall balance. The premise may have some merit, but the implementation is simply not there to make it interesting enough.
  3. Lots of nice bugs, missing files (404s), interesting names files (tiddlesverifybitchmuhaha.php), poor layout, poor use of css ..., as a game it rings a bell, I've seen something like it but can't remember what it was. Needs a lot of work prior to production especially with the in-game currency, far too easy to make $$ which suggests either some major bugs or some very bad planning.
  4. Try ALTER TABLE `users` ADD `mine_level` INT UNSIGNED NOT NULL DEFAULT 1; ALTER TABLE `users` ADD `mine_exp` INT UNSIGNED NOT NULL DEFAULT 0; ALTER TABLE `users` ADD `mine_needed` INT UNSIGNED NOT NULL DEFAULT 1000; Notice: The ADD keyword is needed. INT(11) -- The (11) is useless, it has no bearing on the size of the value that can be stored. I've used UNSIGNED as it's unlikely your mine level and/or experience will go below zero. I've change the default mine_exp to 0 -- feel free to adjust to suit.
  5. There's more faults in that bit of code than you can shake a stick at ... but you could try a couple of little of changes that help as you've not provided any information on what is going wrong. Changing the error messages to make it clear which part of the code is failing is useful, but I ran successful test by changing just one line: <?php function do_pic_change() { global $db, $userid, $h; if (!isset($_POST['verf']) || !verify_csrf_code('prefs_picchange', stripslashes($_POST['verf']))) { csrf_error('picchange'); } $_POST['newpic'] = (isset($_POST['newpic']) && is_string($_POST['newpic'])) ? trim($_POST['newpic']) : ''; if (empty($_POST['newpic'])) { echo 'You did not enter a new pic.<br />&gt; <a href="' . gen_url('preferences', true) . '&action=picchange">Back</a>'; } else { //if (strlen($_POST['newpic']) < 8 || !(substr($_POST['newpic'], 0, 7) == 'http://' || substr($_POST['newpic'], 0, 8 == 'https://'))) { if (!filter_var($_POST['newpic'], FILTER_VALIDATE_URL)) { echo 'Invalid Image - Invalid URL.<br />&gt; <a href="' . gen_url('preferences', true) . '&action=picchange">Go Back</a>'; die($h->endpage()); } $image = getimagesize($_POST['newpic']); if (!is_array($image)) { echo 'Invalid Image - Cannot retrieve image dimensions.<br />&gt; <a href="' . gen_url('preferences', true) . '&action=picchange">Go Back</a>'; die($h->endpage()); } $db->query('UPDATE `users` SET `display_pic` = "' . $_POST['newpic'] . '" WHERE `userid` = ' . $userid); echo htmlentities($_POST['newpic'], ENT_QUOTES, 'ISO-8859-1') . '<br />Pic changed!<br />&gt; <a href="' . gen_url('index', true) . '">Go Home</a>'; } } I've made a few changes: * Removed unnecessary references to global variables * Added extra information in the error messages to help debug the problem * Change one line leaving the original commented out Testing this against the url https://upload.wikimedia.org/wikipedia/commons/4/40/Image_test.png works nicely.
  6. You know, if somebody at work posted two files totalling over 400 lines with the simple "I'm getting big numbers" complaint, my response would not be unkind, but I'd suggest that perhaps they went back to the drawing board, tried to find out what the problem was themselves, better yet, explain what the problem is with screen grabs where appropriate, and provide description of what is happening, where it is happening, and what the expected behaviour is. A lot of the people here are lucky enough to work in the industry, but looking through poorly formatted code, without a clue as to what the issue is strikes me as being more work, less play! Saying that, the whole delta updates i.e. timestamp based rather than cron based updates looks very messy, especially as it can be done in a couple of queries and not within a loop. If you had for example a user that hadn't logged in for one month, that loop could run over 8,000 times, generating over 1,500 queries when 2 would suffice. Given you know the current time, you know the time the user was last updated, that gives you a time difference in seconds. Assuming that is greater than some small figure (say 300 seconds) then you can update the user's fields: will, brave, hp and energy with the time difference multiplied by the increase per second of each field which is simple to calculate. The problem with doing this, is loss but this is only addressed by using real numbers for the four fields; the maximal values can remain integers; which in turn does cause a couple of other minor issues. Nothing against the original author of this, conceptually it's a neat trick, but anytime you have a query in a loop, you need to start asking questions. With the default DB schema, even a simple SELECT operation will lock the entire table for all other operations, so this method will quickly limit the amount of simultaneous users you can have on any system, and has the potential to cause unpredictable and difficult to debug timeouts. Finally, it's great to update your own player like this; I use a similar technique, but what happens to other players? NPCs being the obvious example. If you have a number of NPCs that people can fight against, how do their stats regenerate? I simply pose the question, I don't offer a solution here, though it is simple to implement.
  7. It should be noted that in your error above; you are using a <?php ... ?> statement block within a string, sorry; it doesn't work like that. The simplest option would be to replace line 60 with echo "<textarea rows='10' cols='50' name='pn_update'>{$ir['user_notepad']}</textarea>"; It might be an idea to get yourself some tools to help cleaning up your code-base; PHPStan which is a static analyser, and ideally an editor that really understands the language; ie PhpStorm. Both can help a lot when trying to get a code-base as poor as this is up and running. Out of the box, PHPStan will find around 60 problems with the code at level 0, running it at level 9 will find in excess of 2,000 problems! I find that if you are wanting to make a working product from a legacy code-base, start at level 0, clean up those problems, increase the level; rinse and repeat. By the time you hit level 6 it is potentially ready to open to the world, however with this particular code, there are lots of gotcha's that will bite you without a lot of care. And it doesn't take a lot of time. If memory serves me, I was able to clean a stock mccodes up to level 6 in around 3 hours - okay, I know the code fairly well, but it's not difficult nor overly time-consuming as long as you start small.
  8. The advantage of using a proper expression evaluator is that it actually understands expressions correctly - there's no need to check for odd characters, or indeed rogue functions as the expression is correctly interpreted with and abstract syntax tree, thus any parse errors in it will raise an exception, any unknown functions will raise an exception, and of course any unknown variables will raise an exception. As a substitute for eval(), it's certainly one of the best solutions I've come across certainly in this use case. It also has the potential; to be used for setting player attributes whilst USEing an item. For example: ""user.hp = min(user.maxhp. user.hp + 3)"" ...though I've not fully tested this idea. @ags_cs4 Simple str_replace'ments still yield an expression which may or not be valid; ie: any function call which takes a variable number of arguments might stress your str_replace/preg_replace statement, and of course 1e4 is a valid decimal number. This approach may work for small simple formulas, but when you start adding in complex function calls, then it gets unwieldy very fast not to mention difficult to validate.
  9. I've recently been asked to examine the crimes system in MCcodes; and thought I'd share some ideas I developed while trying to improve the system. When using the staff console on a stock mccodes system to create a new crime, the formula for success is given by default as "((WILL*0.8)/2.5)+(LEVEL/4)" which is compared to rand(1, 100), with a value of less than or equal meaning success. Complex? No really, confusing? Yes. Okay, so what are the problems with this system? I believe in the early days of mccodes, people were managing to inject expressions into the crime formula, and since this was passed through eval(), all sorts of fun and games ensued. Negating the problems of security, how can we improve the expression such that is potentially more sane, and fitting to our system? The first thing is to use a proper expression evaluator; something that will sensible throw an exception if it cannot understand the expression under evaluation. I use Symfony's expression language for this -- https://symfony.com/doc/current/components/expression_language.html as it seems to cover all the use cases I need.The simplest use case would be: use Symfony\Component\ExpressionLanguage\ExpressionLanguage; $formula = '((WILL*0.8)/2.5)+(LEVEL/4)'; $context = [ 'WILL' => 100, // This would in reality come from $ir['will'] 'LEVEL' => 1, // This would in reality come from $ir['level'] ]; $expressionLanguage = new ExpressionLanguage(); $successChance = $expressionLanguage->evaluate($formula, $context); Which would, as a base chance, yield a success chance of 32.25% The problem with this should be apparent, in that the stock system is very limited in the variables it passes to eval(), LEVEL, CRIMEXP, EXP, WILL and IQ. Okay, not difficult to expand, but it quickly gets out of hand. It would better to have the ability to pass the entire user in ($ir). The biggest problem is of course the use of the eval() method, which is something that you should probably strive to remove from all of your projects. As it executes PHP code directly, with no safety net it is obviously open to abuse at all levels so proper expression evaluators are a far better solution. But there's a problem. Suppose we want a simple formula base on crime-experience. Maybe something like log(CRIMEXP + 1, 1.25) + 50, which; assuming a current crimexp of 0, would yield a base success chance of 50%. For this, we have to pass in a list of whitelisted functions to the expression evaluator: use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; class CrimeFunctions implements ExpressionFunctionProviderInterface { public function getFunctions(): array { return [ ExpressionFunction::fromPhp('log'), ]; } } $formula = 'log(CRIMEXP + 1, 1.25) + 50'; $context = [ 'CRIMEXP' => 0, // This would in reality come from $ir['crimexp'] ]; $expressionLanguage = new ExpressionLanguage(null, new CrimeFunctions()); $successChance = $expressionLanguage->evaluate($formula, $context); Okay, so that's functions safely whitelisted, obviously, you would probably return a while set of useful functions from the CrimeFunctions->getFunctions() call. As for passing in the entire object, that's easy enough: use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; class CrimeFunctions implements ExpressionFunctionProviderInterface { public function getFunctions(): array { return [ ExpressionFunction::fromPhp('abs'), ExpressionFunction::fromPhp('ceil'), ExpressionFunction::fromPhp('exp'), ExpressionFunction::fromPhp('floor'), ExpressionFunction::fromPhp('log'), ExpressionFunction::fromPhp('max'), ExpressionFunction::fromPhp('min'), ExpressionFunction::fromPhp('pi'), ExpressionFunction::fromPhp('pow'), ExpressionFunction::fromPhp('sqrt'), ]; } } $formula = 'log(user.crimexp + 1, 1.25) + 50'; // Note how we have change the name of the CRIMEXP field to user.crimexp $context = ['user' => (object)$ir]; // Note we are passing in the entire user object this time $expressionLanguage = new ExpressionLanguage(null, new CrimeFunctions()); $successChance = $expressionLanguage->evaluate($formula, $context); Much better. We now have a safe expression evaluator, that allows us to use a number of whitelisted functions and has access to all the different fields within the user (and userstats) record. This in turn allows us for more complex expression that could initially be obtained; for example you may decide that you want some crimes to add in a degreee of intelligence: log(user.crimexp + 1, 1.25) + log(user.IQ + 1, 2) + 50 or maybe add in a variety of attributes: log(user.crimexp + 1, 1.25) + log(max(user.strength, user.agility) / 4 + 1) + 50 The possibilities become endless. It's worth experimenting with a spreadsheet to determine the best formulas to use - too many sites use the same tired old ((WILL*0.8)/2.5)+(LEVEL/4) expression, maybe only altering the WILL multiplier which after a while becomes obvious. It's also a good idea to have something in place that a) ensures your players always have some chance of succeeding, and b) always have some chance of failing; i.e: max(5, min(log(user.crimexp + 1, 1.25), 95)) This would ensure a 5% minimum success rate, but equally only a 95% maximum success rate. Wrapping Up Use an decent expression evaluator tool over the dangerous eval() function Whitelist only the functions you need Make expansion easy by passing in the user context as a whole rather than individual fields Experiment with your formulas Make both failure and success a possibility N.B. It has been pointed out that perhaps instead of passing in the entire $ir array as an object, you create a context that whitelists key fields to prevent passing sensitive fields like password/salt/email etc.
  10. Inveteratus

    DeadlyCity

    I'm always impressed when anybody releases new game; be it stock mccodes, or something with a little more flair, but I do think sadly this is one of these projects that is not going to survive without considerable work. The trouble is bugs and a lack of thinking about how the player will want to interact. Bugs are rife and every day I discover more. Some serious, some simple, some that may take a lot of thinking about. A classic bug in point is the bank which offers a 2% interest per day, but charges a 15% deposit fee. Two points here. If I have $100, and deposit $100, I am left with $15 and the bank now has $85. So I guess the 15% is just a threat! Second issue is the 2% interest rate per day. After only 40~41 days that will have doubled, in a year that amounts to a value of around $117,313, or some 117 thousand % APR which I must admit, I wish I had in real life! Surely this is in error. So if I had say $48 million in the bank, then after only 35 days that will have doubled, I'd be getting just under $1,000,000 per day interest for the first 3 days, after that it will just increase dramatically. After one year I would have almost $73 billion which apart from being than a straight unsigned integer in the database, is frankly a ludicrous amount. If memory serves me, stock Mccodes has a 2% interest rate for the normal bank, and a whopping 7% interest for the cyber bank. I'm not going got work that out as I suspect it may exceed an unsigned bigint in the database! Going back to DeadlyCity, the interface was recently changed, and I can't say I like it at all. The light/dark themes are always good on sites, but in a game about crime? Sorry, it should be dark, but not just dark, but dingy, the corners slightly rolled up, the edges a bit worn etc. Okay, I know that takes time, and I for one am NOT a front-end developer so I know that is an arduous and expensive process, but nevertheless, some attempt at testing again needs to take place. The site doesn't render well across different display sizes, some are frankly unusable. Icons are used rather than textual menus on most cases, and the icons are not strictly representative of what you'd expect, so you spend a little more time looking around trying to find what you want. It's a minor niggle yes, but I've ditched keyboards for having a key in the wrong place or too small, or to close to another, so these things do matter. Finally, it does show some promise. There are some interesting points that if they are developed correctly could make it an enjoyable project, one to actually play with friends. The UI needs a lot of work, the story-line needs building upon, and the figures really need to be looked at, but unlike a lot of lot of projects, it is sitting on my desktop as we speak, I dip into now and again during the day while working on other projects so I'm certainly not dismissing it altogether. Best of luck to the developer and lets hope I've not put people off. The take-away from this is really to think about your figures carefully, use a spreadsheet and test everything.
  11. It should be noted that I don't consider this a definitive solution - rather it's a workaround. The reason being that you are adding another query, and it would probably be better to use a template manager such as Twig or maybe Smarty. Your workflow then becomes: requires/includes, and bootstrap your session check to see if the user is permitted to access this page handle any POST requests and perform redirects handle the GET request push all the up-to-date information out to your templating system
  12. While playing a number of mccodes games over the years, a lot of them exhibit a page "lag", where you perhaps commit a crime, our brave (nerve) bar goes down by one, your money goes up by $100, but you don't see these changes until the next page load. It's a very common problem and easily explained as the code as it stands outputs the user data with your bars and money *before* the page itself runs and outputs itself. So the simple solution, at the cost of a single extra query is to tweak the header.php script from: <?php class headers { function startheaders() { // ... } function userdata($ir, $lv, $fm, $cm, $dosessh = 1) { // ... } function menuarea() { // ... } function smenuarea() { // ... } function endpage() { // ... } } to: <?php class headers { private $_menu = '_nomenuarea'; // new constructor to save the body data public function __construct() { ob_start(); } // new destructor to display everything correctly public function __destruct() { global $db, $userid, $ir, $atkpage; // Get the body html $body = ob_get_clean(); // Refresh the global user information array $sql = 'SELECT u.*, us.* FROM users u LEFT JOIN userstats us USING (userid) WHERE userid = ' . $userid; $ir = $db->fetch_row($db->query($sql)); // Prep some basic variables for the header $fm = money_formatter($ir['money']); $cm = money_formatter($ir['crystals'], ''); $lv = date('F j, Y, g:i a', $ir['laston']); // Output the headers and userdata $this->_startheaders(); $this->_userdata($ir, $lv, $fm, $cm, $atkpage); // Call the correct menu call_user_func([$this, $this->_menu]); // Output the body echo $body; // And tidy up $this->_endpage(); } // These functions are called by globals.php/sglobals.php and intentionally do nothing public function startheaders() { } public function userdata($ir, $lv, $fm, $cm, $dosessh = 1) { } public function menuarea() { $this->menu = "_menuarea"; } public function smenuarea() { $this->menu = "_smenuarea"; } public function endpage() { } // These functions are the original functions called by globals.php/sglobals.php // Note, they have all been prefixed with _ private function _startheaders() { // ... } private function _userdata($ir, $lv, $fm, $cm, $dosessh = 1) { // ... } private function _menuarea() { // ... } private function _smenuarea() { // ... } private function _endpage() { // ... } // Finally add a "no-menu" for when no menu function has been called private function _nomenuarea() { echo '</td>'; echo '<td width="2" class="linegrad" bgcolor="#ffffff">&nbsp;</td>'; echo '<td width="80%" bgcolor="#ffffff" valign="top">'; echo '<center>'; } } It has the added advantage of meaning that that no longer have to call $h->endpage() anywhere in your pages, as it is automatically called. Obviously, if you have made changes to your header.php, then you have to fiddle with it quite a bit to shoehorn this concept in, and of course you may need to adjust the new _nomenuarea() method to suit.
  13. Well Cepheus should be getting a major update this week as will the blog. Working on the world and building view which is more complex than anticipated, but fun to write. Getting accurate resource calculations while offline without crons has proven to be an interesting process, but suggests a number of options for other games. Always interested to see more mods though I've not done anything with MCCodes in a while.
  14. Well, it's taking me a little longer than I expected to get the next point release done. Sadly work and family come first and I've had a bit of rush on at work of late. As for Inertia, I'll take a look; it's always useful to discover new technologies. Had a little time to think about the flow, it's a bit unstructured but for the sake of completeness I'll pop it in. Looking at tables: Users: [id, name, email, password, ... etc] Players: [id, user_id, ... etc] Systems: [id, ?player_id, x, y, ... etc Habitats: [id, world_id, resource_xxx_level, storage_xxx_level, ... etc] Buildings: [id, name, resource_xxx_consumption, resource_xxx_production, resource_xxx_storage, ... etc] Sites: [id, system_id, x, y, building_id, level, ... etc] See the blog for a better view of this! There's something gathering momentum in my head regarding combat, but it's a while of; I need to try to balance the resource production side of things first. Anyway, I think this architecture works; of course I need to update all the resources in the background without crons or queued jobs, but that's easy enough. There are some concerns with the structure, which I suspect will be taken care of with a little cheating on the normalisation front, but I'll leave that until such times as I get the updating mechanism in play and see how it works in real-time. Had a quick look at Inertia; looks interesting, but I'm not a fan of Vue and I'm ashamed to admit I've never touched React. Svelte might be an option as it looks interesting though I'll need to fire up a few test projects to get to grips with it properly. Regardless, good pointer @Script47, gave me some interesting reading material on the train.
  15. Google Fonts is your friend
  16. Ah short tags. Yes, they are often used in legacy code. Good spot. Always worth running your files through PHP's own syntax checker -- `php -l filename.php` if you suspect anything odd.
  17. The handling of the $_POST array is very strange, especially the ID element, Initially you check if it is number then take the absolute value. abs() returns an int or a float. Later on you check to see if is a string made up of digits. - ctype_digit() expects a string. It may be wise to extract the variables from the $_POST array early on; for example: $report_id = array_key_exists('ID', $_POST) && ctype_digit($POST['ID']) ? (int)$_POST['ID'] : 0; $status = array_key_exists('status', $_POST) && ctype_digit($_POST['status']) ? (int)$_POST['status'] : 0; $message = array_key_exists('message', $_POST) && is_string($_POST['message']) ? trim($_POST['message']) : ''; Now, both $report_id and $status are positive integers, while $message is a string. I'd probably start the ball rolling with `if ($report_id > 0)`, then check to see if status is within the range 1-5, check to see of your message is not empty, then finally check to see if a report actually exists with the given $report_id.
  18. Designing the game Well it's taken me a little longer than anticipated to work out the rough details, however I think I'm now in a position to start drafting up the initial stages. Obviously, there is going to be a number of changes made over time as I perfect the concept and play-test it, but it should be possibly to get the vary basic draft up and running over the next few days. The concept I started with the simple idea of a resource management game and that's where I'm going to end up. There will be a number of different resources, a number of different buildings creating and using the resources, and at a later stage, some special buildings that may change the levels of resource production / consumption. Looking at this, it should be possible to design a system that has, for example, 6 resources: production_1..6 (ie wood, stone, food) consumption_1..6 storage_1..6 time (for building, upgrading etc) By using these as field names I can hopefully make quite a generic template for other types of games. The next problem is in creating the buildings. Obviously I need production buildings of each of the resources and getting those levels correct is a case of firing up a spreadsheet and playing with some numbers. First I want some method of controlling the overall "inflation", that is the cost increase per level of the various resources be it in time, in production, in consumption etc. By varying this figure between 1.3 and 1.5 it looks like that is a passable start. Next I want the costs for building and/or upgrading certain buildings to be simple to calculate, all based on some initial values and the rate of inflation. | Level | Resource 1 | Resource 2 | Resource 3 | | ----- | ---------- | ---------- | ---------- | | 1 | 85 | 100 | 10 | | 2 | 110 | 130 | 13 | | 3 | 143 | 169 | 16 | | 4 | 186 | 219 | 21 | | 5 | 242 | 285 | 28 | | 6 | 315 | 371 | 37 | | 7 | 410 | 482 | 48 | | 8 | 533 | 627 | 62 | | 9 | 693 | 815 | 81 | | 10 | 901 | 1,060 | 106 | This assumes an inflation rate of 1.3 and the simple formula: floor(starting_value * inflation ^ (level - 1)) The starting_value I've set in the above to 85, 100, and 10 respectively. If I add in an efficiency value for each resource, one for production, one for consumption and one for storage, I can manipulate this by adding new buildings. As an example, if I have a base efficiency of 50% - I may be producing 121 units of resource 1 at level 5. If I build a refinery for example, that efficiency may increase to 60% pushing the production up to 145.2. Building more refineries or rather increasing the level of the refinery would increase the efficiency up may beyond 100% and of course I'd need a limit on the maximum level of refinery. This can be done with a simple max_level or maybe just by making it prohibitively expensive to upgrade. Putting it all into practice I can envisage a number of plots of land - each of which can contain one building. There needs to a limit on the number of plots to prevent runaway planets, and there needs to be a limit on the number of buildings of any one type; in some cases 1, in most, as many plots as there are. Now since I don't want to use crons, it would make sens for the back-end to pass a timestamp as ell as the inflation value, the efficiency, production, storage and consumption values to Javascript on every page load in probably a simple JSON block. Javascript can then be used to increase the global counters; or rather only the display of the counters, every second or every few seconds. If the user refreshes the page, or clicks on any link, then a little middleware can easily update the values stored in the database again based on the last update. No crons, no horrible updates without where clauses which means I can reduce the page locking in the database allowing for more simultaneous players. Wrapping up The ideas are in place, however I now have to translate those into code. From what I can see, this is not going to be too complex, though like all of these things, once you start writing code, you quickly discover unanticipated problems. Still, hopefully I'll be able to get something in play fairly quickly though I suspect I'll not be overly concerned about the UI at this stage, and just make sure I can get a working proof of concept.
  19. Try running your code through Exakat. It's a very powerful static analysis tool which is capable of determining the minimum PHP version and what extensions are required along with provided a number of very handy reports on the state of your code.
  20. Revision 0.1.1 released; full authentication, with tests across the board. It's not a big release per-say, however it does provide you with a working system, a full authentication layer and tests for all controllers. As a starting point, this has the potential to be used in many projects. Did I mention it's free? The next stage is to start to develop the game itself; though I must admit, part me of thinks I should look towards the building of an in-game communication system encompassing mail, and chat.
  21. Yes, I saw an article recently about VSCode's remote containers; not tried it yet as I'm fairly tuned into PHPStorm and have a number of plugins that I'd be lost without. Still worth a go. As for the SSL cert, well the blog is pure HTML, so no need for it, however I am hoping to bring up the git repo tonight, so I'll be apply certs in due course. As always, it's been a rush to try to clean up some of the posts, to rustle some some tools to help generate bit of code, write demos etc. Time is not my friend especially with a full-time job to contend with!
  22. I'm a Linux user mainly and have been for a while. Laravel's Sail seems the fastest and simplest way forward for most users as I've briefly tried it on a Mac and it works nicely, though not had the opportunity to try it on Windows. I'd guess with Laravel's attention to detail it will work as anticipated. My primary aim with the Docker is to minimise the potential differences in environments and to use something that I know is easy to migrate to native services on production servers. Valet I've never tried; as I was under the impression it required some of virtual system: VirtualBox, Qemu. Parallels and/or Hyper-V. Maybe it's worth visiting. Thanks for the pointer.
  23. I've had in mind a little side project for a while; in fact it's something that has been knocking around my head for many years. I suspect that it may well knock around for a few more unless I solve all the interesting problems. Rather than explain what it is I thought I may write up the process of creating it from scratch; and try to explain the reasoning behind the relevant components. It is potentially a long-winded process for some, but I reckon having a working, documented plan as well as a full test suite; using unit, feature and acceptance testing as well as a decent level of static analysis in place, I think the code can be something to be proud of, and something that can be shared with people further down the line. I would like to have the code peer-reviewed as well, so I'll be asking a couple of friends to look into the code, see if I've missed anything important. As for the code itself, yes, I will be making it available, and better yet, it will be open-source. I've seen a lot of smaller browser-based games fail badly because they have not opened themselves up to other people, and in fact those games have rapidly become stale, often badly managed and sometimes very toxic environments. Github, or Bitbucket? Not sure; I'll probably just host it myself using gitweb as it's an easy option. There's a tremendous amount of stuff to get through before a game can be launched, and a fair bit of maths to create and check formulas, nothing overly difficult but time-consuming. Some processes, I'll probably skip for brevity, and in order to make things easier for people following along, I will release code at key stages and try to move reusable features out to modules or components where possible. Wrapping up As a side-project, it is not a small thing, but equally it's unlikely to permit me to retire early; money may be possible to make from it, but that's not why I'm doing this. It's a bit of fun, a chance to learn some new concepts, and broaden my skills. After all, why else do we write programs? You can follow the progress at The Cepheus Project and from time to time I'll no doubt pop a post in here. Warning: It's early days yet, I'm still finalising some of he pages so url's may change. As a preliminary, and to copy in those people who don't wish to visit an external site; this is my thoughts on choosing the stack: Choosing the stack I'm not a fan of these so-called game "engines"; the term is, I feel, misused too often doesn't really reflect the nature of the product. So, I'll start with a language, add a framework for speed and efficiency, then add the remainder of the code components. PHP Everybody loves PHP, but let's make sure we use an up-to-date version. As of writing, this is PHP 8.1 and since I have PHP 8.1.7 installed on my development box, this is an ideal starting point. I don't know as yet what mods will be needed, but a plain install of 8.1 should be sufficient for now. The Framework I considered a number of options here, but Laravel seems to be the best choice as it comes with a lot of features out of the box that are going to save a lot of time. Yes I probably could have written my own, using any number of Symfony components, but that would have probably ended up very similar to a Laravel framework without the bells and whistles, so I'll just settle for Laravel and save a lot of unnecessary work for myself. CSS There's a number of different CSS frameworks these days, some people like the batteries included approach, while I've grown rather fond of Tailwind, which allows for rapid prototyping and equally allows me to create simple reusable components with all the relevant classes defined properly in CSS leaving the HTML nice and clean. Better yet, by adding in support for SASS, we can make the CSS a little more friendly with a hierarchical flow. Fonts Normally, I'd use Google Fonts to provide these, but being privacy conscious, I'm going to host some fonts locally which ensures Google doesn't perform any tracking. Overkill? perhaps, but I know a lot of people who are not keen on Google watching everything they do. JavaScript As for JavaScript, this caused me some problems. These days I think I like pretty much vanilla JS, so I'm going to use Alpine.js as it provides a very lightweight system and will hopefully help reduce the complexity when writing components, since I've no doubt there will be a lot of replication in the code. Databases MySQL will be ideal as it's well proven, well-rounded, and most people are fairly comfortable with it. I'm also going to add Redis for caching and later on: session storage. Node For the build process, I'm going to need Node.js. I have v16.14.0 installed on my development box and of course you will need Node's package manager: npm. Again I have this installed; version 8.3.1; on my box. Wrapping up Finally, I'll be using Docker for development to encapsulate everything into nice clean containers and to make the whole system portable between developers. Production-wise, I'll be using native services rather than Docker at least until the natives cause a problem!
  24. Crime/Mafia doesn't really interest me in part as there are some very good games out there already, in part as I feel they are too combative. I'm much more of a cooperative thinker although I accept that some level of inter-player combat be-it simple rankings or actual combat is valuable in its own right. Saying that, I'm easy; getting a feel for what is out there and what sort of features people are are actively using as well as the "polish" of current projects is very helpful. Perhaps I may be able to contribute in some small way to some of the open-source "engines" while I muse on my side project.
×
×
  • Create New...