Skip to content

Releases: NullSablex/rust-samp

v3.0.0

17 May 20:42
a08348d

Choose a tag to compare

Compared to v2.2.0 (2026/03/15).

Headline: native Open Multiplayer component ABI implemented in pure
Rust (Itanium and MSVC); a single binary now works as a SA-MP
plugin and as a first-class Open Multiplayer component, with no extra
configuration.

Migrating from v2.x (or from the upstream samp-rs fork)

This release contains breaking changes. A plugin written against
v2.x will not compile against v3.0.0 without edits. Minimum diff:

Before (v2.x / upstream) After (v3.0.0)
fn process_tick(&mut self) { … } fn on_tick(&mut self, _ctx: TickContext) { … }
samp::plugin::enable_process_tick() samp::plugin::enable_tick() (or enable_tick_with(TickConfig))
samp::cell::string::put_in_buffer(buf, s)? buf.write_str(s)? / unsized.write_str(size, s)? (put_in_buffer is pub(crate) now)
samp::raw::functions::Logprintf (variadic) Same path, now extern "C" fn(*const i8) — the SDK formats in Rust and passes a single C string
example-hello/ / example-counter/ / plugin-example/ examples/hello/ / examples/counter/ / examples/advanced/

Open Multiplayer support comes turned on by default — the build
produces both the SA-MP exports and the ComponentEntryPoint. To
keep the v2.x behavior unchanged, enable the new samp-only feature:

samp = { git = "...", tag = "v3.0.0", features = ["samp-only"] }

Two new requirements that affect builds:

  • The workspace's [profile.release] adds lto = "thin",
    codegen-units = 1, strip = true. Override in your own
    Cargo.toml if you need otherwise.
  • The i686 target is now strictly required at compile time
    (OmpComponent has const _ layout asserts). Set
    target = "i686-unknown-linux-gnu" in .cargo/config.toml if you
    were relying on the host target picking up automatically.

The full step-by-step walkthrough lives in
docs/migration.md — including the new
TickConfig knobs (sa_mp_only(), omp_only(Duration), custom
omp_interval) and how to choose between them.

Crate versions

  • samp: 2.2.0 → 3.0.0
  • samp-sdk: 2.2.0 → 3.0.0
  • samp-codegen: 1.2.0 → 1.3.0

Breaking changes

  • SampPlugin::process_tick replaced by
    SampPlugin::on_tick(&mut self, ctx: TickContext) — unified
    callback that fires on both servers. Cadence is the server's main
    loop on SA-MP and the SDK-owned ITimersComponent timer on native
    Open Multiplayer (interval configurable). TickContext::source
    reports the origin (TickSource::SaMp /
    TickSource::OmpTimer); TickContext::elapsed is the
    wall-clock interval since the previous dispatch.
  • samp::plugin::enable_process_tick replaced by
    samp::plugin::enable_tick() (default config) and
    samp::plugin::enable_tick_with(config: TickConfig) (explicit
    per-server toggle + Open Multiplayer interval).
  • samp::cell::string::put_in_buffer is now pub(crate) (was
    pub). The public API for writing strings is Buffer::write_str
    and UnsizedBuffer::write_str.
  • samp_sdk::raw::functions::Logprintf signature changed from
    variadic extern "C" fn(*const i8, ...) to fixed-arity
    extern "C" fn(*const i8) — the SDK formats the message in Rust
    and passes a single C string, matching what logprintf("%s", msg)
    does at the ABI level.
  • Example crates renamed: example-hello/examples/hello/,
    example-counter/examples/counter/,
    plugin-example/examples/advanced/. Workspace members
    updated accordingly.

Added — native Open Multiplayer support

  • samp_sdk::omp — new top-level module with eight submodules:
    • componentOmpComponent, IComponentVTable,
      IUIDProviderVTable, opaque types (ICore, IComponentList,
      ILogger, IEarlyConfig), default vtable implementations for
      both ABIs.
    • component_apiOmpComponentHandle trait, generic
      component_name<T>() / component_version<T>() helpers.
    • coreLogLevel, core_print_ln, core_log_ln,
      core_print_ln_u8, core_log_ln_u8.
    • eventsPawnEventHandler, PawnEventHandlerVTable.
    • serverPAWN_COMPONENT_UID, NUM_AMX_FUNCS,
      PawnComponent, ServerComponentList, ServerComponent,
      ServerPawnComponent, IEventDispatcherPawn, IPawnScript,
      AmxFunctionTable, plus the free functions
      query_component, add_pawn_event_handler,
      remove_pawn_event_handler, get_pawn_event_dispatcher,
      get_amx_from_script, get_amx_functions.
    • timersTIMERS_COMPONENT_UID, TimersComponent,
      ITimersComponent, ITimer, TimerHandlerVTable,
      TimerTimeOutHandler, create_repeating_timer, kill_timer,
      query_timers_component.
    • typesUID, SemanticVersion (with new and
      with_prerel), StringView (with as_str, try_as_str,
      from_static), Colour (with rgb, rgba, from_rgba_u32,
      to_rgba_u32 and the WHITE, BLACK, NONE constants),
      Vector2, Vector3, Vector4, ComponentType.
    • vtablesubobject_ptr, vtable_slot,
      secondary_call_target helpers for safe access to secondary
      vtables.
  • samp::omp re-exports the module above.
  • samp::plugin new functions: enable_tick,
    enable_tick_with, omp_core, omp_query_component,
    omp_query::<T> (typed wrapper for OmpComponentHandle
    implementors).
  • samp::plugin new types: TickConfig, TickContext,
    TickSource.
  • SampPlugin new hooks: on_tick(ctx),
    on_omp_ready (gated by not(feature = "samp-only")),
    on_component_free (same gating).
  • samp::log re-export — #[native]-expanded code now uses
    samp::log::error!, so user crates no longer need to declare
    log as a direct dependency just to satisfy the macro.

Added — initialize_plugin! extensions

  • Optional metadata fields: uid: <u64 expression>,
    component_name: "...", component_version: (x, y, z).
  • samp-codegen reads [package.metadata.samp] from the project's
    Cargo.toml. Resolution order per field:
    macro argument > [package.metadata.samp] > derived value
    (CARGO_PKG_NAME, parsed CARGO_PKG_VERSION, FNV-1a 64 of
    CARGO_PKG_NAME@CARGO_PKG_VERSION for the UID).
  • When the UID is missing from both sources, the generated value is
    persisted back into Cargo.toml under [package.metadata.samp]
    so subsequent builds reuse the same identifier.
  • Generates the SA-MP exports (Load, Unload, Supports,
    AmxLoad, AmxUnload, ProcessTick) and the Open Multiplayer
    ComponentEntryPoint by default. Opt out with the samp-only
    feature.

Added — #[native] extensions

  • Accepts associated functions (no self), in addition to
    methods.
  • Return type detection: Result / AmxResult is matched against
    Ok/Err; any other type implementing AmxCell is used as the
    return cell directly (no spurious Ok(...) wrapping).
  • Accepts &AmxString (and any other &T) parameters — the macro
    materializes the owned value from args.next_arg() and injects
    &local at the call site.
  • Validates the name = "..." literal at proc-macro time:
    interior \0 bytes now produce a compile error instead of
    panicking at CString::new during server load.
  • Wraps every invocation in std::panic::catch_unwind. Panics that
    would otherwise cross the extern "C" boundary (process abort on
    Rust 1.71+) are caught, logged as
    [<NativeName>] panic in native: <payload>, and converted to a
    0 return.
  • Argument parsing failures now log
    [<NativeName>] failed to parse argument #<i> '<name>' (expected type: <Type>)
    — both the positional index and the expected type are included.

Added — features and build infrastructure

  • New samp-only feature on both samp and samp-sdk: removes
    every Open Multiplayer code path. The plugin still loads on Open
    Multiplayer, but in legacy mode (no component API).
  • New workspace [profile.release]: lto = "thin",
    codegen-units = 1, strip = true.
  • Cargo.lock is now committed (removed from .gitignore).
  • Cargo.toml per crate exposes
    package.metadata.docs.rs.default-target = "i686-pc-windows-msvc"
    • features = ["encoding"] so docs.rs builds with the right
      target.
  • New build scripts:
    • scripts/build-linux.sh — produces .so
      (i686-unknown-linux-gnu) and .dll
      (i686-pc-windows-msvc via cargo-xwin --xwin-arch x86, or
      i686-pc-windows-gnu with --samp-only).
    • scripts/build-windows.sh — produces .dll natively and .so
      through WSL or Docker/cross (autodetected; forceable with
      --wsl / --docker).
  • New helper scripts used by the benchmark workflow:
    scripts/append-bench-history.py, scripts/extract-bench.py,
    scripts/render-bench-entry.py.
  • New GitHub workflows: docs.yml (publishes the MkDocs site),
    release.yml (creates releases on v* tags, attaches a source
    tarball with only the essential crates), release-drafter.yml,
    labels.yml, bench-release.yml (per-release benchmark history
    on the bench-data branch).
  • .github/labels.yml and .github/release-drafter.yml for the
    workflows above.
  • rust.yml workflow: action versions bumped to
    actions/checkout@v6, actions/upload-artifact@v7,
    actions/cache/restore@v5, actions/cache/save@v5 (Node 24
    baseline); benchmark job restricted to -p samp-sdk to avoid
    Unrecognized option: 'save-baseline'; artefact retention now
    capped at 14 days.

Added — tests and benchmarks

  • Unit tests grew from 80 (v2.2.0) to 207 (this release) — +127
    tests
    .
  • New per-module test files:
    • samp-sdk/src/tests/amx_cell.rs (10 tests).
    • samp-sdk/src/tests/amx_string.rs (8 tests).
    • samp-sdk/src/tests/buffer.rs (12 tes...
Read more

v2.2.0

15 Mar 00:36
cf07ec0

Choose a tag to compare

Aviso:

A versão 2.1.0 não havia sido declarada anteriormente, então como uma compensação e correção estou trazendo a v2.2.0 com novas adições e melhorias de código. Desde já peço desculpas.

What's Changed

Full Changelog: v2.1.0...v2.2.0

v2.1.0

23 Feb 04:10
2f04c37

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: https://github.com/NullSablex/rust-samp/commits/v2.1.0

v1.0.1

19 Feb 01:03
75b8962

Choose a tag to compare

What's Changed

Full Changelog: https://github.com/NullSablex/rust-samp/commits/v1.0.1

v1.0.0

19 Feb 00:55
a50723d

Choose a tag to compare