Топ-3 сервера с модами в rust

Где лучше всего играть

В этой статье мы сделаем обозрение на три сервера, где играть, если можно так сказать, комфортнее всего. Комфортная игра с моей субъективной точки зрения – это пять минимальных условий:

  1. Лут, падающий из бочек, и находящийся в ящиках, десятикратно увеличен;
  2. Существует мгновенный крафт;
  3. Добыча полезных ископаемых увеличена в несколько раз;
  4. В одну клетку помещается не тысяча камней, а сто тысяч и т.д. Это называется увеличенными стаками;
  5. Ускорена выплавка ресурсов.

С этой точки зрения максимально удобными в моём случае являются три сервера.

3 место

BailisticRust. Молодой сервер. Будем надеяться, со временем получит большее развитие. Единственный недостаток – дисбаланс выплавки. На 4000 единицы серы появляется одна единица угля. То есть, уголь плавится в стандартном режиме. Двери открываются как на зеркальных шкафах, не «на» и не «от» себя, а вбок. С одной стороны, это очень удобно. Всё отвечает минимуму потребностей моего комфорта, есть плагин для разрушения построенных объектов и прочие прелести, присущие двум другим местам.

2 место

SkyRust. Целая линейка серверов. Есть соло, кланы. Тут лута выпадает поменьше из бочек, но всё же увеличено выпадение троекратно. Так же есть телепортации, ускорена выплавка, добыча, изменён лут, находящийся в ящике, который сбрасывает самолёт.

Проходимость очень большая. Дома стоят почти один на другом. Спрятаться или замаскироваться получится вряд ли, но зато есть экшен.

1 место

На первом месте – CrazyRust. Вайп на нём происходит раз в неделю, потому что там наблюдается огромная проходимость игроков. Средний онлайн – 30-40 человек стабильно. Там есть всё, о чем я говорил выше, описывая комфортный сервер и даже больше этого.

Есть плагин – разделитель. Он сам за вас посчитает, сколько дерева нужно положить в печь для выплавки всей руды, что в ней находится.

Он же разделит руду на три и более равные части, чтобы всё выплавилось максимально быстро.

Есть телепортация игроков друг к другу. Можно устанавливать точку телепортации в своём доме, чтобы быстро возвращаться домой, где бы вы ни находились. При этом обязательно, чтобы у вас не было никаких ранений и губительных воздействий типа холода, радиации или кровотечения.

Изюминка сервера, если можно так сказать, заключается в том, что некоторые компоненты периодически перестают выпадать из бочек и ящиков. Ну, нет их, и всё! Все недостающие части остаётся покупать только в магазине сервера за очки, которые начисляются спустя каждый час вашей игры и за убийства.

Loading a Plugin

Now we are ready to actually do some awesome stuff, loading the plugin into our app. To load the plugin we are going to use the crate. The crate will do the actual loading of the shared libraries and takes care of the lower level stuff so we don’t have to. Our first step, then, is to add that crate to the for our app.

Then update your app’s file to look like this:

There is a little bit going on here, but it is still fairly simple, thanks to the library. We create a struct that represents the functions that we can call in loaded plugins. We use to load our plugin shared library, and store it in . We can then call the function, and it will execute the function in our plugin. The function in our plugin should then call with a message that should be printed to the console.

Before we run it, lets create a directory in our app crate directory and copy our file into it from our plugin’s build directory. After that, go ahead and test it with :

It works! You should also be able to run it manually, but you will have to re-copy the libstd library back into the build directory because we ran a earlier:

Notice that Rust bundled the new dependencies of our app, such as the crate, into our ; it is now 534 kilobytes instead of the original 14 kilobytes. Apparently, even though it dynamically links , it decided to statically link the crate to . This is fine and is nice because we don’t need to have a shared library for every crate dependency. If we wanted to expose one of the crates that our app depends on to our plugins, we could do that simply by re-exporting the library in our app library ( this is yet to be tested ).

Create a Plugin

The next thing we are going to do is create our plugin crate. Go ahead and cd back to your project folder and create the plugin crate alongside the app crate and the move to the plugin dir.

For this crate we are going to make similar and changes that we make for our app to make it dynamically link all of its dependencies. The only difference in this case is that we don’t need need to set the to include in the file. Instead we set it to only:

Cargo.toml:

.cargo/config:

The reason the build is not needed for plugins is because we don’t plan on linking any other rust libraries to the plugin crate. The rlib build is only used when linking other rust libraries/binaries to this one. Granted, if you wanted to let your plugin have plugins, you would still want to build the , but we’re not going to take this that far here.

After that, we will add a function that will be called by our app to execute the plugin’s functionality. Eventually plugins will be able to do more than just but for now that is all we will do with it.

src/lib.rs:

Notice that we specify as an external crate; if we had added as a Cargo dependency, we could have done instead. Our run function is simple and just prints some output before calling the that we created in our app library. The attribute on the function tells the compiler not to add any extra metadata to that symbol in the compiled output, this allows us to call the function by name when we later load it into our app dynamically.

Attempting to the crate right now will tell us that it can’t find the crate. This is because we didn’t add it as a dependency to our file. Now, if we added the crate to the plugin’s dependencies, it would be able to compile, but it would also re-compile the app library, when we already have the app compiled. There is no reason to compile the app library twice, especially if it is a big app, so, instead, lets add the app library to our plugin’s search path so that it will find our already built crate.

To tell cargo how to find our app crate, we create a script. The script can be used to do any kind of setup necessary to compile a library. In our case we just need to feed cargo some specially understood flags that tell it where to find our pre-compiled library.

build.rs:

Now we can run and we will get a new file in our ( if it fails see note below ). As we intended, the plugin only contains the code that is in the plugin and weighs only 14 kilobytes. Yay, we have successfully built a plugin! Lets go over what happened when we built it.

When we run , cargo will first run our script and read the standard output of that script to look for cargo directives. In this case, our script tells cargo to look in the debug build dir of our app for libraries and to link to the library. When compiling our rust library, the compiler will read our app’s which contains all of the metadata needed to compile rust code that talks to that library, similar to C/C++ header files. After the rust code is compiled, it will call the system linker to link our plugin library, , to so that it can call functions defined in our app library.

Now that we have an app and a plugin, we need to make our app load the plugin!

Что делают моды в Rust

Они трансформируют игровой процесс в лучшую или худшую сторону. Кому-то интереснее собирать по несколько тысяч камней и потихоньку строить дом, а кто-то хочет два раза ударить киркой по камню, затем до следующего вайпа использовать добытый при этом строительный материал. Игроки бывают разные, поэтому и моды отвечают требованиям разных людей.

Мод может увеличивать скорость добычи полезных ископаемых. Вы, как уже было сказано, ударите по дереву топором и вырубите при этом не 10 единиц древесины, а несколько тысяч. Можно наоборот уменьшить добычу ресурсов и при ударе будет выходить только 5 единиц.

Кто-то любит хардкорное выживание, а кто-то хочет пострелять и порейдить. Есть моды, которые изначально выдают игрокам не камень и факел, а лук, стрелы, в общем-то, любой набор предметов.

Improving the Plugin API ( And Our App )

Now that we have basics of plugin loading, lets make our app do something. We’re going to setup a simple app that will infinitely prompt for a command, and respond to the user’s input. The only command that comes with the app will be the command that lets the user exit the program. Otherwise, all other commands will be provided by plugins.

Let’s get that loop going without plugins first:

src/lib.rs:

Now we can our app and get our own little command prompt.

Now we want to refine our plugin API a bit. Instead of using a function to execute our plugins, we are going to use an function which is expected to return a pointer to a struct that implements a trait. The trait will require that each plugin implement the function so that it can handle commands pass to the user.

Here is the full updated :

And our updated :

Now we can:

  • rebuild our app
  • rebuild our plugin
  • copy the newly built into our app’s directory, and
  • run our app to get our mini command prompt

Here is an example of the result:

We used our plugin to provide custom commands to our command prompt!

This is as far as this tutorial will take you and there is obviously a lot that could be improved. For one, you probably don’t want to be loading plugins by name and you are going to want to be able to have more than one. All of that is simple to implement on top of the base that we have worked on here and I leave it up to the reader to explore how to do that if they so desire.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector