This guide explains the key changes in Concord 3.0.0 and provides instructions for migrating from earlier versions.
Voice connection functionality has been completely removed from Concord 3.0.0.
Old behavior:
// Previously, you could enable voice connection like this
discord_voice_join(client, guild_id, channel_id);New behavior:
// Voice connections are no longer supported natively
// Use CogLink instead: https://github.com/PerformanC/CogLinkFor applications that require voice connections, we recommend using CogLink, which is a separate project providing a LavaLink client designed to work with Concord.
The configuration format has been significantly restructured in 3.0.0.
Old format:
{
"logging": { // logging directives
"level": "trace", // trace, debug, info, warn, error, fatal
"filename": "bot.log", // the log output file
"quiet": false, // change to true to disable logs in console
"overwrite": true, // overwrite file if already exists, append otherwise
"use_color": true, // display color for log entries
"http": {
"enable": true, // generate http specific logging
"filename": "http.log" // the HTTP log output file
},
"disable_modules": ["WEBSOCKETS", "USER_AGENT"] // disable logging for these modules
},
"discord": { // discord directives
"token": "YOUR-BOT-TOKEN", // replace with your bot token
"default_prefix": {
"enable": false, // enable default command prefix
"prefix": "YOUR-COMMANDS-PREFIX" // replace with your prefix
}
}
}New format:
{
"token": "YOUR-BOT-TOKEN", // replace with your bot token
"log": { // logging directives
"level": "TRACE", // TRACE, DEBUG, INFO, WARN, ERROR, FATAL
"trace": "bot.log", // the log output file (null to disable)
"quiet": false, // true to disable logs in console
"overwrite": true, // true overwrites the file on each run
"color": true, // display color on console
"http": "http.log", // the HTTP log output file (null to disable)
"ws": "ws.log", // the WebSockets log output file (null to disable)
"disable": ["WEBSOCKETS", "HTTP"] // disable logging for specific modules
}
}Key differences:
- Bot token moved from
discord.tokento top-leveltoken - Default prefix configuration (
discord.default_prefix) removed loggingrenamed tolog- Log levels are now in UPPERCASE
filenamerenamed totraceuse_colorrenamed tocolorhttp.enableandhttp.filenamesimplified to justhttp- New
wsoption for WebSockets logging disable_modulesrenamed todisable
For more detailed information about the new configuration format, see config.json directives guide.
The logging system has been transitioned from the old log library to the new logmod library.
Old behavior:
#include <concord/log.h>
// Old logging approach
log_info("Starting bot...");New behavior:
#include <concord/logmod.h>
// New logging approach
logmod_log(INFO, NULL, "Starting bot...");The gencodecs preprocessor pipeline has been replaced by
Reflect-C reflection. The
per-type JSON codec functions are gone; a single set of generic macros
replaces them, and they now require your struct discord * client (the
codecs run through the client's reflection registry).
Old behavior:
struct discord_user user = { 0 };
// returned a jsmn-style count, > 0 on success
if (discord_user_from_json(json, len, &user) > 0) {
printf("%s\n", user.username);
}
discord_user_cleanup(&user);
char *buf = NULL; size_t size = 0;
discord_create_message_to_json(&buf, &size, ¶ms);New behavior:
struct discord_user user = { 0 };
// returns a CCORDcode, CCORD_OK (0) on success
if (CCORD_OK == discord_data_from_json(struct discord_user, client,
json, len, &user)) {
printf("%s\n", user.username);
}
discord_data_cleanup(client, &user);
char *buf = NULL; size_t size = 0;
discord_data_to_json(struct discord_create_message, client, ¶ms,
&buf, &size);
discord_data_unwrap(client, ¶ms); /* see ownership notes below */Key differences:
discord_T_from_json(...)→discord_data_from_json(struct T, client, ...)discord_T_to_json(buf, size, data)→discord_data_to_json(struct T, client, data, buf, size)(argument order: data first, buffer last)discord_T_cleanup(&data)→discord_data_cleanup(client, &data)- Return value semantics inverted:
from_jsonused to return a positive count on success; it now returns aCCORDcodewhere success isCCORD_OK(zero). Code testing the old return with> 0or truthiness must be updated. - A
struct discord *client is now required for every codec call.
Ownership notes:
discord_data_cleanup()keeps the old_cleanupcontract: every non-NULLpointer member is owned and freed. Never call it on hand-built structs pointing at string literals or stack objects.- New requirement: after
discord_data_to_json()of a struct you own (e.g. stack-built params), calldiscord_data_unwrap(client, ¶ms)once done. Encoding caches a reflection wrap keyed by the struct's address; unwrap releases it without touching your data. Decoded structs don't need this —discord_data_cleanup()releases both the data and the wrap.
Behavioral fixes that come with the new codecs (no code changes needed, but previously-broken fields now work):
discord_channel.voice_quality_modenow decodes (the wire key isvideo_quality_mode; it never populated before)discord_role_tag.premium_subscribenow serializes under its real wire keypremium_subscriber
The client constructors have been renamed; compatibility macros keep old source code compiling, but new code should use the new names.
Old behavior:
struct discord *client = discord_init(TOKEN);
struct discord *client = discord_config_init("config.json");New behavior:
struct discord *client = discord_from_token(TOKEN);
struct discord *client = discord_from_json("config.json");
// new: programmatic configuration, no config file needed
struct discord *client = discord_from_config(&(struct discord_config){
.token = TOKEN,
});discord_init and discord_config_init remain as #define aliases, so
existing code recompiles — but they are gone as symbols, which breaks
shared-library (libdiscord.so) users until recompiled.
Multi-client shutdown replaces the old global shutdown helpers:
| Old | New |
|---|---|
ccord_shutdown_async() |
discord_shutdown_all() (compat macro kept) |
ccord_shutting_down() |
discord_shutdown_all_ongoing() (no compat macro) |
discord_dup_shutdown_fd() |
ccord_notifier_* API in <concord/concord-notifier.h> |
The discord_embed_* builder helpers (discord_embed_set_title(),
discord_embed_set_description(), discord_embed_set_footer(),
discord_embed_set_image(), discord_embed_add_field(), etc.) have
been removed. Populate the embed structures directly instead:
Old behavior:
struct discord_embed embed = { .color = 3447003 };
discord_embed_set_title(&embed, "Title");
discord_embed_add_field(&embed, "Field", "Value", true);New behavior:
struct discord_embed embed = {
.color = 3447003,
.title = "Title",
.fields = &(struct discord_embed_fields){
.size = 1,
.array = &(struct discord_embed_field){
.name = "Field", .value = "Value", .Inline = true,
},
},
};Designated initializers with compound literals (as the examples in
examples/embed.c show) replace the dynamic builders; nothing is
heap-allocated, so there is nothing to free afterwards.
Function wrappers that were already deprecated in v2 (or wrapped endpoints Discord has removed) are gone:
| Removed | Use instead |
|---|---|
discord_set_presence() |
discord_update_presence() |
discord_modify_current_user_nick() |
discord_modify_current_member() |
discord_set_on_wakeup() / discord_set_next_wakeup() |
the discord_timer() / discord_timer_interval() API |
discord_list_active_threads() |
removed (Discord dropped the endpoint) |
discord_return_error() |
return CCORDcode values; see discord_strerror() / discord_code_as_string() |
discord_get_logconf() |
discord_get_logmod() (returns the new logmod handle) |
In v2, several misuse paths (invalid parameters, allocation failures)
called abort(). These now return CCORDcode errors instead — check
return values where you previously relied on the library crashing loudly.
Codecs are generated at build time through the reflect-c git
submodule into the untracked generated/ directory.
Old behavior:
git clone https://github.com/Cogmasters/concord.git
cd concord && makeNew behavior:
git clone --recurse-submodules https://github.com/Cogmasters/concord.git
cd concord && make
# or, for an existing clone:
git submodule update --init reflect-cThe top-level make initializes the submodule and regenerates codecs
automatically; make reflectc-gen regenerates them explicitly. When
cross-compiling, the generator tools must run on the host:
make reflectc-gen HOSTCC=gcc
make CC=aarch64-linux-gnu-gcc(replacing the old cd gencodecs && make HOSTCC=... CC=... flow)
Concord 3.0.0 now requires libcurl 8.7.1 or higher compiled with WebSockets support.
Old requirement:
Any libcurl version was generally acceptable
New requirement:
libcurl 8.7.1 or higher WITH --enable-websockets flag
The voice target has been removed from the Makefile.
Old behavior:
# This would compile with voice support
make voiceNew behavior:
# Voice targets removed
# Regular build is now sufficient
makeA new PKGCONFIGDIR variable has been added to the Makefile for installing the concord.pc file.
Old behavior:
# No specific package config directory
make installNew behavior:
# Specify a custom package config directory
PKGCONFIGDIR=/usr/local/lib/pkgconfig make installFollow these steps to migrate your application to Concord 3.0.0:
-
Update dependencies:
# Compile libcurl with WebSockets support git clone https://github.com/curl/curl.git cd curl ./buildconf ./configure --enable-websockets --with-openssl make -j$(nproc) sudo make install
-
Update your code:
- Remove any voice-related functionality
- Replace all
loglibrary calls withlogmod - Update header includes from
<concord/log.h>to<concord/logmod.h> - Update your configuration file to the new format
- Replace per-type codec calls (
discord_T_from_json/_to_json/_cleanup) with thediscord_data_*macros, passing your client; checkfrom_jsonresults againstCCORD_OKinstead of> 0, and adddiscord_data_unwrap()after encoding structs you own
-
Rebuild your application:
# Fetch the reflect-c submodule (existing clones) git submodule update --init reflect-c # Rebuild with Concord 3.0.0 make clean make
If you're using VS Code, the include paths have been updated in c_cpp_properties.json:
Old paths:
"includePath": [
"${workspaceFolder}/**"
]New paths:
"includePath": [
"${workspaceFolder}/core",
"${workspaceFolder}/generated",
"${workspaceFolder}/reflect-c",
"${workspaceFolder}/include"
]- For voice functionality, see CogLink
- Refer to the updated README.md for complete build instructions
- Join our Discord server for additional support
If you encounter any issues during migration, please open an issue on the GitHub repository.