diff --git a/apps/openmw/mwdialogue/keywordsearch.hpp b/apps/openmw/mwdialogue/keywordsearch.hpp
index 3b784cd59c..2c98eac218 100644
--- a/apps/openmw/mwdialogue/keywordsearch.hpp
+++ b/apps/openmw/mwdialogue/keywordsearch.hpp
@@ -87,7 +87,7 @@ namespace MWDialogue
                 // some keywords might be longer variations of other keywords, so we definitely need a list of
                 // candidates the first element in the pair is length of the match, i.e. depth from the first character
                 // on
-                std::vector<typename std::pair<int, typename Entry::childen_t::const_iterator>> candidates;
+                std::vector<typename std::pair<std::ptrdiff_t, typename Entry::childen_t::const_iterator>> candidates;
 
                 while ((j + 1) != end)
                 {
@@ -148,11 +148,11 @@ namespace MWDialogue
             // resolve overlapping keywords
             while (!matches.empty())
             {
-                int longestKeywordSize = 0;
+                std::size_t longestKeywordSize = 0;
                 typename std::vector<Match>::iterator longestKeyword = matches.begin();
                 for (typename std::vector<Match>::iterator it = matches.begin(); it != matches.end(); ++it)
                 {
-                    int size = it->mEnd - it->mBeg;
+                    std::size_t size = it->mEnd - it->mBeg;
                     if (size > longestKeywordSize)
                     {
                         longestKeywordSize = size;
@@ -199,7 +199,7 @@ namespace MWDialogue
 
         void seed_impl(std::string_view keyword, value_t value, size_t depth, Entry& entry)
         {
-            int ch = Misc::StringUtils::toLower(keyword.at(depth));
+            auto ch = Misc::StringUtils::toLower(keyword.at(depth));
 
             typename Entry::childen_t::iterator j = entry.mChildren.find(ch);
 
diff --git a/apps/openmw/mwstate/character.cpp b/apps/openmw/mwstate/character.cpp
index 9a3bc46742..a486ff4bec 100644
--- a/apps/openmw/mwstate/character.cpp
+++ b/apps/openmw/mwstate/character.cpp
@@ -132,9 +132,9 @@ const MWState::Slot* MWState::Character::createSlot(const ESM::SavedGame& profil
 
 void MWState::Character::deleteSlot(const Slot* slot)
 {
-    int index = slot - mSlots.data();
+    std::ptrdiff_t index = slot - mSlots.data();
 
-    if (index < 0 || index >= static_cast<int>(mSlots.size()))
+    if (index < 0 || static_cast<std::size_t>(index) >= mSlots.size())
     {
         // sanity check; not entirely reliable
         throw std::logic_error("slot not found");
@@ -147,9 +147,9 @@ void MWState::Character::deleteSlot(const Slot* slot)
 
 const MWState::Slot* MWState::Character::updateSlot(const Slot* slot, const ESM::SavedGame& profile)
 {
-    int index = slot - mSlots.data();
+    std::ptrdiff_t index = slot - mSlots.data();
 
-    if (index < 0 || index >= static_cast<int>(mSlots.size()))
+    if (index < 0 || static_cast<std::size_t>(index) >= mSlots.size())
     {
         // sanity check; not entirely reliable
         throw std::logic_error("slot not found");
diff --git a/apps/openmw_test_suite/openmw/options.cpp b/apps/openmw_test_suite/openmw/options.cpp
index fc89264f8c..fe319f64fa 100644
--- a/apps/openmw_test_suite/openmw/options.cpp
+++ b/apps/openmw_test_suite/openmw/options.cpp
@@ -36,7 +36,7 @@ namespace
         (result.emplace_back(makeString(args)), ...);
         for (int i = 1; i <= std::numeric_limits<char>::max(); ++i)
             if (i != '&' && i != '"' && i != ' ' && i != '\n')
-                result.push_back(std::string(1, i));
+                result.push_back(std::string(1, static_cast<char>(i)));
         return result;
     }
 
diff --git a/apps/openmw_test_suite/sqlite3/request.cpp b/apps/openmw_test_suite/sqlite3/request.cpp
index 23efe9dc2e..c299493952 100644
--- a/apps/openmw_test_suite/sqlite3/request.cpp
+++ b/apps/openmw_test_suite/sqlite3/request.cpp
@@ -151,7 +151,7 @@ namespace
         const std::int64_t value = 1099511627776;
         EXPECT_EQ(execute(*mDb, insert, value), 1);
         Statement select(*mDb, GetAll("ints"));
-        std::vector<std::tuple<int>> result;
+        std::vector<std::tuple<std::int64_t>> result;
         request(*mDb, select, std::back_inserter(result), std::numeric_limits<std::size_t>::max());
         EXPECT_THAT(result, ElementsAre(std::tuple(value)));
     }
@@ -205,7 +205,7 @@ namespace
         const std::int64_t value = 1099511627776;
         EXPECT_EQ(execute(*mDb, insert, value), 1);
         Statement select(*mDb, GetExact<std::int64_t>("ints"));
-        std::vector<std::tuple<int>> result;
+        std::vector<std::tuple<std::int64_t>> result;
         request(*mDb, select, std::back_inserter(result), std::numeric_limits<std::size_t>::max(), value);
         EXPECT_THAT(result, ElementsAre(std::tuple(value)));
     }
diff --git a/apps/openmw_test_suite/toutf8/toutf8.cpp b/apps/openmw_test_suite/toutf8/toutf8.cpp
index f189294cf2..9a259c69ab 100644
--- a/apps/openmw_test_suite/toutf8/toutf8.cpp
+++ b/apps/openmw_test_suite/toutf8/toutf8.cpp
@@ -47,7 +47,7 @@ namespace
     {
         std::string input;
         for (int c = 1; c <= std::numeric_limits<char>::max(); ++c)
-            input.push_back(c);
+            input.push_back(static_cast<char>(c));
         Utf8Encoder encoder(FromType::CP437);
         const std::string_view result = encoder.getUtf8(input);
         EXPECT_EQ(result.data(), input.data());
@@ -99,7 +99,7 @@ namespace
     {
         std::string input;
         for (int c = 1; c <= std::numeric_limits<char>::max(); ++c)
-            input.push_back(c);
+            input.push_back(static_cast<char>(c));
         Utf8Encoder encoder(FromType::CP437);
         const std::string_view result = encoder.getLegacyEnc(input);
         EXPECT_EQ(result.data(), input.data());
diff --git a/components/esm3/esmreader.cpp b/components/esm3/esmreader.cpp
index 92a04fb487..c52e739f5f 100644
--- a/components/esm3/esmreader.cpp
+++ b/components/esm3/esmreader.cpp
@@ -244,16 +244,16 @@ namespace ESM
         skipHString();
     }
 
-    void ESMReader::getHExact(void* p, int size)
+    void ESMReader::getHExact(void* p, std::size_t size)
     {
         getSubHeader();
-        if (size != static_cast<int>(mCtx.leftSub))
+        if (size != mCtx.leftSub)
             reportSubSizeMismatch(size, mCtx.leftSub);
         getExact(p, size);
     }
 
     // Read the given number of bytes from a named subrecord
-    void ESMReader::getHNExact(void* p, int size, NAME name)
+    void ESMReader::getHNExact(void* p, std::size_t size, NAME name)
     {
         getSubNameIs(name);
         getHExact(p, size);
@@ -326,10 +326,10 @@ namespace ESM
         skip(mCtx.leftSub);
     }
 
-    void ESMReader::skipHSubSize(int size)
+    void ESMReader::skipHSubSize(std::size_t size)
     {
         skipHSub();
-        if (static_cast<int>(mCtx.leftSub) != size)
+        if (mCtx.leftSub != size)
             reportSubSizeMismatch(mCtx.leftSub, size);
     }
 
diff --git a/components/esm3/esmreader.hpp b/components/esm3/esmreader.hpp
index 7d0b9b980c..b67cc0f8bb 100644
--- a/components/esm3/esmreader.hpp
+++ b/components/esm3/esmreader.hpp
@@ -238,10 +238,10 @@ namespace ESM
         void skipHRefId();
 
         // Read the given number of bytes from a subrecord
-        void getHExact(void* p, int size);
+        void getHExact(void* p, std::size_t size);
 
         // Read the given number of bytes from a named subrecord
-        void getHNExact(void* p, int size, NAME name);
+        void getHNExact(void* p, std::size_t size, NAME name);
 
         ESM::FormId getFormId(bool wide = false, NAME tag = "FRMR");
 
@@ -275,7 +275,7 @@ namespace ESM
         void skipHSub();
 
         // Skip sub record and check its size
-        void skipHSubSize(int size);
+        void skipHSubSize(std::size_t size);
 
         // Skip all subrecords until the given subrecord or no more subrecords remaining
         void skipHSubUntil(NAME name);
diff --git a/components/esm3/loadland.cpp b/components/esm3/loadland.cpp
index 98e07b530f..8b8a8f90fa 100644
--- a/components/esm3/loadland.cpp
+++ b/components/esm3/loadland.cpp
@@ -25,7 +25,7 @@ namespace ESM
 
         // Loads data and marks it as loaded. Return true if data is actually loaded from reader, false otherwise
         // including the case when data is already loaded.
-        bool condLoad(ESMReader& reader, int flags, int& targetFlags, int dataFlag, void* ptr, unsigned int size)
+        bool condLoad(ESMReader& reader, int flags, int& targetFlags, int dataFlag, void* ptr, std::size_t size)
         {
             if ((targetFlags & dataFlag) == 0 && (flags & dataFlag) != 0)
             {
@@ -206,7 +206,7 @@ namespace ESM
             mLandData = std::make_unique<LandData>();
 
         mLandData->mHeightOffset = 0;
-        std::fill(std::begin(mLandData->mHeights), std::end(mLandData->mHeights), 0);
+        std::fill(std::begin(mLandData->mHeights), std::end(mLandData->mHeights), 0.0f);
         mLandData->mMinHeight = 0;
         mLandData->mMaxHeight = 0;
         for (int i = 0; i < LAND_NUM_VERTS; ++i)
diff --git a/components/esm3/loadlevlist.cpp b/components/esm3/loadlevlist.cpp
index 627edbadce..f37009d6f9 100644
--- a/components/esm3/loadlevlist.cpp
+++ b/components/esm3/loadlevlist.cpp
@@ -87,7 +87,7 @@ namespace ESM
 
         esm.writeHNT("DATA", mFlags);
         esm.writeHNT("NNAM", mChanceNone);
-        esm.writeHNT<uint32_t>("INDX", mList.size());
+        esm.writeHNT("INDX", static_cast<uint32_t>(mList.size()));
 
         for (const auto& item : mList)
         {
diff --git a/components/esm3/loadscpt.cpp b/components/esm3/loadscpt.cpp
index 2eb272fe8b..ae56a7b4f4 100644
--- a/components/esm3/loadscpt.cpp
+++ b/components/esm3/loadscpt.cpp
@@ -150,7 +150,7 @@ namespace ESM
         if (!hasHeader)
             esm.fail("Missing SCHD subrecord");
         // Reported script data size is not always trustworthy, so override it with actual data size
-        mData.mScriptDataSize = mScriptData.size();
+        mData.mScriptDataSize = static_cast<uint32_t>(mScriptData.size());
     }
 
     void Script::save(ESMWriter& esm, bool isDeleted) const
diff --git a/components/esm4/reader.cpp b/components/esm4/reader.cpp
index 9811cf6103..2d9a929bb2 100644
--- a/components/esm4/reader.cpp
+++ b/components/esm4/reader.cpp
@@ -83,8 +83,8 @@ namespace ESM4
 
             stream.next_in = reinterpret_cast<Bytef*>(compressed.data());
             stream.next_out = reinterpret_cast<Bytef*>(decompressed.data());
-            stream.avail_in = compressed.size();
-            stream.avail_out = decompressed.size();
+            stream.avail_in = static_cast<uInt>(compressed.size());
+            stream.avail_out = static_cast<uInt>(decompressed.size());
 
             if (const int ec = inflateInit(&stream); ec != Z_OK)
                 return getError("inflateInit error", ec, stream.msg);
@@ -112,9 +112,9 @@ namespace ESM4
                 const auto prevTotalIn = stream.total_in;
                 const auto prevTotalOut = stream.total_out;
                 stream.next_in = reinterpret_cast<Bytef*>(compressed.data());
-                stream.avail_in = std::min(blockSize, compressed.size());
+                stream.avail_in = static_cast<uInt>(std::min(blockSize, compressed.size()));
                 stream.next_out = reinterpret_cast<Bytef*>(decompressed.data());
-                stream.avail_out = std::min(blockSize, decompressed.size());
+                stream.avail_out = static_cast<uInt>(std::min(blockSize, decompressed.size()));
                 const int ec = inflate(&stream, Z_NO_FLUSH);
                 if (ec == Z_STREAM_END)
                     break;