Skip to content
View in the app

A better way to browse. Learn more.

MagicDuel Community

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Seigheart

Moderators
  • Joined

  • Last visited

Everything posted by Seigheart

  1. @Syrian Please tell me you saved that video >.>
  2. I’d love some help bringing our MagicDuel subreddit back to life. Rather than waiting for someone else to post, could we each take the initiative to share something we’re creating, doing, or enjoying in MD? MD has had a tonne of updates over the last few months—the Forge, fishing, farming and gathering improvements, the Evo Shop, Primordials, and more. There’s plenty happening, but people outside the game won’t see much of it unless we share it. Mur has been updating the Top 100 listings, and voting and honest reviews certainly help. But I think our strongest way of attracting genuinely interested players is showing our own enthusiasm. An active subreddit could give people a window into the communit, not just a description of the game, but the things we actually make and enjoy together. What could we post? Our Primordials: pictures, progress, personalities, and the stories behind them. Fishing competitions: winning catches, results, screenshots, congratulations, and memorable moments—not just event announcements. Forge creations and crafting: what we made, what inspired it, and how it turned out. Creature models and 3D prints: work in progress, finished prints, and painted models. Player projects: CSS redesigns, MDScript experiments, puzzle ideas, artwork, and writing. Quests and community events: invitations, preparations, stories afterward, and thanks to the people involved. Everyday discoveries and discussions: an interesting experience, a favourite scene, a question, or something that reminded you why you enjoy MD. I’ve been particularly focused on editing MagicDuel’s CSS, exploring MDScript ideas, and planning PHP puzzles I’d love to implement. I want to share more of that, and I’d really like others to join me with whatever interests them. You don’t need a polished project to contribute A screenshot and a few sentences are enough. Ask a question, congratulate a competition winner, or leave a thoughtful comment on someone else’s creation. Getting the subreddit active means having conversations, not simply filling it with announcements. With Christmas approaching, this could be something we build together. We could share seasonal projects, organize beginner-friendly activities, and show prospective players that there’s a welcoming community here for them to join. When a creation also fits another Reddit community, 3D printing, miniature painting, web design, or puzzles, we can share it there too, following their rules and being open about our connection to MD. But let’s start by making our own subreddit somewhere worth visiting. Could everyone reading this post one thing they’ve made, discovered, or enjoyed in MD—and take a moment to respond to someone else’s post? I’d love help making this a community effort. We already have the creativity and the passion. Let’s make more of it visible. Visit the MagicDuel subreddit
  3. I have something like that in the works coming up in the Lore Manor
  4. Can hand drawn, and then painted count?
  5. Maybe more advanced weather manipulators(like marvolo) could get that ability to manipulate weather immediately
  6. Done! Thank you!
  7. MDScript for Players: What I Learned Building Clickies ====================================================== Hi all, Seigheart here. I built the Primordial Keeper, the Primordial Archive and the Cartographer's Cipher, and along the way I ran into pretty much every wall MDScript has. So I've put together what I wish someone had handed me at the start. It's all taken from the official MD Script Manual on the forum and from scripts that actually run in game. Where I'm not sure about something, I'll say so. What It Is and Where It Goes ---------------------------- MDScript is a cut-down PHP that runs on the server whenever someone clicks your clicky. No classes, no $ variables. You get a fixed set of @ variables and that's it. Open your clicky with "edit own" and you'll see four fields: Title at the top, Content on the left, Script on the right, and Password at the bottom. Hit save&compile to apply your changes. Content holds HTML: text, images, forms. Only the part between <body> and </body> gets used, and newlines are ignored because it's HTML, so use <p> or <br>. Here's the thing that confuses everyone at first. If the Script box is empty, your Content shows as it is. The moment the Script box has anything in it, the Content disappears until your script does echo @content[0];. You can cut the Content box into pieces with this exact line: <!-- content separator --> The pieces become @content[0], @content[1] and so on, starting at 0. It has to say "content separator", not "content section". Then you can show different pieces under different conditions. Plenty of us just leave Content empty and print everything from the Script box with echo. That's what I do. One more thing: what you see in the editor right after save&compile can differ from what a normal visitor sees, and that includes storage. Always test as a visitor. Your First Script ----------------- Every script needs a locations line: (locations 1_0x0_1) No quotes, no ; at the end. For several locations, separate them with commas and no spaces, e.g. (locations 1_0x0_1,1_1x1_1). You get 12 at most. Variables don't work in it. The editor shows the right line for your spot above the code field ("Add location setting: (locations X)"). Put it on the first line. The manual says "anywhere", but the error message says first line, so I go with the error message. For reference, 1_0x0_1 is the Gazebo of Equilibrium. I'm not 100% sure what each number in a coordinate means, so don't take my word on that. Watch out for this one: an "incorrect location" error can show up when the real mistake is somewhere else in your code entirely. Printing is easy. echo and print write HTML into the page: (locations 1_0x0_1) echo "<p>Hello, traveller!</p>"; Variables are where it gets odd. You can't make your own. You get @va to @vz (26 general ones), plus @tpl, @temp and @log, which work the same way and just have friendlier names. Then there are the special ones: @input (form data), @content (Content pieces) and @storage (saved data). Even loop counters have to come from that set: for (@vi = 0; @vi < 4; @vi++) { ... }. foreach (@vp as @vk => @vh) works fine. Arrays work too, so one variable can hold a lot: @vu['colour'] = 'gold';. Forms and @input ---------------- Put a form in your Content box or echo one from your script: <form method="post" action=""> <button type="submit" name="go" value="A">Option A</button> </form> It posts back to the same clicky, and whatever was sent shows up in @input: if (isset(@input['go']) and @input['go'] == 'A') { echo "You picked A"; } $_POST isn't allowed. Always use @input. Now, two gotchas. First, field names. A field name containing a banned bit of text breaks the script. The forum example is a field with "val" in its name, which had to be renamed hidden_button. Second, and this one bit me constantly: the word "value" itself. The filter checks your whole script, strings included, and "value" contains "val". If you echo your buttons from the Script box, build the word in pieces: @vv = 'va' . 'lue'; echo "<button type='submit' name='go' " . @vv . "='A'>Option A</button>"; HTML typed straight into the Content box isn't part of your script, so value="Yes" is fine there. The official tutorial does exactly that. Always check what comes in, because players can send anything. Use isset() first, trim() it, compare it to the exact things you expect, and wrap anything you print back in htmlspecialchars() or strip_tags(). For numbers, check it's only digits, e.g. strspn(@vx, '0123456789') == strlen(@vx). There's no JavaScript button handling here. Every button is just another post back to the server. Remembering Things ------------------ Storage with mds_storage() This is the main way to keep data: @vo = mds_storage('myname', 'toau'); It gives you back a number. From then on, read and write @storage[@vo], and whatever's in there gets saved. The second part is the type: - totu: this object, this user - toau: this object, all users - aotu: all objects, this user - aoau: all objects, all users (kept apart per editor) The same name with a different type is a different storage. You can't read another editor's storage, and an empty storage gets deleted. Start it as an array the first time. If it ends up as a plain number, later writes fail with "Cannot use a scalar value as an array". This is the opener I use: if (!isset(@storage[@vo]) or is_scalar(@storage[@vo])) { @storage[@vo] = array(); } For one record per player inside a shared storage: @storage[@vo][uv('name')] = ...; I haven't tested the size limits myself, or what happens if two players save in the exact same instant. My guess is the last write wins, but I don't know for sure. The old mds_storage_load / mds_storage_read names reportedly get rejected because they contain "load" and "read". Just use mds_storage(). store() and retrieve() store(@vh); in one item and retrieve(@vh); in another. It can hold whole arrays. The forum says it's one value per scripter and player, but I haven't checked that myself. Session Data This is the temporary, fast option. mds_store_sessdata(value, box) (alias storetmp) saves, and mds_retrieve_sessdata(@holder, box) (alias retrievetmp) reads. You get 10 boxes (0 to 9) per player, and each editor has their own set. Strings only, max 250 characters, so serialize() arrays first. It lasts until the player logs out and is shared by all your items. Keys Keys are yes/no flags on the player: mds_give_rpcq_keys('zq77-door'); // give mds_has_rpcq_keys('zq77-a,zq77-b') // true only if the player has ALL of them mds_take_rpcq_keys('zq77-door'); // take away They're comma-separated text, no arrays. And they're global: any script checking the same name sees the same key. The game saves them as rpcq-<name>. So pick a unique, secret prefix, or someone will collide with you or fake your keys. Keys aren't for keeping numbers. Use storage for counts. Where keys really shine is linking two clickies. That's how I connected the Primordial Keeper and the Cartographer's Cipher, and it's how you'd build a quest that starts at one clicky and ends at another. One thing I'm not sure of: whether a key you give in this click can be checked in the same click. I build around it so it doesn't matter. Reading the Player ------------------ uv('name') reads facts about whoever is clicking. It's read only. The names I know of: id, ve, vp, xpl, maxve, maxvp, land, alliance, age (active days), loyalty, honor, name, mp, heads, won, lost, avatar_level (0 none, 1 B/W, 2 gold access), avatar, xp, kills, illusion, location (coordinates text), stored_heat, and since 2013: tag, description, principles, landscore. Funny one: "description" contains a banned piece, so you have to write uv('descri' . 'ption'). Land numbers are 1 No Homeland, 2 Marind Bell, 3 Loreroot, 4 Golemus, 5 Necrovion, 6 Underground, 7 Archives, 8 No Mans Land, 9 unknown, 10 Lands of the East. date('z') gives you the MD day (day of the year). Server time zone is Europe/Helsinki. A few other checks on the player: - mds_has_item('Silver coin'): how many of that item they hold. Coins and resources count. - mds_is_itc('ITC...MDI'): checks an item transfer code and gives back its details, or false. - mds_is_ctc('CTC...MDC'): checks a creature transfer code and gives back the creature's details, or false. - mds_location_visits('current'): how often they've been here. Handy for hiding spoilers. - mds_player_heat(), mds_get_resource_count(), mds_current_weather(). Fair warning: you can only check items. Nothing documented lets a script give or take items, creatures or quests. Quests get built out of keys and storage. Examples -------- All six of these pass a PHP syntax check and a banned-word scan. Swap 1_0x0_1 for your own location, and change the zq77- key prefix and the storage names to your own. The real test is still save&compile in game. Hello and a Click Counter (locations 1_0x0_1) // Hello and a shared counter for this clicky. @va = uv('name'); @vo = mds_storage('myhellocount', 'toau'); if (!isset(@storage[@vo]) or is_scalar(@storage[@vo])) { @storage[@vo] = array(0); } @storage[@vo][0]++; echo "<p>Hello, " . htmlspecialchars(@va) . "!</p>"; echo "<p>This clicky has been clicked " . @storage[@vo][0] . " times.</p>"; A Button Menu (locations 1_0x0_1) // A menu of buttons. Each button posts go=A, go=B or go=C. @vv = 'va' . 'lue'; echo "<form method='post' action=''>"; echo "<button type='submit' name='go' " . @vv . "='A'>Lore</button> "; echo "<button type='submit' name='go' " . @vv . "='B'>Map tip</button> "; echo "<button type='submit' name='go' " . @vv . "='C'>Who am I?</button>"; echo "</form>"; @vg = isset(@input['go']) ? trim(@input['go']) : ''; if (@vg == 'A') { echo "<p>Long ago, a gazebo stood here in perfect balance.</p>"; } elseif (@vg == 'B') { echo "<p>Look for clickies near the stairs.</p>"; } elseif (@vg == 'C') { echo "<p>You are " . htmlspecialchars(uv('name')) . ", with " . uv('age') . " active days.</p>"; } A Once-a-Day Greeting (locations 1_0x0_1) // Once per MD day per player. date('z') is the day of the year. @va = uv('name'); @vd = date('Y') . '-' . date('z'); @vo = mds_storage('mydailygreet', 'toau'); if (!isset(@storage[@vo]) or is_scalar(@storage[@vo])) { @storage[@vo] = array(); } if (isset(@storage[@vo][@va]) and @storage[@vo][@va] == @vd) { echo "<p>You have had your greeting today. Come back tomorrow!</p>"; } else { @storage[@vo][@va] = @vd; echo "<p>Good day, " . htmlspecialchars(@va) . "! Here is your daily blessing.</p>"; } A Small Quest with Keys (locations 1_0x0_1) // A three step quest kept in keys. Pick your own odd prefix so nobody guesses it. @vv = 'va' . 'lue'; @vg = isset(@input['go']) ? trim(@input['go']) : ''; if (mds_has_rpcq_keys('zq77-step2')) { echo "<p>The quest is complete. Well done!</p>"; } elseif (mds_has_rpcq_keys('zq77-step1')) { if (mds_has_item('Silver coin') >= 1) { mds_give_rpcq_keys('zq77-step2'); echo "<p>You show the silver coin. The quest is complete!</p>"; } else { echo "<p>Step 2: come back holding a Silver coin.</p>"; } } elseif (@vg == 'S') { mds_give_rpcq_keys('zq77-step1'); echo "<p>Quest started. Step 2: come back holding a Silver coin.</p>"; } else { echo "<form method='post' action=''><p>A stranger asks for help.</p>"; echo "<button type='submit' name='go' " . @vv . "='S'>Accept the quest</button></form>"; } A Riddle Door with a Typed Answer (locations 1_0x0_1) // A riddle door. The form field is named 'guess' (a field name holding v-a-l fails). @vv = 'va' . 'lue'; if (mds_has_rpcq_keys('zq77-door')) { echo "<p>The door is unlocked for you.</p>"; } else { @vg = isset(@input['guess']) ? strtolower(trim(strip_tags(@input['guess']))) : ''; if (@vg == 'echo') { mds_give_rpcq_keys('zq77-door'); echo "<p>Correct! The door swings wide.</p>"; } else { if (@vg != '') { echo "<p>Wrong. Think again.</p>"; } echo "<form method='post' action=''>"; echo "<p>I speak without a mouth and hear without ears. What am I?</p>"; echo "<input type='te" . "xt' name='guess' maxlength='30'> "; echo "<button type='submit' name='go' " . @vv . "='1'>Answer</button></form>"; } } Notice the 'te' . 'xt'. "Text" is on my cautious list below. Content Pieces (from the Official Beginner Tutorial) Content box: <form method="post"><input type="submit" name="wizard" value="Yes"/></form><!-- content separator --><p>Then go to the next room.</p> Script box: (locations 1_0x0_1) // Content box holds: a Yes button, then the separator, then a reply. echo @content[0]; if (isset(@input['wizard']) and @input['wizard'] == 'Yes') { echo @content[1]; } The Word Filter --------------- This is the part that cost me the most time. The filter is a plain text check over your whole script: code, strings and comments. It doesn't care about grammar. If a banned piece shows up anywhere, even buried inside a longer word, you get one of these: [STRICT RESTRICTION], [GENERAL RESTRICTION], [LANGUAGE RESTRICTION] (function not supported) or [SEQUENCE RESTRICTION] (banned character sequence). While building my clickies it caught "catches", "gradient" and "Herald", and a lot more. Here's what I know is banned, from the manual, Kaya's 2013 tests and errors I've hit in game: script, extend, val, split, parse, open, mod, ini, ext, try, error, call, load, read, INF, is_a, T_AS, T_SR, E_PARSE, sprintf, key_exists, rename, catch, object, gradient, era, new, use, pass, stat, move, sid, die, true, and three dots in a row (...). Also not allowed: $ variables, $_POST, var_dump. Then there's my cautious list. Some are known PHP danger words and some have caused me trouble. I haven't confirmed every one of them is actually banned, but I avoid them all to be safe: http, text, value, empty, null, break, save, session, var, safe, file, exit, global, function, include, require, eval, exec, system, shell, class, static, header, cookie, server, request, onclick, onload, javascript, iframe, alert, document, window, import, join, link, and __. The fix is to split the word with . (which joins two strings): echo "ex" . "tend"; @vv = 'va' . 'lue'; @vg = "linear-gra" . "di" . "ent("; For three dots, put spaces between them: . . . These are the everyday words that tripped me up, what's hiding in them, and what I did instead: - valid, invalid, value (val): 'va' . 'lid' - gradient (gradient, die): "linear-gra" . "di" . "ent(" - Herald, Seraph, Hourglass Seraph (era): 'Her' . 'ald' - already, ready, spread, Stonetread (read): 'Stonetre' . 'ad' - next (ext): reword it ("the day rolls over in") - shining (ini): reword - stately, status (stat): reword - catches (catch): reword - entry, Try (try): reword - remove (move): reword - side (sid): reword - compass, password (pass): reword - used (use): reword - moderation (mod): reword (I went with "warden") - object-fit in CSS (object): 'obj' . 'ect-fit' - justify-content in CSS (content): avoid it - description in uv (script): 'descri' . 'ption' - a true argument (true): pass 1 instead - array_values (val): loop over the array instead - is_array (is_a): use is_scalar - next(), str_split, preg_split (ext, split): not usable - page load, new day (load, new): reword Image file names and CSS count too. A picture called "mirrorseraph.gif" will trip "era". The Functions You Can Use ------------------------- MD Functions - mds_has_rpcq_keys('a,b'): True if the player has ALL the keys. - mds_give_rpcq_keys('a,b'): Gives the keys. - mds_take_rpcq_keys('a,b'): Takes the keys. - uv('name') (also mds_read_uvars): Reads a player fact (see Reading the Player). - mds_storage(name, type): Opens or creates storage; gives the index into @storage. - mds_storage_load, add, read: Old storage names; load and read reportedly blocked, not 100% sure. - mds_store_sessdata(value, box) / storetmp: Saves text (max 250) in session box 0 to 9. - mds_retrieve_sessdata(@holder, box) / retrievetmp: Reads a session box into a variable. - store(@v) / retrieve(@v): Simple keep and fetch across items. - mds_template(template, data, return, columns, td_attributes): Fills [[name]] placeholders; a list of records gives a table. - debug(@v, 'label'): Shows a coloured dump box (the manual's mds_debug) - mds_no_warnings(): Hides MDScript warnings only. - mds_has_item('name'): How many of an item the player has. - mds_is_itc(code): Checks an item code (pass only the ITC...MDI part); id, uid, playername, name, creationdate, transferdate, tag, or false. - mds_is_ctc(code): Checks a creature code (CTC...MDC part); id, uid, playername, cid, tokens, dateBorn, transfercount, tradevalue, customName, vitality, level, experience, battlesWon, age, or false. - mds_creature_icon(id, attrs): Prints a creature picture (creature ID, not the code) - mds_player_avatar(name, attrs): Prints an avatar; max 5 per script. - mds_player_heat(): The player's active heat. - mdsi_takeheat(amount): Moves heat from the player into the item; asking for more than they have takes all and keeps nothing. - mdsi_item_heat(): ['current' => total, 'players' => [name => heat]]. - mds_location_visits(loc or 'current'): How many times the player has visited. - mds_check_group_location(players, coords): How many of those players are online there. - mds_current_weather(): E.g. "heavyrain", or false. - mds_get_resource_count(): [resource => count]. mds_is_atc was only ever wished for on the forum. As far as I know it doesn't exist. Allowed PHP Functions (210) Mur's original list has 236. Kaya found that 26 of them fail because their names contain banned pieces, which leaves these 210: - Arrays: array, array_change_key_case, array_chunk, array_combine, array_diff, array_diff_assoc, array_diff_key, array_fill, array_fill_keys, array_flip, array_intersect, array_intersect_key, array_keys, array_merge, array_merge_recursive, array_multisort, array_pad, array_pop, array_product, array_push, array_rand, array_replace, array_replace_recursive, array_reverse, array_search, array_shift, array_slice, array_splice, array_sum, array_unique, array_unshift, arsort, asort, count, current, each, end, in_array, key, krsort, ksort, list, natcasesort, natsort, pos, prev, range, reset, rsort, shuffle, sizeof, sort, uasort - Text: base64_decode, base64_encode, chop, chr, count_chars, crc32, crypt, echo, explode, get_html_translation_table, hash, htmlspecialchars, htmlspecialchars_decode, implode, lcfirst, md5, number_format, ord, print, printf, serialize, str_ireplace, str_pad, str_repeat, str_replace, str_rot13, str_shuffle, str_word_count, strcasecmp, strchr, strcmp, strcspn, strip_tags, stripos, stripslashes, stristr, strlen, strnatcasecmp, strnatcmp, strncasecmp, strncmp, strpbrk, strpos, strrchr, strrev, strrpos, strspn, strstr, strtok, strtolower, strtoupper, strtr, substr, substr_compare, substr_count, substr_replace, trim, ucfirst, ucwords, unserialize, url, urldecode, urlencode, vprintf, wordwrap - Dates and times: date, date_add, date_create, date_diff, date_format, date_offset_get, date_sub, date_sunrise, date_sunset, date_timestamp_get, date_timezone_get, getdate, gettimeofday, gmdate, gmmktime, gmstrftime, idate, localtime, microtime, mktime, strftime, strptime, strtotime, time, timezone_location_get, timezone_name_get, timezone_offset_get, timezone_transitions_get - Patterns: preg_filter, preg_match, preg_match_all, preg_quote, preg_replace - Type checks: is_binary, is_bool, is_double, is_float, is_int, is_integer, is_nan, is_null, is_numeric, is_scalar, is_string, isset, unset - Maths and other: abs, acos, acosh, asin, asinh, atan, atan2, atanh, base_convert, bindec, ceil, cos, cosh, decbin, dechex, decoct, deg2rad, exp, expm1, floor, getrandmax, hexdec, hypot, log, log10, log1p, max, min, mt_getrandmax, mt_rand, octdec, pi, pow, rad2deg, rand, round, sin, sinh, sqrt, srand, tan, tanh - Old encryption: mcrypt_cbc, mcrypt_cfb, mcrypt_ecb, mcrypt_ofb url is on the list but isn't a real PHP function. The basic language pieces like if, else, elseif, for, foreach, isset, array, list, echo and print all work. These are on the list but don't work: array_count_values, array_intersect_assoc, array_values, chunk_split, date_interval_format, date_modify, date_parse, date_sun_info, fmod, the three geoip_ functions, is_array, is_finite, is_infinite, lcg_value, mt_srand, next, preg_last_error, preg_replace_callback, preg_split, similar_text, str_split, timezone_open, vfprintf, vsprintf. Also array_key_exists (removed) and var_dump (disabled). Anything not on the list (for example ctype_digit) gives you a [LANGUAGE RESTRICTION]. Limits, Tips and Testing ------------------------ The limits I know of: 12 locations per script, 10 session boxes of 250 characters, and 5 mds_player_avatar calls per script. A member mentioned about 5 seconds of run time and a memory cap, but I haven't seen that confirmed officially. There's no official figure for maximum script size or storage size. To find bugs, print values: print "V=" . @va; or debug(@va, 'va');. If a fatal error breaks the page, a blue "edit in case of error" link lets you fix it. Design for the popup. The live clicky window is small, about 535 px wide and 165 px tall before it scrolls. Build everything server-side with buttons. Each click is a fresh run, so keep state in storage or keys. Know the staff rules. Don't copy or improve game or MD Shop features, no chats or messaging, don't show pictures of places players can't reach, "alternate reality" items need 70+ active days, and there's zero tolerance for abusive or tricking scripts. And never send players to the wrong internal page; staff warn that can get you banned. If you have PHP on your computer, you can check grammar like a missing ; or unmatched brackets. Remove the (locations ...) line, change every @ to $, add <?php at the top, then run php -l. Line numbers will be off by one. It only catches syntax, though. It won't catch banned words, banned functions or wrong variable names, so search your script for the words above too. The real test is save&compile and then clicking it as a visitor. The Official Docs ----------------- - MD Script Manual (forum section): https://forum.magicduel.com/forum/168-md-script-manual/ - Step-by-step introduction for absolute beginners: https://forum.magicduel.com/topic/16837-a-step-by-step-introduction-to-mdscript-for-absolute-beginners/ - Variables: https://forum.magicduel.com/topic/5494-variables/ - Location setting: https://forum.magicduel.com/topic/6799-location-setting/ - Content sections: https://forum.magicduel.com/topic/5495-managing-content-sections/ - Storing values: https://forum.magicduel.com/topic/5492-how-to-store-valuesvariables-using-mdscript/ - Key control: https://forum.magicduel.com/topic/5498-key-control/ - User variables: https://forum.magicduel.com/topic/5499-user-variables/ - Restrictions and errors: https://forum.magicduel.com/topic/5493-restrictions-and-errors/ - PHP functions available: https://forum.magicduel.com/topic/5500-php-functions-availble-in-mdscript/ - Templates: https://forum.magicduel.com/topic/5496-templates/ - Debugging: https://forum.magicduel.com/topic/5497-debugging-your-code/ - Index of basic functions: https://forum.magicduel.com/topic/14268-index-of-basic-mdscript-functions-links/ - Content rules: https://forum.magicduel.com/topic/7137-new-rules-regarding-md-script-and-item-customizations/ Skip the "Old MD Script Language Reference". It's out of date. Happy scripting, and if you build something, show me! Seigheart
  8. I am open to any challengers
  9. It would be just as easy to update as the pages are if they break.
  10. Nautical themed for our pirate friends
  11. These were done with 5 word prompts
  12. In the same spirit as the automated assisted player profile page creator, I think we could really spice things up by doing the same for the whole game's layout. The idea is a built-in layout and theme editor where players can restyle the interface using AI prompts to change anything: panel frames, backgrounds, menu buttons, colours, ornaments and fonts. It would be purely cosmetic, so no game info, warnings or rules text could ever be hidden or changed. Players could save their layouts, share them with others, and maybe showcase the best ones. On top of that, there could be preset themes for each land, for example: Loreroot: a lush elven forest of deep greens and dark bark, with gold fireflies. Necrovion: death and decay, with dripping black tar, toxic green witchfire and bone. Presets for the other lands too, built from each land's own art and lore. It could also help with wide and ultrawide monitors, which leave a lot of empty space at the sides right now. A layout option could put that space to use with themed backgrounds and wider panels. I've been testing a few of these looks locally with a browser stylesheet, and the game feels much more alive with them. What do you all think?
  13. 154,229 AP is wild. Wow. TK got rich this weekend.
  14. Not really though. Auctions require time invested in the game to be sold off (labour or days on crits). We aren't getting new players sticking around long enough to do that. I'm trying create a path forward for new players to catch up with us old farts.
  15. I hear you, Mur, and I agree non-paying players need a real way to earn silver. Right now it takes a lot of time and effort for them to get very far without gold and silver. We already have many ways for creative people to earn it, through crafting, trading, events and services for other players, and those paths could be strengthened. Starting a new account without any shop purchases... It's rough. My line of thought is beyond just gold and silver/forge fires. It's more concern with other players trying to catch up. What I'm really after is this: if gold and silver weren't so uncommon, people would be more willing to spend them instead of hoarding them. Coin that keeps moving between players, both paying and non-paying, makes for a healthier market than coin sitting in a few vaults. More movement in the market is good for everyone.
  16. That's a fair concern, and I agree the forge already leans toward whoever can spend the most. A per-item monthly cap, like the one I suggested for Magical Forge Fire, would stop anyone from pouring their whole budget into gold. But maybe the bigger problem is that gold just piles up. Perhaps we need more gold sinks to pull it back out of the economy. Fish worries me too. Now that fish can be sold for copper at the Fish Market, I foresee a lot of market turmoil when the population returns. Some ideas for draining coin back out: Armour repairs: let players pay a machine to repair armour, priced so crafters can still undercut it. That way coin leaves the game and crafters keep their work. Public machines: charge silver to operate them, and gold for higher-tier jobs like cutting diamonds. Pickles: raise the price at the pickle vendor and make it climb the more someone buys in a month. Heavy users pay more, and casual players hardly notice. Auction tax: We love this one Sinks like these would keep supporter gold from flooding the market, whichever way the packages end up.
  17. Howdy folks, The monthly supporter packages are one of the best ways we have to ensure long term financial health, and I'm grateful to everyone who supports MagicDuel. But a fixed bundle doesn't fit every player. A crafter burns through Forge Fire, a collector wants gold, and a fighter may care most about credits for tokens. Many of us end up with rewards we never touch while running short of the ones we need/want. The people who may be on the fence about being subscribers could be pushed over the edge to commit to monthly subscriptions. So I'd like to propose a simple change: give each supporter tier a monthly point budget, and let players spend it on the rewards they actually want. How it would work: Each tier grants Supporter Points every month, and every reward has a fixed point cost. Here are example values to start the discussion: Reward Point cost 1 Gold 15 1 Silver 1 1 Regular Forge Fire 15 1 Magical Forge Fire 40 10 Credits 10 Other current package items Valued at their usual share of a package A supporter whose tier grants 500 points could take all gold, mix Magical Forge Fire with silver, or split it however they like. The total value matches what the tier gives now. Only the mix changes. Why it helps Supporters get rewards they'll actually use, which makes supporting feel more worthwhile. Crafters, fighters and collectors are all served equally, without separate packages for each. Prices stay balanced, because every item has one clear value and the total budget is fixed. It's easy to tune. If something is too strong or too weak, only its point cost needs to change. Possible safeguards A monthly cap on high-impact items like Magical Forge Fire, so the economy isn't flooded. Unspent points could roll over for one month, so nobody loses value over a busy week. The current fixed packages could stay as "quick pick" presets for players who don't want to choose. I'd love to hear what other supporters think the right values would be, and whether there are items you'd want added to the list. With respect and a well-stoked forge, Seigheart Master Craftsman of the Maker's Circle
  18. In the same string of thoughts, can we upload individual images for named shop items (Seigheart's Autograph for example). It wont let me upload for just mine.
  19. Greetings, fellow wanderers, MagicDuel has been around for a long time, and it's still one of the most unique games out there. But a realm is only as alive as the people in it, and right now we need more new faces walking off the boat at Gateway Island. I'm putting together a plan to spread the word about MagicDuel, and I'm looking for a few people to help me carry it out. ==== PLEASE NOTE ==== This is my own private strategy. It is not official, and it is not sponsored or endorsed by MagicDuel or its staff. The details will be shared privately with those who join. ==== WHY IT MATTERS ==== More players means more duels, more trades, a livelier market, and more people to share the stories and secrets of the Realm with. Every new player we bring in keeps MagicDuel growing. And when they arrive, we're ready for them. There's help on Gateway Island, guides on the forum, and a permanent New Player Quest waiting to teach them how to fight. ==== GET INVOLVED ==== If you're willing to help, please PM me and I'll fill you in on the plan. Thank you to everyone who keeps this realm alive. Seigheart
  20. Not necessarily extreme, but a bit spooky on Halloween
  21. Greetings, travelers of the realm. The lanterns are burning low and Halloween is nearly over, so here's a look back at the Shattered Epitaph event. Thank you to everyone who hunted, guessed and gathered alongside the Lantern Wraith this week. The story A little girl's voice was sealed inside a broken Epitaph, and its shards were scattered across the lands. The Lantern Wraith, a restless spirit, searched every corner to gather them, then handed them back to the living one whisper at a time. Your task was to find the pieces, trade them, and rebuild the stone before her voice faded for good. The trail of whispers (Oct 25 to 28) Ten shards, pieces 22 through 31, were hidden with rhyming hints that led from one to the next. The trail ran from the Fields of Abandonment through Wind's Sanctuary, the Gates of Ages, Reconciliation Pass, Shadow Hutwood, Fenths Press, the Plains of Liberty and the MDA Main Gates, ending at The Aramory. Riddles at the Gazebo Anyone who asked the Wraith for a shard got a MagicDuel riddle instead. Wrong answers earned a rhyming jab and another try. Two players solved theirs: Marvolo answered Liquid Dust and won piece 48. Seigheart answered AP and won piece 53. Else, Nep, Chewett, Ledah, Marcorias, Sephirah Caelum and Sunfire were challenged too. Well played to all of you for stepping up. Candy storms The Wraith gave out 52 Halloween Candy codes in all: a few at the Gazebo on Oct 29 and 30, a trickle on the 31st, then two storms with twelve codes at dusk and twenty-eight more after nightfall. Unclaimed candy lasts until November 18. The final scatter (Oct 31) In the last hours, the Wraith left the remaining 24 shards one per scene across the realm: Tranquil Plains, Fenths Press, the Meeting of the Roads, Maple Road, Hill Garden Hub, Left Field Slope, Right Field Rise, Shadow Hutwood, the Garden Tools Hut, Fortune's Well, the Gazebo of Equilibrium, the Gates of Marind Bell, the Champion's Dome, Wind's Game, the Plains of Deceit, Reconciliation Pass, the Path of Loneliness, the Howling Gates, the Clash of Ages, the Road of Battles, all three rooms of the Paper Cabin, and back where it all began at the Fields of Abandonment. By the numbers 36 Epitaph shards released (pieces 22 to 57) 2 riddles solved 52 candy codes given out Thank you Thank you to Aelis, Seph, and Samon for helping shape this event, and to everyone who came out to hunt, trade and solve. Putting this together was a real pleasure. Whoever holds the most complete Epitaph, let's see it. Her voice is in your hands now. Happy Halloween, and may your lanterns stay lit. Seigheart, Master Craftsman of the Maker's Circle
  22. Greetings, newcomers of Gateway Island, Fighting is at the heart of the Realm, and the best way to learn it is to step into the arena. So I've set up a quest just for you, and it isn't going anywhere. This is a permanent quest, open to every new player who arrives, today or a year from now. ==== THE QUEST ==== Learn how fighting works in the Realm. 1. Fight me and win 3 times. 2. Fight me and lose 3 times. 3. Read the battle log after each fight to see why you won or lost. Winning teaches you what works. Losing teaches you even more. The battle log is where the real lessons are, so don't skip it. ==== REWARD ==== A Silver Coin! ==== REQUIREMENTS ==== Open to new players. No special level or creatures needed, just a ritual and some patience. ==== HOW TO START ==== Send a PM to Fenrir Greycloth on GWI (Found in the Arena most days), and we'll get you started. Fenrir Greycloth is my alt on Gateway Island, so you'll be fighting me under another name. Don't be shy. Every great duelist started with their first fight. See you on the island. Seigheart (as Fenrir Greycloth on GWI)
  23. The Maker's Circle Opens Its K Doc Travelers of the Realm, As founder of the Maker's Circle, I share the knowledge I possess, not hoard it. Too long have the secrets of the trade been kept behind closed doors, whispered between a few and lost when they wander off. No more. The Circle's K Doc is now open to all who wish to learn, and to all who wish to add what they know. Inside you will find the craft as we understand it, gathered and written down so no maker has to wander blind: The exact words of every instruction. Each command recorded in its precise phrasing, so your work answers the first time and not the fifth. Resource maps. Where each material can be found, so you spend your steps gathering instead of searching. Cauldron training. How the cauldron works, what it accepts, and how to train your hand at it. Resource gathering assistance. Guidance on collecting what you need, and help from fellow makers when a material proves stubborn. Resource splitters. Where to acquire them, what they cost, and how to put them to good use. And more besides. It is a living record. Bring what you discover, and leave it richer than you found it. To join, use this code: KCEWPKTAW76N326373IM Know this before you enter. Joining is a pledge. By taking up the code, you promise to follow the rules of the Circle and to remain in character within its pages. The Rules of the Circle: 1. Respect every maker. Speak kindly, disagree with care, and leave no one feeling small at the workbench. 2. Measure twice, cut once. Test what you write before you share it, so no one wastes their materials on a wrong recipe. 3. Credit the maker. If a discovery is not yours, name the one who found it. 4. Share your tools. Knowledge kept in a locked chest helps no one. Add what you learn. 5. Mend, don't break. Fix a mistake when you find one, and never damage another's work. 6. Every master was once an apprentice. Welcome the new, and answer their questions with patience. 7. Stay in character. Within these pages, we are makers of the Realm. Knowledge shared is knowledge that endures. I look forward to seeing what we build together. Seigheart Founder of the Maker's Circle

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.