Jump to content

Please be aware we are currently sourcing funding for MULTIMART, please click here if you're interested... All donations will go toward MULTIMART and its progression.


  • Content count

  • Joined

  • Last visited

  • Days Won


TheOnlyDroid last won the day on October 19

TheOnlyDroid had the most liked content!

Community Reputation

59 Excellent


About TheOnlyDroid

  • Rank
    Glorified System's Administrator
  • Birthday June 7

Recent Profile Visitors

1,489 profile views
  1. Echo (ULTRA ULTRA) Review

    After many months of wait, countless times watching trailers and gameplay reveals... I honestly thought that I'd enjoy Echo, but I found myself enjoying the environmental design, shader implementation and asset design rather than the overall gameplay... The game starts off showing the capabilities of Unreal Engine 4 (UE4 / Formerly UDK (UE3)) and what you can achieve with some hard work and a little elbow grease... Even the menu was thoughtfully laid out and implemented as "En"s eye following your cursor and revealing the menus as you move.... There was a single fundamental flaw when it came to the introduction of the game, The Menu; As fluid as, well designed and pretty as it seemed... I sat for a solid twenty minutes thinking that the game was still loading or I might have been waiting for some instructional text to pop on my monitor, this wasn't the case; I moved my mouse and low and behold I was amazed by it, I sat for a further twenty minutes moving my cursor and admiring the work, elbow grease and pure imagination ULTRA ULTRA had put into it. Being entrapped by what at first glace looked/seemed and felt like an enjoyable experience, I was immediately turned around and sat on my own arse fannying about waiting for excruciatingly long cut-scenes to finish, I mean the voice acting alone was grasping at me and enticing me to play more; So that's what I did... Thirty minutes into the game I found myself walking around what seemed/looked like an entrapped planet of snow to further spend twenty minutes admiring the level and asset design of the snow covered catwalks further into the planets core... To Quote PC Gamer's "Lauren Morton" Further into Echo, you're wandering the halls of "The Palace" a marble and goal leaf covered "installation" (to put it simply), again entrapped by Marvellous level, asset, character and art design... But the fact remains its heavily reliant on the Modular asset design the game and levels become excruciatingly repetitive and hard to look at (let alone acknowledge), in the early game especially when you first enter the palace you cannot help yourself but take your time and admire what you at first glace think is something pretty and unique. That combined with the Integrated Heads Up Display (HUD) that at first glace seems like a half baked Idea, at least during the first hour of the game (depending how slow you're going)... Just adds the cherry on top, with the sly issue being there's not much in the way of information at least again at the start of the time game, you're expected to know where to go; I found myself listening for Audio cues to find the correct route in the early game. I know what you're saying "But Droid"/"But Austin", its a unique puzzle game with one of a kind idea's and systems, I'm aware of that but when you spend five minutes looking for something to press your interact button on just to get into the nitty gritty of the game before even entering "The Palace" you can see why its something worth mentioning... However I will give them the benefit of the doubt in the late game at least, Objectives are clearly marked with distance once you start getting into the state where "Cycles" begin and clones of your character "En" start emerging from the ground like little spawns of satan scaring the life out of you until you realise that its starting to mimic some kind of humanoid form . Instead of the game feeling like you're being challenged like you'd expect from a Puzzle game that incorporates stealth you find yourself playing a elongated game of Tug-Of-War with the AI and the game, trying to avoid actions that you wouldn't want to be used on you, the immediate regret of having to use your stupidly over-powered energy weapon that'll kill as many Echos are you're able to line up (Yes however many you manage to line up). You'll find yourself running and hiding behind obstacles that you've seen time and time again, the modular asset design and level design may have boded well during development and seemed like an amazing idea to cut down on development time but has only come back to bite the user and for that fact the game in the backside and hinder what could've been an enjoyable experience. Speaking of Hiding being overly used modular environment assets, the only way to actually hide from any of the Echos is to run and find the nearest and suitable large chunk of Gold Covered Marble, may that be the stair case you saw thirty minutes ago twenty plus times or that giant pillar you've seen in the hallways and Ball Room looking puzzle section you've seen countless times.. I found myself laughing at the limitless ways to give being giant marble structures instead of the game having suitable "Stealth Like Components" such as Snake's cardboard box or Ezio Auditore da Firenze's hay stack; Maybe even the countless amounts of game that incorporate lockers that you can hide in (Wouldn't that be a fantastic idea). Don't get me wrong and be mislead by what I'm saying, ULTRA ULTRA and for that matter ECHO does try and guide you through some sort of half baked tutorial on stealth, a guide to hiding behind marble I guess you could call it.... But to be completely frank, its better if you just ignore it and ignore the stealth for that matter if you're looking for an experience that is heavily grounded on amazing voice acting and story telling, yes that's actually something to take note of in the game... Entrapped by the incredible back story, the voice acting... Story telling second to "The Last Of Us", maybe I'm being just a tad generous there; Overall the story experience is amazing but it surely isn't something to be compared to "The Last Of Of Us" or for that matter anything created by Naughty Dog... In the end what makes the game enjoyable isn't the capabilities of the stealth mechanics but the Story Telling, Voice acting and amazing Design; Modular or not you cannot help but admire the textures and shaders, the sheer effort and love put into something. Coming from a development background in both Game Design and Programming, I can't help but feel like the games I have worked on myself have received this same Criticism to somewhat of the same degree.. But when you're left with something Thoughtful and Creative to work on, something that'll help you make your next game; May that be a second echo or something entirely different they've already got story telling down to something that is enjoyable.. Its a shame that Echo was let down by what I can only describe as a Half Baked stealth system and a game of tug-of-war against a system that would like to see you fail (I mean that's the point).. In the end I did get Echo refunded after playing for a couple of hours, enough to get the general gist of the game and have a decent idea of the games background. Side Note: Feel free to private message me here with feedback on the review as well as telling me if you'd like to see more of these by reacting/liking the topic and leaving a thoughtful reply.
  2. Please ignore the "My Multimart" section of the site, all functions/systems related to this are in heavy development and you'll be unable to access them out-right until each system is completed.

  3. We'd still love to hear what you have to say.
  4. Is SA-MP even worth spending time on?

    Frankly SA-MP is dead in the water... Its about time people realised this, Kalcor may still be updating it however this does not mean it'll continue to live; You see this with the lack of new features/fixes that are mandatory for it to continue to strive like it was doing back in 2012/2009... Just because "NGG" closed does not mean its not worth making a community, in fact quite the opposite, NGG was the pinnacle of Toxic, Abusive and Pathetic community standards; Why anyone carried on playing SA-MP on a server they cobbled together from an open source script and snippets on the SA-MP Forums in the beginning still baffles me to this very day.
  5. I like the idea, but I personally would like to still incorporate a Subscription based system.. This being personal opinion, however maybe the idea you've had can still hold some weight... Maybe a single monthly payment that'll help with the costs, something in a fair price range along side a donation system that'll purely act as a way for a member of the community to contribute to the running costs but not at a monthly rate.
  6. This thread has been created at the request of the community to discuss the current time changes that will be put into place at the end of the calendar month. Feel free to discuss anything that you may be thinking about the changes stated in the thread / threads posted below; And a member of the staff team will respond accordingly.. Consider this a Multimart AMA. https://www.multimart.org/topic/1766-09102017-donations-upgrades-gje9b/
  7. You may have noticed that as of recently, I have taken over a lot of the Internal Multimart Service on behalf of @Husky.. This is due to Husky having little time to dedicate (fully, Might I add) to Multimart, rest-assured this does not mean he's forgotten or given up about/with Multimart.. This is why I have gone from Moderating Multimart's Content to maintaining the Servers and Forum Security, this is why you may have noticed my lack of activity when it comes to posting as of recently... Anyhow, to the matter at hand, when WE changed over to IP.Board at an independent cost to us, we originally asked for help for the total cost of converting to a more stable, maintained and security determined Forum System with a larger development community and more features that are better suited for us without myself having to spend hours of my times developing systems/features that only need to be updated for every minor release prior to usupdating... We are still looking for Community Funding, for theseimprovements; As Multimart has withheld implementing main-stream advertisements on the site, such as those found on Facebook, Twitter and so on; This will no longer be the case as we'll be implementing them at the end of the month to help with maintaining server costs. With this change we will also be implementing a new "Subscription" based Donation system, allowing for a tiered system.. We do not plan on having hundreds of "tiers" however we do plan on having enough to warrant them.. This will allow users some of the following abilities. Rest- assured all tiers will have the ability to disable/hide Advertisements on the site, this however will be limited to our Mainstream Advertisements and no those shown on Community Threads (every 15 posts or so)... Further more, we would like to request help from the community to assist with some Upgrades that'll allow us to maintain Multimart, this'll also allow us to implement a few new features to Multimart including Downloads (YAAAAY) but as we've already got IP.Board we will only require $300 this includes the renewal fee for our existing Support and maintenance provided by Invision Software. Anyway onto the benefits of Subscribing to a package (billed monthly) as I promised I would detail. Please be aware that this is purely an outline of our plans for our Tier based Subscriptions, as such are not set in stone and will possibly change once implemented. Now some of you may have questions regarding how existing "VIP" Members will be effected, I would like to personally assure you that you will receive a free two (2) to three (3) month subscription based on the amount you've assisted Multimart with maintaining our services. Best Regards, Austin "TheOnlyDroid"
  8. [ENG] Countryside Roleplay [Heavy RP]

    @Shplink Is this just another South Central Script Change?
  9. jurgenk - scam

    @jurgenk You have 24 Hours to reply to the topic or face having the right to post content on Multimart Removed.
  10. @Rida - You have twenty four hours to respond.
  11. BizzyD - ignorance

    @BizzyD You have twenty four hours to respond.
  12. Back to CS and I'm dominating again  :x


  13. The Talk Topic - Moe's Tavern

    Approved...... To Note, I've known KyleSmith for a long time, back when he was developing semi-decent RP scripts and he always came off as a stuck up prick, his vlogs just proved it.
  14. Hello Multimart Community, I'd like to inform everyone of a few changes that will slowly be put into place regarding how Community Complaints will be handled, this is infront of our Custom Complaints system being developed and tested ready for functional use on the Forum... These changes may or may not effect Community Complaints massively from a Member Prospective, however from a Staffing Prospective we deemed is necessary to Moderate Post Replies, what this means is the following. Creation Of Threads will remain unchanged and no moderation will be required. Creation of comments/posts will now be moderated this will prevent "thread spam" from people who are not involved in the complain at all Old thread will now be archived after two weeks, after this period only staff(and maybe thread creators) will be able to view the complaint Unrelated replies will be soft-deleted meaning only staff can view the response, this is in case someone approves a reply that doesn't concern the poster Furthermore, on the topic of the Custom Complaints system that will be developed in due time... Here's a brief over-view on how it'll function. Creation Of Reports Members of the community will be able to freely create reports on other members of the community along with reasoning behind it, our goal is to "improve" the current reporting system provided by Invision Power (IP) allowing us to filter reports to specific reasons. Responses Once you've created a report on a specific user.. You and the reported person only with staff will only be able to reply to that report, unless a staff member adds another member of the community to the report for a specified reason, kind of how Personal Messages currently work with IP.Board allowing you to invite people to the conversation. Viewing Reports Once a report has been closed and marked accordingly by a member of the Staff Team at Multimart anyone in the community will be able to view it along with any attachments (this is the idea, we may restrict this to staff once an out-come has been assigned), this will also free up space when it comes to On-Going reports and reducing the clutter... Anyone who visits the Community Complaint system will be able to view the on-going reports but only Who's involved (staff not included) along with how many replies the Report has gotten from both the Reporter and Reportee as well as any staff Replies. So why is this system needed? Its been a long time coming with allot of planning on my end, as-well-as allot of research into how IP.Board functions when it comes to the current released version... I have allot of experience with the older version of IP.Board how-ever as with any "software" for the internet its internal code changes a lot during development, from version to version and security update to security update.. A lot of this research was to ensure that I personally understood how Other developers and IP.Board Staff/Developers handled internal security and coding practices to allow for the most secure "Addon" to Multimart Possible without opening up too many loop holes into the system (hopefully none)... Best Regards, Austin "TheOnlyDroid"
  15. This article talks about some key factors to consider when designing a plugin system in C++, and also provides some practical examples of how we’ve addressed these issues in our own code. There’s a lot to cover here, such as binary compatibility, strict API versioning, and interprocess memory management. Sounds like fun right? Well, if you get it wrong then it sure as hell won’t be, sometime in the near future you’ll most likely have a suicide inducing customer support nightmare on your hands, but if you get it right then it’s really not so bad. If you’re looking for the code, we’ve released it as an open source LibSourcey module called Pluga on Github. ABI and Binary Compatibility The first thing to consider when designing your Plugin API is ABI compatibility. Unlike dynamically scripted languages, C++ demands that any shared libraries loaded by the runtime are binary compatible, otherwise all hell breaks loose. Essentially, this means that both the application and plugins must be compiled using the exactly the same development environment. If you can, try and stick to this one simple rule: only pass POD (plain old data) data types across process boundaries. By sticking to POD types the binaries will have no interdependent shared libraries, and you can avoid binary compatibility issues altogether. The tradeoff is that standard libraries differ from compiler to compiler, platform to platform, even version to version, so they should always be deemed to be binary incompatible. This means that unless you want to force clients to use exactly the same OS, compiler and third party dependencies as you when buildng plugins for your application, then you’ll need to avoid using STL containers or other complex types in your Plugin API. “But this is C++!?”, you cry in anguish, and unless you’re rockin’ a mullet with a stubbie cooler then who could blame you? Unfortunately that’s just the way it is, so in this case all we can do is bite our collective upper lip and move on. There are alternatives, such as embedding the standard libraries in your project using STLport or similar to ensure consistency between platforms, but why bother? It seems like overkill, wouldn’t it be easier to just to pass a void* or a char* buffer and encode/decode it as required across the process boundary? The method we’ve been using recently is actually quite simple. The plugin implements a onCommand method which accepts arbitrary commands from the application. The advantage of using this type of interface is that you’re able to implement almost any kind of functionality without having to add new methods and break the API each time you roll out a new feature. Obviously it doesn’t have it be this simple, but you get the idea! Command nodes (see code below) are namespaced using a REST style interface like so resource:action, and the data buffer contains either a JSON encoded message which for representing and converting to an STL container such a std::vector or std::map to pass to the internal API, or it may just be a raw data buffer that can be used directly. Take, for example, the following code: bool onCommand(const char* node, const char* data, unsigned int size) { try { // Handle a JSON encoded options hash if (strcmp(node, "options:set") == 0) { json::Value root; json::Reader reader; if (!reader.parse(data, size, root)) throw std::runtime_error("Invalid JSON format: " + reader.getFormatedErrorMessages()); // Do something with JSON data here... } // Handle raw file data else if (strcmp(node, "file:write") == 0) { std::string path("test.bin"); std::ofstream ofs(path, std::ios::out|std::ios::binary); if (!ofs.is_open()) throw std::runtime_error("Cannot write to output file: " + path); ofs.write(data, size); ofs.close(); } // Handle unknown commands else throw std::runtime_error("Unknown command"); } catch (std::exception& exc) { // Catch exceptions here and return false. // You could set a lastError string here which is exposed to // the application that returns the error message as a char*. // See the full example for details. std::cerr << "Command error: " << exc.what() << std::endl; return false; } return true; } Interprocess Memory Handling One other simple rule that will save you no small amount of frustration later on down the track is: any memory allocated by a process should be deallocated by the same process. Let’s say the application asks the plugin to allocate and return a char* buffer, and then proceeds to delete the buffer when it’s done with it. Honk! Big no no, you’re just asking for a crash. This is good: bool askPluginForSomeSugar(Plugin* plugin) { // allocate buffer of some sort char* data = plugin->gimmeSomeSugarBaby(); // do something cool with data // hand the pointer back to the plugin to be deallocated plugin->putSugarBackInTheBowl(data); } This is bad: bool askPluginForSomeSugar(Plugin* plugin) { // allocate buffer of some sort char* data = plugin->gimmeSomeSugarBaby(); // do something cool with data // don't manage memory data allocated by the other process! delete[] data; } Plugin System API The Pluga plugin system API consists of a single header file that defines a set of macros which export a PluginDetails structure. The PluginDetails structure exposes basic plugin information, a compile time API version, and a static initialiser function to the main application on runtime. By having an intermediary PluginDetails structure that’s loaded on runtime before the plugin is instantiated, we can do things like sanity check the API version, and print information about the plugin. Note that the system API also forward declares the IPlugin type, which must be defined externally in your own code. See the Plugin API for more information about that. // // LibSourcey // Copyright (C) 2005, Sourcey <http://sourcey.com> // // LibSourcey is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // LibSourcey is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. // #ifndef SCY_Pluga_H #define SCY_Pluga_H #include "scy/base.h" namespace scy { namespace pluga { // Forward declare the plugin class which must be defined externally. class IPlugin; // Define the API version. // This value is incremented whenever there are ABI breaking changes. #define SCY_PLUGIN_API_VERSION 1 #ifdef WIN32 # define SCY_PLUGIN_EXPORT __declspec(dllexport) #else # define SCY_PLUGIN_EXPORT // empty #endif // Define a type for the static function pointer. SCY_EXTERN typedef IPlugin* (*GetPluginFunc)(); // Plugin details structure that's exposed to the application. struct PluginDetails { int apiVersion; const char* fileName; const char* className; const char* pluginName; const char* pluginVersion; GetPluginFunc initializeFunc; }; #define SCY_STANDARD_PLUGIN_STUFF \ SCY_PLUGIN_API_VERSION, \ __FILE__ #define SCY_PLUGIN(classType, pluginName, pluginVersion) \ extern "C" { \ SCY_PLUGIN_EXPORT scy::pluga::IPlugin* getPlugin() \ { \ static classType singleton; \ return &singleton; \ } \ SCY_PLUGIN_EXPORT scy::pluga::PluginDetails exports = \ { \ SCY_STANDARD_PLUGIN_STUFF, \ #classType, \ pluginName, \ pluginVersion, \ getPlugin, \ }; \ } } } // namespace scy::pluga #endif // SCY_Pluga_H Plugin API The plugin API defines the IPlugin class that’s forward declared in the Plugin System APIheader. The IPlugin class is the interface that the application uses to interact with the plugin, and as such it’s also the virtual base class that’s extended from when implementing plugins. Below is a bare-bones example that only implements a single onCommand method: // testpluginapi.h #ifndef SCY_TestPluginAPI_H #define SCY_TestPluginAPI_H #include "scy/pluga/pluga.h" namespace scy { namespace pluga { class IPlugin // Virtual plugin interface. { public: IPlugin() {}; virtual ~IPlugin() {}; virtual bool onCommand(const char* node, const char* data, unsigned int size) = 0; // Handles a command from the application. }; } } // namespace scy::pluga #endif Implementing Plugins Plugin implementations extend from the Plugin API interface to implement plugin functionality. // testplugin.h #ifndef SCY_TestPlugin_H #define SCY_TestPlugin_H #include "testpluginapi.h" class TestPlugin: public scy::pluga::IPlugin // Test plugin implementation. { public: TestPlugin(); virtual ~TestPlugin(); virtual bool onCommand(const char* node, const char* data, unsigned int size); // Handles a command from the application. }; #endif // testplugin.cpp #include "testplugin.h" #include <iostream> SCY_PLUGIN(TestPlugin, "Test Plugin", "0.1.1") TestPlugin::TestPlugin() { std::cout << "TestPlugin: Create" << std::endl; } TestPlugin::~TestPlugin() { std::cout << "TestPlugin: Destroy" << std::endl; } bool TestPlugin::onCommand(const char* node, const char* data, unsigned int size) { std::cout << "TestPlugin: Command: " << node << ": " << data << std::endl; // Process commands as required return true; } A Simple Application The following is a totally minimal example application that shows how to use the LibSourcey SharedLibrary class to load the plugin shared library, instantiate the IPlugin, call it’s methods, and destroy it. #include "scy/pluga/pluga.h" #include "scy/sharedlibrary.h" #include "testpluginapi.h" #include <iostream> #include <assert.h> using namespace scy; int main(int argc, char** argv) { // Set the plugin shared library location std::string path(SCY_INSTALL_PREFIX); path += "/bin/testplugin/testplugin"; #if WIN32 # ifdef _DEBUG path += "d.dll"; # else path += ".dll"; # endif #else path += ".so"; #endif try { // Load the shared library std::cout << "Loading: " << path << std::endl; SharedLibrary lib; lib.open(path); // Get plugin descriptor and exports pluga::PluginDetails* info; lib.sym("exports", reinterpret_cast<void**>(&info)); std::cout << "Plugin Info: " << "\n\tAPI Version: " << info->apiVersion << "\n\tFile Name: " << info->fileName << "\n\tClass Name: " << info->className << "\n\tPlugin Name: " << info->pluginName << "\n\tPlugin Version: " << info->pluginVersion << std::endl; // API Version checking if (info->apiVersion != SCY_PLUGIN_API_VERSION) throw std::runtime_error( util::format("Plugin ABI version mismatch. Expected %s, got %s.", SCY_PLUGIN_API_VERSION, info->apiVersion)); // Instantiate the plugin auto plugin = reinterpret_cast<pluga::IPlugin*>(info->initializeFunc()); // Call plugin methods assert(plugin->onCommand("some:command", "random:data", 11)); // Close the plugin and free memory std::cout << "Closing" << std::endl; lib.close(); } catch (std::exception& exc) { std::cerr << "Error: " << exc.what() << std::endl; assert(0); } return 0; } Installing Pluga For more detailed instructions and full working example see the Pluga insallation guide. All that’s requires is to build build LibSourcey with the Pluga module enabled. And there you have it, a super simple C++ plugin system that you can use in your own projects. Enjoy! Official Public Source: https://sourcey.com/building-a-simple-cpp-cross-platform-plugin-system/ Contributions Applied / Otherwise limited Liability.